quickjs_runtime
quickjs_runtime is a library for quickly getting started with embedding a javascript engine in your rust project.
DISCLAIMER: This project is far from what I would call "Battle Tested", use at your own risk.
quickjs_runtime focuses purely on making quickjs easy to use and does not add any additional features, that's where these projects come in:
- A more feature-rich runtime: GreenCopperRuntime.
- The commandline client: GreenCopperCmd.
- And then there is GreenCopper which aspires to be a full fledged application platform: GreenCopperServer.
This project is heavily inspired by the awesome quickjs wrapper at theduke/quickjs-rs and still uses its low level bindings libquickjs-sys.
The big difference to quickjs-rs is that quickjs_runtime executes all quickjs related code in a dedicated single-threaded EventLoop.
Please see the DOCS for all inner workings
This lib serves two main goals:
1. Provide simple utils for working with quickjs (these are located in the quickjs_utils mod)
- The QuickJsRuntime struct, this is to be used from a single thread
- E.g. objects::set_property(), functions::invoke_func()
- Wrap JSValue to provide reference counting (+1 on init, -1 on drop) (JSValueRef)
- Pass a module loader
2. Wrap quickjs for use as a ready to go JavaScript Runtime
- This is the EsRuntime struct, it provides an EventQueue which has a thread_local QuickJsRuntime
- All values are copied or abstracted in an EsValueFacade
- So no need to worry about Garbage collection
- evaluate script and invoke functions while waiting for results blocking or with async/await
- Get Promise result blocking or with async/await
What works?
Script and Modules
- console (.log/info/debug/trace/error) (docs)
- Eval script (docs)
- Create promises in JavaScript which execute async
- Eval modules (docs)
- Load modules (dynamic and static) (docs)
- fetch api (moved to GreenCopperRuntime)
- setImmediate
- setTimeout/Interval (and clear)
- script preprocessing (impls for ifdef/macro's/typescript can be found in GreenCopperRuntime)
Rust-Script interoperability
- Return Promises from rust functions and resolve them from rust (docs)
- Add functions from rust (docs)
- Invoke JS functions from rust (docs)
- Pass primitives, objects and arrays from and to rust (docs)
- Create Classes from rust (docs)
- async/await support on eval/call_function/promise resolution (docs)
- import native Modules (e.g. dynamic loading of rust functions or Proxy classes) (docs)
Future / Todo
- Worker support
- WebAssembly support
goals
Same goals as https://github.com/HiRoFa/es_runtime but with using quickjs
so
- slower js
but
- smaller footprint
- much faster compilation
For some of my projects those are a big plus!
examples
Here are some quickstarts:
Cargo.toml
[]
= "0.5"
= "0.4.11"
= "2.0.2"
main.rs
use EsRuntimeBuilder;
use Script;
use LevelFilter;
use block_on;
use Arc;
use EsRuntime;
async
invoke a js method from rust
let res = rt.call_function.await;
match res
add a function from rust and invoke it
rt.set_function
.ok
.expect;
let method_a_res = rt.eval.await;
match method_a_res
eval a module
rt.eval_module.await
.ok
.expect;
eval a module with a dynamic import
rt.eval_module.await
.ok
.expect;
get a function from js and invoke it in rust
rt.set_function
.ok
.expect;
rt.eval.await.ok.expect;
// wait a sec for the async onvoker to run
sleep;