@cello-protocol/client 0.0.21 → 0.0.22

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 (53) hide show
  1. package/dist/client-send-helpers.d.ts +25 -0
  2. package/dist/client-send-helpers.d.ts.map +1 -0
  3. package/dist/client-send-helpers.js +118 -0
  4. package/dist/client-send-helpers.js.map +1 -0
  5. package/dist/client-startup.d.ts +74 -0
  6. package/dist/client-startup.d.ts.map +1 -0
  7. package/dist/client-startup.js +337 -0
  8. package/dist/client-startup.js.map +1 -0
  9. package/dist/client-wiring.d.ts +120 -0
  10. package/dist/client-wiring.d.ts.map +1 -0
  11. package/dist/client-wiring.js +289 -0
  12. package/dist/client-wiring.js.map +1 -0
  13. package/dist/client.d.ts +29 -169
  14. package/dist/client.d.ts.map +1 -1
  15. package/dist/client.js +222 -5396
  16. package/dist/client.js.map +1 -1
  17. package/dist/connection-inbound-handler.d.ts +47 -0
  18. package/dist/connection-inbound-handler.d.ts.map +1 -0
  19. package/dist/connection-inbound-handler.js +325 -0
  20. package/dist/connection-inbound-handler.js.map +1 -0
  21. package/dist/connection-manager.d.ts +191 -0
  22. package/dist/connection-manager.d.ts.map +1 -0
  23. package/dist/connection-manager.js +692 -0
  24. package/dist/connection-manager.js.map +1 -0
  25. package/dist/frame-dispatch.d.ts +28 -0
  26. package/dist/frame-dispatch.d.ts.map +1 -0
  27. package/dist/frame-dispatch.js +118 -0
  28. package/dist/frame-dispatch.js.map +1 -0
  29. package/dist/registration-manager.d.ts +54 -0
  30. package/dist/registration-manager.d.ts.map +1 -0
  31. package/dist/registration-manager.js +248 -0
  32. package/dist/registration-manager.js.map +1 -0
  33. package/dist/relay-stream-manager.d.ts +136 -0
  34. package/dist/relay-stream-manager.d.ts.map +1 -0
  35. package/dist/relay-stream-manager.js +834 -0
  36. package/dist/relay-stream-manager.js.map +1 -0
  37. package/dist/seal-manager.d.ts +133 -0
  38. package/dist/seal-manager.d.ts.map +1 -0
  39. package/dist/seal-manager.js +803 -0
  40. package/dist/seal-manager.js.map +1 -0
  41. package/dist/session-assignment-parser.d.ts +33 -0
  42. package/dist/session-assignment-parser.d.ts.map +1 -0
  43. package/dist/session-assignment-parser.js +149 -0
  44. package/dist/session-assignment-parser.js.map +1 -0
  45. package/dist/session-manager.d.ts +132 -0
  46. package/dist/session-manager.d.ts.map +1 -0
  47. package/dist/session-manager.js +605 -0
  48. package/dist/session-manager.js.map +1 -0
  49. package/dist/signaling-manager.d.ts +85 -0
  50. package/dist/signaling-manager.d.ts.map +1 -0
  51. package/dist/signaling-manager.js +597 -0
  52. package/dist/signaling-manager.js.map +1 -0
  53. package/package.json +3 -3
@@ -0,0 +1,605 @@
1
+ /**
2
+ * SessionManager — SESSION-002, MSG-004, SESSION-007
3
+ *
4
+ * Extracted from CelloClientImpl. Owns the complete session lifecycle:
5
+ * - Session assignment acceptance (receiveSessionAssignment)
6
+ * - Outbound message sending (sendMessage, #sendMessageLocked)
7
+ * - Content delivery (sendContentFrame, waitForOwnEcho)
8
+ * - Inbound message queuing (enqueueReceivedMessage, enqueueSessionSealedEvent)
9
+ * - Async blocking receive (receiveSessionMessageAsync, receiveMessageAsync)
10
+ * - Session listing (listSessions)
11
+ *
12
+ * State owned here (not in facade):
13
+ * - #sessions: SessionRecord map
14
+ * - #sessionMessageQueues + #anyMessageQueue: inbound message queues
15
+ * - #receiveWaiters + #receiveAnyWaiters: async-receive wake resolvers
16
+ * - #outboundQueues: per-session send serialization chains
17
+ * - #pendingAckResolvers: in-flight ack resolvers
18
+ * - #ownEchoResolvers: echo wait resolvers (set by relay reader, resolved here)
19
+ * - #ownPendingContent: pre-buffered own sends (keyed by content_hash_hex)
20
+ * - #contentHandlerRegistered: content stream protocol guard
21
+ * - #onSessionAssignmentHandler: inbound session callback
22
+ */
23
+ import { createHash } from "node:crypto";
24
+ import { Encoder } from "cbor-x";
25
+ import * as lp from "it-length-prefixed";
26
+ import { computeGenesisPrevRoot, buildSessionEstablishmentTbs, } from "@cello-protocol/protocol-types";
27
+ import { verifyFrostSignature, CONTEXT_SESSION_ESTABLISHMENT } from "@cello-protocol/crypto";
28
+ import { CELLO_CONTENT_PROTOCOL_ID } from "@cello-protocol/transport";
29
+ const CBOR_ENC = new Encoder({ tagUint8Array: false });
30
+ const RELAY_PROTOCOL_ID = "/cello/relay/1.0.0";
31
+ export class SessionManager {
32
+ #ctx;
33
+ // ─── Owned state ─────────────────────────────────────────────────────────────
34
+ // session_id_hex → SessionRecord (SESSION-002)
35
+ #sessions = new Map();
36
+ // track whether content handler has been registered on this node
37
+ #contentHandlerRegistered = false;
38
+ // Callback for inbound session assignments (participant B role). MCP-002.
39
+ #onSessionAssignmentHandler;
40
+ // session_id_hex → Promise<void> chain for outbound serialization
41
+ #outboundQueues = new Map();
42
+ // session_id_hex → pending ack resolver (sequence_number → ack data)
43
+ #pendingAckResolvers = new Map();
44
+ // session_id_hex → own_echo_resolvers (sequence_number → resolve fn)
45
+ // Populated from relay stream reader via notifyOwnEcho(); resolved when echo arrives.
46
+ #ownEchoResolvers = new Map();
47
+ // session_id_hex → own-send pre-buffered content keyed by content_hash_hex
48
+ #ownPendingContent = new Map();
49
+ // session_id_hex → FIFO queue of ReceivedMessage (for receiveMessage)
50
+ #sessionMessageQueues = new Map();
51
+ // FIFO arrival order across all sessions: { sessionIdHex, message }
52
+ #anyMessageQueue = [];
53
+ // SESSION-007: wake resolvers for receiveSessionMessageAsync (per-session) and receiveMessageAsync (any-session)
54
+ #receiveWaiters = new Map();
55
+ #receiveAnyWaiters = new Set();
56
+ constructor(ctx) {
57
+ this.#ctx = ctx;
58
+ }
59
+ // ─── State accessors (called by RelayStreamManager, SealManager, facade) ─────
60
+ getSession(sessionIdHex) {
61
+ return this.#sessions.get(sessionIdHex);
62
+ }
63
+ getSessions() {
64
+ return this.#sessions;
65
+ }
66
+ setSession(sessionIdHex, record) {
67
+ this.#sessions.set(sessionIdHex, record);
68
+ }
69
+ deleteSession(sessionIdHex) {
70
+ this.#sessions.delete(sessionIdHex);
71
+ }
72
+ getOutboundQueue(sessionIdHex) {
73
+ return this.#outboundQueues.get(sessionIdHex);
74
+ }
75
+ setOutboundQueue(sessionIdHex, queue) {
76
+ this.#outboundQueues.set(sessionIdHex, queue);
77
+ }
78
+ deleteOutboundQueue(sessionIdHex) {
79
+ this.#outboundQueues.delete(sessionIdHex);
80
+ }
81
+ getPendingAckResolver(sessionIdHex) {
82
+ return this.#pendingAckResolvers.get(sessionIdHex);
83
+ }
84
+ setPendingAckResolver(sessionIdHex, resolve) {
85
+ this.#pendingAckResolvers.set(sessionIdHex, resolve);
86
+ }
87
+ deletePendingAckResolver(sessionIdHex) {
88
+ this.#pendingAckResolvers.delete(sessionIdHex);
89
+ }
90
+ getOwnEchoResolvers(sessionIdHex) {
91
+ return this.#ownEchoResolvers.get(sessionIdHex);
92
+ }
93
+ initOwnEchoResolvers(sessionIdHex) {
94
+ this.#ownEchoResolvers.set(sessionIdHex, new Map());
95
+ }
96
+ deleteOwnEchoResolvers(sessionIdHex) {
97
+ this.#ownEchoResolvers.delete(sessionIdHex);
98
+ }
99
+ getOwnPendingContent(sessionIdHex) {
100
+ return this.#ownPendingContent.get(sessionIdHex);
101
+ }
102
+ initOwnPendingContent(sessionIdHex) {
103
+ this.#ownPendingContent.set(sessionIdHex, new Map());
104
+ }
105
+ deleteOwnPendingContent(sessionIdHex) {
106
+ this.#ownPendingContent.delete(sessionIdHex);
107
+ }
108
+ getSessionMessageQueue(sessionIdHex) {
109
+ return this.#sessionMessageQueues.get(sessionIdHex);
110
+ }
111
+ deleteSessionMessageQueue(sessionIdHex) {
112
+ this.#sessionMessageQueues.delete(sessionIdHex);
113
+ }
114
+ /** Initialize the message queue for a session (called from loadPersistedState). */
115
+ initSessionMessageQueue(sessionIdHex) {
116
+ if (!this.#sessionMessageQueues.has(sessionIdHex)) {
117
+ this.#sessionMessageQueues.set(sessionIdHex, []);
118
+ }
119
+ }
120
+ getAnyMessageQueue() {
121
+ return this.#anyMessageQueue;
122
+ }
123
+ setOnSessionAssignmentHandler(handler) {
124
+ this.#onSessionAssignmentHandler = handler;
125
+ }
126
+ /**
127
+ * Clean up all per-session state owned by SessionManager.
128
+ * Called by facade.closeSession — companion to RelayStreamManager.closeSession and SealManager.closeSession.
129
+ */
130
+ closeSession(sessionIdHex) {
131
+ this.#sessions.delete(sessionIdHex);
132
+ this.#outboundQueues.delete(sessionIdHex);
133
+ this.#ownEchoResolvers.delete(sessionIdHex);
134
+ this.#ownPendingContent.delete(sessionIdHex);
135
+ this.#sessionMessageQueues.delete(sessionIdHex);
136
+ // Clear pending ack resolver (already unblocked by facade before calling closeSession)
137
+ this.#pendingAckResolvers.delete(sessionIdHex);
138
+ // Clear receive waiters for this session
139
+ this.#receiveWaiters.delete(sessionIdHex);
140
+ }
141
+ // ─── Called by RelayStreamManager after relay receives a message ─────────────
142
+ enqueueReceivedMessage(sessionIdHex, message) {
143
+ let queue = this.#sessionMessageQueues.get(sessionIdHex);
144
+ if (!queue) {
145
+ queue = [];
146
+ this.#sessionMessageQueues.set(sessionIdHex, queue);
147
+ }
148
+ queue.push(message);
149
+ this.#anyMessageQueue.push({ sessionIdHex, message });
150
+ this.wakeReceiveWaiters(sessionIdHex);
151
+ }
152
+ // ─── SESSION-002 ─────────────────────────────────────────────────────────────
153
+ /**
154
+ * Process a SessionAssignment pushed by the directory.
155
+ * SESSION-002 AC-002, AC-003, AC-004, AC-005, SI-003.
156
+ *
157
+ * Crypto refs:
158
+ * Ed25519 verification: RFC 8032
159
+ * SHA-256: FIPS 180-4
160
+ */
161
+ async receiveSessionAssignment(assignment, myPubkey) {
162
+ const { session_id, session_timestamp } = assignment;
163
+ const pubA = assignment.participant_a.pubkey;
164
+ const pubB = assignment.participant_b.pubkey;
165
+ // SESSION-004 Step 1: Check signature_type (SI-003, AC-003)
166
+ // M1 'single' frames are hard-refused in M2 — even if the single-key sig verifies.
167
+ if (assignment.signature_type === "single") {
168
+ return { ok: false, reason: "unsupported_signature_type" };
169
+ }
170
+ // SESSION-004 Step 2: Determine role and verification key (AC-007)
171
+ const myPubkeyHex = Buffer.from(myPubkey).toString("hex");
172
+ const pubAHex = Buffer.from(pubA).toString("hex");
173
+ const isInitiator = myPubkeyHex === pubAHex;
174
+ let verifyKey;
175
+ if (isInitiator) {
176
+ // CRITICAL-1: initiator MUST have a thresholdSigner injected.
177
+ // Falling back to assignment.signer_pubkey (frame-provided) would be attacker-controlled.
178
+ const thresholdSigner = this.#ctx.getThresholdSigner();
179
+ if (!thresholdSigner) {
180
+ return { ok: false, reason: "frost_signer_not_configured" };
181
+ }
182
+ verifyKey = thresholdSigner.getPrimaryPubkey();
183
+ }
184
+ else {
185
+ // Counterparty (B): use signer_pubkey from the frame (A's primary_pubkey).
186
+ // TypeScript discriminated union guarantees signer_pubkey is present for 'frost' frames.
187
+ verifyKey = assignment.signer_pubkey;
188
+ }
189
+ // SESSION-004 Step 3: Build TBS and verify FROST signature (AC-002, SI-001)
190
+ // TBS = canonical CBOR([session_id, pubA, pubB, genesis_prev_root, session_timestamp])
191
+ // buildSessionEstablishmentTbs imported from protocol-types (HIGH-5: single source of truth)
192
+ const genesis_prev_root_for_tbs = computeGenesisPrevRoot(pubA, pubB, session_id, session_timestamp);
193
+ const tbs = buildSessionEstablishmentTbs(session_id, pubA, pubB, genesis_prev_root_for_tbs, session_timestamp);
194
+ // Verify FROST signature with domain separation (context\0tbs framing)
195
+ if (!verifyFrostSignature(assignment.directory_signature, tbs, CONTEXT_SESSION_ESTABLISHMENT, verifyKey)) {
196
+ return { ok: false, reason: "frost_signature_invalid" };
197
+ }
198
+ // Step 4: Determine counterparty
199
+ const counterparty = isInitiator ? assignment.participant_b : assignment.participant_a;
200
+ // genesis_prev_root was already computed above for TBS — reuse it
201
+ const genesis_prev_root = genesis_prev_root_for_tbs;
202
+ // Step 4: Register content protocol handler on this node (if not already registered).
203
+ // Set the flag before awaiting handle() to prevent concurrent calls from both registering.
204
+ if (!this.#contentHandlerRegistered) {
205
+ this.#contentHandlerRegistered = true;
206
+ try {
207
+ await this.#ctx.node.handle(CELLO_CONTENT_PROTOCOL_ID, (stream) => {
208
+ this.#ctx.handleContentStream(stream);
209
+ });
210
+ }
211
+ catch {
212
+ // Already registered by a concurrent call — safe to ignore.
213
+ }
214
+ }
215
+ // Step 5: Dial relay on /cello/relay/1.0.0 and complete challenge-response auth (AC-003)
216
+ const relayPeerId = assignment.relay_endpoint.peer_id;
217
+ const relayMultiaddr = assignment.relay_endpoint.multiaddrs[0];
218
+ if (relayMultiaddr) {
219
+ try {
220
+ await this.#ctx.node.dial(relayMultiaddr);
221
+ }
222
+ catch {
223
+ // Connection may already exist — proceed
224
+ }
225
+ }
226
+ let relayStream;
227
+ try {
228
+ relayStream = await this.#ctx.node.newStream(relayPeerId, RELAY_PROTOCOL_ID);
229
+ }
230
+ catch {
231
+ return { ok: false, reason: "relay_auth_error" };
232
+ }
233
+ // Auth challenge-response
234
+ let relayIter;
235
+ try {
236
+ const authResult = await this.#ctx.performRelayAuth(relayStream, myPubkey);
237
+ if (!authResult.ok) {
238
+ return { ok: false, reason: authResult.reason };
239
+ }
240
+ relayIter = authResult.iter;
241
+ }
242
+ catch {
243
+ return { ok: false, reason: "relay_auth_error" };
244
+ }
245
+ // Step 6: Dial counterparty on /cello/content/1.0.0 (AC-004)
246
+ try {
247
+ const counterpartyMultiaddr = counterparty.multiaddrs[0];
248
+ if (counterpartyMultiaddr) {
249
+ try {
250
+ await this.#ctx.node.dial(counterpartyMultiaddr);
251
+ }
252
+ catch {
253
+ // Already connected or not yet reachable — proceed
254
+ }
255
+ }
256
+ const contentStream = await this.#ctx.node.newStream(counterparty.peer_id, CELLO_CONTENT_PROTOCOL_ID);
257
+ // Close gracefully — content stream will be re-established per message in M1
258
+ contentStream.close().catch(() => { });
259
+ }
260
+ catch {
261
+ // Counterparty not yet listening — store session as active anyway.
262
+ }
263
+ // Step 7: Store session record (AC-004)
264
+ const sessionIdHex = Buffer.from(session_id).toString("hex");
265
+ const record = {
266
+ session_id,
267
+ counterparty_pubkey: counterparty.pubkey,
268
+ counterparty_peer_id: counterparty.peer_id,
269
+ counterparty_multiaddrs: counterparty.multiaddrs,
270
+ relay_endpoint: {
271
+ peer_id: assignment.relay_endpoint.peer_id,
272
+ multiaddrs: assignment.relay_endpoint.multiaddrs,
273
+ },
274
+ directory_endpoint: {
275
+ peer_id: assignment.directory_endpoint.peer_id,
276
+ multiaddrs: assignment.directory_endpoint.multiaddrs,
277
+ },
278
+ directory_pubkey: assignment.directory_pubkey,
279
+ genesis_prev_root,
280
+ last_seen_seq: 0,
281
+ last_sent_seq: 0,
282
+ status: "active",
283
+ local_tree_leaves: [],
284
+ next_expected_seq: 1,
285
+ desynchronized: false,
286
+ };
287
+ this.#sessions.set(sessionIdHex, record);
288
+ // PERSIST-024: persist session to DB
289
+ if (this.#ctx.persistence) {
290
+ void this.#ctx.persistence.persistSession(sessionIdHex, record);
291
+ }
292
+ // Initialize per-session state in this manager and RelayStreamManager
293
+ this.#outboundQueues.set(sessionIdHex, Promise.resolve());
294
+ this.#ownEchoResolvers.set(sessionIdHex, new Map());
295
+ this.#ownPendingContent.set(sessionIdHex, new Map());
296
+ this.#sessionMessageQueues.set(sessionIdHex, []);
297
+ this.#ctx.initRelaySession(sessionIdHex);
298
+ // Cache myPubkeyHex for the stream reader (same key across all sessions on this client)
299
+ if (!this.#ctx.getMyPubkeyHex())
300
+ this.#ctx.setMyPubkeyHex(myPubkeyHex);
301
+ this.#ctx.runRelayStreamReader(sessionIdHex, relayStream, myPubkeyHex, relayIter);
302
+ // Fire inbound session handler if this client is participant B.
303
+ if (myPubkeyHex !== pubAHex) {
304
+ const handler = this.#onSessionAssignmentHandler;
305
+ if (handler) {
306
+ handler({
307
+ sessionIdHex,
308
+ counterpartyPubkeyHex: Buffer.from(counterparty.pubkey).toString("hex"),
309
+ genesisPrevRootHex: Buffer.from(genesis_prev_root).toString("hex"),
310
+ });
311
+ }
312
+ }
313
+ // ADAPTER-003: if the persistent signaling stream is already open, it handles
314
+ // session_sealed/seal_rejected events for all sessions.
315
+ // Only open a per-session stream when the persistent stream is not available.
316
+ if (!this.#ctx.getPersistentSignalingStream()) {
317
+ void this.#ctx.connectDirectorySignalingStream(sessionIdHex, assignment, myPubkey);
318
+ }
319
+ return { ok: true, sessionId: session_id };
320
+ }
321
+ listSessions() {
322
+ return Array.from(this.#sessions.values());
323
+ }
324
+ // ─── MSG-004 implementation ──────────────────────────────────────────────────
325
+ async sendMessage(sessionIdHex, content) {
326
+ // Per-session outbound serialization queue: next send not started until echo received
327
+ const prev = this.#outboundQueues.get(sessionIdHex) ?? Promise.resolve();
328
+ let release;
329
+ const next = new Promise((r) => { release = r; });
330
+ this.#outboundQueues.set(sessionIdHex, prev.then(() => next));
331
+ await prev;
332
+ try {
333
+ return await this.#sendMessageLocked(sessionIdHex, content);
334
+ }
335
+ finally {
336
+ release();
337
+ }
338
+ }
339
+ async #sendMessageLocked(sessionIdHex, content) {
340
+ const session = this.#sessions.get(sessionIdHex);
341
+ if (!session)
342
+ return { ok: false, reason: "session_not_found" };
343
+ if (session.desynchronized)
344
+ return { ok: false, reason: "session_desynchronized" };
345
+ if (session.status === "sealing" || session.status === "sealed" || session.status === "seal_deferred" || session.status === "seal_rejected")
346
+ return { ok: false, reason: "session_sealed" };
347
+ // SESSION-006 AC-001/AC-003: transport_lost means relay stream is gone or being reconnected
348
+ if (session.status === "transport_lost")
349
+ return { ok: false, reason: "transport_unavailable" };
350
+ const relayStream = this.#ctx.getRelayStream(sessionIdHex);
351
+ if (!relayStream || relayStream.status !== "open") {
352
+ return { ok: false, reason: "transport_unavailable" };
353
+ }
354
+ // content_hash = SHA-256(0x00 || content) per MERKLE-001
355
+ const contentHash = new Uint8Array(createHash("sha256").update(new Uint8Array([0x00])).update(content).digest());
356
+ // Build Structure 1 TBS: [1, content_hash, myPubkey, session_id, last_seen_seq, timestamp]
357
+ const myPubkeyHex = this.#ctx.getMyPubkeyHex();
358
+ const myPubkeyBytes = Buffer.from(myPubkeyHex, "hex");
359
+ const tbs = CBOR_ENC.encode([
360
+ 1,
361
+ contentHash,
362
+ myPubkeyBytes,
363
+ session.session_id,
364
+ session.last_seen_seq,
365
+ Date.now(),
366
+ ]);
367
+ const signature = await this.#ctx.keyProvider.sign(tbs);
368
+ // Submit hash_submit to relay on the persistent relay stream
369
+ const hashSubmitFrame = CBOR_ENC.encode({
370
+ type: "hash_submit",
371
+ session_id: session.session_id,
372
+ leaf_kind: 0x00,
373
+ structure1_cbor: tbs,
374
+ sender_signature: signature,
375
+ });
376
+ const contentHashHex = Buffer.from(contentHash).toString("hex");
377
+ this.#ownPendingContent.get(sessionIdHex)?.set(contentHashHex, {
378
+ content_bytes: content,
379
+ arrived_at: Date.now(),
380
+ });
381
+ // PERSIST-024 AC-008: Persist pending hash BEFORE relay submission.
382
+ const enqueuedAt = Date.now();
383
+ if (this.#ctx.persistence) {
384
+ void this.#ctx.persistence.persistPendingHash({ sessionId: sessionIdHex, hashHex: contentHashHex, enqueuedAt });
385
+ }
386
+ // Set up ack resolver before sending to avoid race with fast relay.
387
+ if (this.#pendingAckResolvers.has(sessionIdHex)) {
388
+ throw new Error(`[cello-client] ack resolver already set for session ${sessionIdHex}; outbound queue invariant violated`);
389
+ }
390
+ let ackResolve;
391
+ const ackPromise = new Promise((r) => { ackResolve = r; });
392
+ this.#pendingAckResolvers.set(sessionIdHex, ackResolve);
393
+ try {
394
+ relayStream.send(lp.encode.single(hashSubmitFrame));
395
+ }
396
+ catch {
397
+ this.#pendingAckResolvers.delete(sessionIdHex);
398
+ this.#ownPendingContent.get(sessionIdHex)?.delete(contentHashHex);
399
+ if (this.#ctx.persistence) {
400
+ void this.#ctx.persistence.removePendingHash(sessionIdHex, contentHashHex);
401
+ }
402
+ return { ok: false, reason: "transport_unavailable" };
403
+ }
404
+ const ack = await ackPromise;
405
+ if (!ack.ok) {
406
+ if (this.#ctx.persistence) {
407
+ void this.#ctx.persistence.removePendingHash(sessionIdHex, contentHashHex);
408
+ }
409
+ return { ok: false, reason: "relay_rejected" };
410
+ }
411
+ const mySeq = ack.sequence_number;
412
+ // PERSIST-024 AC-008: Relay ACKed — remove from pending_hashes.
413
+ if (this.#ctx.persistence) {
414
+ void this.#ctx.persistence.removePendingHash(sessionIdHex, contentHashHex);
415
+ }
416
+ // Send content to counterparty on /cello/content/1.0.0
417
+ const sess2 = this.#sessions.get(sessionIdHex);
418
+ if (sess2 && !sess2.desynchronized) {
419
+ void this.sendContentFrame(sess2, content, contentHash);
420
+ }
421
+ // Wait for our own echoed leaf_deliver
422
+ await this.waitForOwnEcho(sessionIdHex, mySeq);
423
+ const sess3 = this.#sessions.get(sessionIdHex);
424
+ if (!sess3 || sess3.desynchronized)
425
+ return { ok: false, reason: "session_desynchronized" };
426
+ return { ok: true };
427
+ }
428
+ async sendContentFrame(session, content, contentHash) {
429
+ const counterpartyPeerId = session.counterparty_peer_id;
430
+ try {
431
+ // Dial counterparty if not connected
432
+ const multiaddr = session.counterparty_multiaddrs[0];
433
+ if (multiaddr) {
434
+ try {
435
+ await this.#ctx.node.dial(multiaddr);
436
+ }
437
+ catch { /* already connected */ }
438
+ }
439
+ const contentStream = await this.#ctx.node.newStream(counterpartyPeerId, CELLO_CONTENT_PROTOCOL_ID);
440
+ const frame = CBOR_ENC.encode({
441
+ type: "content_frame",
442
+ session_id: session.session_id,
443
+ content_hash: contentHash,
444
+ content_bytes: content,
445
+ });
446
+ contentStream.send(lp.encode.single(frame));
447
+ await contentStream.close();
448
+ }
449
+ catch {
450
+ // Content path failure is silent; 30s grace timer fires if receiver doesn't get content
451
+ }
452
+ }
453
+ async waitForOwnEcho(sessionIdHex, seqNum) {
454
+ return new Promise((resolve) => {
455
+ const resolvers = this.#ownEchoResolvers.get(sessionIdHex);
456
+ if (resolvers) {
457
+ resolvers.set(seqNum, resolve);
458
+ }
459
+ else {
460
+ resolve(); // session was closed
461
+ }
462
+ });
463
+ }
464
+ receiveMessage(sessionIdHex) {
465
+ const queue = this.#sessionMessageQueues.get(sessionIdHex);
466
+ if (!queue || queue.length === 0)
467
+ return null;
468
+ return queue.shift();
469
+ }
470
+ receiveAnyMessage() {
471
+ return this.#anyMessageQueue.shift() ?? null;
472
+ }
473
+ // ─── SESSION-007: async blocking receive ─────────────────────────────────────
474
+ #computeOtherSessionsPending(excludeSessionIdHex) {
475
+ const pending = [];
476
+ for (const [sid, queue] of this.#sessionMessageQueues.entries()) {
477
+ if (sid !== excludeSessionIdHex && queue.length > 0) {
478
+ pending.push(sid);
479
+ }
480
+ }
481
+ return pending;
482
+ }
483
+ wakeReceiveWaiters(sessionIdHex) {
484
+ // Wake per-session waiters
485
+ const sessionWaiters = this.#receiveWaiters.get(sessionIdHex);
486
+ if (sessionWaiters) {
487
+ for (const resolve of sessionWaiters)
488
+ resolve();
489
+ sessionWaiters.clear();
490
+ }
491
+ // Wake any-session waiters
492
+ for (const resolve of this.#receiveAnyWaiters)
493
+ resolve();
494
+ this.#receiveAnyWaiters.clear();
495
+ }
496
+ async receiveSessionMessageAsync(sessionIdHex, timeoutMs) {
497
+ const deadline = Date.now() + timeoutMs;
498
+ while (true) {
499
+ // Check queue first (fast path: already has messages)
500
+ const queue = this.#sessionMessageQueues.get(sessionIdHex);
501
+ if (queue && queue.length > 0) {
502
+ const item = queue.shift();
503
+ // Remove from #anyMessageQueue as well to keep in sync
504
+ const idx = this.#anyMessageQueue.findIndex((e) => e.sessionIdHex === sessionIdHex && e.message === item);
505
+ if (idx !== -1)
506
+ this.#anyMessageQueue.splice(idx, 1);
507
+ // Attach otherSessionsPending
508
+ const pending = this.#computeOtherSessionsPending(sessionIdHex);
509
+ const result = pending.length > 0 ? { ...item, otherSessionsPending: pending } : item;
510
+ if (pending.length > 0) {
511
+ this.#ctx.logger.info("session.receive.pending_hint", {
512
+ currentSessionId: sessionIdHex,
513
+ pendingSessionCount: pending.length,
514
+ correlationId: sessionIdHex,
515
+ });
516
+ }
517
+ return result;
518
+ }
519
+ const remaining = deadline - Date.now();
520
+ if (remaining <= 0)
521
+ return null;
522
+ // Register wake resolver and race against timeout
523
+ await new Promise((resolve) => {
524
+ let set = this.#receiveWaiters.get(sessionIdHex);
525
+ if (!set) {
526
+ set = new Set();
527
+ this.#receiveWaiters.set(sessionIdHex, set);
528
+ }
529
+ set.add(resolve);
530
+ setTimeout(() => {
531
+ // Remove resolver if timeout fires before wake
532
+ this.#receiveWaiters.get(sessionIdHex)?.delete(resolve);
533
+ resolve();
534
+ }, remaining);
535
+ });
536
+ }
537
+ }
538
+ async receiveMessageAsync(timeoutMs) {
539
+ const deadline = Date.now() + timeoutMs;
540
+ while (true) {
541
+ // Check any-session queue first (fast path)
542
+ if (this.#anyMessageQueue.length > 0) {
543
+ const entry = this.#anyMessageQueue.shift();
544
+ // Remove from per-session queue as well
545
+ const perSession = this.#sessionMessageQueues.get(entry.sessionIdHex);
546
+ if (perSession) {
547
+ const idx = perSession.indexOf(entry.message);
548
+ if (idx !== -1)
549
+ perSession.splice(idx, 1);
550
+ }
551
+ // Attach otherSessionsPending
552
+ const pending = this.#computeOtherSessionsPending(entry.sessionIdHex);
553
+ const result = pending.length > 0
554
+ ? { ...entry.message, sessionIdHex: entry.sessionIdHex, otherSessionsPending: pending }
555
+ : { ...entry.message, sessionIdHex: entry.sessionIdHex };
556
+ if (pending.length > 0) {
557
+ this.#ctx.logger.info("session.receive.pending_hint", {
558
+ currentSessionId: entry.sessionIdHex,
559
+ pendingSessionCount: pending.length,
560
+ correlationId: entry.sessionIdHex,
561
+ });
562
+ }
563
+ return result;
564
+ }
565
+ const remaining = deadline - Date.now();
566
+ if (remaining <= 0)
567
+ return { type: "timeout" };
568
+ // Register wake resolver and race against timeout
569
+ await new Promise((resolve) => {
570
+ this.#receiveAnyWaiters.add(resolve);
571
+ setTimeout(() => {
572
+ this.#receiveAnyWaiters.delete(resolve);
573
+ resolve();
574
+ }, remaining);
575
+ });
576
+ }
577
+ }
578
+ enqueueSessionSealedEvent(sessionIdHex, sealedRoot, closeTimestamp) {
579
+ // Use sessionIdHex as correlationId — minted at session initiation, unique per session flow.
580
+ const correlationId = sessionIdHex;
581
+ this.#ctx.logger.info("session.sealed.received", {
582
+ sessionId: sessionIdHex,
583
+ sealedRoot: Buffer.from(sealedRoot).toString("hex"),
584
+ closeTimestamp,
585
+ checkpointStatus: "pending",
586
+ correlationId,
587
+ });
588
+ const lifecycleEvent = {
589
+ type: "session_sealed",
590
+ sessionIdHex,
591
+ sealedRoot: new Uint8Array(sealedRoot),
592
+ closeTimestamp,
593
+ checkpointStatus: "pending",
594
+ };
595
+ let queue = this.#sessionMessageQueues.get(sessionIdHex);
596
+ if (!queue) {
597
+ queue = [];
598
+ this.#sessionMessageQueues.set(sessionIdHex, queue);
599
+ }
600
+ queue.push(lifecycleEvent);
601
+ this.#anyMessageQueue.push({ sessionIdHex, message: lifecycleEvent });
602
+ this.wakeReceiveWaiters(sessionIdHex);
603
+ }
604
+ }
605
+ //# sourceMappingURL=session-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"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"}