Client SDKs
Two clients, one catalog: the browser's and .NET's, both decoding against what the server says rather than its C# types.
Status: โ Implemented ยท Visibility: Public ยท Level: ๐ต Core ยท Category: Subscriptions
๐ฏ What it solves
A client has to decode a compact, quantized, versioned stream, keep a mirror of what its session holds, draw movers smoothly between frames, and send commands in the server's encoding โ without being regenerated every time the server's types change.
โ๏ธ How it works (in brief)
TypeScript (@typhondb/client, src/Typhon.Client.TypeScript, ESM + .d.ts):
ReconnectingClient/Connectionโ the handshake, catalog caching by hash,PINGscheduling (PingScheduler), reconnection with backoff per close code.FrameApplierโ applies eachTICKinto aWorldStore: per-archetypeArchetypeStores of typed columns (field(name)), live slots, and per-frame entered/updated/left lists;SelfState, acks, events andAggregateGrids beside them.Clock+evaluateLive(store, renderTick, frac, out)โ render time and motion-segment extrapolation, including tick-period changes under overload.CommandQueue(one batch per rendered frame) andRegionSender(ClientRegionfootprints, โค 5 Hz).StreamRecorder/replayStreamโ record and replay a session.typhon-codegenโ compiles a specialised decoder from/typhon/catalog.jsonfor the hot path.
.NET (Typhon.Client):
TyphonClientoverws://,wss://ortcp://: connect, reconnect policy,SendCommandAsync(name, values), aWorldStorewith per-archetype columns andSelfState, aRecorder. Built for bots, tools, load tests and integration tests.
๐ป Usage
const client = new ReconnectingClient({
url: 'wss://play.example.com/ws', kind: 'player', token, caps: Capabilities.Stats,
handlers: {
onWelcome: (session) => {
applier = new FrameApplier(session.plan, { clock });
queue = new CommandQueue({ plan: session.plan });
},
onTick: (message, recvMs) => applier.apply(message, recvMs),
},
});
await using var bot = new TyphonClient(new ClientOptions
{
Endpoint = new Uri("tcp://127.0.0.1:9100"),
Kind = "player",
});
await bot.ConnectAsync();
await bot.SendCommandAsync("MoveTo", new RecordValues
{
["X"] = FieldValue.Of(10.0),
["Z"] = FieldValue.Of(20.0),
});
โ ๏ธ Guarantees & limits
- Golden vectors pin the wire: the engine, the .NET client and the TypeScript SDK decode the committed vectors identically, bit for bit.
- Forward compatible: a client skips blocks and fixed-size fields it does not know (AC-14).
- Steady state: the TypeScript SDK shows no retained heap growth over a 10-minute replay; with code generation a steady-state frame of 10 k records decodes in โ 0.3 ms on the reference laptop.
- Packaging: neither SDK is published to a package registry yet (NuGet / npm); use them from the repository.
๐งช Tests
src/Typhon.Client.TypeScript/testโ vitest suites: framing, apply, motion, reconnect, codegen, golden streams- EngineStreamGoldenTests โ the .NET client against the engine's golden stream