@actuallab/fusion-rpc
v14.3.34
Published
Bridge between Fusion and RPC - FusionHub, compute service registration
Downloads
1,423
Readme
@actuallab/fusion-rpc
The bridge between @actuallab/fusion and
@actuallab/rpc: FusionHub — a compute-aware RPC
hub whose client proxies cache results locally and drop them the moment the .NET server says the
value changed. This is the TypeScript equivalent of Fusion's client-side RPC infrastructure
(Remote Compute Service interceptor, RpcComputeCallType).
This is the package you want if your goal is "call Fusion Compute Services running on a .NET server from a JS/TS client, and get real-time updates".
Installation
npm install @actuallab/fusion-rpcESM-first with a CJS fallback; ships its own .d.ts. Pulls in @actuallab/core,
@actuallab/fusion, and @actuallab/rpc.
Quick start
import { FusionHub, defineComputeService } from '@actuallab/fusion-rpc';
import { RpcClientPeer, RpcPeerStateMonitor } from '@actuallab/rpc';
// 1. Define the service — the name must match the .NET interface name exactly.
const TodoApiDef = defineComputeService('ITodoApi', {
// Compute methods: cached locally, invalidated by the server
Get: { args: ['', ''] }, // (session, id) → TodoItem
ListIds: { args: ['', 0] }, // (session, count) → string[]
GetSummary: { args: [''] }, // (session) → TodoSummary
// Commands: opt out of compute caching
AddOrUpdate: { args: [{}], callTypeId: 0 },
Remove: { args: [{}], callTypeId: 0 },
});
// 2. Hub + peer. The RpcClientPeer ctor starts the connect/reconnect loop.
const hub = new FusionHub();
const peer = new RpcClientPeer(hub, 'ws://localhost:5005/rpc/ws');
hub.addPeer(peer);
// 3. Typed client proxy — addClient is idempotent per (peer, service),
// so every consumer shares one Computed and one invalidation stream.
const api = hub.addClient<ITodoApi>(peer, TodoApiDef);
// 4. Optional: connection status for the UI
const monitor = new RpcPeerStateMonitor(peer);
// Cached until the server invalidates it
const ids = await api.ListIds('~', 10);Render it with
useComputedState and the component
refreshes itself whenever the server-side data changes.
How invalidation flows
- The client calls a compute method —
FusionHubsends it withCallType = 1. - The server computes, responds with
$sys.Ok; the client caches the result locally. - Server-side data changes and the server-side
Computed<T>is invalidated. - The server sends
$sys-c.Invalidatefor that call id. - The client invalidates its local replica; the invalidation cascades into every dependent
@computeMethodandComputedState<T>— and React re-renders.
An Invalidate that arrives before the result retries the call transparently (up to 3 attempts
while connected). On disconnect, compute replicas self-invalidate instead of being re-sent, since
the server's tracking for them is gone; regular in-flight calls are re-sent as usual.
API surface
| API | Description |
|-----|-------------|
| FusionHub | RpcHub + compute-aware proxies, invalidation wiring, acceptConnection(ws) for hosting |
| defineComputeService(name, methods) | Service definition where methods default to callTypeId: 1 (compute); use callTypeId: 0 for commands |
| FUSION_CALL_TYPE_ID | The compute call type id (1) |
| RpcOutboundComputeCall | The outbound call type that carries invalidation handling |
Notes
- Cancellation. A caller's
AbortSignaltravels throughAsyncContext(abortSignalKey); aborting sends$sys.Cancel, and the resulting cancellation error is never cached. - Hosting compute services in Node.
hub.addService(def, impl)wraps compute methods and wires invalidation to$sys-c.Invalidate. Use a class with@computeMethodmembers whenever service methods call each other — a plain-object impl calls them as raw functions and loses the dependency edges.
Documentation
@actuallab/fusion-rpcreference — full setup example, invalidation and reconnect details- TypeScript port overview
- TodoApp sample (React + Fusion)
License
MIT — see LICENSE.
