Library
Module
Module type
Parameter
Class
Class type
val log_value : Value.t -> unit
log_value v
Log the javascript value v
via console.log
.
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.
The implementation of the node module on the ocaml side is done by providing a function of the following type.
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 *)
...
Having a node function and a state and a message decoder, a node module is generated by a call to the following function.
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'
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.
The implementation of a browser application with javascript interop on the ocaml side is done by providing a function of the following type.
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.
The browser function has the form
let browser
(state: 'state) (* initial state *)
(element: string option) (* optional element id *)
(callback: Value.t -> unit) (* send messages to javascript *)
: 'msg -> unit
=
... (* initialisation code *)
...
fun msg ->
... (* receive a message from the javascript side *)
...
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 are 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 in the dom tree. This can be used to avoid conflicting dom accesses between the javascript side and the ocaml browser application.
If your application written in ocaml wants to communicate with javascript code, then the following functions might be interesting.
With the function make_global
it is possible to make a javascript value generated via ocaml available to the surrounding javascript code. In many cases you will make a function globally available to the javascript code. This function can receive initialization data and callback functions. With the callback functions you can post messages to the surrounding javascript code. Furthermore the globally accessible function might return a function which can be used by the surrounding javscript code to post messages to the ocaml application.
If you write a web worker, you have to make function with the name onmessage
available to the global environment. This function has type Value.t -> Value.t
and it usually returns Value.undefined
. Via get_global
you can find out, if a function named postMessage
exists (it exists in the global environment of a webworker) and then you can use this function to send messages to the creator of the web worker.
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.
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.