The TypeScript client (@sen/client)¶
A TypeScript library that lets a browser or Node.js program talk to a running Sen process
over the jsonrpc component's wire (JSON-RPC 2.0 + WebSocket). Connect, walk
the live object graph, subscribe to property changes and events, invoke methods, and (in
React apps) drive a UI off the same data without writing your own subscription bookkeeping.
It ships in-tree at
components/jsonrpc/clients/typescript/
and is the primary client for the Sen web explorer and for any custom operator UI
built against Sen.
When to use it¶
| Want to ... | Reach for |
|---|---|
| Build a browser UI that drives Sen interactively | @sen/client + @sen/client/react |
| Write a Node.js script that polls / scripts a running Sen | @sen/client (no React) |
| Build a backend service that bridges Sen to another protocol | @sen/client |
| Talk to Sen from a non-TypeScript language | Write a client against jsonrpc.stl directly |
The data types in the examples below can be generated from your own model rather than written by
hand: sen generate ts writes TypeScript declarations for your structs, enums and variants, and an
interface for each event's payload. Methods and properties are not generated, so calls are still
made by name. See Code generation.
Hello, animals¶
In one terminal, start a Sen process exposing the bundled animals package:
That spins up rufus (a Cat) and elon (a Dog) on my.tutorial. Only the cat matches the
query below; the dog is there so the interest has something to filter out. The JSON-RPC server
listens on ws://127.0.0.1:8080.
In a second terminal:
import { connect } from "@sen/client";
const client = await connect({ url: "ws://127.0.0.1:8080" });
const cats = await client.declareInterest({
name: "cats",
query: "SELECT animals.Cat FROM my.tutorial",
});
cats.onObjectAdded(async (cat) => {
console.log(`got ${cat.className} named ${cat.name}`);
cat.onPropertyChanged("position", (pos) => console.log("position:", pos));
await cat.awaitPropertySubscribed("position");
await cat.invoke("jumpToLocation", { x: 42, y: 17 });
});
You should see the initial position print, then the post-jump position. The
onObjectAdded handler fires uniformly for objects matched at declare-time and for late
arrivals.
onPropertyChanged returns as soon as it has registered the handler, while the subscribe
it triggers travels to the server and back. Without the awaitPropertySubscribed line the
jump can land first, and then the only value you see is the one after the jump. Use the
same pattern for events, where the partner call is awaitEventSubscribed.
Concepts¶
The handles are layered:
Client-- the connection. One per Sen process. Owns the WebSocket, hands out interests, surfaces connection-state events.InterestHandle-- a live query. Keeps a local cache of matching objects in sync with the server. Tells you when objects appear or disappear.ObjectHandle-- one object in an interest's match set. The unit of work for property reads/writes, event subscriptions, method calls.
You only ever construct a Client. Interests and objects come from it.
Full reference¶
The package's README is the comprehensive user reference, covering:
- Queries + pre-subscribing properties / events at declare time
- Property reads, writes, and subscriptions (and
onAnyChange) - Events (
onEventTriggered) - Method invocation (
invoke) - Runtime value types (
Quantity,Variant) + narrowing helpers - Error model (
JsonRpcError,TransportError,TimeoutError) - Reconnection +
reestablishAll - Batch reads (
getObjectsBatchState) for dashboard-style refresh - React bindings (
@sen/client/react):useObject,useObjects,useProperty,useEvents,useInvoke,useSetProperty,useTopology,useTypeSpec, and themakeStore/useCellprimitives for fine-grained subscriptions.
Browser example¶
examples/browser/
in the package is a static HTML page that loads the built bundle and runs the hello-world above in a
real browser. Use it as a sanity check after npm run build, or as a starting point for a custom
browser UI.
Architecture¶
For contributors: see
components/jsonrpc/clients/typescript/architecture.md
for the layer diagram, per-module responsibilities, key invariants, and extension points.