Expand description
kevy-wasm — kevy’s embedded KV engine behind a hand-written C ABI.
Compiled to wasm32-unknown-unknown, this crate exports a flat
extern "C" surface (no binding generator, zero dependencies beyond
the kevy workspace) that a small hand-written ES-module loader
(pkg/kevy.js) wraps into an idiomatic JavaScript API. The same
functions are plain Rust functions on native targets, which is how
the unit tests drive them.
§ABI conventions
- Instances are
u32handles from [kevy_open]; every other call takes the handle first.0is never a valid handle. - Bytes in cross as
(ptr, len)pairs pointing into linear memory the caller obtained from [kevy_alloc] (and returns with [kevy_free]). - Bytes out land in a per-instance result buffer read via
[
kevy_out_ptr] / [kevy_out_len]; the buffer is valid until the next call on the same handle, so callers copy out immediately. - Status codes:
>= 0is success (meaning is per-function),-1is an operation error (UTF-8 message in the result buffer),-2is an invalid handle. - Numbers cross as
f64where the JS side works with plainNumbervalues (clocks, TTLs, counts). All are well inside the 2^53 exact-integer range.
§Threading and clocks
The browser target has no threads and no OS clock: instances open
with the manual TTL reaper, the host calls [kevy_tick] on its own
cadence, and feeds Date.now() through [kevy_set_clock] first.
§Persistence
The browser has no filesystem, so durability is host-mediated: with
frame capture enabled, every write also encodes the same RESP frame
a kevy AOF stores on disk. The host pumps [kevy_aof_frames_out]
into its own storage (OPFS, IndexedDB, anything append-capable) and
feeds the log back through [kevy_aof_frame_in] on the next open.
[kevy_aof_dump] produces a compacted image for log rewriting. The
byte format is exactly kevy-persist’s AOF format, so a log written
by a browser tab replays in a native kevy just as well.
Modules§
- abi_aof
- The host-mediated persistence pump. The browser has no filesystem,
so the engine never touches storage itself: writes (when capture is
on) queue their AOF frames here, the host drains them into whatever
it has (OPFS, IndexedDB), and feeds the stored log back on the next
open. Frames are
kevy-persistAOF format byte-for-byte — a log pumped out of a browser tab replays in a native kevy unchanged. - abi_cmd
- The raw command channel the client contract mandates for every port
(
docs/client-contract.md§5.2 / §7: “every port MUST expose a raw command channelcmd(argv) -> Reply”). The typed KV/TTL/pubsub/AOF exports intentionally lag the full verb grammar; this is the escape hatch that reaches whatever the compiled-in dispatcher owns an arm for. - abi_
core - Lifecycle, memory, and clock exports: everything the loader needs before and around the data-plane calls.
- abi_kv
- The KV + TTL data plane: string values, expiry, counters, keyspace scans. Every write that succeeds also records its AOF frame (when capture is on) in the exact byte shape a native kevy AOF carries, so the host-pumped log replays anywhere.
- abi_
pubsub - Pub/sub exports. The wasm target has no threads, so delivery is a
polling drain: subscriptions queue frames inside the engine and the
host pulls them with
kevy_poll_eventson its own cadence (typically a microtask right after each publish, plus the timer that also drives the TTL tick).
Constants§
- ABI_
VERSION - ABI contract version reported by
abi_core::kevy_abi_version. Bumped on any incompatible change to the export surface or the packed byte formats, so loaders can refuse a mismatched module.