@sumicom/quicksave-message-bus 0.7.0 → 0.8.0
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.
- package/README.md +141 -0
- package/dist/client.d.ts +12 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +50 -11
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +12 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +50 -2
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +21 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +7 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# @sumicom/quicksave-message-bus
|
|
2
|
+
|
|
3
|
+
Transport-agnostic **command + subscribe** message bus. Built for Quicksave's
|
|
4
|
+
PWA ↔ agent RPC channel, but has no Quicksave-specific code — it only needs
|
|
5
|
+
a duplex transport that can deliver JSON frames.
|
|
6
|
+
|
|
7
|
+
## What it gives you
|
|
8
|
+
|
|
9
|
+
Three primitives over a single transport:
|
|
10
|
+
|
|
11
|
+
| Primitive | Shape |
|
|
12
|
+
| -------------- | ---------------------------------------------------------------- |
|
|
13
|
+
| `command` | One-shot request/response (`verb` + payload → result or error) |
|
|
14
|
+
| `subscribe` | Path-based (`/sessions/:id/cards`), delivers **snapshot + updates** until unsub |
|
|
15
|
+
| `publish` | Server-side fan-out to every peer subscribed to a path |
|
|
16
|
+
| `getSnapshot` | One-shot read of a subscribable path — resolves with the same data `sub` would, without creating a subscription |
|
|
17
|
+
|
|
18
|
+
Key properties:
|
|
19
|
+
|
|
20
|
+
- **Snapshot-on-subscribe**: the first frame after `sub` is always a full
|
|
21
|
+
snapshot. On reconnect the client auto-resends `sub` frames and gets a
|
|
22
|
+
fresh snapshot, eliminating the "stale-after-reconnect" window.
|
|
23
|
+
- **Command queueing**: `command(..., { queueWhileDisconnected: true })`
|
|
24
|
+
holds the request until the transport reconnects, then flushes.
|
|
25
|
+
- **Typed path params**: `PathParams<'/sessions/:id/cards'>` → `{ id: string }`.
|
|
26
|
+
- **Transport-agnostic**: implement `ServerTransport` / `ClientTransport` and
|
|
27
|
+
drop it in. A `FakeTransport` ships under `/fake` for tests.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install @sumicom/quicksave-message-bus
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Quick example
|
|
36
|
+
|
|
37
|
+
**Server** (Node, any transport):
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { MessageBusServer } from '@sumicom/quicksave-message-bus';
|
|
41
|
+
|
|
42
|
+
const bus = new MessageBusServer(transport);
|
|
43
|
+
|
|
44
|
+
bus.onCommand<StartPayload, StartResult>('session:start', async (payload, ctx) => {
|
|
45
|
+
return await startSession(payload);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
bus.onSubscribe<'/sessions/:id/cards', CardHistory, CardUpdate>(
|
|
49
|
+
'/sessions/:id/cards',
|
|
50
|
+
{
|
|
51
|
+
snapshot: async ({ params }) => getCardHistory(params.id),
|
|
52
|
+
onSubscribed: ({ params, peer }) => trackSubscriber(params.id, peer),
|
|
53
|
+
},
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// Push updates to all subscribers of this exact path
|
|
57
|
+
bus.publish('/sessions/abc123/cards', { kind: 'card', event });
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Client** (browser or Node):
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { MessageBusClient } from '@sumicom/quicksave-message-bus';
|
|
64
|
+
|
|
65
|
+
const bus = new MessageBusClient(transport);
|
|
66
|
+
|
|
67
|
+
const result = await bus.command<StartResult, StartPayload>(
|
|
68
|
+
'session:start',
|
|
69
|
+
{ prompt: 'hello' },
|
|
70
|
+
{ timeoutMs: 30_000, queueWhileDisconnected: true },
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const unsub = bus.subscribe<CardHistory, CardUpdate>(
|
|
74
|
+
'/sessions/abc123/cards',
|
|
75
|
+
{
|
|
76
|
+
onSnapshot: (history) => setInitialState(history),
|
|
77
|
+
onUpdate: (event) => applyUpdate(event),
|
|
78
|
+
onError: (err) => console.warn('sub failed:', err),
|
|
79
|
+
},
|
|
80
|
+
);
|
|
81
|
+
// later:
|
|
82
|
+
unsub();
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Wire protocol
|
|
86
|
+
|
|
87
|
+
Frames (JSON):
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
// Client → Server
|
|
91
|
+
{ kind: 'cmd', id, verb, payload }
|
|
92
|
+
{ kind: 'sub', path }
|
|
93
|
+
{ kind: 'unsub', path }
|
|
94
|
+
|
|
95
|
+
// Server → Client
|
|
96
|
+
{ kind: 'result', id, ok: true, data }
|
|
97
|
+
{ kind: 'result', id, ok: false, error }
|
|
98
|
+
{ kind: 'snap', path, data }
|
|
99
|
+
{ kind: 'upd', path, data }
|
|
100
|
+
{ kind: 'sub-error', path, error }
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Transports are responsible for framing, delivery, and emitting peer
|
|
104
|
+
connect/disconnect events; the bus has no opinion on wire format below
|
|
105
|
+
that.
|
|
106
|
+
|
|
107
|
+
## Transport contract
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
interface ServerTransport {
|
|
111
|
+
send(peer: PeerId, frame: ServerFrame): void;
|
|
112
|
+
onFrame(handler: (peer: PeerId, frame: ClientFrame) => void): void;
|
|
113
|
+
onPeerConnected(handler: (peer: PeerId) => void): void;
|
|
114
|
+
onPeerDisconnected(handler: (peer: PeerId) => void): void;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
interface ClientTransport {
|
|
118
|
+
send(frame: ClientFrame): void;
|
|
119
|
+
onFrame(handler: (frame: ServerFrame) => void): void;
|
|
120
|
+
onConnected(handler: () => void): void;
|
|
121
|
+
onDisconnected(handler: () => void): void;
|
|
122
|
+
isConnected(): boolean;
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
For an example over an existing WebSocket layer, see Quicksave's
|
|
127
|
+
`apps/agent/src/messageBus/busServerTransport.ts` and
|
|
128
|
+
`apps/pwa/src/lib/busClientTransport.ts`.
|
|
129
|
+
|
|
130
|
+
## Testing with the fake transport
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import { FakeServerTransport, FakeClientTransport } from '@sumicom/quicksave-message-bus/fake';
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Pairs in-memory; lets you drive connect/disconnect manually. Used in this
|
|
137
|
+
package's own test suite.
|
|
138
|
+
|
|
139
|
+
## License
|
|
140
|
+
|
|
141
|
+
MIT
|
package/dist/client.d.ts
CHANGED
|
@@ -19,6 +19,18 @@ export declare class MessageBusClient {
|
|
|
19
19
|
private subs;
|
|
20
20
|
private queue;
|
|
21
21
|
constructor(transport: ClientTransport);
|
|
22
|
+
/**
|
|
23
|
+
* One-shot snapshot read for any subscribable path. Resolves with the
|
|
24
|
+
* same value the server would deliver on the `snap` frame of a
|
|
25
|
+
* `subscribe` — but without creating a subscription, so no updates
|
|
26
|
+
* follow and no `onSubscribed`/`onUnsubscribed` callbacks fire on the
|
|
27
|
+
* server. Intended for views that want a point-in-time value and don't
|
|
28
|
+
* care about live updates.
|
|
29
|
+
*
|
|
30
|
+
* Note: one-shot reads deliberately skip seq tracking; a concurrent
|
|
31
|
+
* `subscribe` on the same path manages its own seq independently.
|
|
32
|
+
*/
|
|
33
|
+
getSnapshot<S = unknown>(path: string, opts?: CommandOptions): Promise<S>;
|
|
22
34
|
/**
|
|
23
35
|
* Issue a one-shot command. Resolves with the server's response data,
|
|
24
36
|
* rejects with the server's error string or a timeout.
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAStD,MAAM,MAAM,kBAAkB,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,IAAI;IACzD,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC9B,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AA4BF,MAAM,MAAM,cAAc,GAAG;IAC3B,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,CAAC;AAQF,qBAAa,gBAAgB;IAKf,OAAO,CAAC,SAAS;IAJ7B,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,IAAI,CAAwC;IACpD,OAAO,CAAC,KAAK,CAAyB;gBAElB,SAAS,EAAE,eAAe;IAM9C;;;;;;;;;;OAUG;IACH,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;IAI7E;;;OAGG;IACH,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CAAC,EACV,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,CAAC,CAAC;IA8Bb;;;;;;;OAOG;IACH,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAChC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,GAClC,MAAM,IAAI;IA+Cb,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,YAAY;IAiBpB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,kBAAkB;CAiB3B"}
|
package/dist/client.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GET_SNAPSHOT_VERB, } from './types.js';
|
|
1
2
|
let idCounter = 0;
|
|
2
3
|
function nextId() {
|
|
3
4
|
idCounter = (idCounter + 1) | 0;
|
|
@@ -14,6 +15,20 @@ export class MessageBusClient {
|
|
|
14
15
|
transport.onConnected(() => this.handleConnected());
|
|
15
16
|
transport.onDisconnected(() => this.handleDisconnected());
|
|
16
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* One-shot snapshot read for any subscribable path. Resolves with the
|
|
20
|
+
* same value the server would deliver on the `snap` frame of a
|
|
21
|
+
* `subscribe` — but without creating a subscription, so no updates
|
|
22
|
+
* follow and no `onSubscribed`/`onUnsubscribed` callbacks fire on the
|
|
23
|
+
* server. Intended for views that want a point-in-time value and don't
|
|
24
|
+
* care about live updates.
|
|
25
|
+
*
|
|
26
|
+
* Note: one-shot reads deliberately skip seq tracking; a concurrent
|
|
27
|
+
* `subscribe` on the same path manages its own seq independently.
|
|
28
|
+
*/
|
|
29
|
+
getSnapshot(path, opts = {}) {
|
|
30
|
+
return this.command(GET_SNAPSHOT_VERB, { path }, opts);
|
|
31
|
+
}
|
|
17
32
|
/**
|
|
18
33
|
* Issue a one-shot command. Resolves with the server's response data,
|
|
19
34
|
* rejects with the server's error string or a timeout.
|
|
@@ -116,10 +131,10 @@ export class MessageBusClient {
|
|
|
116
131
|
this.handleResult(frame);
|
|
117
132
|
return;
|
|
118
133
|
case 'snap':
|
|
119
|
-
this.handleSnapshot(frame
|
|
134
|
+
this.handleSnapshot(frame);
|
|
120
135
|
return;
|
|
121
136
|
case 'upd':
|
|
122
|
-
this.handleUpdate(frame
|
|
137
|
+
this.handleUpdate(frame);
|
|
123
138
|
return;
|
|
124
139
|
case 'sub-error':
|
|
125
140
|
this.handleSubError(frame.path, frame.error);
|
|
@@ -138,21 +153,41 @@ export class MessageBusClient {
|
|
|
138
153
|
else
|
|
139
154
|
pending.reject(new Error(frame.error));
|
|
140
155
|
}
|
|
141
|
-
handleSnapshot(
|
|
142
|
-
const state = this.subs.get(path);
|
|
156
|
+
handleSnapshot(frame) {
|
|
157
|
+
const state = this.subs.get(frame.path);
|
|
143
158
|
if (!state)
|
|
144
159
|
return;
|
|
145
|
-
|
|
160
|
+
// Drop strictly-older snapshots. If seq === lastSeq we still apply so
|
|
161
|
+
// onSnapshot fires once per wire subscription; at equal seq the data
|
|
162
|
+
// is equivalent to what the raced upd delivered, so applying is a
|
|
163
|
+
// no-op-plus-callback rather than a rollback.
|
|
164
|
+
if (frame.seq !== undefined &&
|
|
165
|
+
state.lastSeq !== undefined &&
|
|
166
|
+
frame.seq < state.lastSeq) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (frame.seq !== undefined)
|
|
170
|
+
state.lastSeq = frame.seq;
|
|
171
|
+
state.lastSnapshot = { data: frame.data };
|
|
146
172
|
for (const cb of state.subscribers)
|
|
147
|
-
cb.onSnapshot(data);
|
|
173
|
+
cb.onSnapshot(frame.data);
|
|
148
174
|
}
|
|
149
|
-
handleUpdate(
|
|
150
|
-
const state = this.subs.get(path);
|
|
175
|
+
handleUpdate(frame) {
|
|
176
|
+
const state = this.subs.get(frame.path);
|
|
151
177
|
if (!state)
|
|
152
178
|
return;
|
|
153
|
-
|
|
179
|
+
// Drop updates we've already seen. Updates at `lastSeq` are redundant
|
|
180
|
+
// (already applied); strictly older are stale.
|
|
181
|
+
if (frame.seq !== undefined &&
|
|
182
|
+
state.lastSeq !== undefined &&
|
|
183
|
+
frame.seq <= state.lastSeq) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (frame.seq !== undefined)
|
|
187
|
+
state.lastSeq = frame.seq;
|
|
188
|
+
state.lastSnapshot = { data: frame.data };
|
|
154
189
|
for (const cb of state.subscribers)
|
|
155
|
-
cb.onUpdate(data);
|
|
190
|
+
cb.onUpdate(frame.data);
|
|
156
191
|
}
|
|
157
192
|
handleSubError(path, error) {
|
|
158
193
|
const state = this.subs.get(path);
|
|
@@ -167,8 +202,12 @@ export class MessageBusClient {
|
|
|
167
202
|
this.queue = [];
|
|
168
203
|
for (const fn of pending)
|
|
169
204
|
fn();
|
|
170
|
-
// Re-establish wire subscriptions.
|
|
205
|
+
// Re-establish wire subscriptions. Clear lastSeq so the fresh snapshot
|
|
206
|
+
// is always accepted — the server may have restarted and reset its
|
|
207
|
+
// counter, in which case our stale lastSeq would erroneously drop
|
|
208
|
+
// everything the new server sends.
|
|
171
209
|
for (const state of this.subs.values()) {
|
|
210
|
+
state.lastSeq = undefined;
|
|
172
211
|
this.transport.send({ kind: 'sub', path: state.path });
|
|
173
212
|
state.wireActive = true;
|
|
174
213
|
}
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,5 +3,6 @@ export type { CommandHandler, SubscribeHandler } from './server.js';
|
|
|
3
3
|
export { MessageBusClient } from './client.js';
|
|
4
4
|
export type { CommandOptions, SubscribeCallbacks } from './client.js';
|
|
5
5
|
export type { ClientTransport, PeerId, ServerTransport, } from './transport.js';
|
|
6
|
+
export { GET_SNAPSHOT_VERB } from './types.js';
|
|
6
7
|
export type { AnyFrame, ClientFrame, CommandFrame, CommandResultFrame, PathParams, ServerFrame, SnapshotFrame, SubscribeErrorFrame, SubscribeFrame, UnsubscribeFrame, UpdateFrame, } from './types.js';
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtE,YAAY,EACV,eAAe,EACf,MAAM,EACN,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtE,YAAY,EACV,eAAe,EACf,MAAM,EACN,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAO/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ServerTransport, PeerId } from './transport.js';
|
|
2
|
-
import type
|
|
2
|
+
import { GET_SNAPSHOT_VERB, type PathParams } from './types.js';
|
|
3
|
+
export { GET_SNAPSHOT_VERB };
|
|
3
4
|
export type CommandHandler<P = unknown, R = unknown> = (payload: P, ctx: {
|
|
4
5
|
peer: PeerId;
|
|
5
6
|
}) => Promise<R> | R;
|
|
@@ -26,6 +27,16 @@ export declare class MessageBusServer {
|
|
|
26
27
|
private subscriptions;
|
|
27
28
|
private active;
|
|
28
29
|
private byPeer;
|
|
30
|
+
/**
|
|
31
|
+
* Monotonic sequence per path. Incremented on publish; read at snapshot
|
|
32
|
+
* capture time so clients can drop frames that are older than what they
|
|
33
|
+
* have already applied. This protects against a race in `handleSubscribe`
|
|
34
|
+
* where a `publish` fires during the `await` before the snapshot is sent —
|
|
35
|
+
* without seq, the late-arriving snapshot would overwrite the newer update.
|
|
36
|
+
*/
|
|
37
|
+
private seqByPath;
|
|
38
|
+
private nextSeq;
|
|
39
|
+
private currentSeq;
|
|
29
40
|
constructor(transport: ServerTransport);
|
|
30
41
|
onCommand<P = unknown, R = unknown>(verb: string, handler: CommandHandler<P, R>): void;
|
|
31
42
|
onSubscribe<Path extends string, S = unknown, U = unknown>(pattern: Path, handler: SubscribeHandler<Path, S, U>): void;
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAoB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAElF,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B,MAAM,MAAM,cAAc,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,IAAI,CACrD,OAAO,EAAE,CAAC,EACV,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,KAClB,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAEpB,MAAM,MAAM,gBAAgB,CAC1B,IAAI,SAAS,MAAM,GAAG,MAAM,EAC5B,CAAC,GAAG,OAAO,EAKX,EAAE,GAAG,OAAO,IACV;IACF,QAAQ,EAAE,CAAC,GAAG,EAAE;QACd,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC;KACd,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC;KACd,KAAK,IAAI,CAAC;IACX,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,EAAE,MAAM,CAAC;KACd,KAAK,IAAI,CAAC;CACZ,CAAC;AAcF,qBAAa,gBAAgB;IAwBf,OAAO,CAAC,SAAS;IAvB7B,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,MAAM,CAAkC;IAChD;;;;;;OAMG;IACH,OAAO,CAAC,SAAS,CAA6B;IAE9C,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,UAAU;gBAIE,SAAS,EAAE,eAAe;IAyB9C,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,GAC5B,IAAI;IAYP,WAAW,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EACvD,OAAO,EAAE,IAAI,EACb,OAAO,EAAE,gBAAgB,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,GACpC,IAAI;IAYP;;;OAGG;IACH,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM;IAYnD,gEAAgE;IAChE,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAQrC,OAAO,CAAC,WAAW;YAcL,aAAa;YA6Bb,eAAe;YAkDf,YAAY;IAuB1B,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,sBAAsB;IAmB9B,OAAO,CAAC,SAAS;CASlB"}
|
package/dist/server.js
CHANGED
|
@@ -1,16 +1,57 @@
|
|
|
1
1
|
import { matchPattern, parsePattern, sortPatternsBySpecificity, } from './path.js';
|
|
2
|
+
import { GET_SNAPSHOT_VERB } from './types.js';
|
|
3
|
+
export { GET_SNAPSHOT_VERB };
|
|
2
4
|
export class MessageBusServer {
|
|
3
5
|
transport;
|
|
4
6
|
commands = new Map();
|
|
5
7
|
subscriptions = [];
|
|
6
8
|
active = new Map();
|
|
7
9
|
byPeer = new Map();
|
|
10
|
+
/**
|
|
11
|
+
* Monotonic sequence per path. Incremented on publish; read at snapshot
|
|
12
|
+
* capture time so clients can drop frames that are older than what they
|
|
13
|
+
* have already applied. This protects against a race in `handleSubscribe`
|
|
14
|
+
* where a `publish` fires during the `await` before the snapshot is sent —
|
|
15
|
+
* without seq, the late-arriving snapshot would overwrite the newer update.
|
|
16
|
+
*/
|
|
17
|
+
seqByPath = new Map();
|
|
18
|
+
nextSeq(path) {
|
|
19
|
+
const next = (this.seqByPath.get(path) ?? 0) + 1;
|
|
20
|
+
this.seqByPath.set(path, next);
|
|
21
|
+
return next;
|
|
22
|
+
}
|
|
23
|
+
currentSeq(path) {
|
|
24
|
+
return this.seqByPath.get(path) ?? 0;
|
|
25
|
+
}
|
|
8
26
|
constructor(transport) {
|
|
9
27
|
this.transport = transport;
|
|
10
28
|
transport.onFrame((peer, frame) => this.handleFrame(peer, frame));
|
|
11
29
|
transport.onPeerDisconnected((peer) => this.handlePeerDisconnected(peer));
|
|
30
|
+
// Reserve the `$getSnapshot` verb for one-shot reads of any subscribable
|
|
31
|
+
// path. The handler reuses `sendSnapshot`-style logic but does not create
|
|
32
|
+
// an `ActiveSub`, so no `onSubscribed`/`onUnsubscribed` callbacks fire
|
|
33
|
+
// and the peer doesn't accumulate sub state for a value it only wanted
|
|
34
|
+
// to read once. Clients access this via `MessageBusClient.getSnapshot`.
|
|
35
|
+
this.commands.set(GET_SNAPSHOT_VERB, async (payload, ctx) => {
|
|
36
|
+
const { path } = (payload ?? {});
|
|
37
|
+
if (typeof path !== 'string' || !path) {
|
|
38
|
+
throw new Error(`${GET_SNAPSHOT_VERB}: missing "path"`);
|
|
39
|
+
}
|
|
40
|
+
const matched = this.findMatch(path);
|
|
41
|
+
if (!matched) {
|
|
42
|
+
throw new Error(`No subscription handler for path: ${path}`);
|
|
43
|
+
}
|
|
44
|
+
return matched.entry.handler.snapshot({
|
|
45
|
+
path,
|
|
46
|
+
params: matched.params,
|
|
47
|
+
peer: ctx.peer,
|
|
48
|
+
});
|
|
49
|
+
});
|
|
12
50
|
}
|
|
13
51
|
onCommand(verb, handler) {
|
|
52
|
+
if (verb === GET_SNAPSHOT_VERB) {
|
|
53
|
+
throw new Error(`Command "${verb}" is reserved; use onSubscribe to expose a path`);
|
|
54
|
+
}
|
|
14
55
|
if (this.commands.has(verb)) {
|
|
15
56
|
throw new Error(`Command "${verb}" is already registered`);
|
|
16
57
|
}
|
|
@@ -32,10 +73,11 @@ export class MessageBusServer {
|
|
|
32
73
|
* Returns the number of peers that received the update.
|
|
33
74
|
*/
|
|
34
75
|
publish(path, data) {
|
|
76
|
+
const seq = this.nextSeq(path);
|
|
35
77
|
let count = 0;
|
|
36
78
|
for (const sub of this.active.values()) {
|
|
37
79
|
if (sub.path === path) {
|
|
38
|
-
this.transport.send(sub.peer, { kind: 'upd', path, data });
|
|
80
|
+
this.transport.send(sub.peer, { kind: 'upd', path, data, seq });
|
|
39
81
|
count++;
|
|
40
82
|
}
|
|
41
83
|
}
|
|
@@ -142,12 +184,18 @@ export class MessageBusServer {
|
|
|
142
184
|
if (!handler) {
|
|
143
185
|
throw new Error(`Subscription pattern "${entry.pattern.pattern}" is no longer registered`);
|
|
144
186
|
}
|
|
187
|
+
// Capture seq BEFORE invoking the handler. Snapshot data reflects state
|
|
188
|
+
// "as of" the moment the handler starts reading; any publish that races
|
|
189
|
+
// during the await assigns a strictly greater seq. The client uses this
|
|
190
|
+
// to drop a late-arriving snapshot whose data has already been
|
|
191
|
+
// superseded by a newer update delivered ahead of it on the wire.
|
|
192
|
+
const seq = this.currentSeq(entry.path);
|
|
145
193
|
const data = await handler.snapshot({
|
|
146
194
|
path: entry.path,
|
|
147
195
|
params: entry.params,
|
|
148
196
|
peer,
|
|
149
197
|
});
|
|
150
|
-
this.transport.send(peer, { kind: 'snap', path: entry.path, data });
|
|
198
|
+
this.transport.send(peer, { kind: 'snap', path: entry.path, data, seq });
|
|
151
199
|
}
|
|
152
200
|
handleUnsubscribe(peer, path) {
|
|
153
201
|
const key = subKey(peer, path);
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,yBAAyB,GAE1B,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -29,11 +29,25 @@ export type SnapshotFrame = {
|
|
|
29
29
|
kind: 'snap';
|
|
30
30
|
path: string;
|
|
31
31
|
data: unknown;
|
|
32
|
+
/**
|
|
33
|
+
* Monotonic per-path sequence number. Snapshot carries the seq of the
|
|
34
|
+
* latest publish at the time the snapshot data was captured; clients drop
|
|
35
|
+
* any snapshot whose seq is not newer than the last-applied frame for the
|
|
36
|
+
* same path, preventing a raced snapshot from overwriting a more-recent
|
|
37
|
+
* update. Absent on frames from legacy servers — clients fall back to the
|
|
38
|
+
* pre-seq behavior (apply unconditionally) in that case.
|
|
39
|
+
*/
|
|
40
|
+
seq?: number;
|
|
32
41
|
};
|
|
33
42
|
export type UpdateFrame = {
|
|
34
43
|
kind: 'upd';
|
|
35
44
|
path: string;
|
|
36
45
|
data: unknown;
|
|
46
|
+
/**
|
|
47
|
+
* Monotonic per-path sequence number assigned at publish time. See
|
|
48
|
+
* `SnapshotFrame.seq`. Absent on frames from legacy servers.
|
|
49
|
+
*/
|
|
50
|
+
seq?: number;
|
|
37
51
|
};
|
|
38
52
|
export type SubscribeErrorFrame = {
|
|
39
53
|
kind: 'sub-error';
|
|
@@ -47,6 +61,13 @@ export type UnsubscribeFrame = {
|
|
|
47
61
|
export type ClientFrame = CommandFrame | SubscribeFrame | UnsubscribeFrame;
|
|
48
62
|
export type ServerFrame = CommandResultFrame | SnapshotFrame | UpdateFrame | SubscribeErrorFrame;
|
|
49
63
|
export type AnyFrame = ClientFrame | ServerFrame;
|
|
64
|
+
/**
|
|
65
|
+
* Reserved command verb for one-shot snapshot retrieval. Clients send
|
|
66
|
+
* `{ path }` and the server invokes the matching subscription handler's
|
|
67
|
+
* `snapshot()` without creating a subscription. Userland `onCommand`
|
|
68
|
+
* handlers cannot re-register this verb.
|
|
69
|
+
*/
|
|
70
|
+
export declare const GET_SNAPSHOT_VERB = "$getSnapshot";
|
|
50
71
|
/** Extract `:param` names from a path pattern as a union of string literals. */
|
|
51
72
|
export type PathParams<P extends string> = P extends `${string}:${infer Param}/${infer Rest}` ? {
|
|
52
73
|
[K in Param | keyof PathParams<`/${Rest}`>]: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,KAAK,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,KAAK,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd;;;;;;;OAOG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAC3E,MAAM,MAAM,WAAW,GACnB,kBAAkB,GAClB,aAAa,GACb,WAAW,GACX,mBAAmB,CAAC;AAExB,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD,gFAAgF;AAChF,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,IACrC,CAAC,SAAS,GAAG,MAAM,IAAI,MAAM,KAAK,IAAI,MAAM,IAAI,EAAE,GAC9C;KAAG,CAAC,IAAI,KAAK,GAAG,MAAM,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,MAAM;CAAE,GACvD,CAAC,SAAS,GAAG,MAAM,IAAI,MAAM,KAAK,EAAE,GAClC;KAAG,CAAC,IAAI,KAAK,GAAG,MAAM;CAAE,GACxB,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC"}
|
package/dist/types.js
CHANGED
|
@@ -4,5 +4,11 @@
|
|
|
4
4
|
* Commands are one-shot request/response.
|
|
5
5
|
* Subscriptions deliver an initial snapshot followed by updates until unsub.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Reserved command verb for one-shot snapshot retrieval. Clients send
|
|
9
|
+
* `{ path }` and the server invokes the matching subscription handler's
|
|
10
|
+
* `snapshot()` without creating a subscription. Userland `onCommand`
|
|
11
|
+
* handlers cannot re-register this verb.
|
|
12
|
+
*/
|
|
13
|
+
export const GET_SNAPSHOT_VERB = '$getSnapshot';
|
|
8
14
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC"}
|