Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: examples/js/users-guide.md

Issue 839553004: Mojo JS Bindings: Update User's Guide, examples (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Running Mojo Applications 1 # Running Mojo Applications
2 2
3 A Mojo application written in JavaScript is launched with mojo_shell like this: 3 A Mojo application written in JavaScript is launched with mojo_shell like this:
4 4
5 ``` 5 ```
6 mojo_shell <js-application-url> 6 mojo_shell <js-application-url>
7 ``` 7 ```
8 8
9 Where js-application-url is a URL understood by the shell. For example 9 Where js-application-url is a URL understood by the shell. For example
10 a file or an http URL that names a JS source file. The JS file itself 10 a file or an http URL that names a JS source file. The JS file itself
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 The inherited Application class constructor initializes the shell and url 77 The inherited Application class constructor initializes the shell and url
78 properties. It's unlikely that you'll want to use the appShell argument 78 properties. It's unlikely that you'll want to use the appShell argument
79 directly. 79 directly.
80 80
81 The initialize() and acceptConnection() methods are defined by application.mojom 81 The initialize() and acceptConnection() methods are defined by application.mojom
82 and they're needed because the JS content handler makes the JS application the 82 and they're needed because the JS content handler makes the JS application the
83 Mojo shell's client. 83 Mojo shell's client.
84 84
85 The intiailize() method is called once, after the constructor has run 85 The intiailize() method is called once, after the constructor has run
86 and before any calls to acceptConnection(). The value of its parameter 86 and before any calls to acceptConnection(). The value of its parameter
87 is argument list specified for this application with 87 is the argument list specified for this application with
88 mojo_shell. Arguments can be specified using the mojo_shell 88 mojo_shell. Arguments can be specified using the mojo_shell
89 `--args-for` command line argument or by just adding them after the 89 `--args-for` command line argument or by just adding them after the
90 application's URL and enclosing the entire expression in quotes. 90 application's URL and enclosing the entire expression in quotes:
91 91
92 ``` 92 ```
93 mojo_shell '<js-application-url> arg1 arg2' 93 mojo_shell '<js-application-url> arg1 arg2'
94 ``` 94 ```
95 See the wget.js for an example of command-line argument use. 95 See the wget.js for an example of command-line argument use.
96 96
97 The acceptConnection() method is called each time another application connects 97 The acceptConnection() method is called each time another application connects
98 to this one. The first call corresponds the mojo_shell's initial connection. 98 to this one. The first call corresponds the mojo_shell's initial connection.
99 The serviceProvider parameter is a JS ServiceProvider, see the "Requesting 99 The serviceProvider parameter is a JS ServiceProvider, see the "Requesting
100 and Providing Services" section below. 100 and Providing Services" section below.
101 101
102 ## JS Bindings 102 # JS Bindings
103 103
104 To use or implement a service you'll need the JS "bindings" for the 104 The JS bindings map from incoming Mojo messages to JS values, and
105 Mojo interface. The bindings are generated by the build system and end 105 similarly from outgoing JS values to Mojo messages.
106
107 To use or implement a service you'll need the JS bindings for the
108 service's Mojo interface. The bindings are generated by the build system and end
106 up in files whose name is the same as the '.mojom' file with a '.js' 109 up in files whose name is the same as the '.mojom' file with a '.js'
107 suffix. It's often helpful to look at the generated '.mojom.js' files. 110 suffix. It's often helpful to look at the generated '.mojom.js' files.
108 111
109
110 The JS bindings for a Mojo interface's API are delivered as a JS module whose 112 The JS bindings for a Mojo interface's API are delivered as a JS module whose
111 name is based on the '.mojom' file's path. For example, to use the Mojo network 113 name is based on the '.mojom' file's path. For example, to use the Mojo network
112 service you need the JS module based on network_service.mojom: 114 service you need the JS module based on network_service.mojom:
113 115
114 ```javascript 116 ```javascript
115 define("main", [ 117 define("main", [
116 "mojo/services/network/public/interfaces/network_service.mojom", 118 "mojo/services/network/public/interfaces/network_service.mojom",
117 "mojo/services/public/js/application", 119 "mojo/services/public/js/application",
118 ] 120 ]
119 function(net, application) { 121 function(net, application) {
(...skipping 22 matching lines...) Expand all
142 name: 'mojo::NetworkService', // Fully qualified Mojo interface name. 144 name: 'mojo::NetworkService', // Fully qualified Mojo interface name.
143 proxyClass: NetworkServiceProxy, 145 proxyClass: NetworkServiceProxy,
144 stubClass: NetworkServiceStub, 146 stubClass: NetworkServiceStub,
145 // ... 147 // ...
146 }; 148 };
147 ``` 149 ```
148 150
149 The 'proxyClass' is used to access another application's NetworkService and the 151 The 'proxyClass' is used to access another application's NetworkService and the
150 'stubClass' is used to create an implementation of NetworkService. 152 'stubClass' is used to create an implementation of NetworkService.
151 153
152 ## The JS Shell Class 154 ## JS Bindings for Basic Types
153 155
154 The JS Shell class simplifies connecting to applications and services. It's a 156 In most cases the mapping from Mojo types to JS types is simple.
155 wrapper for the Application's appShell argument. The Application constructor
156 creates a Shell and assigns it to `this.shell`.
157 157
158 The Shell's connectToService() method returns a "proxy" to a service provided by 158 Mojo Type | JS Type
159 another application. 159 ------------- | -------------
160 bool | true or false
161 int8, uint8 | Number
162 int16, uint16 | Number
163 int32, uint32 | Number
164 int64, uint64 | Number*
165 float, double | Number
166 string | String
167 array | Array
168 map | Map
160 169
161 In the netService case above the Shell connects to the Mojo application at 170 The support for 64 bit integers is currently limited to 53 bits per
162 "mojo:network_service", then connects to its service called 171 the current JS standard. Only integer values in the range from
163 NetworkService.name with an instance of NetworkService.proxyClass. The proxy 172 ``Number.MIN_SAFE_INTEGER`` to ``Number.MAX_SAFE_INTEGER`` can be
164 instance is returned. The netService proxy can be used immediately. 173 represented exactly. Larger and smaller values are approximated by
174 double precision Numbers.
165 175
176 Unspecified bool parameter or struct field values default to false
177 unless an explicit Mojo default was specified.
178
179 Unspecified integer values similarly default to 0.
180
181 Unspecified nullable string, array, and map values similarly default to
182 null and can be specified as null. In Mojom a nullable type has a
183 ``?`` suffix.
184
185 ## JS Bindings for Structs
186
187 Mojo structs are mapped to JS objects. An eponymous class is generated for each
188 struct type. The struct class constructor has an object-valued parameter to make
189 it a little easier to specify a struct value. For example:
190
191 ```javascript
192 // Mojom definitions
193 struct Foo {
194 string? name;
195 array<int32>? values;
196 };
197
198 interface I {
199 PassFoo(Foo foo);
200 }
201
202 // JavaScript Usage, assuming we have a proxy for I, iProxy
203
204 // Rough and ready struct construction:
205 var foo = new Foo;
206 foo.name = "foo";
207 foo.values = [1,2,3];
208 iProxy.PassFoo(foo);
209
210 // Using the Foo constructor parameter:
211 iProxy.PassFoo(new Foo({name: "foo", values: [1,2,3]}));
212 iProxy.PassFoo(new Foo); // name, values are null
213 iProxy.PassFoo(new Foo({name: null}); // Same as previous line.
214 ```
215
216 An unspecified nullable struct parameter or struct field value defaults to
217 null.
218
219
220 ## JS Bindings for Interface Parameters
221
222 ## Stubs and Proxies
223
224 TODO: briefly introduce message pipes.
225 TODO: explain what stubs and proxies are, explain what's meant by "local" and "r emote".
226 TODO: explain the StubBindings and ProxyBindings functions.
227 TODO: support creating a proxy from a handle new MyProxy(someHandle);
228 TODO: explain the Connection object and how it relates to this stuff.
229
230 From a user's point of view, the bindings are in terms of the (remote)
231 proxy class and the (local) stub class. Properties are added to instances
232 of these classes using functions called StubBindings and ProxyBindings.
233
234 The caller and callee use cases that follow are in terms of the following mojom :
235
236 ```
237 [Client=Bar]
238 interface Foo {
239 }
240
241 [Client=Foo] // Redundant but always implicitly true.
242 interface Bar {
243 }
244
245 interface I {
246 provideFoo(Foo foo);
247 requestFoo(Foo& foo); // effectively: provideFoo(Bar bar)
248 }
249 ```
250
251 ## Callers
252
253 Assuming that we have a proxy for interface I, iProxy.
254
255 An iProxy.provideFoo() call implies that we have an implementation of
256 Foo, and want a proxy for Bar (Foo's client).
257
258 ```javascript
259 var barProxy;
260 iProxy.provideFoo(function(remote) {
261 barProxy = remote;
262 return myFooImpl;
263 });
264 ```
265
266 An iProxy.requestFoo() call implies that we have an implementation of
267 Bar and want a proxy for Foo (Bar's client).
268
269 ```javascript
270 var fooProxy;
271 iProxy.requestFoo(function(remote) {
272 fooProxy = remote;
273 return myBarImpl;
274 });
275 ```
276
277 In the requestFoo() case, if no client were defined for Bar the function
278 parameter need not return anything.
279
280 The wget.js example includes a request for the URLLoader service.
281
282 ## Callees
283
284 An implementation of provideFoo(Foo foo) implies that we have an
285 implementation of Bar (Foo's client) and want a proxy to the Foo
286 that has been passed to us.
287
288 ```javascript
289 void provideFoo(fooProxy) {
290 ProxyBindings(fooProxy).setLocalDelegate(myMyBarImpl);
291 }
292 ```
293
294 An implementation of requestFoo(Foo& foo) implies that we have an
295 implementation of Foo and want a proxy for the Bar (Foo's client)
296 that's been passed to us.
297
298 ```javascript
299 void requestFoo(barProxy) {
300 ProxyBindings(barProxy).setLocallocalDelegate(myFooImpl);
301 }
302 ```
166 303
167 ## Mojo Responses are Promises 304 ## Mojo Responses are Promises
168 305
169 Mojo functions can return zero or more values called a "response". For example 306 Mojo functions can return zero or more values called a "response". For example
170 the EchoString function below returns a string or null. 307 the EchoString function below returns a string or null.
171 308
172 ```javascript 309 ```javascript
173 interface EchoService { 310 interface EchoService {
174 EchoString(string? value) => (string? value); 311 EchoString(string? value) => (string? value);
175 }; 312 };
176 ``` 313 ```
177 314
178 The response is delivered to the function caller asynchronously. In C++ the 315 The response is delivered to the function caller asynchronously. In C++ the
179 caller provides a Callback object whose Run() method has one argument for 316 caller provides a Callback object whose Run() method has one argument for
180 each response parameter. In JS, Mojo functions that specify a response return 317 each response parameter. In JS, Mojo functions that specify a response return
181 a Promise object. The Promise resolves to an object with one property per 318 a Promise object. The Promise resolves to an object with one property per
182 response parameter. In the EchoString case that would be something like 319 response parameter. In the EchoString case that would be something like
183 `{value: "foo"}`. 320 `{value: "foo"}`.
184 321
185 Similarly, the implementation of a Mojo interface functions that specify a 322 Similarly, the implementation of a Mojo interface functions that specify a
186 response, must return a Promise. The implementation of EchoString() could 323 response, must return a Promise. The implementation of EchoString() could
187 be written like this: 324 be written like this:
188 325
189 ```javascript 326 ```javascript
190 MyEchoStringImpl.prototype.EchoString = function(s) { 327 MyEchoStringImpl.prototype.EchoString = function(s) {
191 return Promise.resolve({value: s}); 328 return Promise.resolve({value: s});
192 }; 329 };
193 ``` 330 ```
194 331
332 # The JS Shell Class
333
334 The JS Shell class simplifies connecting to applications and services. It's a
335 wrapper for the Application's appShell argument. The Application constructor
336 creates a Shell and assigns it to `this.shell`.
337
338 The Shell's connectToService() method returns a "proxy" to a service provided by
339 another application.
340
341 ```javascript
342 define("main", [
343 "mojo/services/network/public/interfaces/network_service.mojom",
344 "mojo/services/public/js/application",
345 ]
346 function(net, application) {
347 class MyApplication extends application.Application {
348 initialize(args) {
349 var netService = this.shell.connectToService(
350 "mojo:network_service", net.NetworkService);
351 // Use netService's NetworkService methods.
352 }
353 ...
354 }
355 ...
356 }
357 return MyApplication;
358 });
359 ```
360
361 In the netService case above the Shell connects to the Mojo application at
362 "mojo:network_service", then connects to its service called
363 NetworkService.name with an instance of NetworkService.proxyClass. The proxy
364 instance is returned. The netService proxy can be used immediately.
365
366 The wget.js example demonstrates using the network service.
367
195 ## Requesting and Providing Services 368 ## Requesting and Providing Services
196 369
197 Mojo applications can connect to services provided by other applications and 370 Mojo applications can connect to services provided by other applications and
198 they can provide services of their own. A service is an implementation of a Mojo 371 they can provide services of their own. A service is an implementation of a Mojo
199 interface that was defined as part of a Mojo module in a ".mojom" file. 372 interface that was defined as part of a Mojo module in a ".mojom" file.
200 373
201 When an application starts, its initialize() method runs and then its 374 When an application starts, its initialize() method runs and then its
202 acceptConnection() method runs. The acceptConnection() method 375 acceptConnection() method runs. The acceptConnection() method
203 indicates that another application has connected to this one and it 376 indicates that another application has connected to this one and it
204 always runs at least once. 377 always runs at least once.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 interface: 415 interface:
243 416
244 ```javascript 417 ```javascript
245 interface EchoService { 418 interface EchoService {
246 EchoString(string? value) => (string? value); 419 EchoString(string? value) => (string? value);
247 }; 420 };
248 ``` 421 ```
249 422
250 ### Requesting a Service Using the Application's Shell 423 ### Requesting a Service Using the Application's Shell
251 424
425 The Shell's `connectToService()` method returns a proxy to a Mojo
426 service provided by another application. The proxy can be used immediately.
427
252 Given the URL of a Mojo application that implements the EchoService we 428 Given the URL of a Mojo application that implements the EchoService we
253 can use the application's shell to get an EchoService proxy. Here's a 429 can use the application's shell to get an EchoService proxy. Here's a
254 complete application: 430 complete application:
255 431
256 ```javascript 432 ```javascript
257 #!mojo:js_content_handler 433 #!mojo:js_content_handler
258 434
259 define("main", [ 435 define("main", [
260 "console", 436 "console",
261 "mojo/services/public/js/application", 437 "mojo/services/public/js/application",
262 "services/js/test/echo_service.mojom" 438 "services/js/test/echo_service.mojom"
263 ], function(console, appModule, echoModule) { 439 ], function(console, appModule, echoModule) {
264 440
265 class EchoShellRequest extends appModule.Application { 441 class EchoShellRequest extends appModule.Application {
266 initialize(args) { 442 initialize(args) {
267 var url = "file:/foo/bar/echo.js"; 443 var url = "file:/foo/bar/echo.js";
268 var echoService = this.shell.connectToService(url, echoModule.EchoService) ; 444 var echoService = this.shell.connectToService(url, echoModule.EchoService) ;
269 echoService.echoString("foo").then(function(result) { 445 echoService.echoString("foo").then(function(result) {
270 console.log("echoString(foo) => " + result.value); 446 console.log("echoString(foo) => " + result.value);
271 }); 447 });
272 } 448 }
273 } 449 }
274 return EchoShellRequest; 450 return EchoShellRequest;
275 }); 451 });
276 ``` 452 ```
277 453
454 ### Requesting a Service from an Application's ServiceProvider
278 455
279 ### Providing a Service 456 The Shell's `connectToApplication()` method returns a JS ServiceProvider
457 object that serves as a proxy to a ServiceProvider implemented by the
458 target application. The ServiceProvider can be used to request services
459 from the target application and to provide services to the target application.
460
461 The echo_share.js and echo_share_target.js applications demonstrate this.
462
463
464 ### Providing a Service with an Application's ServiceProvider
280 465
281 A complete application that unconditionally provides the EchoService 466 A complete application that unconditionally provides the EchoService
282 looks like this: 467 looks like this:
283 468
284 ```javascript 469 ```javascript
285 #!mojo:js_content_handler 470 #!mojo:js_content_handler
286 471
287 define("main", [ 472 define("main", [
288 "mojo/services/public/js/application", 473 "mojo/services/public/js/application",
289 "services/js/test/echo_service.mojom" 474 "services/js/test/echo_service.mojom"
(...skipping 17 matching lines...) Expand all
307 object that implements the methods in the Mojo EchoService 492 object that implements the methods in the Mojo EchoService
308 interface. If the EchoService defined a client interface, the factory 493 interface. If the EchoService defined a client interface, the factory
309 function's client parameter would be a proxy for the initiator's 494 function's client parameter would be a proxy for the initiator's
310 client service. EchoService doesn't have a client so we could have 495 client service. EchoService doesn't have a client so we could have
311 omitted this parameter. 496 omitted this parameter.
312 497
313 Each time another application connects to this one, the EchoServiceImpl 498 Each time another application connects to this one, the EchoServiceImpl
314 function will be called. The caller will be able to run the 499 function will be called. The caller will be able to run the
315 echoString() method and will get its response via a Promise. 500 echoString() method and will get its response via a Promise.
316 501
502 The echo_share.js and echo_share_target.js applications demonstrate this.
317 503
318 ## Final note 504 ## Final note
319 505
320 An initiator's serviceProvider object can be retained and used to 506 An initiator's serviceProvider object can be retained and used to
321 request or provide services at any time, not just from within 507 request or provide services at any time, not just from within
322 application's acceptConnection() method. 508 application's acceptConnection() method.
323 509
324 510
325 # Interface Parameters
326
327 The caller and callee use cases that follow are in terms of the following mojom :
328
329 ```
330 [Client=Bar]
331 interface Foo {
332 }
333
334 [Client=Foo] // Redundant but always implicitly true.
335 interface Bar {
336 }
337
338 interface I {
339 provideFoo(Foo foo);
340 requestFoo(Foo& foo); // effectively: provideFoo(Bar bar)
341 }
342 ```
343
344 ## Stubs and Proxies
345
346 TODO: briefly introduce message pipes.
347 TODO: explain what stubs and proxies are, explain what's meant by "local" and "r emote".
348 TODO: explain the StubBindings and ProxyBindings functions.
349 TODO: support creating a proxy from a handle new MyProxy(someHandle);
350 TODO: explain the Connection object and how it relates to this stuff.
351
352 From a user's point of view, the bindings are in terms of the (remote)
353 proxy class and the (local) stub class. Properties are added to instances
354 of these classes using functions called StubBindings and ProxyBindings.
355
356
357
358 ## Callers
359
360 Assuming that we have a proxy for interface I, iProxy.
361
362 An iProxy.provideFoo() call implies that we have an implementation of
363 Foo, and want a proxy for Bar (Foo's client).
364
365 ```javascript
366 var barProxy;
367 iProxy.provideFoo(function(remote) {
368 barProxy = remote;
369 return myFooImpl;
370 });
371 ```
372
373 An iProxy.requestFoo() call implies that we have an implementation of
374 Bar and want a proxy for Foo (Bar's client).
375
376 ```javascript
377 var fooProxy;
378 iProxy.requestFoo(function(remote) {
379 fooProxy = remote;
380 return myBarImpl;
381 });
382 ```
383
384 In the requestFoo() case, if no client were defined for Bar the function
385 parameter need not return anything.
386
387 The wget.js example includes a request for the URLLoader service.
388
389 ## Callees
390
391 An implementation of provideFoo(Foo foo) implies that we have an
392 implementation of Bar (Foo's client) and want a proxy to the Foo
393 that has been passed to us.
394
395 ```javascript
396 void provideFoo(fooProxy) {
397 ProxyBindings(fooProxy).setLocalDelegate(myMyBarImpl);
398 }
399 ```
400
401 An implementation of requestFoo(Foo& foo) implies that we have an
402 implementation of Foo and want a proxy for the Bar (Foo's client)
403 that's been passed to us.
404
405 ```javascript
406 void requestFoo(barProxy) {
407 ProxyBindings(barProxy).setLocallocalDelegate(myFooImpl);
408 }
409 ```
OLDNEW
« examples/js/cube.js ('K') | « examples/js/share_echo_target.js ('k') | examples/js/wget.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698