- Zig 100%
- Shell <1%
- C <1%
zeldi #
durable-object cells for zig, compiled to wasm and run by a small host, modeled on deno's celld. each cell handles one event at a time and keeps its state in its own zkv store, on local disk or in an S3 bucket.
celld runs one trusted Workers application per fleet, and its security doc says it is not for hostile tenants. zeldi aims to run many tenants that don't trust each other on one small machine. each tenant's cells run as wasm on WAMR in a process of its own, jailed on linux. a cell reaches nothing past its own store except through the host: the operator grants it origins, methods and secrets in the app config.
http (by host and path) websocket streams
│ │
┌───────────▼────────────────────────────────────────▼───────────┐
│ supervisor: routes, alarms, streams, outbound fetch by grant, │
│ secrets, the node log and lease, the cells' store objects │
└───────────┬─────────────────────────────────┬──────────────────┘
│ frames on a socket │
┌───────────▼───────────┐ ┌───────────▼───────────┐
│ runner for tenant a │ │ runner for tenant b │
│ jailed on linux │ │ jailed on linux │
│ cell cell cell │ │ cell │
└───────────────────────┘ └───────────────────────┘
stores on local disk or a bucket
install #
requires zig 0.17.0. the build fetches the rest.
git clone https://tangled.org/zzstoatzz.io/zeldi
cd zeldi && zig build
use #
an app depends on zeldi as a zig package and builds each cell with addCell:
const zeldi = b.dependency("zeldi", .{ .optimize = .ReleaseSafe });
b.installArtifact(zeldi.artifact("zeldi"));
const cell = @import("zeldi").addCell(b, zeldi, "hello", b.path("hello.zig"));
then runs the host with an app config that names its tenants, cells, routes and grants:
zig-out/bin/zeldi dev --config app.json --operator-port 9090
develop #
zig build test # unit tests and the smoke test
zig build smoke # boot zeldi with the test cells
docs #
the docs directory holds the cell ABI, tenants and the jail, remote storage, and what apps need from the runtime.