Node.js Evaluation Loop (NEL)
NEL
is an npm module for running
Node.js REPL sessions.
NEL
is a spin-off library from
IJavascript. This fact explains some
of the design decisions in NEL
, such as returning results in MIME format, and
the functionality provided for completion and inspection of Javascript
expressions. See the section on usage for more details.
NEL
is used by the following Jupyter kernels:
Main Features
- Run Javascript code within a
Node.js
session. The result can be formatted
as:
- Run Javascript code
asynchronously.
- Generate a list of completion
options for an
incomplete piece of Javascript code.
- Inspect a Javascript
expression and
return information such as type or even documentation (currently, only for
Javascript builtins).
Announcements
NEL v1.3.0
: API enhancement (added option awaitExecution)NEL v1.2.0
: API enhancement (Session#transpile may return a Promise)NEL v1.1.0
: API enhancement (added $$.clear({wait}))NEL v1.0.0
: Stable APINEL v0.5.6
: API enhancement (added $$.input() and onRequest callback)NEL v0.5.5
: Accept Promises as outputNEL v0.5.4
: API enhancement (added $$.display() and onDisplay callback)NEL v0.5
: API enhancement (added transpile option)NEL v0.4
: API enhancement (added onStdout and onStderr callbacks)NEL v0.3
: New API (simplify API by hiding type module:nel~Task)NEL v0.2
: API change (removed Session#executionCount)NEL v0.1.1
: API enhancement (experimental $$mimer$$
and $$defaultMimer$$
)NEL v0.1
: Output change (changed function output)NEL v0.0
: Initial release
Install
npm install nel
Usage
The documentation generated by JSDoc can be found
here.
Hello, World!
var nel = require("nel");
var session = new nel.Session();
var code = "['Hello', 'World!'].join(', ');";
session.execute(code, {
onSuccess: console.log,
onError: console.error,
});
Exceptions
code = "throw new Error('Hello, World!');";
session.execute(code, {
onSuccess: console.log,
onError: console.error,
});
stdout
and stderr
code = "console.log('Hello, World!');";
session.execute(code, {
onSuccess: console.log,
onError: console.error,
onStdout: console.log,
onStderr: console.error,
});
onDisplay
callback
The Jupyter messaging protocol
introduces the concept of display. A display is very much like an execution
result. It is associated with an execution request and in protocol version 5.1
and above it can be assigned an ID for subsequent updates. Here's an example of
the support provided by NEL
:
code = "$$.display().text('Hello, World!');";
session.execute(code, {
onDisplay: console.log,
});
code = "$$.display('test').text('Hello, World!');";
session.execute(code, {
onDisplay: console.log,
});
onRequest
callback and $$.input(options, callback)
The Jupyter messaging protocol
defines an stdin socket, so that a kernel can request an input from the user.
NEL
defines $$.input(options, callback)
to create such a request.
Here are two examples (first one passing a callback to $$.input
; second one
using a Promise
returned by $$.input()
):
code = "$$.input({prompt:'?', password: true}, function(error, reply) {$$.done(reply)});";
session.execute(code, {
onRequest: function(request, onReply) {
assert(request.input.prompt === "?");
assert(request.input.password === true);
onReply({input: "opensesame"});
},
onSuccess: console.log,
});
code = "(function($$) {$$.input({prompt:'?', password: true}).then($$.done);})($$);";
session.execute(code, {
onRequest: function(request, onReply) {
assert(request.input.prompt === "?");
assert(request.input.password === true);
onReply({input: "opensesame"});
},
onSuccess: console.log,
});
onRequest
callback and $$.clear(options)
The Jupyter messaging protocol
defines the message clear_output
for kernels to request the output of a cell
to be cleared. NEL
provides $$.clear(options)
to implement such a request.
Here's an example showing the use:
code = "$$.clear({wait: true});";
session.execute(code, {
onRequest: console.log
});
MIME output
A session may return results in MIME formats other than 'text/plain'.
code = "$$html$$ = \"<div style='background-color:olive;width:50px;height:50px'></div>\";";
session.execute(code, {
onSuccess: console.log,
onError: console.error,
});
code = "$$svg$$ = \"<svg><rect width=80 height=80 style='fill: orange;'/></svg>\";";
session.execute(code, {
onSuccess: console.log,
onError: console.error,
});
code = "$$png$$ = require('fs').readFileSync('image.png').toString('base64');";
session.execute(code, {
onSuccess: console.log,
onError: console.error,
});
code = "$$jpeg$$ = require('fs').readFileSync('image.jpg').toString('base64');";
session.execute(code, {
onSuccess: console.log,
onError: console.error,
});
code = "$$mime$$ = {\"text/html\": \"<div style='background-color:olive;width:50px;height:50px'></div>\"};";
session.execute(code, {
onSuccess: console.log,
onError: console.error,
});
Promises are accepted as output
When the result of an execution request is a Promise
, NEL
enables
asynchronous execution automatically and waits for the Promise
to resolve:
code = "Promise.resolve('Hello, World!');";
session.execute(code, {
onSuccess: console.log,
});
Generate a completion list
NEL
can parse simple Javascript variable expressions and generate a list of
completion options:
session.complete(
"set",
3,
{
onSuccess: console.log,
onError: console.error,
}
);
Note that the cursor position can be located anywhere within the Javascript
code:
session.complete(
"set",
2,
{
onSuccess: console.log,
onError: console.error,
}
);
Inspect an expression
NEL
can parse simple Javascript variable expressions and inspect their value:
code = "var a = [1, 2, 3];";
session.execute(code, null, onError);
session.inspect(
code,
5,
{
onSuccess: console.log,
onError: console.error,
}
);
NEL
can also provide relevant documentation (currently only available for
Javascript builtins):
session.inspect(
"parseInt",
8,
{
onSuccess: console.log,
onError: console.error,
}
);
Callbacks beforeRun
and afterRun
var beforeRun = function() { console.log("This callback runs first"); }
code = "'I run next'";
var afterRun = function() { console.log("This callback runs last"); }
session.execute(code, {
onSuccess: console.log,
onError: console.error,
beforeRun: beforeRun,
afterRun: afterRun,
});
Contributions
First of all, thank you for taking the time to contribute. Please, read
CONTRIBUTING.md
and use the issue tracker for
any contributions: support requests, bug reports, enhancement requests, pull
requests, ...
TODO
- Add tests for customising output
- Add
Node.js
documentation