Slicing Tierless Programs in JavaScript
This is a first prototype of the tier splitting tool Stip.js. (tested on Chrome and Firefox)
Stip.js - How To
At the moment we only support a small subset of JavaScript and the generated code is for Node.js with a remote communication library or for the Meteor framework.
Stip.js uses program dependency graphs to tier split the JavaScript code. By clicking the eval-button (shortcut Ctrl-E or Cmd-Ein the editor), the program dependency graph will be calculated and is displayed beneath the code. By clicking the Tier split-button (Ctrl-S or Cmd-S), STiP.js will try to tier split your code. Therefore you have to use the annotations @client and @server, followed by a block statement. JavaScript programs can also be transformed to continuation passing style by clicking the CPS transform button (Ctrl-K or Cmd-K).
Annotations
To guide the transpiler, Stip.js uses annotations inside comments. This way, other tools like refactoring tools or IDEs can still be used.
Each of the following annotations should thus be used inside comments, e.g. /* @server */
.
Annotation | Explanation |
---|---|
@server |
Followed by a block statement. Indicates that all statements in that block end up in the server tier. |
@client |
Followed by a block statement. Indicates that all statements in that block end up in the client tier. |
@shared |
Stip.js calculates the dependencies for each tier, and duplicates code that is not annotated (i.e. not inside a block annotated as server or client) but referred to by a tier. However, sometimes code (e.g. custom error definitions) is not referred to by a tier, but should be accessible by both tiers. Herefore this annotation can be used. The block statement tagged with this annotation is duplicated on each tier. |
@broadcast |
Server-side only, above a statement containing a call to a client function. A call to a function on a client tier tagged with @broadcast, is transformed into a call from the server to every client. This is the default for server calls to client functions. |
@reply |
Server-side only, inside function body above a statement containing a call to a client function. A call to a function on a client tier tagged with @reply, is transformed into a call from the server to the client who called the server function. |
@blocking |
Followed by a statement containing a function call. It means that the call should be transformed to continuation passing style, with the remainder of the program as its continuation. Stip.js normally figures out, via data dependencies, which parts of the program are dependent on the call. However, in case of e.g. the sleep function, which will have no data dependencies, the remainder of the program should wait before executing. To achieve this, the blocking annotation can be used. |
@assumes |
Sometimes it could be that certain fuctions are available in the running environment, for instance a random function.
To keep Stip.js happy, certain info about that function should be given: its name, number of arguments and return type.
An example, where the random and add function are available in the environment:
/* @assumes [random():Num, add(x,y):Num] */
|
Example
The following example is a very simple chat. On the server side only one function is defined, that calls a function on every client that will update their UI. Each client has its own name (based on a random number) and an event handler for a "send"-button. When this button is clicked, the message of the user is obtained from the DOM and the serverfunction broadcast
is called.
We use jQuery for DOM operations. A more advanced chat application can be found in the snippets.
The result after the transpilation process: