Introduction to the Run Project
Run is a compact JavaScript library designed to execute user-provided code within a Web Worker. Its primary goal is to enable data transformation through code snippets while ensuring a safer execution environment.
Key Features
This library takes a JavaScript code snippet (as a string) and associated data, returning the results of the code's execution. It strives to execute untrusted code as securely as possible by utilizing Web Workers, which inherently provide a few safety features:
- No Access to the DOM: Web Workers cannot interact with the Document Object Model (DOM), limiting their ability to interfere with the user interface or modify the application's visual elements.
- Isolated Thread: They operate in a separate thread, ensuring that the execution of code snippets does not block or slow down the user interface.
- Limited Domain Context: Web Workers do not have access to the domain-specific context of their host application, providing an additional layer of security.
- Network Operations Restricted: They are generally unable to make network calls, though this is still under investigation.
The primary scenario for using Run is within low-code applications where users may need to execute various code snippets, which may not all be written by the same individual.
Integration with Other Tools
Run is set to be a part of an upcoming Open Source Dashboard SDK known as Slashd. There is also a sandbox application available here for experimentation and demonstration purposes.
Installation
Run can be easily integrated into your projects through several methods:
-
UnPkg CDN: Simply include the script in your HTML:
<script src="https://unpkg.com/@slashd/run"></script>
-
SkyPack CDN:
<script type="module"> import SlashdRun from 'https://cdn.skypack.dev/@slashd/run' // your code </script>
-
Package Manager: Install using npm:
npm install @slashd/run
And include it in your project:
<script src="node_modules/@slashd/run/dist/slashd-run.min.js"></script>
Or with ES6:
import SlashdRun from '@slashd/run'
How to Use
To use Run, you can create tasks that serve as independent workers:
import SlashdRun from '@slashd/run'
const task = new SlashdRun()
The exe
method of a task returns a promise, making it compatible with await
:
const myCode = `return Math.random() * param`
const res = await task.exe(myCode, {param:20})
Handle errors in code execution:
const myCode = `return MathRandom * param`
try{
const res = await task.exe(myCode, {param:20})
}catch(e){
console.log(e)
}
Support for asynchronous code execution is also available:
const myCode = `return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(Math.random())
}, 2000)
})`
const res = await task.exe(myCode)
For network capabilities, you can set restrict:false
:
const myCode = `return await fetch('https://jsonplaceholder.typicode.com/todos').then(res => res.json())`
const res = await task.exe(myCode, {restrict:false})
Configuration
You can include external libraries by specifying them in the deps
setup property:
const task = new SlashdRun({deps:['https://unpkg.com/lodash']})
To prevent network restrictions within the Web Worker:
const task = new SlashdRun({restrict:false})
For a global configuration, including the same settings across multiple tasks, the init
method can be utilized:
import { init } from '@slashd/run'
init({deps:['https://unpkg.com/lodash'], restrict:false})
Terminate a worker when it's no longer needed:
task.destroy()
Worker Pool
To manage worker creation efficiently, a pool of workers can be created using:
import { init, getFromPool } from '@slashd/run'
init({maxWorkers:3})
const task = getFromPool()
To dispose of the pool:
import { disposePool } from '@slashd/run'
disposePool()
Contribute
To contribute to the project, install dependencies with:
npm i
And start the development server:
npm start
In conclusion, Run is a versatile and secure library suitable for executing JavaScript snippets across different environments, emphasizing safety and flexibility through its use of Web Workers.