The core of rpl is
eval() function and
node’s vm.runInNewContext(). Unlike these systems,
rpl is designed to run code as full-fledged scripts and to manage its
execution as a proper full-fledged process.
The precedecessor to
rpl, called mistakes.io,
eval() at its core - it
would execute each
1..n subset of code text in
eval() and display the result.
While this worked very well for imperative code that didn’t use timing
The problem is that some programs will finish executing in one pass:
But other programs will never exit:
process.nextTick, and so on. It’s very difficult to ‘clear all
intervals’ without brutal hacks.
The other problem of running code in a sandbox is scope: if you run something
eval('x = 10'), the variable
x will now be defined in the outer scope.
vm.runInContext method gives more control over scope access, there
isn’t a browser equivalent with the same behavior.
Terrarium’s solution is true nesting in both cases - for node, it creates a
module on the fly and runs it with
child_process.fork to create a new subprocess
with a stream for communication. In a browser, it creates a new HTML resource
window.top as a communication mechanism.
This allows the sub-scripts in question to do anything normal code can do - in a browser, you can create elements and attach events to them, and in node, you can create web servers, access files, and all the rest. And all this without hacks necessary even in node core to make the default node REPL act like software.
Terrarium is a low-level API: you create a sandbox, write code to it, and receive instrumentation data. The API is identical between node and the browser.
terrarium-stream is a slightly
higher-level API that connects the node
stream lifecycle - creating, reading, writing, destroying - to terrarium.
rpl is able to interface with browser & node
code and build an extremely simple websocket-based interface using