#plugin-system #worker #api #run-time #browser #http-api #native

no-std valor_core

Plugin runtime as HTTP API running in server and browser

6 releases

0.5.2-beta.0 Apr 18, 2021
0.5.1-beta.0 Apr 17, 2021
0.4.7-beta.0 Jan 29, 2021

#40 in #plugin-system

40 downloads per month
Used in valor_bin

GPL-3.0-or-later

40KB
808 lines

Valiu Open Runtime Docs

A plugin based system that allows combining several independently developed Javascript, WebAssembly or native modules under a single API(HTTP only initially). "Vlugins" are simple message handlers that can run natively or in the Web and are recommended to use web friendly dependencies, like following the Web Worker API, so that the same file can run unchanged in the server as well as in the browser(intercepting HTTP calls from a service worker).

"Vlugin" system

Whether it's compiled as a native library, a WASM or JavaScript module, vlugins implement the Vlugin interface that allows receiving compatible messages like http requests and answer back with another message like an HTTP response.

When following the Web Worker API you'll find it's powerful enough to get most tasks done, you can write native plugins that access all sort of operating system APIs or web only plugins that access the DOM for example but it is recommended that you only access functionality available to Workers to maximize portability. There's plenty of powerful APIs like fetch, IndexDB or WebSocket available that suit most common needs and for more complex services you can consider to use databases that talk HTTP like CouchDB or consider persisting state in a blockchain or a decentralized storage like IPFS. The preferred way would definitely be writing Rust plugins that use dependencies that can compile to WASM like Surf for example, an HTTP client that uses fetch when compiled to WASM and a performant backend when compiled natively.

Plugin types:

Rust(WASM) JS Rust(Native) WASI
Server ⚠️ ⚠️
Browser ⚠️ ⚠️ ✖️

⚠️ Caution with native plugins, they use the extern "Rust" ABI which is unstable so your plugins and the runtime should be compiled with the same rustc version. Also load only native plugins you trust and don't make the plugin registry API public as it may be potentially unsafe.

Writing plugins

Rust plugins

The recommended way to get the best performance and support would be to create a plugin in Rust. The #[vlugin] macro makes it convenient to define plugins with a simple top-level function, taking care of generating a Vlugin trait implementation and exporting a factory function that instantiates your plugin whether is compiled to WASM or as a native library.

use valor::*;

#[vlugin]
pub async fn on_request(_req: http::Request) -> http::Response {
    "OK response from a plugin".into()
}

For slightly more complex needs check the example with state.

JS plugins

⚠️ This is a work in progress, there aren't helpers yet and there's no support in the server(will come powered by Deno).

Running plugins

Native

Use valor_bin to run a server that can automatically register plugins defined in a JSON file or enable the /_plugins endpoint to register plugins dynamically. E.g. LD_LIBRARY_PATH=plugins/ cargo run -- -p plugins.json -w. Native plugins will be searched in the system's library path that in this example is set to the path where the compiled plugins are.

Dependencies

~7–12MB
~190K SLoC