@actuallab/fusion-rpc 14.3.26 → 14.3.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +102 -0
  2. package/package.json +4 -4
package/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # @actuallab/fusion-rpc
2
+
3
+ [![npm](https://img.shields.io/npm/v/@actuallab/fusion-rpc)](https://www.npmjs.com/package/@actuallab/fusion-rpc)
4
+ [![Documentation](https://img.shields.io/badge/Documentation-6B5B95)](https://fusion.actuallab.net/PartTS-FusionRpc)
5
+ [![License](https://img.shields.io/npm/l/@actuallab/fusion-rpc)](https://github.com/ActualLab/Fusion/blob/master/LICENSE)
6
+
7
+ The bridge between [`@actuallab/fusion`](https://www.npmjs.com/package/@actuallab/fusion) and
8
+ [`@actuallab/rpc`](https://www.npmjs.com/package/@actuallab/rpc): `FusionHub` — a compute-aware RPC
9
+ hub whose client proxies cache results locally and drop them the moment the .NET server says the
10
+ value changed. This is the TypeScript equivalent of Fusion's client-side RPC infrastructure
11
+ (Remote Compute Service interceptor, `RpcComputeCallType`).
12
+
13
+ **This is the package you want** if your goal is "call [Fusion](https://fusion.actuallab.net/)
14
+ Compute Services running on a .NET server from a JS/TS client, and get real-time updates".
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @actuallab/fusion-rpc
20
+ ```
21
+
22
+ ESM-first with a CJS fallback; ships its own `.d.ts`. Pulls in `@actuallab/core`,
23
+ `@actuallab/fusion`, and `@actuallab/rpc`.
24
+
25
+ ## Quick start
26
+
27
+ ```ts
28
+ import { FusionHub, defineComputeService } from '@actuallab/fusion-rpc';
29
+ import { RpcClientPeer, RpcPeerStateMonitor } from '@actuallab/rpc';
30
+
31
+ // 1. Define the service — the name must match the .NET interface name exactly.
32
+ const TodoApiDef = defineComputeService('ITodoApi', {
33
+ // Compute methods: cached locally, invalidated by the server
34
+ Get: { args: ['', ''] }, // (session, id) → TodoItem
35
+ ListIds: { args: ['', 0] }, // (session, count) → string[]
36
+ GetSummary: { args: [''] }, // (session) → TodoSummary
37
+
38
+ // Commands: opt out of compute caching
39
+ AddOrUpdate: { args: [{}], callTypeId: 0 },
40
+ Remove: { args: [{}], callTypeId: 0 },
41
+ });
42
+
43
+ // 2. Hub + peer. The RpcClientPeer ctor starts the connect/reconnect loop.
44
+ const hub = new FusionHub();
45
+ const peer = new RpcClientPeer(hub, 'ws://localhost:5005/rpc/ws');
46
+ hub.addPeer(peer);
47
+
48
+ // 3. Typed client proxy — addClient is idempotent per (peer, service),
49
+ // so every consumer shares one Computed and one invalidation stream.
50
+ const api = hub.addClient<ITodoApi>(peer, TodoApiDef);
51
+
52
+ // 4. Optional: connection status for the UI
53
+ const monitor = new RpcPeerStateMonitor(peer);
54
+
55
+ // Cached until the server invalidates it
56
+ const ids = await api.ListIds('~', 10);
57
+ ```
58
+
59
+ Render it with
60
+ [`useComputedState`](https://fusion.actuallab.net/PartTS-React#usecomputedstate) and the component
61
+ refreshes itself whenever the server-side data changes.
62
+
63
+ ## How invalidation flows
64
+
65
+ 1. The client calls a compute method — `FusionHub` sends it with `CallType = 1`.
66
+ 2. The server computes, responds with `$sys.Ok`; the client caches the result locally.
67
+ 3. Server-side data changes and the server-side `Computed<T>` is invalidated.
68
+ 4. The server sends `$sys-c.Invalidate` for that call id.
69
+ 5. The client invalidates its local replica; the invalidation cascades into every dependent
70
+ `@computeMethod` and `ComputedState<T>` — and React re-renders.
71
+
72
+ An `Invalidate` that arrives *before* the result retries the call transparently (up to 3 attempts
73
+ while connected). On disconnect, compute replicas self-invalidate instead of being re-sent, since
74
+ the server's tracking for them is gone; regular in-flight calls are re-sent as usual.
75
+
76
+ ## API surface
77
+
78
+ | API | Description |
79
+ |-----|-------------|
80
+ | `FusionHub` | `RpcHub` + compute-aware proxies, invalidation wiring, `acceptConnection(ws)` for hosting |
81
+ | `defineComputeService(name, methods)` | Service definition where methods default to `callTypeId: 1` (compute); use `callTypeId: 0` for commands |
82
+ | `FUSION_CALL_TYPE_ID` | The compute call type id (`1`) |
83
+ | `RpcOutboundComputeCall` | The outbound call type that carries invalidation handling |
84
+
85
+ ## Notes
86
+
87
+ - **Cancellation.** A caller's `AbortSignal` travels through `AsyncContext` (`abortSignalKey`);
88
+ aborting sends `$sys.Cancel`, and the resulting cancellation error is never cached.
89
+ - **Hosting compute services in Node.** `hub.addService(def, impl)` wraps compute methods and wires
90
+ invalidation to `$sys-c.Invalidate`. Use a class with `@computeMethod` members whenever service
91
+ methods call each other — a plain-object impl calls them as raw functions and loses the
92
+ dependency edges.
93
+
94
+ ## Documentation
95
+
96
+ - [`@actuallab/fusion-rpc` reference](https://fusion.actuallab.net/PartTS-FusionRpc) — full setup example, invalidation and reconnect details
97
+ - [TypeScript port overview](https://fusion.actuallab.net/PartTS)
98
+ - [TodoApp sample (React + Fusion)](https://github.com/ActualLab/Fusion.Samples/tree/master/src/TodoApp)
99
+
100
+ ## License
101
+
102
+ MIT — see [LICENSE](https://github.com/ActualLab/Fusion/blob/master/LICENSE).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actuallab/fusion-rpc",
3
- "version": "14.3.26",
3
+ "version": "14.3.32",
4
4
  "description": "Bridge between Fusion and RPC - FusionHub, compute service registration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -26,9 +26,9 @@
26
26
  "clean": "rm -rf dist"
27
27
  },
28
28
  "dependencies": {
29
- "@actuallab/core": "14.3.26",
30
- "@actuallab/fusion": "14.3.26",
31
- "@actuallab/rpc": "14.3.26"
29
+ "@actuallab/core": "14.3.32",
30
+ "@actuallab/fusion": "14.3.32",
31
+ "@actuallab/rpc": "14.3.32"
32
32
  },
33
33
  "publishConfig": {
34
34
  "access": "public"