@replit/river 0.207.2 → 0.208.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.
Files changed (65) hide show
  1. package/dist/adapter-ChksXKVN.d.ts +46 -0
  2. package/dist/adapter-Cuc4JtfV.d.cts +46 -0
  3. package/dist/chunk-2JNVDUMN.js +2238 -0
  4. package/dist/chunk-2JNVDUMN.js.map +1 -0
  5. package/dist/{chunk-4HE7UYRL.js → chunk-DKW3GC3M.js} +6 -5
  6. package/dist/{chunk-4HE7UYRL.js.map → chunk-DKW3GC3M.js.map} +1 -1
  7. package/dist/{chunk-46IVOKJU.js → chunk-ETZAHFGQ.js} +80 -61
  8. package/dist/chunk-ETZAHFGQ.js.map +1 -0
  9. package/dist/codec/index.cjs +157 -23
  10. package/dist/codec/index.cjs.map +1 -1
  11. package/dist/codec/index.d.cts +5 -1
  12. package/dist/codec/index.d.ts +5 -1
  13. package/dist/codec/index.js +6 -20
  14. package/dist/codec/index.js.map +1 -1
  15. package/dist/connection-BF4zg6Qv.d.cts +35 -0
  16. package/dist/{connection-a18e31d5.d.ts → connection-Donr3JRB.d.ts} +4 -3
  17. package/dist/index-C9tpZjBN.d.cts +37 -0
  18. package/dist/index-D8IOd3LG.d.ts +37 -0
  19. package/dist/logging/index.d.cts +2 -1
  20. package/dist/logging/index.d.ts +2 -1
  21. package/dist/{message-ffacb98a.d.ts → message-Di94OL80.d.cts} +1 -35
  22. package/dist/message-Di94OL80.d.ts +108 -0
  23. package/dist/router/index.cjs +62 -43
  24. package/dist/router/index.cjs.map +1 -1
  25. package/dist/router/index.d.cts +27 -7
  26. package/dist/router/index.d.ts +27 -7
  27. package/dist/router/index.js +1 -1
  28. package/dist/testUtil/index.cjs +828 -725
  29. package/dist/testUtil/index.cjs.map +1 -1
  30. package/dist/testUtil/index.d.cts +5 -4
  31. package/dist/testUtil/index.d.ts +5 -4
  32. package/dist/testUtil/index.js +23 -25
  33. package/dist/testUtil/index.js.map +1 -1
  34. package/dist/transport/impls/ws/client.cjs +293 -233
  35. package/dist/transport/impls/ws/client.cjs.map +1 -1
  36. package/dist/transport/impls/ws/client.d.cts +6 -5
  37. package/dist/transport/impls/ws/client.d.ts +6 -5
  38. package/dist/transport/impls/ws/client.js +5 -7
  39. package/dist/transport/impls/ws/client.js.map +1 -1
  40. package/dist/transport/impls/ws/server.cjs +269 -200
  41. package/dist/transport/impls/ws/server.cjs.map +1 -1
  42. package/dist/transport/impls/ws/server.d.cts +6 -5
  43. package/dist/transport/impls/ws/server.d.ts +6 -5
  44. package/dist/transport/impls/ws/server.js +5 -7
  45. package/dist/transport/impls/ws/server.js.map +1 -1
  46. package/dist/transport/index.cjs +438 -342
  47. package/dist/transport/index.cjs.map +1 -1
  48. package/dist/transport/index.d.cts +7 -6
  49. package/dist/transport/index.d.ts +7 -6
  50. package/dist/transport/index.js +5 -10
  51. package/dist/transport-CCaWx1Rb.d.cts +1566 -0
  52. package/dist/{services-43528f4b.d.ts → transport-CZb3vdB4.d.ts} +294 -293
  53. package/dist/{wslike-e0b32dd5.d.ts → wslike-Dng9H1C7.d.cts} +1 -1
  54. package/dist/wslike-Dng9H1C7.d.ts +40 -0
  55. package/package.json +3 -3
  56. package/dist/chunk-24EWYOGK.js +0 -1287
  57. package/dist/chunk-24EWYOGK.js.map +0 -1
  58. package/dist/chunk-46IVOKJU.js.map +0 -1
  59. package/dist/chunk-A7RGOVRV.js +0 -438
  60. package/dist/chunk-A7RGOVRV.js.map +0 -1
  61. package/dist/chunk-AJGIY2UB.js +0 -56
  62. package/dist/chunk-AJGIY2UB.js.map +0 -1
  63. package/dist/chunk-XV4RQ62N.js +0 -377
  64. package/dist/chunk-XV4RQ62N.js.map +0 -1
  65. package/dist/types-3e5768ec.d.ts +0 -20
@@ -99,7 +99,8 @@ var ProtocolError = {
99
99
  RetriesExceeded: "conn_retry_exceeded",
100
100
  HandshakeFailed: "handshake_failed",
101
101
  MessageOrderingViolated: "message_ordering_violated",
102
- InvalidMessage: "invalid_message"
102
+ InvalidMessage: "invalid_message",
103
+ MessageSendFailure: "message_send_failure"
103
104
  };
104
105
  var EventDispatcher = class {
105
106
  eventListeners = {};
@@ -164,23 +165,20 @@ var NaiveJsonCodec = {
164
165
  );
165
166
  },
166
167
  fromBuffer: (buff) => {
167
- try {
168
- const parsed = JSON.parse(
169
- decoder.decode(buff),
170
- function reviver(_key, val) {
171
- if (val?.$t) {
172
- return base64ToUint8Array(val.$t);
173
- } else {
174
- return val;
175
- }
168
+ const parsed = JSON.parse(
169
+ decoder.decode(buff),
170
+ function reviver(_key, val) {
171
+ if (val?.$t) {
172
+ return base64ToUint8Array(val.$t);
173
+ } else {
174
+ return val;
176
175
  }
177
- );
178
- if (typeof parsed === "object")
179
- return parsed;
180
- return null;
181
- } catch {
182
- return null;
176
+ }
177
+ );
178
+ if (typeof parsed !== "object" || parsed === null) {
179
+ throw new Error("unpacked msg is not an object");
183
180
  }
181
+ return parsed;
184
182
  }
185
183
  };
186
184
 
@@ -209,9 +207,6 @@ var defaultServerTransportOptions = {
209
207
  ...defaultTransportOptions
210
208
  };
211
209
 
212
- // transport/message.ts
213
- var import_typebox = require("@sinclair/typebox");
214
-
215
210
  // transport/id.ts
216
211
  var import_nanoid = require("nanoid");
217
212
  var alphabet = (0, import_nanoid.customAlphabet)(
@@ -219,148 +214,7 @@ var alphabet = (0, import_nanoid.customAlphabet)(
219
214
  );
220
215
  var generateId = () => alphabet(12);
221
216
 
222
- // transport/message.ts
223
- var TransportMessageSchema = (t) => import_typebox.Type.Object({
224
- id: import_typebox.Type.String(),
225
- from: import_typebox.Type.String(),
226
- to: import_typebox.Type.String(),
227
- seq: import_typebox.Type.Integer(),
228
- ack: import_typebox.Type.Integer(),
229
- serviceName: import_typebox.Type.Optional(import_typebox.Type.String()),
230
- procedureName: import_typebox.Type.Optional(import_typebox.Type.String()),
231
- streamId: import_typebox.Type.String(),
232
- controlFlags: import_typebox.Type.Integer(),
233
- tracing: import_typebox.Type.Optional(
234
- import_typebox.Type.Object({
235
- traceparent: import_typebox.Type.String(),
236
- tracestate: import_typebox.Type.String()
237
- })
238
- ),
239
- payload: t
240
- });
241
- var ControlMessageAckSchema = import_typebox.Type.Object({
242
- type: import_typebox.Type.Literal("ACK")
243
- });
244
- var ControlMessageCloseSchema = import_typebox.Type.Object({
245
- type: import_typebox.Type.Literal("CLOSE")
246
- });
247
- var currentProtocolVersion = "v2.0";
248
- var acceptedProtocolVersions = ["v1.1", currentProtocolVersion];
249
- function isAcceptedProtocolVersion(version2) {
250
- return acceptedProtocolVersions.includes(version2);
251
- }
252
- var ControlMessageHandshakeRequestSchema = import_typebox.Type.Object({
253
- type: import_typebox.Type.Literal("HANDSHAKE_REQ"),
254
- protocolVersion: import_typebox.Type.String(),
255
- sessionId: import_typebox.Type.String(),
256
- /**
257
- * Specifies what the server's expected session state (from the pov of the client). This can be
258
- * used by the server to know whether this is a new or a reestablished connection, and whether it
259
- * is compatible with what it already has.
260
- */
261
- expectedSessionState: import_typebox.Type.Object({
262
- // what the client expects the server to send next
263
- nextExpectedSeq: import_typebox.Type.Integer(),
264
- nextSentSeq: import_typebox.Type.Integer()
265
- }),
266
- metadata: import_typebox.Type.Optional(import_typebox.Type.Unknown())
267
- });
268
- var HandshakeErrorRetriableResponseCodes = import_typebox.Type.Union([
269
- import_typebox.Type.Literal("SESSION_STATE_MISMATCH")
270
- ]);
271
- var HandshakeErrorCustomHandlerFatalResponseCodes = import_typebox.Type.Union([
272
- // The custom validation handler rejected the handler because the client is unsupported.
273
- import_typebox.Type.Literal("REJECTED_UNSUPPORTED_CLIENT"),
274
- // The custom validation handler rejected the handshake.
275
- import_typebox.Type.Literal("REJECTED_BY_CUSTOM_HANDLER")
276
- ]);
277
- var HandshakeErrorFatalResponseCodes = import_typebox.Type.Union([
278
- HandshakeErrorCustomHandlerFatalResponseCodes,
279
- // The ciient sent a handshake that doesn't comply with the extended handshake metadata.
280
- import_typebox.Type.Literal("MALFORMED_HANDSHAKE_META"),
281
- // The ciient sent a handshake that doesn't comply with ControlMessageHandshakeRequestSchema.
282
- import_typebox.Type.Literal("MALFORMED_HANDSHAKE"),
283
- // The client's protocol version does not match the server's.
284
- import_typebox.Type.Literal("PROTOCOL_VERSION_MISMATCH")
285
- ]);
286
- var HandshakeErrorResponseCodes = import_typebox.Type.Union([
287
- HandshakeErrorRetriableResponseCodes,
288
- HandshakeErrorFatalResponseCodes
289
- ]);
290
- var ControlMessageHandshakeResponseSchema = import_typebox.Type.Object({
291
- type: import_typebox.Type.Literal("HANDSHAKE_RESP"),
292
- status: import_typebox.Type.Union([
293
- import_typebox.Type.Object({
294
- ok: import_typebox.Type.Literal(true),
295
- sessionId: import_typebox.Type.String()
296
- }),
297
- import_typebox.Type.Object({
298
- ok: import_typebox.Type.Literal(false),
299
- reason: import_typebox.Type.String(),
300
- code: HandshakeErrorResponseCodes
301
- })
302
- ])
303
- });
304
- var ControlMessagePayloadSchema = import_typebox.Type.Union([
305
- ControlMessageCloseSchema,
306
- ControlMessageAckSchema,
307
- ControlMessageHandshakeRequestSchema,
308
- ControlMessageHandshakeResponseSchema
309
- ]);
310
- var OpaqueTransportMessageSchema = TransportMessageSchema(
311
- import_typebox.Type.Unknown()
312
- );
313
- function handshakeRequestMessage({
314
- from,
315
- to,
316
- sessionId,
317
- expectedSessionState,
318
- metadata,
319
- tracing
320
- }) {
321
- return {
322
- id: generateId(),
323
- from,
324
- to,
325
- seq: 0,
326
- ack: 0,
327
- streamId: generateId(),
328
- controlFlags: 0,
329
- tracing,
330
- payload: {
331
- type: "HANDSHAKE_REQ",
332
- protocolVersion: currentProtocolVersion,
333
- sessionId,
334
- expectedSessionState,
335
- metadata
336
- }
337
- };
338
- }
339
- function handshakeResponseMessage({
340
- from,
341
- to,
342
- status
343
- }) {
344
- return {
345
- id: generateId(),
346
- from,
347
- to,
348
- seq: 0,
349
- ack: 0,
350
- streamId: generateId(),
351
- controlFlags: 0,
352
- payload: {
353
- type: "HANDSHAKE_RESP",
354
- status
355
- }
356
- };
357
- }
358
- function isAck(controlFlag) {
359
- return (controlFlag & 1 /* AckBit */) === 1 /* AckBit */;
360
- }
361
-
362
217
  // transport/sessionStateMachine/common.ts
363
- var import_value = require("@sinclair/typebox/value");
364
218
  var SessionState = /* @__PURE__ */ ((SessionState2) => {
365
219
  SessionState2["NoConnection"] = "NoConnection";
366
220
  SessionState2["BackingOff"] = "BackingOff";
@@ -429,34 +283,16 @@ var StateMachineState = class {
429
283
  var CommonSession = class extends StateMachineState {
430
284
  from;
431
285
  options;
286
+ codec;
432
287
  tracer;
433
288
  log;
434
- constructor({ from, options, log, tracer }) {
289
+ constructor({ from, options, log, tracer, codec }) {
435
290
  super();
436
291
  this.from = from;
437
292
  this.options = options;
438
293
  this.log = log;
439
294
  this.tracer = tracer;
440
- }
441
- parseMsg(msg) {
442
- const parsedMsg = this.options.codec.fromBuffer(msg);
443
- if (parsedMsg === null) {
444
- this.log?.error(
445
- `received malformed msg: ${Buffer.from(msg).toString("base64")}`,
446
- this.loggingMetadata
447
- );
448
- return null;
449
- }
450
- if (!import_value.Value.Check(OpaqueTransportMessageSchema, parsedMsg)) {
451
- this.log?.error(`received invalid msg: ${JSON.stringify(parsedMsg)}`, {
452
- ...this.loggingMetadata,
453
- validationErrors: [
454
- ...import_value.Value.Errors(OpaqueTransportMessageSchema, parsedMsg)
455
- ]
456
- });
457
- return null;
458
- }
459
- return parsedMsg;
295
+ this.codec = codec;
460
296
  }
461
297
  };
462
298
  var IdentifiedSession = class extends CommonSession {
@@ -516,9 +352,6 @@ var IdentifiedSession = class extends CommonSession {
516
352
  return metadata;
517
353
  }
518
354
  constructMsg(partialMsg) {
519
- if (this._isConsumed) {
520
- throw new Error(ERR_CONSUMED);
521
- }
522
355
  const msg = {
523
356
  ...partialMsg,
524
357
  id: generateId(),
@@ -536,7 +369,10 @@ var IdentifiedSession = class extends CommonSession {
536
369
  send(msg) {
537
370
  const constructedMsg = this.constructMsg(msg);
538
371
  this.sendBuffer.push(constructedMsg);
539
- return constructedMsg.id;
372
+ return {
373
+ ok: true,
374
+ value: constructedMsg.id
375
+ };
540
376
  }
541
377
  _handleStateExit() {
542
378
  }
@@ -568,6 +404,23 @@ var IdentifiedSessionWithGracePeriod = class extends IdentifiedSession {
568
404
  super._handleClose();
569
405
  }
570
406
  };
407
+ function sendMessage(conn, codec, msg) {
408
+ const buff = codec.toBuffer(msg);
409
+ if (!buff.ok) {
410
+ return buff;
411
+ }
412
+ const sent = conn.send(buff.value);
413
+ if (!sent) {
414
+ return {
415
+ ok: false,
416
+ reason: "failed to send message"
417
+ };
418
+ }
419
+ return {
420
+ ok: true,
421
+ value: msg.id
422
+ };
423
+ }
571
424
 
572
425
  // transport/sessionStateMachine/SessionConnecting.ts
573
426
  var SessionConnecting = class extends IdentifiedSessionWithGracePeriod {
@@ -581,13 +434,11 @@ var SessionConnecting = class extends IdentifiedSessionWithGracePeriod {
581
434
  this.listeners = props.listeners;
582
435
  this.connPromise.then(
583
436
  (conn) => {
584
- if (this._isConsumed)
585
- return;
437
+ if (this._isConsumed) return;
586
438
  this.listeners.onConnectionEstablished(conn);
587
439
  },
588
440
  (err) => {
589
- if (this._isConsumed)
590
- return;
441
+ if (this._isConsumed) return;
591
442
  this.listeners.onConnectionFailed(err);
592
443
  }
593
444
  );
@@ -620,8 +471,8 @@ var SessionConnecting = class extends IdentifiedSessionWithGracePeriod {
620
471
  }
621
472
  }
622
473
  _handleClose() {
623
- this.bestEffortClose();
624
474
  super._handleClose();
475
+ this.bestEffortClose();
625
476
  }
626
477
  };
627
478
 
@@ -639,6 +490,147 @@ var SessionNoConnection = class extends IdentifiedSessionWithGracePeriod {
639
490
  // tracing/index.ts
640
491
  var import_api2 = require("@opentelemetry/api");
641
492
 
493
+ // transport/message.ts
494
+ var import_typebox = require("@sinclair/typebox");
495
+ var TransportMessageSchema = (t) => import_typebox.Type.Object({
496
+ id: import_typebox.Type.String(),
497
+ from: import_typebox.Type.String(),
498
+ to: import_typebox.Type.String(),
499
+ seq: import_typebox.Type.Integer(),
500
+ ack: import_typebox.Type.Integer(),
501
+ serviceName: import_typebox.Type.Optional(import_typebox.Type.String()),
502
+ procedureName: import_typebox.Type.Optional(import_typebox.Type.String()),
503
+ streamId: import_typebox.Type.String(),
504
+ controlFlags: import_typebox.Type.Integer(),
505
+ tracing: import_typebox.Type.Optional(
506
+ import_typebox.Type.Object({
507
+ traceparent: import_typebox.Type.String(),
508
+ tracestate: import_typebox.Type.String()
509
+ })
510
+ ),
511
+ payload: t
512
+ });
513
+ var ControlMessageAckSchema = import_typebox.Type.Object({
514
+ type: import_typebox.Type.Literal("ACK")
515
+ });
516
+ var ControlMessageCloseSchema = import_typebox.Type.Object({
517
+ type: import_typebox.Type.Literal("CLOSE")
518
+ });
519
+ var currentProtocolVersion = "v2.0";
520
+ var acceptedProtocolVersions = ["v1.1", currentProtocolVersion];
521
+ function isAcceptedProtocolVersion(version2) {
522
+ return acceptedProtocolVersions.includes(version2);
523
+ }
524
+ var ControlMessageHandshakeRequestSchema = import_typebox.Type.Object({
525
+ type: import_typebox.Type.Literal("HANDSHAKE_REQ"),
526
+ protocolVersion: import_typebox.Type.String(),
527
+ sessionId: import_typebox.Type.String(),
528
+ /**
529
+ * Specifies what the server's expected session state (from the pov of the client). This can be
530
+ * used by the server to know whether this is a new or a reestablished connection, and whether it
531
+ * is compatible with what it already has.
532
+ */
533
+ expectedSessionState: import_typebox.Type.Object({
534
+ // what the client expects the server to send next
535
+ nextExpectedSeq: import_typebox.Type.Integer(),
536
+ nextSentSeq: import_typebox.Type.Integer()
537
+ }),
538
+ metadata: import_typebox.Type.Optional(import_typebox.Type.Unknown())
539
+ });
540
+ var HandshakeErrorRetriableResponseCodes = import_typebox.Type.Union([
541
+ import_typebox.Type.Literal("SESSION_STATE_MISMATCH")
542
+ ]);
543
+ var HandshakeErrorCustomHandlerFatalResponseCodes = import_typebox.Type.Union([
544
+ // The custom validation handler rejected the handler because the client is unsupported.
545
+ import_typebox.Type.Literal("REJECTED_UNSUPPORTED_CLIENT"),
546
+ // The custom validation handler rejected the handshake.
547
+ import_typebox.Type.Literal("REJECTED_BY_CUSTOM_HANDLER")
548
+ ]);
549
+ var HandshakeErrorFatalResponseCodes = import_typebox.Type.Union([
550
+ HandshakeErrorCustomHandlerFatalResponseCodes,
551
+ // The ciient sent a handshake that doesn't comply with the extended handshake metadata.
552
+ import_typebox.Type.Literal("MALFORMED_HANDSHAKE_META"),
553
+ // The ciient sent a handshake that doesn't comply with ControlMessageHandshakeRequestSchema.
554
+ import_typebox.Type.Literal("MALFORMED_HANDSHAKE"),
555
+ // The client's protocol version does not match the server's.
556
+ import_typebox.Type.Literal("PROTOCOL_VERSION_MISMATCH")
557
+ ]);
558
+ var HandshakeErrorResponseCodes = import_typebox.Type.Union([
559
+ HandshakeErrorRetriableResponseCodes,
560
+ HandshakeErrorFatalResponseCodes
561
+ ]);
562
+ var ControlMessageHandshakeResponseSchema = import_typebox.Type.Object({
563
+ type: import_typebox.Type.Literal("HANDSHAKE_RESP"),
564
+ status: import_typebox.Type.Union([
565
+ import_typebox.Type.Object({
566
+ ok: import_typebox.Type.Literal(true),
567
+ sessionId: import_typebox.Type.String()
568
+ }),
569
+ import_typebox.Type.Object({
570
+ ok: import_typebox.Type.Literal(false),
571
+ reason: import_typebox.Type.String(),
572
+ code: HandshakeErrorResponseCodes
573
+ })
574
+ ])
575
+ });
576
+ var ControlMessagePayloadSchema = import_typebox.Type.Union([
577
+ ControlMessageCloseSchema,
578
+ ControlMessageAckSchema,
579
+ ControlMessageHandshakeRequestSchema,
580
+ ControlMessageHandshakeResponseSchema
581
+ ]);
582
+ var OpaqueTransportMessageSchema = TransportMessageSchema(
583
+ import_typebox.Type.Unknown()
584
+ );
585
+ function handshakeRequestMessage({
586
+ from,
587
+ to,
588
+ sessionId,
589
+ expectedSessionState,
590
+ metadata,
591
+ tracing
592
+ }) {
593
+ return {
594
+ id: generateId(),
595
+ from,
596
+ to,
597
+ seq: 0,
598
+ ack: 0,
599
+ streamId: generateId(),
600
+ controlFlags: 0,
601
+ tracing,
602
+ payload: {
603
+ type: "HANDSHAKE_REQ",
604
+ protocolVersion: currentProtocolVersion,
605
+ sessionId,
606
+ expectedSessionState,
607
+ metadata
608
+ }
609
+ };
610
+ }
611
+ function handshakeResponseMessage({
612
+ from,
613
+ to,
614
+ status
615
+ }) {
616
+ return {
617
+ id: generateId(),
618
+ from,
619
+ to,
620
+ seq: 0,
621
+ ack: 0,
622
+ streamId: generateId(),
623
+ controlFlags: 0,
624
+ payload: {
625
+ type: "HANDSHAKE_RESP",
626
+ status
627
+ }
628
+ };
629
+ }
630
+ function isAck(controlFlag) {
631
+ return (controlFlag & 1 /* AckBit */) === 1 /* AckBit */;
632
+ }
633
+
642
634
  // transport/stringifyError.ts
643
635
  function coerceErrorString(err) {
644
636
  if (err instanceof Error) {
@@ -648,7 +640,7 @@ function coerceErrorString(err) {
648
640
  }
649
641
 
650
642
  // package.json
651
- var version = "0.207.2";
643
+ var version = "0.208.0";
652
644
 
653
645
  // tracing/index.ts
654
646
  function getPropagationContext(ctx) {
@@ -662,7 +654,7 @@ function getPropagationContext(ctx) {
662
654
  function createSessionTelemetryInfo(tracer, sessionId, to, from, propagationCtx) {
663
655
  const parentCtx = propagationCtx ? import_api2.propagation.extract(import_api2.context.active(), propagationCtx) : import_api2.context.active();
664
656
  const span = tracer.startSpan(
665
- `river.session.${sessionId}`,
657
+ `river.session`,
666
658
  {
667
659
  attributes: {
668
660
  component: "river",
@@ -678,7 +670,7 @@ function createSessionTelemetryInfo(tracer, sessionId, to, from, propagationCtx)
678
670
  }
679
671
  function createConnectionTelemetryInfo(tracer, connection, info) {
680
672
  const span = tracer.startSpan(
681
- `connection ${connection.id}`,
673
+ `river.connection`,
682
674
  {
683
675
  attributes: {
684
676
  component: "river",
@@ -708,9 +700,9 @@ var SessionWaitingForHandshake = class extends CommonSession {
708
700
  this.handshakeTimeout = setTimeout(() => {
709
701
  this.listeners.onHandshakeTimeout();
710
702
  }, this.options.handshakeTimeoutMs);
711
- this.conn.addDataListener(this.onHandshakeData);
712
- this.conn.addErrorListener(this.listeners.onConnectionErrored);
713
- this.conn.addCloseListener(this.listeners.onConnectionClosed);
703
+ this.conn.setDataListener(this.onHandshakeData);
704
+ this.conn.setErrorListener(this.listeners.onConnectionErrored);
705
+ this.conn.setCloseListener(this.listeners.onConnectionClosed);
714
706
  }
715
707
  get loggingMetadata() {
716
708
  return {
@@ -720,23 +712,23 @@ var SessionWaitingForHandshake = class extends CommonSession {
720
712
  };
721
713
  }
722
714
  onHandshakeData = (msg) => {
723
- const parsedMsg = this.parseMsg(msg);
724
- if (parsedMsg === null) {
715
+ const parsedMsgRes = this.codec.fromBuffer(msg);
716
+ if (!parsedMsgRes.ok) {
725
717
  this.listeners.onInvalidHandshake(
726
- "could not parse message",
718
+ `could not parse handshake message: ${parsedMsgRes.reason}`,
727
719
  "MALFORMED_HANDSHAKE"
728
720
  );
729
721
  return;
730
722
  }
731
- this.listeners.onHandshake(parsedMsg);
723
+ this.listeners.onHandshake(parsedMsgRes.value);
732
724
  };
733
725
  sendHandshake(msg) {
734
- return this.conn.send(this.options.codec.toBuffer(msg));
726
+ return sendMessage(this.conn, this.codec, msg);
735
727
  }
736
728
  _handleStateExit() {
737
- this.conn.removeDataListener(this.onHandshakeData);
738
- this.conn.removeErrorListener(this.listeners.onConnectionErrored);
739
- this.conn.removeCloseListener(this.listeners.onConnectionClosed);
729
+ this.conn.removeDataListener();
730
+ this.conn.removeErrorListener();
731
+ this.conn.removeCloseListener();
740
732
  clearTimeout(this.handshakeTimeout);
741
733
  this.handshakeTimeout = void 0;
742
734
  }
@@ -758,9 +750,9 @@ var SessionHandshaking = class extends IdentifiedSessionWithGracePeriod {
758
750
  this.handshakeTimeout = setTimeout(() => {
759
751
  this.listeners.onHandshakeTimeout();
760
752
  }, this.options.handshakeTimeoutMs);
761
- this.conn.addDataListener(this.onHandshakeData);
762
- this.conn.addErrorListener(this.listeners.onConnectionErrored);
763
- this.conn.addCloseListener(this.listeners.onConnectionClosed);
753
+ this.conn.setDataListener(this.onHandshakeData);
754
+ this.conn.setErrorListener(this.listeners.onConnectionErrored);
755
+ this.conn.setCloseListener(this.listeners.onConnectionClosed);
764
756
  }
765
757
  get loggingMetadata() {
766
758
  return {
@@ -769,24 +761,24 @@ var SessionHandshaking = class extends IdentifiedSessionWithGracePeriod {
769
761
  };
770
762
  }
771
763
  onHandshakeData = (msg) => {
772
- const parsedMsg = this.parseMsg(msg);
773
- if (parsedMsg === null) {
764
+ const parsedMsgRes = this.codec.fromBuffer(msg);
765
+ if (!parsedMsgRes.ok) {
774
766
  this.listeners.onInvalidHandshake(
775
- "could not parse message",
767
+ `could not parse handshake message: ${parsedMsgRes.reason}`,
776
768
  "MALFORMED_HANDSHAKE"
777
769
  );
778
770
  return;
779
771
  }
780
- this.listeners.onHandshake(parsedMsg);
772
+ this.listeners.onHandshake(parsedMsgRes.value);
781
773
  };
782
774
  sendHandshake(msg) {
783
- return this.conn.send(this.options.codec.toBuffer(msg));
775
+ return sendMessage(this.conn, this.codec, msg);
784
776
  }
785
777
  _handleStateExit() {
786
778
  super._handleStateExit();
787
- this.conn.removeDataListener(this.onHandshakeData);
788
- this.conn.removeErrorListener(this.listeners.onConnectionErrored);
789
- this.conn.removeCloseListener(this.listeners.onConnectionClosed);
779
+ this.conn.removeDataListener();
780
+ this.conn.removeErrorListener();
781
+ this.conn.removeCloseListener();
790
782
  if (this.handshakeTimeout) {
791
783
  clearTimeout(this.handshakeTimeout);
792
784
  this.handshakeTimeout = void 0;
@@ -805,25 +797,15 @@ var SessionConnected = class extends IdentifiedSession {
805
797
  conn;
806
798
  listeners;
807
799
  heartbeatHandle;
808
- heartbeatMisses = 0;
809
- isActivelyHeartbeating;
810
- lastConstructedMsgs = [];
811
- pushLastConstructedMsgs = (msg) => {
812
- const trackedMsg = {
813
- id: msg.id,
814
- seq: msg.seq,
815
- streamId: msg.streamId,
816
- stack: new Error().stack
817
- };
818
- this.lastConstructedMsgs.push(trackedMsg);
819
- if (this.lastConstructedMsgs.length > 10) {
820
- this.lastConstructedMsgs.shift();
821
- }
822
- };
800
+ heartbeatMissTimeout;
801
+ isActivelyHeartbeating = false;
823
802
  updateBookkeeping(ack, seq) {
824
803
  this.sendBuffer = this.sendBuffer.filter((unacked) => unacked.seq >= ack);
825
804
  this.ack = seq + 1;
826
- this.heartbeatMisses = 0;
805
+ if (this.heartbeatMissTimeout) {
806
+ clearTimeout(this.heartbeatMissTimeout);
807
+ }
808
+ this.startMissingHeartbeatTimeout();
827
809
  }
828
810
  assertSendOrdering(constructedMsg) {
829
811
  if (constructedMsg.seq > this.seqSent + 1) {
@@ -831,30 +813,32 @@ var SessionConnected = class extends IdentifiedSession {
831
813
  this.log?.error(msg, {
832
814
  ...this.loggingMetadata,
833
815
  transportMessage: constructedMsg,
834
- tags: ["invariant-violation"],
835
- extras: {
836
- lastConstructedMsgs: this.lastConstructedMsgs
837
- }
816
+ tags: ["invariant-violation"]
838
817
  });
839
818
  throw new Error(msg);
840
819
  }
841
820
  }
842
821
  send(msg) {
843
822
  const constructedMsg = this.constructMsg(msg);
844
- this.pushLastConstructedMsgs(constructedMsg);
845
823
  this.assertSendOrdering(constructedMsg);
846
824
  this.sendBuffer.push(constructedMsg);
847
- this.conn.send(this.options.codec.toBuffer(constructedMsg));
825
+ const res = sendMessage(this.conn, this.codec, constructedMsg);
826
+ if (!res.ok) {
827
+ this.listeners.onMessageSendFailure(constructedMsg, res.reason);
828
+ return res;
829
+ }
848
830
  this.seqSent = constructedMsg.seq;
849
- return constructedMsg.id;
831
+ return res;
850
832
  }
851
833
  constructor(props) {
852
834
  super(props);
853
835
  this.conn = props.conn;
854
836
  this.listeners = props.listeners;
855
- this.conn.addDataListener(this.onMessageData);
856
- this.conn.addCloseListener(this.listeners.onConnectionClosed);
857
- this.conn.addErrorListener(this.listeners.onConnectionErrored);
837
+ this.conn.setDataListener(this.onMessageData);
838
+ this.conn.setCloseListener(this.listeners.onConnectionClosed);
839
+ this.conn.setErrorListener(this.listeners.onConnectionErrored);
840
+ }
841
+ sendBufferedMessages() {
858
842
  if (this.sendBuffer.length > 0) {
859
843
  this.log?.info(
860
844
  `sending ${this.sendBuffer.length} buffered messages, starting at seq ${this.nextSeq()}`,
@@ -862,30 +846,15 @@ var SessionConnected = class extends IdentifiedSession {
862
846
  );
863
847
  for (const msg of this.sendBuffer) {
864
848
  this.assertSendOrdering(msg);
865
- this.conn.send(this.options.codec.toBuffer(msg));
849
+ const res = sendMessage(this.conn, this.codec, msg);
850
+ if (!res.ok) {
851
+ this.listeners.onMessageSendFailure(msg, res.reason);
852
+ return res;
853
+ }
866
854
  this.seqSent = msg.seq;
867
855
  }
868
856
  }
869
- this.isActivelyHeartbeating = false;
870
- this.heartbeatHandle = setInterval(() => {
871
- const misses = this.heartbeatMisses;
872
- const missDuration = misses * this.options.heartbeatIntervalMs;
873
- if (misses >= this.options.heartbeatsUntilDead) {
874
- this.log?.info(
875
- `closing connection to ${this.to} due to inactivity (missed ${misses} heartbeats which is ${missDuration}ms)`,
876
- this.loggingMetadata
877
- );
878
- this.telemetry.span.addEvent("closing connection due to inactivity");
879
- this.conn.close();
880
- clearInterval(this.heartbeatHandle);
881
- this.heartbeatHandle = void 0;
882
- return;
883
- }
884
- if (this.isActivelyHeartbeating) {
885
- this.sendHeartbeat();
886
- }
887
- this.heartbeatMisses++;
888
- }, this.options.heartbeatIntervalMs);
857
+ return { ok: true, value: void 0 };
889
858
  }
890
859
  get loggingMetadata() {
891
860
  return {
@@ -893,25 +862,46 @@ var SessionConnected = class extends IdentifiedSession {
893
862
  ...this.conn.loggingMetadata
894
863
  };
895
864
  }
865
+ startMissingHeartbeatTimeout() {
866
+ const maxMisses = this.options.heartbeatsUntilDead;
867
+ const missDuration = maxMisses * this.options.heartbeatIntervalMs;
868
+ this.heartbeatMissTimeout = setTimeout(() => {
869
+ this.log?.info(
870
+ `closing connection to ${this.to} due to inactivity (missed ${maxMisses} heartbeats which is ${missDuration}ms)`,
871
+ this.loggingMetadata
872
+ );
873
+ this.telemetry.span.addEvent(
874
+ "closing connection due to missing heartbeat"
875
+ );
876
+ this.conn.close();
877
+ }, missDuration);
878
+ }
896
879
  startActiveHeartbeat() {
897
880
  this.isActivelyHeartbeating = true;
881
+ this.heartbeatHandle = setInterval(() => {
882
+ this.sendHeartbeat();
883
+ }, this.options.heartbeatIntervalMs);
898
884
  }
899
885
  sendHeartbeat() {
900
886
  this.log?.debug("sending heartbeat", this.loggingMetadata);
901
- this.send({
887
+ const heartbeat = {
902
888
  streamId: "heartbeat",
903
889
  controlFlags: 1 /* AckBit */,
904
890
  payload: {
905
891
  type: "ACK"
906
892
  }
907
- });
893
+ };
894
+ this.send(heartbeat);
908
895
  }
909
896
  onMessageData = (msg) => {
910
- const parsedMsg = this.parseMsg(msg);
911
- if (parsedMsg === null) {
912
- this.listeners.onInvalidMessage("could not parse message");
897
+ const parsedMsgRes = this.codec.fromBuffer(msg);
898
+ if (!parsedMsgRes.ok) {
899
+ this.listeners.onInvalidMessage(
900
+ `could not parse message: ${parsedMsgRes.reason}`
901
+ );
913
902
  return;
914
903
  }
904
+ const parsedMsg = parsedMsgRes.value;
915
905
  if (parsedMsg.seq !== this.ack) {
916
906
  if (parsedMsg.seq < this.ack) {
917
907
  this.log?.debug(
@@ -950,20 +940,22 @@ var SessionConnected = class extends IdentifiedSession {
950
940
  transportMessage: parsedMsg
951
941
  });
952
942
  if (!this.isActivelyHeartbeating) {
953
- void Promise.resolve().then(() => {
954
- this.sendHeartbeat();
955
- });
943
+ this.sendHeartbeat();
956
944
  }
957
945
  };
958
946
  _handleStateExit() {
959
947
  super._handleStateExit();
960
- this.conn.removeDataListener(this.onMessageData);
961
- this.conn.removeCloseListener(this.listeners.onConnectionClosed);
962
- this.conn.removeErrorListener(this.listeners.onConnectionErrored);
948
+ this.conn.removeDataListener();
949
+ this.conn.removeCloseListener();
950
+ this.conn.removeErrorListener();
963
951
  if (this.heartbeatHandle) {
964
952
  clearInterval(this.heartbeatHandle);
965
953
  this.heartbeatHandle = void 0;
966
954
  }
955
+ if (this.heartbeatMissTimeout) {
956
+ clearTimeout(this.heartbeatMissTimeout);
957
+ this.heartbeatMissTimeout = void 0;
958
+ }
967
959
  }
968
960
  _handleClose() {
969
961
  super._handleClose();
@@ -995,6 +987,47 @@ var SessionBackingOff = class extends IdentifiedSessionWithGracePeriod {
995
987
  }
996
988
  };
997
989
 
990
+ // codec/adapter.ts
991
+ var import_value = require("@sinclair/typebox/value");
992
+ var CodecMessageAdapter = class {
993
+ constructor(codec) {
994
+ this.codec = codec;
995
+ }
996
+ toBuffer(msg) {
997
+ try {
998
+ return {
999
+ ok: true,
1000
+ value: this.codec.toBuffer(msg)
1001
+ };
1002
+ } catch (e) {
1003
+ return {
1004
+ ok: false,
1005
+ reason: coerceErrorString(e)
1006
+ };
1007
+ }
1008
+ }
1009
+ fromBuffer(buf) {
1010
+ try {
1011
+ const parsedMsg = this.codec.fromBuffer(buf);
1012
+ if (!import_value.Value.Check(OpaqueTransportMessageSchema, parsedMsg)) {
1013
+ return {
1014
+ ok: false,
1015
+ reason: "transport message schema mismatch"
1016
+ };
1017
+ }
1018
+ return {
1019
+ ok: true,
1020
+ value: parsedMsg
1021
+ };
1022
+ } catch (e) {
1023
+ return {
1024
+ ok: false,
1025
+ reason: coerceErrorString(e)
1026
+ };
1027
+ }
1028
+ }
1029
+ };
1030
+
998
1031
  // transport/sessionStateMachine/transitions.ts
999
1032
  function inheritSharedSession(session) {
1000
1033
  return {
@@ -1009,7 +1042,8 @@ function inheritSharedSession(session) {
1009
1042
  options: session.options,
1010
1043
  log: session.log,
1011
1044
  tracer: session.tracer,
1012
- protocolVersion: session.protocolVersion
1045
+ protocolVersion: session.protocolVersion,
1046
+ codec: session.codec
1013
1047
  };
1014
1048
  }
1015
1049
  function inheritSharedSessionWithGrace(session) {
@@ -1038,7 +1072,8 @@ var SessionStateGraph = {
1038
1072
  options,
1039
1073
  protocolVersion,
1040
1074
  tracer,
1041
- log
1075
+ log,
1076
+ codec: new CodecMessageAdapter(options.codec)
1042
1077
  });
1043
1078
  session.log?.info(`session ${session.id} created in NoConnection state`, {
1044
1079
  ...session.loggingMetadata,
@@ -1053,7 +1088,8 @@ var SessionStateGraph = {
1053
1088
  from,
1054
1089
  options,
1055
1090
  tracer,
1056
- log
1091
+ log,
1092
+ codec: new CodecMessageAdapter(options.codec)
1057
1093
  });
1058
1094
  session.log?.info(`session created in WaitingForHandshake state`, {
1059
1095
  ...session.loggingMetadata,
@@ -1131,6 +1167,7 @@ var SessionStateGraph = {
1131
1167
  listeners,
1132
1168
  ...carriedState
1133
1169
  });
1170
+ session.startMissingHeartbeatTimeout();
1134
1171
  session.log?.info(
1135
1172
  `session ${session.id} transition from Handshaking to Connected`,
1136
1173
  {
@@ -1166,7 +1203,8 @@ var SessionStateGraph = {
1166
1203
  options,
1167
1204
  tracer: pendingSession.tracer,
1168
1205
  log: pendingSession.log,
1169
- protocolVersion
1206
+ protocolVersion,
1207
+ codec: new CodecMessageAdapter(options.codec)
1170
1208
  }
1171
1209
  );
1172
1210
  pendingSession._handleStateExit();
@@ -1176,6 +1214,7 @@ var SessionStateGraph = {
1176
1214
  listeners,
1177
1215
  ...carriedState
1178
1216
  });
1217
+ session.startMissingHeartbeatTimeout();
1179
1218
  conn.telemetry = createConnectionTelemetryInfo(
1180
1219
  session.tracer,
1181
1220
  conn,
@@ -1353,8 +1392,7 @@ var Transport = class {
1353
1392
  * @param message The received message.
1354
1393
  */
1355
1394
  handleMsg(message) {
1356
- if (this.getStatus() !== "open")
1357
- return;
1395
+ if (this.getStatus() !== "open") return;
1358
1396
  this.eventDispatcher.dispatchEvent("message", message);
1359
1397
  }
1360
1398
  /**
@@ -1442,8 +1480,7 @@ var Transport = class {
1442
1480
  });
1443
1481
  }
1444
1482
  deleteSession(session, options) {
1445
- if (session._isConsumed)
1446
- return;
1483
+ if (session._isConsumed) return;
1447
1484
  const loggingMetadata = session.loggingMetadata;
1448
1485
  if (loggingMetadata.tags && options?.unhealthy) {
1449
1486
  loggingMetadata.tags.push("unhealthy-session");
@@ -1463,7 +1500,7 @@ var Transport = class {
1463
1500
  }
1464
1501
  // common listeners
1465
1502
  onSessionGracePeriodElapsed(session) {
1466
- this.log?.warn(
1503
+ this.log?.info(
1467
1504
  `session to ${session.to} grace period elapsed, closing`,
1468
1505
  session.loggingMetadata
1469
1506
  );
@@ -1516,12 +1553,16 @@ var Transport = class {
1516
1553
  );
1517
1554
  }
1518
1555
  const sameSession = session.id === sessionId;
1519
- if (!sameSession) {
1556
+ if (!sameSession || session._isConsumed) {
1520
1557
  throw new Error(
1521
1558
  `session scope for ${sessionId} has ended (transition), can't send`
1522
1559
  );
1523
1560
  }
1524
- return session.send(msg);
1561
+ const res = session.send(msg);
1562
+ if (!res.ok) {
1563
+ throw new Error(res.reason);
1564
+ }
1565
+ return res.value;
1525
1566
  };
1526
1567
  }
1527
1568
  };
@@ -1792,13 +1833,32 @@ var ClientTransport = class extends Transport {
1792
1833
  this.handleMsg(msg2);
1793
1834
  },
1794
1835
  onInvalidMessage: (reason) => {
1795
- this.deleteSession(connectedSession, { unhealthy: true });
1836
+ this.log?.error(`invalid message: ${reason}`, {
1837
+ ...connectedSession.loggingMetadata,
1838
+ transportMessage: msg
1839
+ });
1796
1840
  this.protocolError({
1797
1841
  type: ProtocolError.InvalidMessage,
1798
1842
  message: reason
1799
1843
  });
1844
+ this.deleteSession(connectedSession, { unhealthy: true });
1845
+ },
1846
+ onMessageSendFailure: (msg2, reason) => {
1847
+ this.log?.error(`failed to send message: ${reason}`, {
1848
+ ...connectedSession.loggingMetadata,
1849
+ transportMessage: msg2
1850
+ });
1851
+ this.protocolError({
1852
+ type: ProtocolError.MessageSendFailure,
1853
+ message: reason
1854
+ });
1855
+ this.deleteSession(connectedSession, { unhealthy: true });
1800
1856
  }
1801
1857
  });
1858
+ const res = connectedSession.sendBufferedMessages();
1859
+ if (!res.ok) {
1860
+ return;
1861
+ }
1802
1862
  this.updateSession(connectedSession);
1803
1863
  this.retryBudget.startRestoringBudget();
1804
1864
  }
@@ -1937,7 +1997,18 @@ var ClientTransport = class extends Transport {
1937
1997
  ...session.loggingMetadata,
1938
1998
  transportMessage: requestMsg
1939
1999
  });
1940
- session.sendHandshake(requestMsg);
2000
+ const res = session.sendHandshake(requestMsg);
2001
+ if (!res.ok) {
2002
+ this.log?.error(`failed to send handshake request: ${res.reason}`, {
2003
+ ...session.loggingMetadata,
2004
+ transportMessage: requestMsg
2005
+ });
2006
+ this.protocolError({
2007
+ type: ProtocolError.MessageSendFailure,
2008
+ message: res.reason
2009
+ });
2010
+ this.deleteSession(session, { unhealthy: true });
2011
+ }
1941
2012
  }
1942
2013
  close() {
1943
2014
  this.retryBudget.close();
@@ -1987,8 +2058,7 @@ var ServerTransport = class extends Transport {
1987
2058
  super.deleteSession(session, options);
1988
2059
  }
1989
2060
  handleConnection(conn) {
1990
- if (this.getStatus() !== "open")
1991
- return;
2061
+ if (this.getStatus() !== "open") return;
1992
2062
  this.log?.info(`new incoming connection`, {
1993
2063
  ...conn.loggingMetadata,
1994
2064
  clientId: this.clientId
@@ -2061,17 +2131,28 @@ var ServerTransport = class extends Transport {
2061
2131
  message: reason
2062
2132
  });
2063
2133
  this.log?.warn(reason, metadata);
2064
- session.sendHandshake(
2065
- handshakeResponseMessage({
2066
- from: this.clientId,
2067
- to,
2068
- status: {
2069
- ok: false,
2070
- code,
2071
- reason
2072
- }
2073
- })
2074
- );
2134
+ const responseMsg = handshakeResponseMessage({
2135
+ from: this.clientId,
2136
+ to,
2137
+ status: {
2138
+ ok: false,
2139
+ code,
2140
+ reason
2141
+ }
2142
+ });
2143
+ const res = session.sendHandshake(responseMsg);
2144
+ if (!res.ok) {
2145
+ this.log?.error(`failed to send handshake response: ${res.reason}`, {
2146
+ ...session.loggingMetadata,
2147
+ transportMessage: responseMsg
2148
+ });
2149
+ this.protocolError({
2150
+ type: ProtocolError.MessageSendFailure,
2151
+ message: res.reason
2152
+ });
2153
+ this.deletePendingSession(session);
2154
+ return;
2155
+ }
2075
2156
  this.protocolError({
2076
2157
  type: ProtocolError.HandshakeFailed,
2077
2158
  code,
@@ -2255,7 +2336,20 @@ var ServerTransport = class extends Transport {
2255
2336
  sessionId
2256
2337
  }
2257
2338
  });
2258
- session.sendHandshake(responseMsg);
2339
+ const res = session.sendHandshake(responseMsg);
2340
+ if (!res.ok) {
2341
+ this.log?.error(`failed to send handshake response: ${res.reason}`, {
2342
+ ...session.loggingMetadata,
2343
+ transportMessage: responseMsg
2344
+ });
2345
+ this.protocolError({
2346
+ type: ProtocolError.MessageSendFailure,
2347
+ message: res.reason
2348
+ });
2349
+ this.deletePendingSession(session);
2350
+ return;
2351
+ }
2352
+ this.pendingSessions.delete(session);
2259
2353
  const connectedSession = ServerSessionStateGraph.transition.WaitingForHandshakeToConnected(
2260
2354
  session,
2261
2355
  // by this point oldSession is either no connection or we dont have an old session
@@ -2282,22 +2376,40 @@ var ServerTransport = class extends Transport {
2282
2376
  this.handleMsg(msg2);
2283
2377
  },
2284
2378
  onInvalidMessage: (reason) => {
2379
+ this.log?.error(`invalid message: ${reason}`, {
2380
+ ...connectedSession.loggingMetadata,
2381
+ transportMessage: msg
2382
+ });
2285
2383
  this.protocolError({
2286
2384
  type: ProtocolError.InvalidMessage,
2287
2385
  message: reason
2288
2386
  });
2289
2387
  this.deleteSession(connectedSession, { unhealthy: true });
2388
+ },
2389
+ onMessageSendFailure: (msg2, reason) => {
2390
+ this.log?.error(`failed to send message: ${reason}`, {
2391
+ ...connectedSession.loggingMetadata,
2392
+ transportMessage: msg2
2393
+ });
2394
+ this.protocolError({
2395
+ type: ProtocolError.MessageSendFailure,
2396
+ message: reason
2397
+ });
2398
+ this.deleteSession(connectedSession, { unhealthy: true });
2290
2399
  }
2291
2400
  },
2292
2401
  gotVersion
2293
2402
  );
2403
+ const bufferSendRes = connectedSession.sendBufferedMessages();
2404
+ if (!bufferSendRes.ok) {
2405
+ return;
2406
+ }
2294
2407
  this.sessionHandshakeMetadata.set(connectedSession.to, parsedMetadata);
2295
2408
  if (oldSession) {
2296
2409
  this.updateSession(connectedSession);
2297
2410
  } else {
2298
2411
  this.createSession(connectedSession);
2299
2412
  }
2300
- this.pendingSessions.delete(session);
2301
2413
  connectedSession.startActiveHeartbeat();
2302
2414
  }
2303
2415
  };
@@ -2320,60 +2432,44 @@ var Connection = class {
2320
2432
  }
2321
2433
  return metadata;
2322
2434
  }
2323
- // can't use event emitter because we need this to work in both node + browser
2324
- _dataListeners = /* @__PURE__ */ new Set();
2325
- _closeListeners = /* @__PURE__ */ new Set();
2326
- _errorListeners = /* @__PURE__ */ new Set();
2327
- get dataListeners() {
2328
- return [...this._dataListeners];
2329
- }
2330
- get closeListeners() {
2331
- return [...this._closeListeners];
2332
- }
2333
- get errorListeners() {
2334
- return [...this._errorListeners];
2335
- }
2435
+ dataListener;
2436
+ closeListener;
2437
+ errorListener;
2336
2438
  onData(msg) {
2337
- for (const cb of this.dataListeners) {
2338
- cb(msg);
2339
- }
2439
+ this.dataListener?.(msg);
2340
2440
  }
2341
2441
  onError(err) {
2342
- for (const cb of this.errorListeners) {
2343
- cb(err);
2344
- }
2442
+ this.errorListener?.(err);
2345
2443
  }
2346
2444
  onClose() {
2347
- for (const cb of this.closeListeners) {
2348
- cb();
2349
- }
2445
+ this.closeListener?.();
2350
2446
  this.telemetry?.span.end();
2351
2447
  }
2352
2448
  /**
2353
- * Handle adding a callback for when a message is received.
2354
- * @param msg The message that was received.
2449
+ * Set the callback for when a message is received.
2450
+ * @param cb The message handler callback.
2355
2451
  */
2356
- addDataListener(cb) {
2357
- this._dataListeners.add(cb);
2452
+ setDataListener(cb) {
2453
+ this.dataListener = cb;
2358
2454
  }
2359
- removeDataListener(cb) {
2360
- this._dataListeners.delete(cb);
2455
+ removeDataListener() {
2456
+ this.dataListener = void 0;
2361
2457
  }
2362
2458
  /**
2363
- * Handle adding a callback for when the connection is closed.
2364
- * This should also be called if an error happens and after notifying all the error listeners.
2459
+ * Set the callback for when the connection is closed.
2460
+ * This should also be called if an error happens and after notifying the error listener.
2365
2461
  * @param cb The callback to call when the connection is closed.
2366
2462
  */
2367
- addCloseListener(cb) {
2368
- this._closeListeners.add(cb);
2463
+ setCloseListener(cb) {
2464
+ this.closeListener = cb;
2369
2465
  }
2370
- removeCloseListener(cb) {
2371
- this._closeListeners.delete(cb);
2466
+ removeCloseListener() {
2467
+ this.closeListener = void 0;
2372
2468
  }
2373
2469
  /**
2374
- * Handle adding a callback for when an error is received.
2375
- * This should only be used for this.logging errors, all cleanup
2376
- * should be delegated to addCloseListener.
2470
+ * Set the callback for when an error is received.
2471
+ * This should only be used for logging errors, all cleanup
2472
+ * should be delegated to setCloseListener.
2377
2473
  *
2378
2474
  * The implementer should take care such that the implemented
2379
2475
  * connection will call both the close and error callbacks
@@ -2381,11 +2477,11 @@ var Connection = class {
2381
2477
  *
2382
2478
  * @param cb The callback to call when an error is received.
2383
2479
  */
2384
- addErrorListener(cb) {
2385
- this._errorListeners.add(cb);
2480
+ setErrorListener(cb) {
2481
+ this.errorListener = cb;
2386
2482
  }
2387
- removeErrorListener(cb) {
2388
- this._errorListeners.delete(cb);
2483
+ removeErrorListener() {
2484
+ this.errorListener = void 0;
2389
2485
  }
2390
2486
  };
2391
2487
  // Annotate the CommonJS export names for ESM import in node: