JavaScript Mojo Example Applications
=====================

hello.js, world.js - A minimal application that connects to another.

wget.js - Uses the network service to load a URL.


--- Running Mojo Applications --- 

A Mojo application written in JavaScript is launched with mojo_shell like this:

  mojo_shell <js-application-url>

Where js-application-url is either a file or an http URL that names a JS source
file. The JS file itself must begin with a Mojo "shebang" that specifies the
Mojo URL of the JS content handler. In other words, the first line of the JS
source file must be:

  #!mojo:js_content_handler

Following the shebang should be a single AMD module called "main" whose value
is an Application class. The JS content handler will create an instance of the
Application and make it the client of the Mojo shell. The JS content handler is
itself a Mojo application and it's responsible for creating an instance of V8
and loading the "main" JS module and all of the modules the main module
depends on. 

The overall structure of a JS Mojo application is this:

  #!mojo:js_content_handler

  define("main", [<list of modules this application depends on>],
    function(<one parameter per dependent module>) {
      function Application(appShell, url) {
      }

      Application.prototype.initialize = function(args) {
      }

      Application.prototype.acceptConnection = function(url, spHandle) {
      }

      return Application;
    });

The hello.js example is little more than this basic skeleton.

The JS content handler loads the "main" module and makes an instance of its
value, which must be the application's class. The application's constructor is 
passed two arguments:

appShell - a pointer to the Mojo shell. Typically this will be wrapped by a
    Shell object, see below.

url - the URL this application was loaded from as a String.

The initialize() and acceptConnection() methods are defined by application.mojom
and they're needed because the JS content handler makes the JS application the
Mojo shell's client.


--- Mojo Application Structure --- 

Mojo applications can connect to services provided by other applications and
they can provide services of their own. A service is an implementation of a Mojo
interface that was defined as part of a Mojo module in a ".mojom" file.

To implement a service you'll need the JS "bindings" for the Mojo interface. The
bindings are generated by the build system and end up in files whose name is the
same as the '.mojom' file with a '.js' suffix. It's often helpful to look at the
generated 'mojom.js' files.

The JS Shell class simplifies connecting to applications and services. It's a
wrapper for the Application's appShell argument. 

The Shell's connectToService() method returns a "proxy" to a service provided by
another application.

The JS bindings for a Mojo interface's API are delivered as a JS module whose
name is based on the '.mojom' file's path. For example, to use the Mojo network
service you need the JS module based on network_service.mojom:

  define("main", [
    "mojo/services/public/interfaces/network/network_service.mojom",
    "mojo/services/public/js/shell",
  ]
    function(netModule, shellModule) {
      function Application(appShell, url) {
        this.shell = new shellModule.Shell(appShell);
      }

      Application.prototype.initialize = function(args) {
       var netService = this.shell.connectToService(
           "mojo:network_service", netModule.NetworkService);

      }
      ...
      return Application;
    });

The first connectToService() parameter is the Mojo URL for the network service
application and the second is the JS "interface" object for NetworkService. The
JS interface object's properties identify the (generated) JS bindings classes
used to provide or connect to a service. For example (from
network_service.mojom.js):

  var NetworkService = {
    name: 'mojo::NetworkService', // Fully qualified Mojo interface name.
    proxyClass: NetworkServiceProxy,
    stubClass: NetworkServiceStub,
    // ...
  };

The 'proxyClass' is used to access another application's NetworkService and the
'stubClass' is used to create an implementation of NetworkService. 

In the netService case above the Shell connects to the Mojo application at
"mojo:network_service", then connects its service called 
'NetworkService.name' with an instance of 'NetworkService.proxyClass'. The proxy
instance is returned.


--- Interface Parameters --- 

Mojo functions with interface valued parameters allow one to request a service
from a service or to provide a service to a service. The
indirect_service example demonstrates this.

The NetworkService CreateURLLoader() method has an interface request parameter:

  interface NetworkService {
    CreateURLLoader(URLLoader& loader); // Return a URLLoader to the caller.
    ...
  }

Interface request parameters can be specified as an instance of the interface's
proxy class. Ordinary interface parameters can be specified as an instance of
the interface's stub class. The stub class constructor has an optional delegate
parameter that defines the stub's implementation.

Here's an example of an interface request parameter taken from wget.js:

  var urlLoader = new loader.URLLoader.proxyClass;
  netService.createURLLoader(urlLoader); // interface& parameter

  var urlRequest = new loader.URLRequest({
    url: "http://www.cnn.com",
    method: "GET",
    auto_follow_redirects: true
  });

  urlLoader.start(urlRequest).then(function(result) {
      // ..Do something with result.response
  });


--- Mojo Responses are Promises --- 

Mojo functions can return zero or more values called a "response". For example
the EchoString function below returns a string or null.

interface EchoService {
  EchoString(string? value) => (string? value);
};

The response is delivered to the function caller asynchronously. In C++ the 
caller provides a Callback object whose Run() method has one argument for
each response parameter. In JS, Mojo functions that specify a response return
a Promise object. The Promise resolves to an object with one property per
response parameter. In the EchoString case that would be something like 
{value: "foo"}.

Similarly, the implementation of a Mojo interface functions that specify a
response, must return a Promise. The implementation of EchoString() could
be written like this:

  MyEchoStringImpl.prototype.EchoString = function(s) {
    return Promise.resolve({value: s});
  };
