https://github.com/taowen/define-function
quick.js based eval
https://github.com/taowen/define-function
eval javascript plugins quickjs wasm
Last synced: 30 days ago
JSON representation
quick.js based eval
- Host: GitHub
- URL: https://github.com/taowen/define-function
- Owner: taowen
- License: mit
- Created: 2022-03-03T02:14:43.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2023-04-24T14:53:48.000Z (almost 3 years ago)
- Last Synced: 2025-09-23T23:11:38.775Z (5 months ago)
- Topics: eval, javascript, plugins, quickjs, wasm
- Language: JavaScript
- Homepage:
- Size: 109 KB
- Stars: 43
- Watchers: 2
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# About
[quick.js](https://bellard.org/quickjs/) based sandbox
```
npm install define-function
```
works in any WebAssembly environment
* node
* browser
* wechat miniprogram
# Usage
define a function dynamically with javascript source code
```js
const def = require('define-function')
const f = await def(`
return 'hello';
`)
f() // 'hello'
```
function can have argument
```js
const def = require('define-function')
const f = await def(`
const [hello, world] = arguments;
return hello + ' ' + world;
`)
f('hello', 'world') // 'hello world'
```
argument can be function
```js
const def = require('define-function')
const f = await def(`
const [print] = arguments;
print('hello')
`)
f((msg) => {
console.log(msg)
}) // 'hello'
```
argument can be async function
```js
const def = require('define-function')
const f = await def(`
const [print, sleep] = arguments;
(async() => {
print('hello')
await sleep(1000);
print('world')
})();
`)
f(
msg => console.log(msg),
milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds))
)
// hello
// world
```
can return promise back to host
```js
const def = require('define-function')
const f = await def(`
const [print, sleep] = arguments;
return (async() => {
print('hello')
await sleep(1000);
print('world')
})();
`)
await f(
msg => console.log(msg),
milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds))
)
console.log('done')
// hello
// world
// done
```
share context between multiple invocations
```js
const { context } = require('define-function')
const ctx = await context()
const f = await ctx.def(`
global.counter = (global.counter || 0)+1;
return counter; // counter can be referenced globally
`)
f() // 1
f() // 2
f() // 3
ctx.dispose()
```
inject value and callbacks into global
```js
const { context } = require('define-function')
const ctx = await context({ global: {
console,
anwerOfEverything() {
return 42;
}
} }) // inject console and anwerOfEverything to global
const f = await ctx.def(`
console.log(anwerOfEverything());
`)
f() // 42
ctx.dispose();
```
import and export es module
```js
const { context } = require('define-function')
const ctx = await context({
loadModuleContent(moduleName) {
if (moduleName !== 'xxx') {
throw new Error('expect xxx');
}
return `export function sayHello() { return 'hello' }`
}
});
const { hello } = await ctx.load(`
import { sayHello } from 'xxx';
export const hello = sayHello();
`)
console.log(hello) // hello
ctx.dispose();
```
# Limit
* function argument does not support Set/Map/Class or anything that can not survive JSON.parse(JSON.stringify), except the argument is a function
* function return value does not support Set/Map/Class or anything that can not survive JSON.parse(JSON.stringify), except promise object
* JSON.stringify and JSON.parse takes time, so the arguments and return value should be as small as possible for best performance
# Similar projects
* https://github.com/justjake/quickjs-emscripten/
* https://github.com/maple3142/wasm-jseval
define-function has a simpler API and support async/await