Isolated Runtime Core
Provides a runtime environment for executing Javascript code loaded from a provided file, within a controlled (isolated) context.
The core functionality of this module is provided by the CodeRunner
class, which takes the root path in which the code to be run resides, and the file in which source code of the functions to exectute is stored.
What does "isolated" actually mean?
The isolation-level provided by this library has several aspects:
- A function cannot
require()
any module other than ones pre-defined upon creating aCodeRunner
instance. - A function cannot access files located in the hosting process in which
CodeRunner
is being used (thus executingprocess.exit(1)
will result in an exception asprocess
will beundefined
- Different invocations of the same function cannot share any state with each other.
Isolation illustrated
Once an instance of CodeRunner
is created, it can be used to execute any number of calls to the functions within the provided file, but some restrictions apply - each run is isolated from a preceding or consequent run, meaning that if your function modifies the global scope to save some state, those changes will not be persisted:
// my-module/index.js { globalbar = globalbar || 0 + n return globalbar}
// index.js globalbar = 0 const runner = root: '/absolute/path/to/root' file: 'my-module.js' const result1 = await runner console // 1 console // 0 const result2 = await runner console // 2console // 0
Note that the assignments made to global.bar
did not change its value, and the functions get its value as 0
every time.
API
root
- an absolute path containing the code-file provided via thefile
argument (e.g.,/var/usr/my-code
)file
- a file-name to run the code from when therun()
method is being called. (e.g.,index.js
)onConsole
- a callback to invoke for every call toconsole.<method>
performed in the executed code. Sinceconsole.<method>
calls are not redirected to thestdout
stream of the parent process hostingCodeRunner
,onConsole
provides a way to act upon those calls and possibly write them the parent process' stdout.onConsole
is invoked with two arguments:(method, ...args)
, wheremethod
is the name of the orignally method invoked onconsole
from the executed function, andargs
are the arguments passed to that console method.sourceExtensions
- allows requiring files with extensions other than.js
, by passing an array of the allows extensions:. e.g.:['.js1', '.xyz']
compiler
- an optional function to transform the code prior to execution. Takes a single argument -code
, that holds the source code to transpile, and expected to return the transpiled code as a string.external
- if you wish to allow your code torequire()
modules that are not relative to the function being executed, those module names can passed through this array. e.g.:['fs', 'lodash']
whitelistedPaths
- a list of absolute paths to allow loading relative modules from. Required since loading relative modules is restricted to paths stemming from theroot
folder by default. e.g:['/var/usr/a', '/b/c/d']
resolve
- an optional function to provide custom module-resolving logic, in case the traditional lookup logic implemented in Node needs to be extended or restricted. Once a modulerequire()
-ed by the executed-code cannot be found, the requested module id (path / name) is passed to this function and it's expected to return a string with the absolute path to the module file, ornull
if the lookup did not succeed.
codeRunner
funcName
- name of the function that should run.args
- an array of arguments to pass to the function.context
- optional global context to be injected to the sandbox.running
- optional callback, which will be called after the function was found, but before it was run.resolveArguments
- optional function, will be applied on the arguments before passing them to the function.