Workbooks Documentation

Source Blocks & Components

Every source block in a workbook is a potential WASM component. The OQL kernel reads the block's language, its heading's :PROPERTIES: drawer, and the block's own header args to build the component spec that goes into the build plan.

The component model

A source block paired with a heading that has :in: / :out: properties constitutes a component: a named, typed unit of work with declared inputs and outputs. The runtime compiles the block to a WASM module, wraps it in a WIT interface matching the declared types, and wires it to other components via the edge map in the build plan.

:in: and :out: properties

Declare input and output variable names on the heading:

** Compute result
   :PROPERTIES:
   :in:  x y
   :out: result
   :END:

#+begin_src javascript
export function compute(x, y) {
  return { result: x + y };
}
#+end_src

Multiple names are space-separated. The OQL kernel matches :in: names to exported function parameters and :out: names to returned object keys. The return value must be an object whose keys include every declared :out: name.

:deps: — component dependencies

:deps: on a heading declares that this component depends on another named block:

** Parse input
   :PROPERTIES:
   :out: parsed
   :END:

#+begin_src javascript
export function parse_input() {
  return { parsed: JSON.parse(inputRaw) };
}
#+end_src

** Process
   :PROPERTIES:
   :deps: parse-input
   :in:  parsed
   :out: result
   :END:

#+begin_src javascript
export function process(parsed) {
  return { result: parsed.value * 2 };
}
#+end_src

:deps: adds edges to the build plan DAG: the output of parse-input feeds the input of process. The runtime resolves the parsed value by running the upstream component first.

:sig: — explicit type signature

By default, the OQL kernel infers component types from the :in: / :out: property names. Use :sig: for explicit WIT-style signatures:

** Score items
   :PROPERTIES:
   :sig: score(items: list<string>) -> list<f64>
   :END:

The :sig: value is a WIT function signature. Supported primitive types: string, s32, s64, f32, f64, bool, list<T>, option<T>, result<T,E>. When :sig: is present it overrides :in: / :out: inference.

Header args

Source block header args control export and execution behaviour. These are standard Org Babel headers:

HeaderEffect
:exports codeRender the block as code only (default for most langs)
:exports resultsRender execution results only
:exports bothRender both block and results
:exports noneCompile but render nothing
:eval noDo not execute this block
:noweb yesAllow <<block-name>> references inside the block

Example:

#+begin_src sh :exports code
echo "this shows in the rendered output"
#+end_src

Language support

LanguageCompiler pathNotes
javascriptJavy → WASMSubset of JS; no DOM, no Node built-ins
rustmrustc.wasm → clang.wasmno_std by default inside sandbox
cclang.wasmC99, standard library via WASI
zigZig WASM targetZig stdlib available
shExec on hostNot sandboxed; runs in workdir

The Rust path uses mrustc.wasm (a Rust compiler compiled to WASM) to produce LLVM IR, then clang.wasm to compile to wasm32-wasi. This runs entirely inside the WASM sandbox — no native Rust toolchain needed at runtime.

Block naming

The component ID in the build plan is derived from the heading title: lowercased, spaces replaced with hyphens. The heading:

** Parse User Input
   :PROPERTIES:
   :out: parsed
   :END:

...becomes component ID parse-user-input in the build plan. Use this ID in :deps: references from other components.

Anonymous blocks

Source blocks without a parent heading that has :in:, :out:, or :deps: are anonymous — they appear in the build plan with no wiring. They are compiled if their language has a WASM backend, but are not connected to any edge. Useful for utility code referenced via :noweb:.