This part isn’t required to use the project — but if you want to experiment with writing plugins in TypeScript, here’s how it works.
The downsides of writing plugins in TypeScript is mostly that your
.wasmfile will be much larger than the one compiled from rust or C:
- ~100KB of wasm for the rust plugin
- ~12MB of wasm for the TypeScript plugin
The reason is that a JavaScript runtime needs to be embedded in the
.wasmfile, which is not the case for the rust plugin.More about the SpiderMonkey runtime embedding.
It is setup in the project, however, I don't rely on plugins written in TypeScript for the moment as would be too much of a performance hit (mostly for the web host).
import type { plugin as pluginApi } from "./types/plugin-api";
export const plugin: typeof pluginApi = {
name: () => "echo",
man: () => "...",
run: (payload: string) => {
return {
status: "success",
stdout: payload,
stderr: undefined,
};
},
};
The jco toolchain helps compile JS/TS code into WebAssembly components.
Build Steps
- Generate TypeScript types:
cd packages/plugin-name
jco types --world-name plugin-api --out-dir ./src/types ../../crates/pluginlab/wit
- Bundle your TS code into a single file (using
rolldownor another bundler).
rolldown ./src/component.ts --file ./dist/component.js
- Componentize it:
jco componentize ./dist/component.js \
--wit ../../crates/pluginlab/wit \
--world-name plugin-api \
--out ./dist/component.wasm \
--disable http --disable random
- (Optional) Optimize the resulting
.wasmfile:
jco opt ./dist/component.wasm -o ./dist/component-opt.wasm
Example: package.json Scripts
{
"wit-types": "jco types ...",
"bundle": "rolldown ...",
"componentize": "jco componentize ...",
"build": "npm run wit-types && npm run bundle && npm run componentize",
"optimize": "jco opt ...",
"typecheck": "tsc --noEmit"
}
📎 Here are links to the implementation of the plugin-echo plugin in TypeScript in the project.
Top comments (0)