Last updated:
The Lunora client surface is TypeScript-first (@lunora/client, @lunora/react,
…), but the wire protocol itself is not TypeScript-bound. It is specified as a
language-independent contract so an SDK in any language can talk to a Lunora
deployment. Seven such SDKs ship today, generated by
lunora sdk generate.
The specification
The normative spec lives at protocol/README.md
in the repository. It covers every layer a client needs:
- Transport map:
POST /_lunora/rpcfor query/mutation/action, theGET /_lunora/wsWebSocket for live subscriptions, and the SSE framing for HTTP streaming routes. - The wire value codec (
encodeWire/decodeWire): howbigint, bytes,Date,Map/Set,URL,NaN/Infinity, and array-positionundefinedare tagged so they survive JSON, while pure-JSON values stay byte-identical. - The stable subscription key: the sorted, canonical encoding that
de-duplicates
(functionPath, args, shardKey). - The RPC envelopes: request body, success/
commitCursor/lastMutationId, and the{ error: { code, message, data } }failure shape. - The WebSocket frames:
connect,subscribe/unsubscribe, theack/data/delta/resume/settled/errorserver frames, and thepokeStart/pokePart/pokeEndshape (partial-replication) protocol. - Auth: the HTTP bearer, the WS
?token=credential, and the short-lived ephemeral WS admin token minted atPOST /_lunora/admin/ws-token.
Conformance fixtures
The spec is backed by a set of golden frames under
protocol/fixtures/:
wire-codec.json, stable-wire-key.json, rpc.json, and ws-frames.json. Both
the reference TypeScript client and every non-TS SDK are tested against these
identical files, so a protocol drift is caught on every side at once:
- TS reference:
packages/client/__tests__/protocol-conformance.test.ts - Python, Go, Ruby, Rust, Swift, Java, Kotlin: the suite under each
sdks/<lang>/
protocol/conformance-cases.json lists the cases every suite must exercise, and
each suite reads it at run time and fails if the run did not cover it, so adding
a name there turns all seven languages red until each one covers it.
An SDK is protocol-conformant when it round-trips every codec fixture
(encode(decode(x)) == x), reproduces every stable key, builds/parses the RPC
envelopes, and produces/consumes the WebSocket frames, including materialising
the poke sequence into the expected rowset.
SDKs built on it
Seven clients are generated from this contract: Python, Go, Ruby, Rust, Swift, Java and Kotlin. Each vendors a hand-written transport implementing the codec, RPC, subscriptions and the shape/poke protocol, pinned to the CLI version that generated it, and needs nothing installed in five of the seven languages.
See Non-JS SDKs for the command, the per-language wiring, and what each one requires.