livenode
livenode copied to clipboard
Live-code your NodeJS applications
Livenode -- Live-code your NodeJS application
Livenode is a small tool that allows me to evaluate arbitrary statements in a live NodeJS program, without restarting the server. This way I can introduce new functions/variables, or redefine existing ones, and immediately test without losing any context.
See my blog post and screencast.
I've been using it for a week and am quite satisfied with it, but it's essentially a quick hack and bugs are likely.
Install
Just git clone the repository for now and symlink bin/livenode
somewhere into your $PATH.
Use with Emacs
This is only tested with Emacs 24.
You need the WebSocket library: https://github.com/ahyatt/emacs-websocket.
Place livenode.el somewhere in your Emacs load path, then add
(require 'livenode) to your .emacs. To start your NodeJS server
with Livenode, just use livenode path/to/your/app.js. Then you can
connect Emacs to the server with M-x livenode and you can use the
following:
C-M-x-- evaluate the statement at pointC-c C-r-- evaluate the regionM-x livenode-gencode-region-- do code rewriting on region
Other editors
If your favorite editor is programmable, chances are it will be trivial to add support for it. You need a JSON library and a WebSocket client library. Patches are welcome.
Editor API
Communication between editor and server happens over a WebSocket connection.
Protocol
Messages that travel over this websocket are JSON-encoded arrays containing two or more elements:
REQUEST . . . . . [ ID, "COMMAND", ARG* ] // editor → server
RESPONSE . . . . [ ID, "COMMAND", RESULT ] // server → editor
NOTIFICATION . . [ 0, "error", ERROR ] // server → editor
The first element is a request ID. When replying to some particular request, the server will include its ID so you can match the result on the editor side (this is necessary since the protocol is fully asynchronous and there's no classic notion of "response to some request" as in HTTP).
The client (editor) should be prepared to receive anytime notifications (those will have the ID == 0). The only notification supported for now is "error" (this string will be the second element of the array) -- the server will send this in the case of an unhandled exception (those normally bring down the server, but Livenode catches them and forwards to the editor).
When there is an immediate error handling a particular request, the response will contain the string "error" in the second element (rather than the command name) and the error instead of the result. Note that this is different from an unhandled exception.
API
The following commands are supported at this time:
-
"eval" (filename, code)-- evaluatecodein the context of the module loaded fromfilename.filenamemust be the absolute, fully-resolved (no symlinks) path name of the module. -
"eval_at_pos" (filename, code, pos)-- evaluate the statement at a given position (pos) in the context of the module identified byfilename. Note thatcodeshould be the whole code in the editor, for this case, andposis the cursor position (1-based). I decided to do it this way to lift the burden of parsing and figuring out the statement from the editor—since we already have a proper parser on the server. -
"rewrite_code" (filename, code)-- apply code rewriting on the givencodeassuming the context of the module identified byfilename.
Both "eval" and "eval_at_pos" return an object that looks like this:
{ code: code, // the rewritten code that has been evaluated
warn: [ WARNING* ], // an array of warnings
result: ... }
Additionally, "eval_at_pos" will also include in this object two
integers, begin and end, which tell us the position of the
statement that has been evaluated (I'm using this in Emacs to flash
the statement after evaluation).
The warnings currently reported are only for undeclared variables. A warning looks like this:
{ message: "i.e. Undeclared variable...",
begin: POSITION,
end: POSITION }
Again, begin and end are positions that the editor can use to
highlight the code that triggered the warning (i.e. the undeclared
variable, for now).
Other kinds of warnings might be added in the future.