@actuallab/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 +91 -0
  2. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # @actuallab/rpc
2
+
3
+ [![npm](https://img.shields.io/npm/v/@actuallab/rpc)](https://www.npmjs.com/package/@actuallab/rpc)
4
+ [![Documentation](https://img.shields.io/badge/Documentation-6B5B95)](https://fusion.actuallab.net/PartTS-Rpc)
5
+ [![License](https://img.shields.io/npm/l/@actuallab/rpc)](https://github.com/ActualLab/Fusion/blob/master/LICENSE)
6
+
7
+ TypeScript client (and Node.js host) for
8
+ [`ActualLab.Rpc`](https://fusion.actuallab.net/PartR) — the WebSocket RPC layer behind
9
+ [Fusion](https://fusion.actuallab.net/). It speaks the same wire protocol as the .NET
10
+ implementation, and handles connection management, serialization, streaming, system calls, and
11
+ automatic reconnection for you.
12
+
13
+ Use it on its own for plain RPC. For compute calls with server-driven invalidation, use
14
+ [`@actuallab/fusion-rpc`](https://www.npmjs.com/package/@actuallab/fusion-rpc), which extends this
15
+ package's `RpcHub`.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install @actuallab/rpc
21
+ ```
22
+
23
+ ESM-first with a CJS fallback; ships its own `.d.ts`. Works in browsers and in Node.js (supply a
24
+ `ws` WebSocket via `peer.webSocketFactory`).
25
+
26
+ ## Quick start
27
+
28
+ ```ts
29
+ import { RpcHub, RpcClientPeer, defineRpcService, RpcType } from '@actuallab/rpc';
30
+
31
+ // The name must match the .NET interface name exactly.
32
+ const SimpleServiceDef = defineRpcService('ISimpleService', {
33
+ Greet: { args: [''] }, // (message) → string
34
+ Counter: { args: [], returns: RpcType.stream }, // () → RpcStream<number>
35
+ Ping: { args: [''], returns: RpcType.noWait }, // fire-and-forget
36
+ });
37
+
38
+ const hub = new RpcHub();
39
+ const peer = new RpcClientPeer(hub, 'ws://localhost:5005/rpc/ws'); // auto-starts
40
+ hub.addPeer(peer); // registers it, so hub.close() shuts it down too
41
+ const client = hub.addClient<ISimpleService>(peer, SimpleServiceDef);
42
+
43
+ console.log(await client.Greet('World'));
44
+
45
+ for await (const i of await client.Counter()) {
46
+ if (i > 10) break; // sends AckEnd to the server
47
+ }
48
+
49
+ client.Ping('hello'); // returns void, dropped while disconnected
50
+ ```
51
+
52
+ `args` is only read for its `length` — the values are placeholders that document the signature.
53
+ Services can also be declared with the `@rpcService` / `@rpcMethod` decorators, which work for both
54
+ clients and server-side implementations.
55
+
56
+ ## API surface
57
+
58
+ | API | Description |
59
+ |-----|-------------|
60
+ | `RpcHub` | Peers, registered services, shared reconnect delayer, `addClient` / `addService` / `close` |
61
+ | `RpcClientPeer` | A client connection with handshake, buffering, and exponential-backoff reconnect (100 ms → 10 s) |
62
+ | `RpcServerPeer`, `RpcWebSocketConnection` | Hosting side: accept an inbound WebSocket |
63
+ | `defineRpcService`, `rpcService`, `rpcMethod`, `RpcType` | Service definitions |
64
+ | `RpcStream<T>`, `toRpcStream` | `AsyncIterable<T>` streams with ack-based backpressure and resume-after-reconnect |
65
+ | `RpcPeerStateMonitor`, `RpcPeerStateKind` | Connection-status state machine with `JustConnected` / `JustDisconnected` grace periods, for UI |
66
+ | `RpcCallTimeouts`, `RpcLimits` | Per-call timeouts and connection-lifecycle timing (keep-alive, handshake, …) |
67
+ | `genericErrorFilter` | Replaces outbound error messages with a generic one when your host serves RPC |
68
+
69
+ ## Notes
70
+
71
+ - **Reconnection is automatic.** The delayer lives on the hub and is shared by all client peers;
72
+ `hub.reconnectDelayer.cancelDelays()` forces an immediate retry (useful for a "Reconnect now"
73
+ button). A connection that drops within 15 s of connecting doesn't reset the backoff.
74
+ - **Serialization.** `json5np` (default) or MessagePack (`msgpack6` / `msgpack6c`), selected with
75
+ the `?f=` URL key. MemoryPack and polymorphic payloads are not supported — they fail loudly.
76
+ - **Node.js.** Construct the peer with `mustStart = false`, set `peer.webSocketFactory`, then call
77
+ `peer.start()`.
78
+ - **Security.** Serve RPC over `https`/`wss`: reconnect proofs need `crypto.subtle`, which is
79
+ unavailable in insecure browser contexts. If your Node host *serves* RPC, consider
80
+ `hub.systemCallSender.errorFilter = genericErrorFilter` so handler exception text (paths,
81
+ connection strings) doesn't reach callers.
82
+
83
+ ## Documentation
84
+
85
+ - [`@actuallab/rpc` reference](https://fusion.actuallab.net/PartTS-Rpc) — full API tables, reconnect proof, wire protocol
86
+ - [TypeScript port overview](https://fusion.actuallab.net/PartTS)
87
+ - [ActualLab.Rpc](https://fusion.actuallab.net/PartR) and [RpcStream](https://fusion.actuallab.net/PartR-RpcStream) — the concepts, in .NET terms
88
+
89
+ ## License
90
+
91
+ 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/rpc",
3
- "version": "14.3.26",
3
+ "version": "14.3.32",
4
4
  "description": "RPC framework for ActualLab TypeScript libraries",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -26,7 +26,7 @@
26
26
  "clean": "rm -rf dist"
27
27
  },
28
28
  "dependencies": {
29
- "@actuallab/core": "14.3.26",
29
+ "@actuallab/core": "14.3.32",
30
30
  "@msgpack/msgpack": "^3.1.3",
31
31
  "denque": "^2.1.0"
32
32
  },