Module Base.Main

Javascript Exceptions

val raise_js : string -> 'a

raise_js error Raise a javascript exception.

Logging

val log_string : string -> unit

log_string str Log the string str via console.log.

val log_value : Value.t -> unit

log_value v Log the javascript value v via console.log.

Node Module

The functions in this section allow the creation of node modules which can interact with the surrounding javascript code. The communication is based on message passing. The javascript side can send messages into the node module implemented in ocaml and the ocaml side can send messages to the javascript side.

In order to start the node module, initialisation data can be provided.

type ('state, 'msg) node_function = 'state -> (Value.t -> unit) -> 'msg -> unit

Type of the implementation function of the node module.

The implementation function has the form

let node (state: 'state) (callback: Value.t -> unit): 'msg -> unit =
    ... (* initialisation code *)
    ...
    fun msg ->
        ... (* receive a message from the javascript side *)
        ...
val node_module : 'state Decode.t -> 'msg Decode.t -> ('state'msg) node_function -> unit

node_module state_decode msg_decode node_function

An ocaml program my_app.ml with an ocaml statement of the form

let _ =
    node_module state_decode msg_decode node_function

compiles to my_app.js which can be loaded as a module in a nodejs script via

           var my_app = require('./my_app.js')

The javascript value my_app is a javascript object of the form

           {init: (initial_state, callback) => { ... }}

which can be used in the following way:

            function callback (msg) {
                ...     // actions on receiving a message from 'my_app'
            }
            var state =
                     ... // initial state which can be decoded
                         // by 'state_decode'

            var post_to_my_app = my_app.init(state, callback)

            post_to_my_app (msg)    // send message to 'my_app',
                                    // must be decodable via 'msg_decode'

Browser Application

The function in this section allow the creation of browser applications which can interact with the surrounding javascript code. The communication is base on message passing. The javascript side can send messages into the ocaml browser application and vice versa.

type ('state, 'msg) browser_function = 'state -> string option -> (Value.t -> unit) -> 'msg -> unit

Type of the implementation function of the browser application with javascript interop.

val browser_application : string -> 'state Decode.t -> 'msg Decode.t -> ('state'msg) browser_function -> unit

browser_application state_decode msg_decode browser_function

An ocaml program my_app.ml with an ocaml statement of the form

let _ =
    browser_application
        "my_app"            (* Unique name in the browser *)
        state_decode
        msg_decode
        browser_function

can be compiled to a javascript file my_app.js. This file my_app.js can be included within a html page in a script tag

            <script type="text/javascript" src="my_app.js"></script>

In the html file we need some javascript code to interact with the browser application.

 <script>
            var state = ...         // javascript value which can be decoded
                                    // by 'state_decode'

            var postMessage         // variable representing a function to
                                    // post messages to 'my_app'

            var callback (msg) {
                ...                 // actions on receiving messages from
                ...                 // 'my_app'
                ...
                postMessage (...)   // send a message to 'my_app'
            }
            </script>

At the end of the body the application my_app can be started by

            <script>
                postMessage = my_app.init (state, 'element_id', callback)
            </script>

Warning: The ocaml browser application shall not be initialized before the body and in particular the element is available. Therefore it is best to initialize the application at the end of the html body.

It is convenient to initialize the browser application with an element id below which the browser application should install itself in the dom tree. This can be used to avoid conflicting dom accesses between the javascript side and the ocaml browser application.

Global Environment

val make_global : string -> Value.t -> unit

make_global name value Make the javascript value value accessible from javascript code via the global name name.

Caution:

If the global name name already exists, it will be overwritten. This has fatal consequences if you overwrite e.g. setTimeout or document or other other used global variables or global functions.

It is recommended to use some prefix like my_app_... in name in order to not pollute the global namespace.

val get_global : string -> Value.t option

get_global name Check, if name exists in the global enviroment and if yes, return the corresponding javascript value. Use Decode to check, if the global is a function, an object, a number etc.

val new_global : string -> Value.t array -> Value.t

new_global constructor args

Construct a new javascript object using the constructor constructor feeding it with the arguments args.

Precondition: The constructor must exist and it has to accept the arguments. If not, an exception is thrown.

val export : (string * Value.t) array -> unit

export [| name1, val1; name2, val2; ... |]

Export the javascript object consisting of the fields name1, name2, ... to the surrounding javascript code.

This function is used if you want to write a module to be used in a node application. In the javascript code you write

var my_app = require('./my_app.js')

and then the javascript variable my_app is an object containing all the exported fields.