worker-sandbox
The Javascript sandbox based on Web Workers.
Usage
Install
npm install --save worker-sandbox
OR
yarn add worker-sandbox
Quickstart
To build a runInContext function as an example:
{ try const sandbox = // Create a sandbox instance await sandbox // Assign the context of the sandbox return await sandbox // Run the code finally sandbox // Destroy the Web Worker instance in the sandbox } // hello world
API
class Sandbox([worker: Worker])
Use the new
operator to create a sandbox instance, and the Sandbox class constructor has no arguments.
const sandbox = sandbox instanceof Sandbox // true
You can also use your own Worker instance, see below.
Sandbox#eval(code: string): Promise<any>
Eval code in the sandbox.
const sandbox = const result = await sandboxresult === 'hello world' // true
Sandbox#execute(code: string): Promise<void>
No return value version of Sandbox#eval
.
const sandbox = const result = await sandboxresult === undefined // true
Sandbox#context: { [string]: any }
This is an asynchronous Proxy object that can be used as syntactic sugar for Sandbox#set
, Sandbox#get
, Sandbox#remove
, Sandbox#call
.
const sandbox = // Get the full contextawait sandboxcontext // {} // Set the value of a specific pathsandboxcontexthelloWorld = 'hello world' // Get the value of a specific pathawait sandboxcontexthelloWorld === 'hello world' // true // Set a specific path as a functionsandboxcontext `: ` // Call a function of a specific path (the actual function runs in the sandbox)await sandboxcontext === 'Sandbox: hello world' // Remove the value of a specific pathdelete sandboxcontexthelloWorlddelete sandboxcontextsayHelloWorldawait sandboxcontexthelloWorld === undefined // trueawait sandboxcontextsayHelloWorld === undefined // true
Sandbox#set(path: string | string[], value: any): Promise<void>
Set the value of a specific path in the sandbox context.
const sandbox = await sandboxawait sandboxawait sandboxawait sandboxawait sandboxcontextarr === 'hello world' // trueawait sandboxcontext'arr[2]' === 'arr[2]' // true
Equivalent to
const sandbox = await sandboxawait sandboxawait sandboxawait sandboxawait sandboxcontextarr === 'hello world' // trueawait sandboxcontext'arr[2]' === 'arr[2]' // true
Equivalent to
const sandbox = sandboxcontextarr = sandboxcontextarr0 = 'hello'sandboxcontextarr1 = 'world'sandboxcontext'arr[2]' = 'arr[2]'await sandboxcontextarr === 'hello world' // trueawait sandboxcontext'arr[2]' === 'arr[2]' // true
Sandbox#assign(obj: any) : Promise<void>
It is the Object.assign()
for Sandbox#context
.
const sandbox = await sandboxawait sandboxcontext === 'hello world' // trueawait sandboxcontext'functions.sayHelloWorld' === 'hello world' // true
Equivalent to
const sandbox = Objectawait sandboxcontext === 'hello world' // trueawait sandboxcontext'functions.sayHelloWorld' === 'hello world' // true
Sandbox#get(path: string | string[]): Promsie<any>
Get the value of a specific path in the sandbox context.
const sandbox = await sandboxawait sandbox === 'hello' // trueawait sandbox === 'world' // true
Equivalent to
const sandbox = sandboxawait sandbox === 'hello' // trueawait sandbox === 'world' // true
Equivalent to
const sandbox = await sandboxawait sandboxcontextobjhello === 'hello' // trueawait sandboxcontextobj'world' === 'world' // true
Sandbox#remove(path: string | string[]): Promise<void>
Remove the value of a specific path in the sandbox context.
const sandbox = await sandboxawait sandboxawait sandboxawait sandboxcontextobj // {}
Equivalent to
const sandbox = await sandboxawait sandboxawait sandboxawait sandboxcontextobj // {}
Equivalent to
const sandbox = await sandboxdelete sandboxcontextobjhellodelete sandboxcontextobjworldawait sandboxcontextobj // {}
Sandbox#call(path: string | string[], ...args: any[]): Promise<any>
Calling a function within a sandbox context within a specific path, the actual function runs in the sandbox.
const sandbox = sandboxcontexthelloWorld = 'hello world'sandboxcontextfunctions = {}sandboxcontextfunctions `: `await sandbox === 'Sandbox: hello world' // true
Equivalent to
const sandbox = sandboxcontexthelloWorld = 'hello world'sandboxcontextfunctions = {}sandboxcontextfunctions `: `await sandbox === 'Sandbox: hello world' // true
Equivalent to
const sandbox = sandboxcontexthelloWorld = 'hello world'sandboxcontextfunctions = {}sandboxcontextfunctions { `: `await sandboxcontextfunctions === 'Sandbox: hello world' // true
Sandbox#callable : { [string]: Function }
This is an asynchronous Proxy object that can be used as syntactic sugar for Sandbox#registerCall
and Sandbox#cancelCall
.
const sandbox = const helloWorld = 'hello world' // Register the Callable functionsandboxcallable { return `: `} // Call the Callable functionawait sandbox === 'Sandbox: hello world' // true // Cancel registered Callable functiondelete sandboxcallablesayHelloWorldawait sandbox // ReferenceError!
Sandbox#registerCall(path: string | string[], func: Function): Promise<void>
Register a Callable function in the sandbox, which can be called in the sandbox, but the actual function is done outside the sandbox.
const sandbox = const helloWorld = 'hello world'await sandboxawait sandbox === 'Sandbox: hello world' // true
Sandbox#cancelCall(path: string | string[]): Promise<void>
Cancel registered Callable function.
const sandbox = const helloWorld = 'hello world'await sandboxawait sandboxawait sandbox // ReferenceError
Sandbox#destroy(): void
Destroy the Web Worker in the instance of the sandbox, which will call the Worker#terminate ()
to terminate the Web Worker.
const sandbox = sandbox
Advanced
Custom worker
The minimal worker code is:
self as any'window' = self PERMISSIONRECEIVEEVAL PERMISSIONRECEIVECALL PERMISSIONRECEIVEASSIGN PERMISSIONRECEIVEACCESS PERMISSIONRECEIVEREMOVE PERMISSIONRECEIVEREGISTER PERMISSIONSENDCALL /* add your context here */
Tips
The await
operator can be omitted when you call Sandbox#set
, Sandbox#assign
,Sandox#remove
, Sandbox#registerCall
,Sandbox#cancelCall
in the async
function. Because the Web Worker inside the sandbox is single-threaded, the asynchronous methods are executed in the order they are called, the await
operator is just need added when calling a function that requires a return value.
const sandbox = for let i = 1000; i--; sandbox sandbox sandboxawait sandboxcontextremovable === undefined // trueawait sandboxcontexthello === 'hello' // trueawait sandboxcontextworld === 'world' // true