orez-sync-executor 0.11.1 → 0.11.2

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 (57) hide show
  1. package/dist/realtime/host.d.ts +7 -0
  2. package/dist/realtime/host.d.ts.map +1 -0
  3. package/dist/realtime/host.js +77 -0
  4. package/dist/realtime/host.js.map +1 -0
  5. package/dist/realtime/hub.d.ts +67 -0
  6. package/dist/realtime/hub.d.ts.map +1 -0
  7. package/dist/realtime/hub.js +456 -0
  8. package/dist/realtime/hub.js.map +1 -0
  9. package/dist/realtime/index.d.ts +24 -0
  10. package/dist/realtime/index.d.ts.map +1 -0
  11. package/dist/realtime/index.js +27 -0
  12. package/dist/realtime/index.js.map +1 -0
  13. package/dist/realtime/local.d.ts +15 -0
  14. package/dist/realtime/local.d.ts.map +1 -0
  15. package/dist/realtime/local.js +63 -0
  16. package/dist/realtime/local.js.map +1 -0
  17. package/dist/realtime/manifest.d.ts +51 -0
  18. package/dist/realtime/manifest.d.ts.map +1 -0
  19. package/dist/realtime/manifest.js +110 -0
  20. package/dist/realtime/manifest.js.map +1 -0
  21. package/dist/realtime/message-port.d.ts +34 -0
  22. package/dist/realtime/message-port.d.ts.map +1 -0
  23. package/dist/realtime/message-port.js +141 -0
  24. package/dist/realtime/message-port.js.map +1 -0
  25. package/dist/realtime/producer-socket.d.ts +10 -0
  26. package/dist/realtime/producer-socket.d.ts.map +1 -0
  27. package/dist/realtime/producer-socket.js +90 -0
  28. package/dist/realtime/producer-socket.js.map +1 -0
  29. package/dist/realtime/producer.d.ts +16 -0
  30. package/dist/realtime/producer.d.ts.map +1 -0
  31. package/dist/realtime/producer.js +51 -0
  32. package/dist/realtime/producer.js.map +1 -0
  33. package/dist/realtime/protocol.d.ts +99 -0
  34. package/dist/realtime/protocol.d.ts.map +1 -0
  35. package/dist/realtime/protocol.js +191 -0
  36. package/dist/realtime/protocol.js.map +1 -0
  37. package/dist/realtime/publisher.d.ts +28 -0
  38. package/dist/realtime/publisher.d.ts.map +1 -0
  39. package/dist/realtime/publisher.js +309 -0
  40. package/dist/realtime/publisher.js.map +1 -0
  41. package/dist/realtime/socket-host.d.ts +25 -0
  42. package/dist/realtime/socket-host.d.ts.map +1 -0
  43. package/dist/realtime/socket-host.js +105 -0
  44. package/dist/realtime/socket-host.js.map +1 -0
  45. package/dist/realtime/store.d.ts +28 -0
  46. package/dist/realtime/store.d.ts.map +1 -0
  47. package/dist/realtime/store.js +0 -0
  48. package/dist/realtime/store.js.map +1 -0
  49. package/dist/realtime/writer.d.ts +17 -0
  50. package/dist/realtime/writer.d.ts.map +1 -0
  51. package/dist/realtime/writer.js +138 -0
  52. package/dist/realtime/writer.js.map +1 -0
  53. package/package.json +5 -1
  54. package/dist/adapters.d.ts +0 -25
  55. package/dist/adapters.d.ts.map +0 -1
  56. package/dist/adapters.js +0 -116
  57. package/dist/adapters.js.map +0 -1
@@ -0,0 +1,7 @@
1
+ import type { RealtimeHub, HubConnection, HubProducer } from './hub.js';
2
+ import type { ClientFrame, HostFrame, ProducerFrame } from './protocol.js';
3
+ import type { RealtimeStore } from './store.js';
4
+ export declare function applyClientFrame(hub: RealtimeHub, connection: HubConnection, frame: ClientFrame): Promise<void>;
5
+ export declare function applyProducerFrame(hub: RealtimeHub, producer: HubProducer, frame: ProducerFrame): void;
6
+ export declare function applyHostFrame(store: RealtimeStore, frame: HostFrame): void;
7
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/realtime/host.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACvE,OAAO,KAAK,EAAE,WAAW,EAAe,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AACvF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAK/C,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,WAAW,EAChB,UAAU,EAAE,aAAa,EACzB,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,IAAI,CAAC,CAIf;AAQD,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,WAAW,EACrB,KAAK,EAAE,aAAa,GACnB,IAAI,CAuBN;AASD,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAc3E"}
@@ -0,0 +1,77 @@
1
+ // Frame routing. Every realtime surface is built from these three functions.
2
+ //
3
+ // A stream has exactly three directions, and there is one applier for each:
4
+ //
5
+ // applyClientFrame subscriber -> hub subscribe, unsubscribe
6
+ // applyProducerFrame producer -> hub begin, publish
7
+ // applyHostFrame hub -> store subscribed, field, subscribe-error
8
+ //
9
+ // Everything else in a surface is channel plumbing: a MessagePort, a
10
+ // WebSocket, or a direct call. Keeping the routing here is what lets a new
11
+ // transport be written without re-deriving which frame maps to which call, and
12
+ // it is why adding one cannot quietly disagree with the others.
13
+ //
14
+ // Subscribers and producers are deliberately separate roles with separate
15
+ // frames. A subscriber socket can never publish, so a leaked streamID buys an
16
+ // attacker nothing: the hub checks the producer HANDLE, and a subscriber does
17
+ // not have one.
18
+ // Apply one subscriber frame. The returned promise resolves when the frame has
19
+ // been applied, which an adapter awaits before processing the next frame from
20
+ // the same socket so a subscribe/unsubscribe pair cannot land out of order.
21
+ export function applyClientFrame(hub, connection, frame) {
22
+ return frame[0] === 'subscribe'
23
+ ? hub.subscribe(connection, frame[1].topic)
24
+ : hub.unsubscribe(connection, frame[1].topic);
25
+ }
26
+ // Apply one producer frame.
27
+ //
28
+ // `begin` is answered either way: the producer cannot start streaming until it
29
+ // knows the host accepted the generation. Updates are answered only when
30
+ // rejected, so a token stream costs one frame per token rather than a round
31
+ // trip per token.
32
+ export function applyProducerFrame(hub, producer, frame) {
33
+ if (frame[0] === 'begin') {
34
+ const { topic, streamID } = frame[1];
35
+ const result = hub.beginGeneration(producer, topic, streamID);
36
+ producer.send([
37
+ 'begin-result',
38
+ {
39
+ streamID,
40
+ topic: result.ok ? result.topicID : null,
41
+ reason: result.ok ? null : result.reason,
42
+ },
43
+ ]);
44
+ return;
45
+ }
46
+ const { update } = frame[1];
47
+ const result = hub.publish(producer, update);
48
+ if (!result.ok) {
49
+ producer.send([
50
+ 'publish-rejected',
51
+ { topic: update.topic, streamID: update.streamID, reason: result.reason },
52
+ ]);
53
+ }
54
+ }
55
+ // Apply one frame the host sent back to a subscriber. Every client transport
56
+ // ends in this call, so a MessagePort client and a WebSocket client cannot drift
57
+ // apart in how they interpret the same frame.
58
+ //
59
+ // A `wake` frame is deliberately ignored here: it belongs to the Zero pull path,
60
+ // not to the field overlay, and a client that shares one socket for both routes
61
+ // it before reaching this.
62
+ export function applyHostFrame(store, frame) {
63
+ switch (frame[0]) {
64
+ case 'field':
65
+ store.applyUpdates(frame[1].updates);
66
+ return;
67
+ case 'subscribed':
68
+ store.handleSubscribed(frame[1].topic, frame[1].status);
69
+ return;
70
+ case 'subscribe-error':
71
+ store.handleSubscribeError(frame[1].topic, frame[1].reason);
72
+ return;
73
+ case 'wake':
74
+ return;
75
+ }
76
+ }
77
+ //# sourceMappingURL=host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/realtime/host.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,EAAE;AACF,4EAA4E;AAC5E,EAAE;AACF,oEAAoE;AACpE,4DAA4D;AAC5D,gFAAgF;AAChF,EAAE;AACF,qEAAqE;AACrE,2EAA2E;AAC3E,+EAA+E;AAC/E,gEAAgE;AAChE,EAAE;AACF,0EAA0E;AAC1E,8EAA8E;AAC9E,8EAA8E;AAC9E,gBAAgB;AAMhB,+EAA+E;AAC/E,8EAA8E;AAC9E,4EAA4E;AAC5E,MAAM,UAAU,gBAAgB,CAC9B,GAAgB,EAChB,UAAyB,EACzB,KAAkB;IAElB,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,WAAW;QAC7B,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAC3C,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;AACjD,CAAC;AAED,4BAA4B;AAC5B,EAAE;AACF,+EAA+E;AAC/E,yEAAyE;AACzE,4EAA4E;AAC5E,kBAAkB;AAClB,MAAM,UAAU,kBAAkB,CAChC,GAAgB,EAChB,QAAqB,EACrB,KAAoB;IAEpB,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QACzB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACpC,MAAM,MAAM,GAAG,GAAG,CAAC,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAA;QAC7D,QAAQ,CAAC,IAAI,CAAC;YACZ,cAAc;YACd;gBACE,QAAQ;gBACR,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;gBACxC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM;aACzC;SACF,CAAC,CAAA;QACF,OAAM;IACR,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;IAC3B,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAC5C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,QAAQ,CAAC,IAAI,CAAC;YACZ,kBAAkB;YAClB,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;SAC1E,CAAC,CAAA;IACJ,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,iFAAiF;AACjF,8CAA8C;AAC9C,EAAE;AACF,iFAAiF;AACjF,gFAAgF;AAChF,2BAA2B;AAC3B,MAAM,UAAU,cAAc,CAAC,KAAoB,EAAE,KAAgB;IACnE,QAAQ,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACjB,KAAK,OAAO;YACV,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAiC,CAAC,CAAA;YAC9D,OAAM;QACR,KAAK,YAAY;YACf,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;YACvD,OAAM;QACR,KAAK,iBAAiB;YACpB,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;YAC3D,OAAM;QACR,KAAK,MAAM;YACT,OAAM;IACV,CAAC;AACH,CAAC"}
@@ -0,0 +1,67 @@
1
+ import type { StreamingFieldSpec, StreamingManifest } from './manifest.js';
2
+ import type { FieldUpdate, RealtimeTopic } from './protocol.js';
3
+ export type RealtimeIdentity = {
4
+ readonly userID: string;
5
+ readonly clientID: string;
6
+ readonly clientGroupID: string;
7
+ };
8
+ export interface HubConnection {
9
+ readonly id: string;
10
+ readonly identity: RealtimeIdentity;
11
+ send(frame: unknown): void;
12
+ }
13
+ export interface HubProducer {
14
+ readonly id: string;
15
+ send(frame: unknown): void;
16
+ }
17
+ export type SubscribeAuthorization = {
18
+ readonly status: 'active' | 'pending';
19
+ } | {
20
+ readonly status: 'denied';
21
+ readonly reason: string;
22
+ };
23
+ export type HubLimits = {
24
+ readonly maxTopicsPerConnection: number;
25
+ readonly maxSubscribersPerTopic: number;
26
+ readonly maxTopicsPerNamespace: number;
27
+ readonly maxBatchBytes: number;
28
+ readonly batchWindowMs: number;
29
+ };
30
+ export declare const DEFAULT_HUB_LIMITS: HubLimits;
31
+ export type HubOptions = {
32
+ readonly manifest: StreamingManifest;
33
+ readonly authorizeSubscribe: (identity: RealtimeIdentity, topic: RealtimeTopic, spec: StreamingFieldSpec) => Promise<SubscribeAuthorization> | SubscribeAuthorization;
34
+ readonly limits?: Partial<HubLimits>;
35
+ readonly scheduleFlush?: (flush: () => void, ms: number) => void;
36
+ };
37
+ export declare class RealtimeHub {
38
+ #private;
39
+ constructor(options: HubOptions);
40
+ subscribe(connection: HubConnection, topic: RealtimeTopic): Promise<void>;
41
+ unsubscribe(connection: HubConnection, topic: RealtimeTopic): Promise<void>;
42
+ dropConnection(connectionID: string): void;
43
+ revokeMembership(clientGroupID: string, removed: readonly RealtimeTopic[]): void;
44
+ revokeAllForGroup(clientGroupID: string): void;
45
+ beginGeneration(producer: HubProducer, topic: RealtimeTopic, streamID: string): {
46
+ readonly ok: true;
47
+ readonly topicID: string;
48
+ } | {
49
+ readonly ok: false;
50
+ readonly reason: string;
51
+ };
52
+ publish(producer: HubProducer, update: FieldUpdate): {
53
+ readonly ok: true;
54
+ } | {
55
+ readonly ok: false;
56
+ readonly reason: string;
57
+ };
58
+ dropProducer(producerID: string): void;
59
+ flush(): void;
60
+ get activeTopics(): number;
61
+ get subscribedTopics(): number;
62
+ generationFor(topicID: string): {
63
+ readonly streamID: string;
64
+ readonly seq: number;
65
+ } | undefined;
66
+ }
67
+ //# sourceMappingURL=hub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub.d.ts","sourceRoot":"","sources":["../../src/realtime/hub.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,456 @@
1
+ // The host-side realtime hub: one pure state machine shared by every
2
+ // TypeScript host (the Cloudflare Durable Object and the browser worker).
3
+ //
4
+ // It owns no I/O. Connections are opaque handles with a `send`, so the same
5
+ // logic drives a hibernatable WebSocket, a MessagePort, and a test harness. A
6
+ // host adapter is then only socket lifecycle plus authentication.
7
+ //
8
+ // The hub ACCUMULATES each generation's value. That is what makes append-mode
9
+ // frames safe: a subscriber arriving at token 900 gets one snapshot of what the
10
+ // hub has, then appends, and no client ever needs a replay buffer. It is also
11
+ // why a lost frame cannot produce a wrong value, since the next snapshot after
12
+ // any reconnect is authoritative.
13
+ import { resolveTopic } from './manifest.js';
14
+ import { canonicalEncode } from './store.js';
15
+ export const DEFAULT_HUB_LIMITS = {
16
+ maxTopicsPerConnection: 256,
17
+ maxSubscribersPerTopic: 512,
18
+ maxTopicsPerNamespace: 4096,
19
+ maxBatchBytes: 512 * 1024,
20
+ batchWindowMs: 25,
21
+ };
22
+ export class RealtimeHub {
23
+ #manifest;
24
+ #authorize;
25
+ #limits;
26
+ #schedule;
27
+ #generations = new Map();
28
+ #subscribers = new Map();
29
+ #connectionTopics = new Map();
30
+ #connections = new Map();
31
+ // producer id -> every generation it currently leases. An application server
32
+ // streaming twenty agent sessions holds one connection, not twenty, so the
33
+ // lease is a set: the socket closing releases all of them at once.
34
+ #producerGenerations = new Map();
35
+ // per-connection outbound batch, flushed on the batching window
36
+ #outbox = new Map();
37
+ #flushScheduled = false;
38
+ // One chain per connection so its subscribe and unsubscribe frames apply in
39
+ // arrival order even though authorization may await. Without it, a
40
+ // subscribe/unsubscribe pair sent back to back could resolve out of order and
41
+ // leave a connection subscribed to a topic it had already dropped.
42
+ #connectionQueue = new Map();
43
+ // Bumped by dropConnection. A subscribe captures the epoch when the frame
44
+ // ARRIVES, not when its queued task runs, so a socket that closes while its
45
+ // authorization is still in flight abandons the subscription instead of
46
+ // completing it against a connection nobody is reading from.
47
+ #connectionEpoch = new Map();
48
+ constructor(options) {
49
+ this.#manifest = options.manifest;
50
+ this.#authorize = options.authorizeSubscribe;
51
+ this.#limits = { ...DEFAULT_HUB_LIMITS, ...options.limits };
52
+ this.#schedule =
53
+ options.scheduleFlush ??
54
+ ((flush, ms) => {
55
+ setTimeout(flush, ms);
56
+ });
57
+ }
58
+ // ---- subscribers --------------------------------------------------------
59
+ // Queued per connection: the returned promise resolves once this frame has
60
+ // been applied, which is what a host adapter awaits before processing the
61
+ // next frame from the same socket.
62
+ subscribe(connection, topic) {
63
+ const epoch = this.#connectionEpoch.get(connection.id) ?? 0;
64
+ return this.#enqueue(connection.id, () => this.#subscribe(connection, topic, epoch));
65
+ }
66
+ unsubscribe(connection, topic) {
67
+ return this.#enqueue(connection.id, () => {
68
+ const resolved = resolveTopic(this.#manifest, topic);
69
+ if ('reason' in resolved)
70
+ return;
71
+ this.#removeSubscription(connection.id, resolved.id);
72
+ });
73
+ }
74
+ #enqueue(connectionID, task) {
75
+ const previous = this.#connectionQueue.get(connectionID) ?? Promise.resolve();
76
+ // a rejected task must not poison the chain for later frames
77
+ const next = previous.then(task).catch(() => { });
78
+ this.#connectionQueue.set(connectionID, next);
79
+ return next;
80
+ }
81
+ #isCurrent(connectionID, epoch) {
82
+ return (this.#connectionEpoch.get(connectionID) ?? 0) === epoch;
83
+ }
84
+ async #subscribe(connection, topic, epoch) {
85
+ if (!this.#isCurrent(connection.id, epoch))
86
+ return;
87
+ this.#connections.set(connection.id, connection);
88
+ const resolved = resolveTopic(this.#manifest, topic);
89
+ if ('reason' in resolved) {
90
+ connection.send([
91
+ 'subscribe-error',
92
+ { topic: describe(topic), reason: resolved.reason },
93
+ ]);
94
+ return;
95
+ }
96
+ const { spec, id } = resolved;
97
+ const owned = this.#connectionTopics.get(connection.id) ?? new Set();
98
+ // a resubscribe after reconnect is not a new subscription
99
+ if (!owned.has(id)) {
100
+ if (owned.size >= this.#limits.maxTopicsPerConnection) {
101
+ connection.send([
102
+ 'subscribe-error',
103
+ { topic: id, reason: 'connection is at its subscription limit' },
104
+ ]);
105
+ return;
106
+ }
107
+ if (!this.#subscribers.has(id) &&
108
+ this.#subscribers.size >= this.#limits.maxTopicsPerNamespace) {
109
+ connection.send([
110
+ 'subscribe-error',
111
+ { topic: id, reason: 'namespace is at its active topic limit' },
112
+ ]);
113
+ return;
114
+ }
115
+ const existing = this.#subscribers.get(id);
116
+ if (existing && existing.size >= this.#limits.maxSubscribersPerTopic) {
117
+ connection.send([
118
+ 'subscribe-error',
119
+ { topic: id, reason: 'topic is at its subscriber limit' },
120
+ ]);
121
+ return;
122
+ }
123
+ }
124
+ const authorization = await this.#authorize(connection.identity, topic, spec);
125
+ // the socket can close while authorization is in flight
126
+ if (!this.#isCurrent(connection.id, epoch))
127
+ return;
128
+ if (authorization.status === 'denied') {
129
+ connection.send(['subscribe-error', { topic: id, reason: authorization.reason }]);
130
+ return;
131
+ }
132
+ owned.add(id);
133
+ this.#connectionTopics.set(connection.id, owned);
134
+ if (authorization.status === 'active') {
135
+ let subscribers = this.#subscribers.get(id);
136
+ if (!subscribers) {
137
+ subscribers = new Set();
138
+ this.#subscribers.set(id, subscribers);
139
+ }
140
+ subscribers.add(connection);
141
+ }
142
+ connection.send(['subscribed', { topic: id, status: authorization.status }]);
143
+ // catch a new subscriber up on a generation already in flight. This is what
144
+ // lets append-mode frames be safe for late joiners, and it is sent
145
+ // immediately rather than batched so a mid-stream mount paints at once.
146
+ const generation = this.#generations.get(id);
147
+ if (authorization.status === 'active' && generation) {
148
+ connection.send([
149
+ 'field',
150
+ {
151
+ updates: [
152
+ {
153
+ topic: id,
154
+ streamID: generation.streamID,
155
+ seq: generation.seq,
156
+ op: 'snapshot',
157
+ value: generation.value,
158
+ },
159
+ ],
160
+ },
161
+ ]);
162
+ }
163
+ }
164
+ dropConnection(connectionID) {
165
+ this.#connectionEpoch.set(connectionID, (this.#connectionEpoch.get(connectionID) ?? 0) + 1);
166
+ this.#connectionQueue.delete(connectionID);
167
+ for (const topicID of this.#connectionTopics.get(connectionID) ?? []) {
168
+ this.#subscribers.get(topicID)?.forEach((connection) => {
169
+ if (connection.id === connectionID)
170
+ this.#subscribers.get(topicID).delete(connection);
171
+ });
172
+ if (this.#subscribers.get(topicID)?.size === 0)
173
+ this.#subscribers.delete(topicID);
174
+ }
175
+ this.#connectionTopics.delete(connectionID);
176
+ this.#connections.delete(connectionID);
177
+ this.#outbox.delete(connectionID);
178
+ }
179
+ #removeSubscription(connectionID, topicID) {
180
+ this.#connectionTopics.get(connectionID)?.delete(topicID);
181
+ const subscribers = this.#subscribers.get(topicID);
182
+ if (!subscribers)
183
+ return;
184
+ for (const connection of subscribers) {
185
+ if (connection.id === connectionID)
186
+ subscribers.delete(connection);
187
+ }
188
+ if (subscribers.size === 0)
189
+ this.#subscribers.delete(topicID);
190
+ }
191
+ // A pull removed rows from a client group's query membership. The client is
192
+ // about to learn the row left its query, so its field subscriptions for those
193
+ // rows go with it, in the same update rather than on a later sweep.
194
+ revokeMembership(clientGroupID, removed) {
195
+ for (const topic of removed) {
196
+ const resolved = resolveTopic(this.#manifest, topic);
197
+ if ('reason' in resolved)
198
+ continue;
199
+ const subscribers = this.#subscribers.get(resolved.id);
200
+ if (!subscribers)
201
+ continue;
202
+ for (const connection of [...subscribers]) {
203
+ if (connection.identity.clientGroupID !== clientGroupID)
204
+ continue;
205
+ this.#removeSubscription(connection.id, resolved.id);
206
+ connection.send([
207
+ 'subscribe-error',
208
+ { topic: resolved.id, reason: 'row left your authorized query membership' },
209
+ ]);
210
+ }
211
+ }
212
+ }
213
+ // Every row a client group can currently subscribe to left its membership.
214
+ // Cheaper than enumerating rows when a whole query is dropped.
215
+ revokeAllForGroup(clientGroupID) {
216
+ for (const [topicID, subscribers] of [...this.#subscribers]) {
217
+ for (const connection of [...subscribers]) {
218
+ if (connection.identity.clientGroupID !== clientGroupID)
219
+ continue;
220
+ this.#removeSubscription(connection.id, topicID);
221
+ connection.send([
222
+ 'subscribe-error',
223
+ { topic: topicID, reason: 'row left your authorized query membership' },
224
+ ]);
225
+ }
226
+ }
227
+ }
228
+ // ---- producers ----------------------------------------------------------
229
+ // Open a generation. A newer generation always supersedes an older one for
230
+ // the same topic, matching how an LLM retry replaces its predecessor. The
231
+ // application still owns final-write fencing in the database; this only
232
+ // decides who may deliver display values.
233
+ beginGeneration(producer, topic, streamID) {
234
+ const resolved = resolveTopic(this.#manifest, topic);
235
+ if ('reason' in resolved)
236
+ return { ok: false, reason: resolved.reason };
237
+ const { spec, id } = resolved;
238
+ const previous = this.#generations.get(id);
239
+ if (previous && previous.streamID !== streamID) {
240
+ if (previous.producer) {
241
+ this.#releaseLease(previous.producer.id, id);
242
+ previous.producer.send(['superseded', { topic: id, streamID: previous.streamID }]);
243
+ }
244
+ }
245
+ this.#generations.set(id, {
246
+ topicID: id,
247
+ spec,
248
+ streamID,
249
+ seq: -1,
250
+ value: spec.mode === 'append' ? '' : null,
251
+ producer,
252
+ });
253
+ const leases = this.#producerGenerations.get(producer.id);
254
+ if (leases)
255
+ leases.add(id);
256
+ else
257
+ this.#producerGenerations.set(producer.id, new Set([id]));
258
+ return { ok: true, topicID: id };
259
+ }
260
+ // Accept one update from a producer, accumulate it, and fan it out. The
261
+ // rejection REASON is returned rather than a bare false: a producer that is
262
+ // told only "refused" has to guess between supersession, a stale sequence, and
263
+ // a manifest bound, and every adapter was inventing the same vague guess.
264
+ publish(producer, update) {
265
+ const generation = this.#generations.get(update.topic);
266
+ if (!generation) {
267
+ return { ok: false, reason: `no open generation for '${update.topic}'` };
268
+ }
269
+ // Only the producer holding this generation may publish. A subscriber
270
+ // socket is never a producer, so a leaked streamID grants nothing: the check
271
+ // is on the producer handle, not the frame contents. A superseded generation
272
+ // needs no flag of its own, because beginGeneration REPLACED it in this map;
273
+ // its old producer falls out here, and its old stream id falls out below.
274
+ if (generation.producer?.id !== producer.id) {
275
+ return { ok: false, reason: `another producer holds '${update.topic}'` };
276
+ }
277
+ if (generation.streamID !== update.streamID) {
278
+ return {
279
+ ok: false,
280
+ reason: `stream ${update.streamID} is not the current generation for '${update.topic}'`,
281
+ };
282
+ }
283
+ if (update.seq <= generation.seq) {
284
+ return {
285
+ ok: false,
286
+ reason: `seq ${update.seq} is not newer than the delivered ${generation.seq}`,
287
+ };
288
+ }
289
+ switch (update.op) {
290
+ case 'snapshot': {
291
+ if (!this.#validate(generation.spec, update.value)) {
292
+ return {
293
+ ok: false,
294
+ reason: `value failed the manifest bounds for '${update.topic}'`,
295
+ };
296
+ }
297
+ generation.value = update.value;
298
+ break;
299
+ }
300
+ case 'append': {
301
+ if (generation.spec.mode !== 'append') {
302
+ return {
303
+ ok: false,
304
+ reason: `'${update.topic}' is replace mode and takes no appends`,
305
+ };
306
+ }
307
+ const next = generation.value + update.text;
308
+ if (byteLength(next) > generation.spec.maxBytes) {
309
+ return {
310
+ ok: false,
311
+ reason: `append would exceed maxBytes for '${update.topic}'`,
312
+ };
313
+ }
314
+ generation.value = next;
315
+ break;
316
+ }
317
+ case 'end':
318
+ case 'abort':
319
+ break;
320
+ }
321
+ generation.seq = update.seq;
322
+ this.#fanOut(update);
323
+ if (update.op === 'end' || update.op === 'abort') {
324
+ this.#generations.delete(update.topic);
325
+ this.#releaseLease(producer.id, update.topic);
326
+ }
327
+ return { ok: true };
328
+ }
329
+ #releaseLease(producerID, topicID) {
330
+ const leases = this.#producerGenerations.get(producerID);
331
+ if (!leases)
332
+ return;
333
+ leases.delete(topicID);
334
+ if (leases.size === 0)
335
+ this.#producerGenerations.delete(producerID);
336
+ }
337
+ // A producer socket closed without a terminal frame (a crash, or a lost
338
+ // connection). The generation's lease is released so the next `begin` is
339
+ // clean; subscribers fall back to their inactivity deadline, which reveals
340
+ // the durable value rather than inventing a recovery value here.
341
+ dropProducer(producerID) {
342
+ const leases = this.#producerGenerations.get(producerID);
343
+ this.#producerGenerations.delete(producerID);
344
+ if (!leases)
345
+ return;
346
+ for (const topicID of leases) {
347
+ const generation = this.#generations.get(topicID);
348
+ if (generation?.producer?.id === producerID)
349
+ this.#generations.delete(topicID);
350
+ }
351
+ }
352
+ #validate(spec, value) {
353
+ if (spec.mode === 'append' && typeof value !== 'string')
354
+ return false;
355
+ if (spec.validate && !spec.validate(value))
356
+ return false;
357
+ return byteLength(canonicalEncode(value)) <= spec.maxBytes;
358
+ }
359
+ #fanOut(update) {
360
+ const subscribers = this.#subscribers.get(update.topic);
361
+ if (!subscribers || subscribers.size === 0)
362
+ return;
363
+ for (const connection of subscribers) {
364
+ const batch = this.#outbox.get(connection.id);
365
+ if (batch)
366
+ batch.push(update);
367
+ else
368
+ this.#outbox.set(connection.id, [update]);
369
+ }
370
+ this.#scheduleFlush();
371
+ }
372
+ // The "is a flush already pending" flag is separate from the cancel handle
373
+ // because a scheduler is allowed to run its callback SYNCHRONOUSLY, which the
374
+ // local in-process host does (there is no socket, so there is nothing to
375
+ // batch for). In that case flush() completes during the schedule call and
376
+ // clears its state before the handle could be assigned, so guarding on the
377
+ // handle alone left it permanently set and no later batch was ever scheduled.
378
+ #scheduleFlush() {
379
+ if (this.#flushScheduled)
380
+ return;
381
+ this.#flushScheduled = true;
382
+ this.#schedule(() => this.flush(), this.#limits.batchWindowMs);
383
+ }
384
+ // Deliver every pending batch. Public so an adapter can force a flush before
385
+ // it lets its runtime go idle.
386
+ flush() {
387
+ this.#flushScheduled = false;
388
+ if (this.#outbox.size === 0)
389
+ return;
390
+ const outbox = [...this.#outbox];
391
+ this.#outbox.clear();
392
+ let requeued = false;
393
+ for (const [connectionID, updates] of outbox) {
394
+ const connection = this.#connections.get(connectionID);
395
+ if (!connection)
396
+ continue;
397
+ // Stop a batch before it exceeds the frame ceiling; the rest goes in the
398
+ // next frame rather than being dropped or sent as one oversized frame.
399
+ let bytes = 0;
400
+ let cut = updates.length;
401
+ for (let index = 0; index < updates.length; index++) {
402
+ bytes += updateBytes(updates[index]);
403
+ if (bytes > this.#limits.maxBatchBytes && index > 0) {
404
+ cut = index;
405
+ break;
406
+ }
407
+ }
408
+ connection.send(['field', { updates: updates.slice(0, cut) }]);
409
+ if (cut < updates.length) {
410
+ this.#outbox.set(connectionID, updates.slice(cut));
411
+ requeued = true;
412
+ }
413
+ }
414
+ if (requeued)
415
+ this.#scheduleFlush();
416
+ }
417
+ // ---- introspection for adapters and tests -------------------------------
418
+ get activeTopics() {
419
+ return this.#generations.size;
420
+ }
421
+ get subscribedTopics() {
422
+ return this.#subscribers.size;
423
+ }
424
+ generationFor(topicID) {
425
+ const generation = this.#generations.get(topicID);
426
+ return generation ? { streamID: generation.streamID, seq: generation.seq } : undefined;
427
+ }
428
+ }
429
+ function describe(topic) {
430
+ return `${topic.table}.${topic.field}`;
431
+ }
432
+ function updateBytes(update) {
433
+ if (update.op === 'append')
434
+ return byteLength(update.text) + 96;
435
+ if (update.op === 'snapshot')
436
+ return byteLength(canonicalEncode(update.value)) + 96;
437
+ return 96;
438
+ }
439
+ function byteLength(value) {
440
+ let bytes = 0;
441
+ for (let index = 0; index < value.length; index++) {
442
+ const code = value.charCodeAt(index);
443
+ if (code < 0x80)
444
+ bytes += 1;
445
+ else if (code < 0x800)
446
+ bytes += 2;
447
+ else if (code >= 0xd800 && code < 0xdc00) {
448
+ bytes += 4;
449
+ index++;
450
+ }
451
+ else
452
+ bytes += 3;
453
+ }
454
+ return bytes;
455
+ }
456
+ //# sourceMappingURL=hub.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub.js","sourceRoot":"","sources":["../../src/realtime/hub.ts"],"names":[],"mappings":"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"}