@replit/river 0.200.0-rc.2 → 0.200.0-rc.20

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 (88) hide show
  1. package/README.md +30 -29
  2. package/dist/chunk-3HI3IJTL.js +285 -0
  3. package/dist/chunk-3HI3IJTL.js.map +1 -0
  4. package/dist/chunk-5L5RNZXH.js +391 -0
  5. package/dist/chunk-5L5RNZXH.js.map +1 -0
  6. package/dist/{chunk-QMM35C3H.js → chunk-BAGOAJ3K.js} +1 -1
  7. package/dist/chunk-BAGOAJ3K.js.map +1 -0
  8. package/dist/{chunk-S5RL45KH.js → chunk-BYCR4VEM.js} +78 -54
  9. package/dist/chunk-BYCR4VEM.js.map +1 -0
  10. package/dist/chunk-DM5QR4HQ.js +60 -0
  11. package/dist/chunk-DM5QR4HQ.js.map +1 -0
  12. package/dist/chunk-OLWVR5AB.js +860 -0
  13. package/dist/chunk-OLWVR5AB.js.map +1 -0
  14. package/dist/chunk-WKBWCRGN.js +437 -0
  15. package/dist/chunk-WKBWCRGN.js.map +1 -0
  16. package/dist/chunk-YBCQVIPR.js +351 -0
  17. package/dist/chunk-YBCQVIPR.js.map +1 -0
  18. package/dist/client-75090f07.d.ts +49 -0
  19. package/dist/connection-c9f96b64.d.ts +32 -0
  20. package/dist/context-9c907028.d.ts +622 -0
  21. package/dist/logging/index.cjs.map +1 -1
  22. package/dist/logging/index.d.cts +1 -1
  23. package/dist/logging/index.d.ts +1 -1
  24. package/dist/logging/index.js +1 -1
  25. package/dist/{index-10ebd26a.d.ts → message-59fe53e1.d.ts} +34 -31
  26. package/dist/router/index.cjs +771 -1159
  27. package/dist/router/index.cjs.map +1 -1
  28. package/dist/router/index.d.cts +14 -48
  29. package/dist/router/index.d.ts +14 -48
  30. package/dist/router/index.js +1238 -15
  31. package/dist/router/index.js.map +1 -1
  32. package/dist/server-109a29e2.d.ts +69 -0
  33. package/dist/services-aa49a9fb.d.ts +811 -0
  34. package/dist/transport/impls/ws/client.cjs +1293 -1034
  35. package/dist/transport/impls/ws/client.cjs.map +1 -1
  36. package/dist/transport/impls/ws/client.d.cts +7 -5
  37. package/dist/transport/impls/ws/client.d.ts +7 -5
  38. package/dist/transport/impls/ws/client.js +11 -11
  39. package/dist/transport/impls/ws/client.js.map +1 -1
  40. package/dist/transport/impls/ws/server.cjs +1437 -1072
  41. package/dist/transport/impls/ws/server.cjs.map +1 -1
  42. package/dist/transport/impls/ws/server.d.cts +7 -5
  43. package/dist/transport/impls/ws/server.d.ts +7 -5
  44. package/dist/transport/impls/ws/server.js +20 -8
  45. package/dist/transport/impls/ws/server.js.map +1 -1
  46. package/dist/transport/index.cjs +1720 -1400
  47. package/dist/transport/index.cjs.map +1 -1
  48. package/dist/transport/index.d.cts +5 -26
  49. package/dist/transport/index.d.ts +5 -26
  50. package/dist/transport/index.js +11 -11
  51. package/dist/util/testHelpers.cjs +1164 -591
  52. package/dist/util/testHelpers.cjs.map +1 -1
  53. package/dist/util/testHelpers.d.cts +41 -38
  54. package/dist/util/testHelpers.d.ts +41 -38
  55. package/dist/util/testHelpers.js +124 -89
  56. package/dist/util/testHelpers.js.map +1 -1
  57. package/package.json +3 -3
  58. package/dist/chunk-47TFNAY2.js +0 -476
  59. package/dist/chunk-47TFNAY2.js.map +0 -1
  60. package/dist/chunk-4VNY34QG.js +0 -106
  61. package/dist/chunk-4VNY34QG.js.map +0 -1
  62. package/dist/chunk-7CKIN3JT.js +0 -2004
  63. package/dist/chunk-7CKIN3JT.js.map +0 -1
  64. package/dist/chunk-CZP4LK3F.js +0 -335
  65. package/dist/chunk-CZP4LK3F.js.map +0 -1
  66. package/dist/chunk-DJCW3SKT.js +0 -59
  67. package/dist/chunk-DJCW3SKT.js.map +0 -1
  68. package/dist/chunk-NQWDT6GS.js +0 -347
  69. package/dist/chunk-NQWDT6GS.js.map +0 -1
  70. package/dist/chunk-ONUXWVRC.js +0 -492
  71. package/dist/chunk-ONUXWVRC.js.map +0 -1
  72. package/dist/chunk-QMM35C3H.js.map +0 -1
  73. package/dist/chunk-S5RL45KH.js.map +0 -1
  74. package/dist/connection-3f117047.d.ts +0 -17
  75. package/dist/connection-f900e390.d.ts +0 -35
  76. package/dist/services-970f97bb.d.ts +0 -1372
  77. package/dist/transport/impls/uds/client.cjs +0 -1687
  78. package/dist/transport/impls/uds/client.cjs.map +0 -1
  79. package/dist/transport/impls/uds/client.d.cts +0 -17
  80. package/dist/transport/impls/uds/client.d.ts +0 -17
  81. package/dist/transport/impls/uds/client.js +0 -44
  82. package/dist/transport/impls/uds/client.js.map +0 -1
  83. package/dist/transport/impls/uds/server.cjs +0 -1522
  84. package/dist/transport/impls/uds/server.cjs.map +0 -1
  85. package/dist/transport/impls/uds/server.d.cts +0 -19
  86. package/dist/transport/impls/uds/server.d.ts +0 -19
  87. package/dist/transport/impls/uds/server.js +0 -33
  88. package/dist/transport/impls/uds/server.js.map +0 -1
@@ -0,0 +1,860 @@
1
+ import {
2
+ OpaqueTransportMessageSchema,
3
+ createSessionTelemetryInfo,
4
+ generateId,
5
+ isAck
6
+ } from "./chunk-BYCR4VEM.js";
7
+ import {
8
+ NaiveJsonCodec
9
+ } from "./chunk-4PVU7J25.js";
10
+
11
+ // transport/options.ts
12
+ var defaultTransportOptions = {
13
+ heartbeatIntervalMs: 1e3,
14
+ heartbeatsUntilDead: 2,
15
+ sessionDisconnectGraceMs: 5e3,
16
+ connectionTimeoutMs: 2e3,
17
+ handshakeTimeoutMs: 1e3,
18
+ enableTransparentSessionReconnects: true,
19
+ codec: NaiveJsonCodec
20
+ };
21
+ var defaultConnectionRetryOptions = {
22
+ baseIntervalMs: 150,
23
+ maxJitterMs: 200,
24
+ maxBackoffMs: 32e3,
25
+ attemptBudgetCapacity: 5,
26
+ budgetRestoreIntervalMs: 200
27
+ };
28
+ var defaultClientTransportOptions = {
29
+ ...defaultTransportOptions,
30
+ ...defaultConnectionRetryOptions
31
+ };
32
+ var defaultServerTransportOptions = {
33
+ ...defaultTransportOptions
34
+ };
35
+
36
+ // transport/sessionStateMachine/common.ts
37
+ import { Value } from "@sinclair/typebox/value";
38
+ var SessionState = /* @__PURE__ */ ((SessionState2) => {
39
+ SessionState2["NoConnection"] = "NoConnection";
40
+ SessionState2["BackingOff"] = "BackingOff";
41
+ SessionState2["Connecting"] = "Connecting";
42
+ SessionState2["Handshaking"] = "Handshaking";
43
+ SessionState2["Connected"] = "Connected";
44
+ SessionState2["WaitingForHandshake"] = "WaitingForHandshake";
45
+ return SessionState2;
46
+ })(SessionState || {});
47
+ var ERR_CONSUMED = `session state has been consumed and is no longer valid`;
48
+ var StateMachineState = class {
49
+ /*
50
+ * Whether this state has been consumed
51
+ * and we've moved on to another state
52
+ */
53
+ _isConsumed;
54
+ close() {
55
+ this._handleClose();
56
+ }
57
+ constructor() {
58
+ this._isConsumed = false;
59
+ return new Proxy(this, {
60
+ get(target, prop) {
61
+ if (prop === "_isConsumed" || prop === "id" || prop === "state") {
62
+ return Reflect.get(target, prop);
63
+ }
64
+ if (prop === "_handleStateExit") {
65
+ return () => {
66
+ target._isConsumed = true;
67
+ target._handleStateExit();
68
+ };
69
+ }
70
+ if (prop === "_handleClose") {
71
+ return () => {
72
+ target._isConsumed = true;
73
+ target._handleStateExit();
74
+ target._handleClose();
75
+ };
76
+ }
77
+ if (target._isConsumed) {
78
+ throw new Error(
79
+ `${ERR_CONSUMED}: getting ${prop.toString()} on consumed state`
80
+ );
81
+ }
82
+ return Reflect.get(target, prop);
83
+ },
84
+ set(target, prop, value) {
85
+ if (target._isConsumed) {
86
+ throw new Error(
87
+ `${ERR_CONSUMED}: setting ${prop.toString()} on consumed state`
88
+ );
89
+ }
90
+ return Reflect.set(target, prop, value);
91
+ }
92
+ });
93
+ }
94
+ };
95
+ var CommonSession = class extends StateMachineState {
96
+ from;
97
+ options;
98
+ log;
99
+ constructor({ from, options, log }) {
100
+ super();
101
+ this.from = from;
102
+ this.options = options;
103
+ this.log = log;
104
+ }
105
+ parseMsg(msg) {
106
+ const parsedMsg = this.options.codec.fromBuffer(msg);
107
+ if (parsedMsg === null) {
108
+ const decodedBuffer = new TextDecoder().decode(Buffer.from(msg));
109
+ this.log?.error(
110
+ `received malformed msg: ${decodedBuffer}`,
111
+ this.loggingMetadata
112
+ );
113
+ return null;
114
+ }
115
+ if (!Value.Check(OpaqueTransportMessageSchema, parsedMsg)) {
116
+ this.log?.error(`received invalid msg: ${JSON.stringify(parsedMsg)}`, {
117
+ ...this.loggingMetadata,
118
+ validationErrors: [
119
+ ...Value.Errors(OpaqueTransportMessageSchema, parsedMsg)
120
+ ]
121
+ });
122
+ return null;
123
+ }
124
+ return parsedMsg;
125
+ }
126
+ };
127
+ var IdentifiedSession = class extends CommonSession {
128
+ id;
129
+ telemetry;
130
+ to;
131
+ protocolVersion;
132
+ /**
133
+ * Index of the message we will send next (excluding handshake)
134
+ */
135
+ seq;
136
+ /**
137
+ * Number of unique messages we've received this session (excluding handshake)
138
+ */
139
+ ack;
140
+ sendBuffer;
141
+ constructor(props) {
142
+ const { id, to, seq, ack, sendBuffer, telemetry, log, protocolVersion } = props;
143
+ super(props);
144
+ this.id = id;
145
+ this.to = to;
146
+ this.seq = seq;
147
+ this.ack = ack;
148
+ this.sendBuffer = sendBuffer;
149
+ this.telemetry = telemetry;
150
+ this.log = log;
151
+ this.protocolVersion = protocolVersion;
152
+ }
153
+ get loggingMetadata() {
154
+ const spanContext = this.telemetry.span.spanContext();
155
+ const metadata = {
156
+ clientId: this.from,
157
+ connectedTo: this.to,
158
+ sessionId: this.id
159
+ };
160
+ if (this.telemetry.span.isRecording()) {
161
+ metadata.telemetry = {
162
+ traceId: spanContext.traceId,
163
+ spanId: spanContext.spanId
164
+ };
165
+ }
166
+ return metadata;
167
+ }
168
+ constructMsg(partialMsg) {
169
+ const msg = {
170
+ ...partialMsg,
171
+ id: generateId(),
172
+ to: this.to,
173
+ from: this.from,
174
+ seq: this.seq,
175
+ ack: this.ack
176
+ };
177
+ this.seq++;
178
+ return msg;
179
+ }
180
+ nextSeq() {
181
+ return this.sendBuffer.length > 0 ? this.sendBuffer[0].seq : this.seq;
182
+ }
183
+ send(msg) {
184
+ const constructedMsg = this.constructMsg(msg);
185
+ this.sendBuffer.push(constructedMsg);
186
+ return constructedMsg.id;
187
+ }
188
+ _handleStateExit() {
189
+ }
190
+ _handleClose() {
191
+ this.sendBuffer.length = 0;
192
+ this.telemetry.span.end();
193
+ }
194
+ };
195
+ var IdentifiedSessionWithGracePeriod = class extends IdentifiedSession {
196
+ graceExpiryTime;
197
+ gracePeriodTimeout;
198
+ listeners;
199
+ constructor(props) {
200
+ super(props);
201
+ this.listeners = props.listeners;
202
+ this.graceExpiryTime = props.graceExpiryTime;
203
+ this.gracePeriodTimeout = setTimeout(() => {
204
+ this.listeners.onSessionGracePeriodElapsed();
205
+ }, this.graceExpiryTime - Date.now());
206
+ }
207
+ _handleStateExit() {
208
+ super._handleStateExit();
209
+ if (this.gracePeriodTimeout) {
210
+ clearTimeout(this.gracePeriodTimeout);
211
+ this.gracePeriodTimeout = void 0;
212
+ }
213
+ }
214
+ _handleClose() {
215
+ super._handleClose();
216
+ }
217
+ };
218
+
219
+ // transport/sessionStateMachine/SessionConnecting.ts
220
+ var SessionConnecting = class extends IdentifiedSessionWithGracePeriod {
221
+ state = "Connecting" /* Connecting */;
222
+ connPromise;
223
+ listeners;
224
+ connectionTimeout;
225
+ constructor(props) {
226
+ super(props);
227
+ this.connPromise = props.connPromise;
228
+ this.listeners = props.listeners;
229
+ this.connPromise.then(
230
+ (conn) => {
231
+ if (this._isConsumed)
232
+ return;
233
+ this.listeners.onConnectionEstablished(conn);
234
+ },
235
+ (err) => {
236
+ if (this._isConsumed)
237
+ return;
238
+ this.listeners.onConnectionFailed(err);
239
+ }
240
+ );
241
+ this.connectionTimeout = setTimeout(() => {
242
+ this.listeners.onConnectionTimeout();
243
+ }, this.options.connectionTimeoutMs);
244
+ }
245
+ // close a pending connection if it resolves, ignore errors if the promise
246
+ // ends up rejected anyways
247
+ bestEffortClose() {
248
+ const logger = this.log;
249
+ const metadata = this.loggingMetadata;
250
+ this.connPromise.then((conn) => {
251
+ conn.close();
252
+ logger?.info(
253
+ "connection eventually resolved but session has transitioned, closed connection",
254
+ {
255
+ ...metadata,
256
+ ...conn.loggingMetadata
257
+ }
258
+ );
259
+ }).catch(() => {
260
+ });
261
+ }
262
+ _handleStateExit() {
263
+ super._handleStateExit();
264
+ if (this.connectionTimeout) {
265
+ clearTimeout(this.connectionTimeout);
266
+ this.connectionTimeout = void 0;
267
+ }
268
+ }
269
+ _handleClose() {
270
+ this.bestEffortClose();
271
+ super._handleClose();
272
+ }
273
+ };
274
+
275
+ // transport/sessionStateMachine/SessionNoConnection.ts
276
+ var SessionNoConnection = class extends IdentifiedSessionWithGracePeriod {
277
+ state = "NoConnection" /* NoConnection */;
278
+ _handleClose() {
279
+ super._handleClose();
280
+ }
281
+ _handleStateExit() {
282
+ super._handleStateExit();
283
+ }
284
+ };
285
+
286
+ // transport/sessionStateMachine/SessionWaitingForHandshake.ts
287
+ var SessionWaitingForHandshake = class extends CommonSession {
288
+ state = "WaitingForHandshake" /* WaitingForHandshake */;
289
+ conn;
290
+ listeners;
291
+ handshakeTimeout;
292
+ constructor(props) {
293
+ super(props);
294
+ this.conn = props.conn;
295
+ this.listeners = props.listeners;
296
+ this.handshakeTimeout = setTimeout(() => {
297
+ this.listeners.onHandshakeTimeout();
298
+ }, this.options.handshakeTimeoutMs);
299
+ this.conn.addDataListener(this.onHandshakeData);
300
+ this.conn.addErrorListener(this.listeners.onConnectionErrored);
301
+ this.conn.addCloseListener(this.listeners.onConnectionClosed);
302
+ }
303
+ get loggingMetadata() {
304
+ return {
305
+ clientId: this.from,
306
+ connId: this.conn.id,
307
+ ...this.conn.loggingMetadata
308
+ };
309
+ }
310
+ onHandshakeData = (msg) => {
311
+ const parsedMsg = this.parseMsg(msg);
312
+ if (parsedMsg === null) {
313
+ this.listeners.onInvalidHandshake(
314
+ "could not parse message",
315
+ "MALFORMED_HANDSHAKE"
316
+ );
317
+ return;
318
+ }
319
+ this.listeners.onHandshake(parsedMsg);
320
+ };
321
+ sendHandshake(msg) {
322
+ return this.conn.send(this.options.codec.toBuffer(msg));
323
+ }
324
+ _handleStateExit() {
325
+ this.conn.removeDataListener(this.onHandshakeData);
326
+ this.conn.removeErrorListener(this.listeners.onConnectionErrored);
327
+ this.conn.removeCloseListener(this.listeners.onConnectionClosed);
328
+ clearTimeout(this.handshakeTimeout);
329
+ this.handshakeTimeout = void 0;
330
+ }
331
+ _handleClose() {
332
+ this.conn.close();
333
+ }
334
+ };
335
+
336
+ // transport/sessionStateMachine/SessionHandshaking.ts
337
+ var SessionHandshaking = class extends IdentifiedSessionWithGracePeriod {
338
+ state = "Handshaking" /* Handshaking */;
339
+ conn;
340
+ listeners;
341
+ handshakeTimeout;
342
+ constructor(props) {
343
+ super(props);
344
+ this.conn = props.conn;
345
+ this.listeners = props.listeners;
346
+ this.handshakeTimeout = setTimeout(() => {
347
+ this.listeners.onHandshakeTimeout();
348
+ }, this.options.handshakeTimeoutMs);
349
+ this.conn.addDataListener(this.onHandshakeData);
350
+ this.conn.addErrorListener(this.listeners.onConnectionErrored);
351
+ this.conn.addCloseListener(this.listeners.onConnectionClosed);
352
+ }
353
+ get loggingMetadata() {
354
+ return {
355
+ ...super.loggingMetadata,
356
+ ...this.conn.loggingMetadata
357
+ };
358
+ }
359
+ onHandshakeData = (msg) => {
360
+ const parsedMsg = this.parseMsg(msg);
361
+ if (parsedMsg === null) {
362
+ this.listeners.onInvalidHandshake(
363
+ "could not parse message",
364
+ "MALFORMED_HANDSHAKE"
365
+ );
366
+ return;
367
+ }
368
+ this.listeners.onHandshake(parsedMsg);
369
+ };
370
+ sendHandshake(msg) {
371
+ return this.conn.send(this.options.codec.toBuffer(msg));
372
+ }
373
+ _handleStateExit() {
374
+ super._handleStateExit();
375
+ this.conn.removeDataListener(this.onHandshakeData);
376
+ this.conn.removeErrorListener(this.listeners.onConnectionErrored);
377
+ this.conn.removeCloseListener(this.listeners.onConnectionClosed);
378
+ if (this.handshakeTimeout) {
379
+ clearTimeout(this.handshakeTimeout);
380
+ this.handshakeTimeout = void 0;
381
+ }
382
+ }
383
+ _handleClose() {
384
+ super._handleClose();
385
+ this.conn.close();
386
+ }
387
+ };
388
+
389
+ // transport/sessionStateMachine/SessionConnected.ts
390
+ import { SpanStatusCode } from "@opentelemetry/api";
391
+ var SessionConnected = class extends IdentifiedSession {
392
+ state = "Connected" /* Connected */;
393
+ conn;
394
+ listeners;
395
+ heartbeatHandle;
396
+ heartbeatMisses = 0;
397
+ isActivelyHeartbeating;
398
+ updateBookkeeping(ack, seq) {
399
+ this.sendBuffer = this.sendBuffer.filter((unacked) => unacked.seq >= ack);
400
+ this.ack = seq + 1;
401
+ this.heartbeatMisses = 0;
402
+ }
403
+ send(msg) {
404
+ const constructedMsg = this.constructMsg(msg);
405
+ this.sendBuffer.push(constructedMsg);
406
+ this.conn.send(this.options.codec.toBuffer(constructedMsg));
407
+ return constructedMsg.id;
408
+ }
409
+ constructor(props) {
410
+ super(props);
411
+ this.conn = props.conn;
412
+ this.listeners = props.listeners;
413
+ this.conn.addDataListener(this.onMessageData);
414
+ this.conn.addCloseListener(this.listeners.onConnectionClosed);
415
+ this.conn.addErrorListener(this.listeners.onConnectionErrored);
416
+ if (this.sendBuffer.length > 0) {
417
+ this.log?.info(
418
+ `sending ${this.sendBuffer.length} buffered messages, starting at seq ${this.nextSeq()}`,
419
+ this.loggingMetadata
420
+ );
421
+ for (const msg of this.sendBuffer) {
422
+ this.conn.send(this.options.codec.toBuffer(msg));
423
+ }
424
+ }
425
+ this.isActivelyHeartbeating = false;
426
+ this.heartbeatHandle = setInterval(() => {
427
+ const misses = this.heartbeatMisses;
428
+ const missDuration = misses * this.options.heartbeatIntervalMs;
429
+ if (misses >= this.options.heartbeatsUntilDead) {
430
+ this.log?.info(
431
+ `closing connection to ${this.to} due to inactivity (missed ${misses} heartbeats which is ${missDuration}ms)`,
432
+ this.loggingMetadata
433
+ );
434
+ this.telemetry.span.addEvent("closing connection due to inactivity");
435
+ this.conn.close();
436
+ clearInterval(this.heartbeatHandle);
437
+ this.heartbeatHandle = void 0;
438
+ return;
439
+ }
440
+ if (this.isActivelyHeartbeating) {
441
+ this.sendHeartbeat();
442
+ }
443
+ this.heartbeatMisses++;
444
+ }, this.options.heartbeatIntervalMs);
445
+ }
446
+ get loggingMetadata() {
447
+ return {
448
+ ...super.loggingMetadata,
449
+ ...this.conn.loggingMetadata
450
+ };
451
+ }
452
+ startActiveHeartbeat() {
453
+ this.isActivelyHeartbeating = true;
454
+ }
455
+ sendHeartbeat() {
456
+ this.log?.debug("sending heartbeat", this.loggingMetadata);
457
+ this.send({
458
+ streamId: "heartbeat",
459
+ controlFlags: 1 /* AckBit */,
460
+ payload: {
461
+ type: "ACK"
462
+ }
463
+ });
464
+ }
465
+ closeConnection() {
466
+ this.conn.removeDataListener(this.onMessageData);
467
+ this.conn.removeCloseListener(this.listeners.onConnectionClosed);
468
+ this.conn.removeErrorListener(this.listeners.onConnectionErrored);
469
+ this.conn.close();
470
+ }
471
+ onMessageData = (msg) => {
472
+ const parsedMsg = this.parseMsg(msg);
473
+ if (parsedMsg === null) {
474
+ this.listeners.onInvalidMessage("could not parse message");
475
+ return;
476
+ }
477
+ if (parsedMsg.seq !== this.ack) {
478
+ if (parsedMsg.seq < this.ack) {
479
+ this.log?.debug(
480
+ `received duplicate msg (got seq: ${parsedMsg.seq}, wanted seq: ${this.ack}), discarding`,
481
+ {
482
+ ...this.loggingMetadata,
483
+ transportMessage: parsedMsg
484
+ }
485
+ );
486
+ } else {
487
+ const reason = `received out-of-order msg, closing connection (got seq: ${parsedMsg.seq}, wanted seq: ${this.ack})`;
488
+ this.log?.warn(reason, {
489
+ ...this.loggingMetadata,
490
+ transportMessage: parsedMsg,
491
+ tags: ["invariant-violation"]
492
+ });
493
+ this.telemetry.span.setStatus({
494
+ code: SpanStatusCode.ERROR,
495
+ message: reason
496
+ });
497
+ this.closeConnection();
498
+ }
499
+ return;
500
+ }
501
+ this.log?.debug(`received msg`, {
502
+ ...this.loggingMetadata,
503
+ transportMessage: parsedMsg
504
+ });
505
+ this.updateBookkeeping(parsedMsg.ack, parsedMsg.seq);
506
+ if (!isAck(parsedMsg.controlFlags)) {
507
+ this.listeners.onMessage(parsedMsg);
508
+ return;
509
+ }
510
+ this.log?.debug(`discarding msg (ack bit set)`, {
511
+ ...this.loggingMetadata,
512
+ transportMessage: parsedMsg
513
+ });
514
+ if (!this.isActivelyHeartbeating) {
515
+ this.sendHeartbeat();
516
+ }
517
+ };
518
+ _handleStateExit() {
519
+ super._handleStateExit();
520
+ this.conn.removeDataListener(this.onMessageData);
521
+ this.conn.removeCloseListener(this.listeners.onConnectionClosed);
522
+ this.conn.removeErrorListener(this.listeners.onConnectionErrored);
523
+ if (this.heartbeatHandle) {
524
+ clearInterval(this.heartbeatHandle);
525
+ this.heartbeatHandle = void 0;
526
+ }
527
+ }
528
+ _handleClose() {
529
+ super._handleClose();
530
+ this.conn.close();
531
+ }
532
+ };
533
+
534
+ // transport/sessionStateMachine/SessionBackingOff.ts
535
+ var SessionBackingOff = class extends IdentifiedSessionWithGracePeriod {
536
+ state = "BackingOff" /* BackingOff */;
537
+ listeners;
538
+ backoffTimeout;
539
+ constructor(props) {
540
+ super(props);
541
+ this.listeners = props.listeners;
542
+ this.backoffTimeout = setTimeout(() => {
543
+ this.listeners.onBackoffFinished();
544
+ }, props.backoffMs);
545
+ }
546
+ _handleClose() {
547
+ super._handleClose();
548
+ }
549
+ _handleStateExit() {
550
+ super._handleStateExit();
551
+ if (this.backoffTimeout) {
552
+ clearTimeout(this.backoffTimeout);
553
+ this.backoffTimeout = void 0;
554
+ }
555
+ }
556
+ };
557
+
558
+ // transport/sessionStateMachine/transitions.ts
559
+ function inheritSharedSession(session) {
560
+ return {
561
+ id: session.id,
562
+ from: session.from,
563
+ to: session.to,
564
+ seq: session.seq,
565
+ ack: session.ack,
566
+ sendBuffer: session.sendBuffer,
567
+ telemetry: session.telemetry,
568
+ options: session.options,
569
+ log: session.log,
570
+ protocolVersion: session.protocolVersion
571
+ };
572
+ }
573
+ function inheritSharedSessionWithGrace(session) {
574
+ return {
575
+ ...inheritSharedSession(session),
576
+ graceExpiryTime: session.graceExpiryTime
577
+ };
578
+ }
579
+ var SessionStateGraph = {
580
+ entrypoints: {
581
+ NoConnection: (to, from, listeners, options, protocolVersion, log) => {
582
+ const id = `session-${generateId()}`;
583
+ const telemetry = createSessionTelemetryInfo(id, to, from);
584
+ const sendBuffer = [];
585
+ const session = new SessionNoConnection({
586
+ listeners,
587
+ id,
588
+ from,
589
+ to,
590
+ seq: 0,
591
+ ack: 0,
592
+ graceExpiryTime: Date.now() + options.sessionDisconnectGraceMs,
593
+ sendBuffer,
594
+ telemetry,
595
+ options,
596
+ protocolVersion,
597
+ log
598
+ });
599
+ session.log?.info(`session ${session.id} created in NoConnection state`, {
600
+ ...session.loggingMetadata,
601
+ tags: ["state-transition"]
602
+ });
603
+ return session;
604
+ },
605
+ WaitingForHandshake: (from, conn, listeners, options, log) => {
606
+ const session = new SessionWaitingForHandshake({
607
+ conn,
608
+ listeners,
609
+ from,
610
+ options,
611
+ log
612
+ });
613
+ session.log?.info(`session created in WaitingForHandshake state`, {
614
+ ...session.loggingMetadata,
615
+ tags: ["state-transition"]
616
+ });
617
+ return session;
618
+ }
619
+ },
620
+ // All of the transitions 'move'/'consume' the old session and return a new one.
621
+ // After a session is transitioned, any usage of the old session will throw.
622
+ transition: {
623
+ // happy path transitions
624
+ NoConnectionToBackingOff: (oldSession, backoffMs, listeners) => {
625
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
626
+ oldSession._handleStateExit();
627
+ const session = new SessionBackingOff({
628
+ backoffMs,
629
+ listeners,
630
+ ...carriedState
631
+ });
632
+ session.log?.info(
633
+ `session ${session.id} transition from NoConnection to BackingOff`,
634
+ {
635
+ ...session.loggingMetadata,
636
+ tags: ["state-transition"]
637
+ }
638
+ );
639
+ return session;
640
+ },
641
+ BackingOffToConnecting: (oldSession, connPromise, listeners) => {
642
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
643
+ oldSession._handleStateExit();
644
+ const session = new SessionConnecting({
645
+ connPromise,
646
+ listeners,
647
+ ...carriedState
648
+ });
649
+ session.log?.info(
650
+ `session ${session.id} transition from BackingOff to Connecting`,
651
+ {
652
+ ...session.loggingMetadata,
653
+ tags: ["state-transition"]
654
+ }
655
+ );
656
+ return session;
657
+ },
658
+ ConnectingToHandshaking: (oldSession, conn, listeners) => {
659
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
660
+ oldSession._handleStateExit();
661
+ const session = new SessionHandshaking({
662
+ conn,
663
+ listeners,
664
+ ...carriedState
665
+ });
666
+ session.log?.info(
667
+ `session ${session.id} transition from Connecting to Handshaking`,
668
+ {
669
+ ...session.loggingMetadata,
670
+ tags: ["state-transition"]
671
+ }
672
+ );
673
+ return session;
674
+ },
675
+ HandshakingToConnected: (oldSession, listeners) => {
676
+ const carriedState = inheritSharedSession(oldSession);
677
+ const conn = oldSession.conn;
678
+ oldSession._handleStateExit();
679
+ const session = new SessionConnected({
680
+ conn,
681
+ listeners,
682
+ ...carriedState
683
+ });
684
+ session.log?.info(
685
+ `session ${session.id} transition from Handshaking to Connected`,
686
+ {
687
+ ...session.loggingMetadata,
688
+ tags: ["state-transition"]
689
+ }
690
+ );
691
+ return session;
692
+ },
693
+ WaitingForHandshakeToConnected: (pendingSession, oldSession, sessionId, to, propagationCtx, listeners, protocolVersion) => {
694
+ const conn = pendingSession.conn;
695
+ const { from, options } = pendingSession;
696
+ const carriedState = oldSession ? (
697
+ // old session exists, inherit state
698
+ inheritSharedSession(oldSession)
699
+ ) : (
700
+ // old session does not exist, create new state
701
+ {
702
+ id: sessionId,
703
+ from,
704
+ to,
705
+ seq: 0,
706
+ ack: 0,
707
+ sendBuffer: [],
708
+ telemetry: createSessionTelemetryInfo(
709
+ sessionId,
710
+ to,
711
+ from,
712
+ propagationCtx
713
+ ),
714
+ options,
715
+ log: pendingSession.log,
716
+ protocolVersion
717
+ }
718
+ );
719
+ pendingSession._handleStateExit();
720
+ oldSession?._handleStateExit();
721
+ const session = new SessionConnected({
722
+ conn,
723
+ listeners,
724
+ ...carriedState
725
+ });
726
+ session.log?.info(
727
+ `session ${session.id} transition from WaitingForHandshake to Connected`,
728
+ {
729
+ ...session.loggingMetadata,
730
+ tags: ["state-transition"]
731
+ }
732
+ );
733
+ return session;
734
+ },
735
+ // disconnect paths
736
+ BackingOffToNoConnection: (oldSession, listeners) => {
737
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
738
+ oldSession._handleStateExit();
739
+ const session = new SessionNoConnection({
740
+ listeners,
741
+ ...carriedState
742
+ });
743
+ session.log?.info(
744
+ `session ${session.id} transition from BackingOff to NoConnection`,
745
+ {
746
+ ...session.loggingMetadata,
747
+ tags: ["state-transition"]
748
+ }
749
+ );
750
+ return session;
751
+ },
752
+ ConnectingToNoConnection: (oldSession, listeners) => {
753
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
754
+ oldSession.bestEffortClose();
755
+ oldSession._handleStateExit();
756
+ const session = new SessionNoConnection({
757
+ listeners,
758
+ ...carriedState
759
+ });
760
+ session.log?.info(
761
+ `session ${session.id} transition from Connecting to NoConnection`,
762
+ {
763
+ ...session.loggingMetadata,
764
+ tags: ["state-transition"]
765
+ }
766
+ );
767
+ return session;
768
+ },
769
+ HandshakingToNoConnection: (oldSession, listeners) => {
770
+ const carriedState = inheritSharedSessionWithGrace(oldSession);
771
+ oldSession.conn.close();
772
+ oldSession._handleStateExit();
773
+ const session = new SessionNoConnection({
774
+ listeners,
775
+ ...carriedState
776
+ });
777
+ session.log?.info(
778
+ `session ${session.id} transition from Handshaking to NoConnection`,
779
+ {
780
+ ...session.loggingMetadata,
781
+ tags: ["state-transition"]
782
+ }
783
+ );
784
+ return session;
785
+ },
786
+ ConnectedToNoConnection: (oldSession, listeners) => {
787
+ const carriedState = inheritSharedSession(oldSession);
788
+ const graceExpiryTime = Date.now() + oldSession.options.sessionDisconnectGraceMs;
789
+ oldSession.conn.close();
790
+ oldSession._handleStateExit();
791
+ const session = new SessionNoConnection({
792
+ listeners,
793
+ graceExpiryTime,
794
+ ...carriedState
795
+ });
796
+ session.log?.info(
797
+ `session ${session.id} transition from Connected to NoConnection`,
798
+ {
799
+ ...session.loggingMetadata,
800
+ tags: ["state-transition"]
801
+ }
802
+ );
803
+ return session;
804
+ }
805
+ }
806
+ };
807
+ var transitions = SessionStateGraph.transition;
808
+ var ClientSessionStateGraph = {
809
+ entrypoint: SessionStateGraph.entrypoints.NoConnection,
810
+ transition: {
811
+ // happy paths
812
+ // NoConnection -> BackingOff: attempt to connect
813
+ NoConnectionToBackingOff: transitions.NoConnectionToBackingOff,
814
+ // BackingOff -> Connecting: backoff period elapsed, start connection
815
+ BackingOffToConnecting: transitions.BackingOffToConnecting,
816
+ // Connecting -> Handshaking: connection established, start handshake
817
+ ConnectingToHandshaking: transitions.ConnectingToHandshaking,
818
+ // Handshaking -> Connected: handshake complete, session ready
819
+ HandshakingToConnected: transitions.HandshakingToConnected,
820
+ // disconnect paths
821
+ // BackingOff -> NoConnection: unused
822
+ BackingOffToNoConnection: transitions.BackingOffToNoConnection,
823
+ // Connecting -> NoConnection: connection failed or connection timeout
824
+ ConnectingToNoConnection: transitions.ConnectingToNoConnection,
825
+ // Handshaking -> NoConnection: connection closed or handshake timeout
826
+ HandshakingToNoConnection: transitions.HandshakingToNoConnection,
827
+ // Connected -> NoConnection: connection closed
828
+ ConnectedToNoConnection: transitions.ConnectedToNoConnection
829
+ // destroy/close paths
830
+ // NoConnection -> x: grace period elapsed
831
+ // BackingOff -> x: grace period elapsed
832
+ // Connecting -> x: grace period elapsed
833
+ // Handshaking -> x: grace period elapsed or invalid handshake message or handshake rejection
834
+ // Connected -> x: grace period elapsed or invalid message
835
+ }
836
+ };
837
+ var ServerSessionStateGraph = {
838
+ entrypoint: SessionStateGraph.entrypoints.WaitingForHandshake,
839
+ transition: {
840
+ // happy paths
841
+ // WaitingForHandshake -> Connected: handshake complete, session ready
842
+ WaitingForHandshakeToConnected: transitions.WaitingForHandshakeToConnected,
843
+ // disconnect paths
844
+ // Connected -> NoConnection: connection closed
845
+ ConnectedToNoConnection: transitions.ConnectedToNoConnection
846
+ // destroy/close paths
847
+ // WaitingForHandshake -> x: handshake timeout elapsed or invalid handshake message or handshake rejection or connection closed
848
+ }
849
+ };
850
+
851
+ export {
852
+ defaultTransportOptions,
853
+ defaultClientTransportOptions,
854
+ defaultServerTransportOptions,
855
+ SessionState,
856
+ SessionStateGraph,
857
+ ClientSessionStateGraph,
858
+ ServerSessionStateGraph
859
+ };
860
+ //# sourceMappingURL=chunk-OLWVR5AB.js.map