@replit/river 0.23.15 → 0.200.0-rc.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 (72) hide show
  1. package/dist/{chunk-5HK7ZQYH.js → chunk-3FALN7ZG.js} +14 -2
  2. package/dist/{chunk-5HK7ZQYH.js.map → chunk-3FALN7ZG.js.map} +1 -1
  3. package/dist/{chunk-RQQZUQGE.js → chunk-6GK2IIDP.js} +2 -2
  4. package/dist/{chunk-JMVKSGND.js → chunk-6RKO3DDG.js} +4 -4
  5. package/dist/chunk-E2ZXI663.js +1995 -0
  6. package/dist/chunk-E2ZXI663.js.map +1 -0
  7. package/dist/{chunk-OXVWMLID.js → chunk-LK74ZG7M.js} +25 -10
  8. package/dist/chunk-LK74ZG7M.js.map +1 -0
  9. package/dist/{chunk-XYEOXPZQ.js → chunk-NDLWNT7B.js} +2 -2
  10. package/dist/{chunk-6LCL2ZZF.js → chunk-QMM35C3H.js} +1 -1
  11. package/dist/chunk-QMM35C3H.js.map +1 -0
  12. package/dist/{chunk-IJTGEBLG.js → chunk-TK7QHUFP.js} +4 -4
  13. package/dist/{chunk-MD4S7GO2.js → chunk-YUY37VAK.js} +23 -7
  14. package/dist/chunk-YUY37VAK.js.map +1 -0
  15. package/dist/{connection-5d0978ce.d.ts → connection-0638316b.d.ts} +1 -1
  16. package/dist/{connection-e57e98ea.d.ts → connection-c6521735.d.ts} +1 -1
  17. package/dist/{index-ea74cdbb.d.ts → index-10ebd26a.d.ts} +33 -33
  18. package/dist/logging/index.cjs.map +1 -1
  19. package/dist/logging/index.d.cts +1 -1
  20. package/dist/logging/index.d.ts +1 -1
  21. package/dist/logging/index.js +1 -1
  22. package/dist/router/index.cjs +1053 -912
  23. package/dist/router/index.cjs.map +1 -1
  24. package/dist/router/index.d.cts +19 -23
  25. package/dist/router/index.d.ts +19 -23
  26. package/dist/router/index.js +12 -6
  27. package/dist/services-34d97070.d.ts +1366 -0
  28. package/dist/transport/impls/uds/client.cjs +33 -5
  29. package/dist/transport/impls/uds/client.cjs.map +1 -1
  30. package/dist/transport/impls/uds/client.d.cts +3 -4
  31. package/dist/transport/impls/uds/client.d.ts +3 -4
  32. package/dist/transport/impls/uds/client.js +6 -6
  33. package/dist/transport/impls/uds/server.cjs +33 -5
  34. package/dist/transport/impls/uds/server.cjs.map +1 -1
  35. package/dist/transport/impls/uds/server.d.cts +4 -4
  36. package/dist/transport/impls/uds/server.d.ts +4 -4
  37. package/dist/transport/impls/uds/server.js +6 -6
  38. package/dist/transport/impls/ws/client.cjs +33 -5
  39. package/dist/transport/impls/ws/client.cjs.map +1 -1
  40. package/dist/transport/impls/ws/client.d.cts +5 -6
  41. package/dist/transport/impls/ws/client.d.ts +5 -6
  42. package/dist/transport/impls/ws/client.js +6 -6
  43. package/dist/transport/impls/ws/server.cjs +33 -5
  44. package/dist/transport/impls/ws/server.cjs.map +1 -1
  45. package/dist/transport/impls/ws/server.d.cts +4 -4
  46. package/dist/transport/impls/ws/server.d.ts +4 -4
  47. package/dist/transport/impls/ws/server.js +6 -6
  48. package/dist/transport/index.cjs +33 -5
  49. package/dist/transport/index.cjs.map +1 -1
  50. package/dist/transport/index.d.cts +27 -5
  51. package/dist/transport/index.d.ts +27 -5
  52. package/dist/transport/index.js +6 -6
  53. package/dist/util/testHelpers.cjs +382 -326
  54. package/dist/util/testHelpers.cjs.map +1 -1
  55. package/dist/util/testHelpers.d.cts +32 -21
  56. package/dist/util/testHelpers.d.ts +32 -21
  57. package/dist/util/testHelpers.js +76 -42
  58. package/dist/util/testHelpers.js.map +1 -1
  59. package/package.json +15 -15
  60. package/dist/chunk-6LCL2ZZF.js.map +0 -1
  61. package/dist/chunk-AEY7BBOZ.js +0 -1865
  62. package/dist/chunk-AEY7BBOZ.js.map +0 -1
  63. package/dist/chunk-MD4S7GO2.js.map +0 -1
  64. package/dist/chunk-OXVWMLID.js.map +0 -1
  65. package/dist/client-e13979ac.d.ts +0 -52
  66. package/dist/handshake-5665ffd3.d.ts +0 -511
  67. package/dist/server-1cfc88d1.d.ts +0 -24
  68. package/dist/services-86c4d10d.d.ts +0 -709
  69. /package/dist/{chunk-RQQZUQGE.js.map → chunk-6GK2IIDP.js.map} +0 -0
  70. /package/dist/{chunk-JMVKSGND.js.map → chunk-6RKO3DDG.js.map} +0 -0
  71. /package/dist/{chunk-XYEOXPZQ.js.map → chunk-NDLWNT7B.js.map} +0 -0
  72. /package/dist/{chunk-IJTGEBLG.js.map → chunk-TK7QHUFP.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createSessionTelemetryInfo
3
- } from "./chunk-OXVWMLID.js";
3
+ } from "./chunk-LK74ZG7M.js";
4
4
  import {
5
5
  NaiveJsonCodec
6
6
  } from "./chunk-4PVU7J25.js";
@@ -280,6 +280,18 @@ var Session = class {
280
280
  get nextExpectedSeq() {
281
281
  return this.ack;
282
282
  }
283
+ /**
284
+ * Check that the peer's next expected seq number matches something that is in our send buffer
285
+ * _or_ matches our actual next seq.
286
+ */
287
+ nextExpectedSeqInRange(nextExpectedSeq) {
288
+ for (const msg of this.sendBuffer) {
289
+ if (nextExpectedSeq === msg.seq) {
290
+ return true;
291
+ }
292
+ }
293
+ return nextExpectedSeq === this.seq;
294
+ }
283
295
  // This is only used in tests to make the session misbehave.
284
296
  /* @internal */
285
297
  advanceAckForTesting(by) {
@@ -332,4 +344,4 @@ export {
332
344
  defaultClientTransportOptions,
333
345
  defaultServerTransportOptions
334
346
  };
335
- //# sourceMappingURL=chunk-5HK7ZQYH.js.map
347
+ //# sourceMappingURL=chunk-3FALN7ZG.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../transport/session.ts","../transport/options.ts"],"sourcesContent":["import { customAlphabet } from 'nanoid';\nimport {\n ControlFlags,\n ControlMessageAckSchema,\n OpaqueTransportMessage,\n PartialTransportMessage,\n TransportClientId,\n TransportMessage,\n} from './message';\nimport { Codec } from '../codec';\nimport { Logger, MessageMetadata } from '../logging/log';\nimport { Static } from '@sinclair/typebox';\nimport {\n PropagationContext,\n TelemetryInfo,\n createSessionTelemetryInfo,\n} from '../tracing';\nimport { SpanStatusCode } from '@opentelemetry/api';\n\nconst nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvxyz', 6);\nexport const unsafeId = () => nanoid();\n\ntype SequenceNumber = number;\n\n/**\n * A connection is the actual raw underlying transport connection.\n * It’s responsible for dispatching to/from the actual connection itself\n * This should be instantiated as soon as the client/server has a connection\n * It’s tied to the lifecycle of the underlying transport connection (i.e. if the WS drops, this connection should be deleted)\n */\nexport abstract class Connection {\n id: string;\n telemetry?: TelemetryInfo;\n constructor() {\n this.id = `conn-${nanoid(12)}`; // for debugging, no collision safety needed\n }\n\n get loggingMetadata(): MessageMetadata {\n const metadata: MessageMetadata = { connId: this.id };\n const spanContext = this.telemetry?.span.spanContext();\n\n if (this.telemetry?.span.isRecording() && spanContext) {\n metadata.telemetry = {\n traceId: spanContext.traceId,\n spanId: spanContext.spanId,\n };\n }\n\n return metadata;\n }\n\n /**\n * Handle adding a callback for when a message is received.\n * @param msg The message that was received.\n */\n abstract addDataListener(cb: (msg: Uint8Array) => void): void;\n abstract removeDataListener(cb: (msg: Uint8Array) => void): void;\n\n /**\n * Handle adding a callback for when the connection is closed.\n * This should also be called if an error happens.\n * @param cb The callback to call when the connection is closed.\n */\n abstract addCloseListener(cb: () => void): void;\n\n /**\n * Handle adding a callback for when an error is received.\n * This should only be used for this.logging errors, all cleanup\n * should be delegated to addCloseListener.\n *\n * The implementer should take care such that the implemented\n * connection will call both the close and error callbacks\n * on an error.\n *\n * @param cb The callback to call when an error is received.\n */\n abstract addErrorListener(cb: (err: Error) => void): void;\n\n /**\n * Sends a message over the connection.\n * @param msg The message to send.\n * @returns true if the message was sent, false otherwise.\n */\n abstract send(msg: Uint8Array): boolean;\n\n /**\n * Closes the connection.\n */\n abstract close(): void;\n}\n\nexport interface SessionOptions {\n /**\n * Frequency at which to send heartbeat acknowledgements\n */\n heartbeatIntervalMs: number;\n /**\n * Number of elapsed heartbeats without a response message before we consider\n * the connection dead.\n */\n heartbeatsUntilDead: number;\n /**\n * Duration to wait between connection disconnect and actual session disconnect\n */\n sessionDisconnectGraceMs: number;\n /**\n * The codec to use for encoding/decoding messages over the wire\n */\n codec: Codec;\n}\n\n/**\n * A session is a higher-level abstraction that operates over the span of potentially multiple transport-level connections\n * - It’s responsible for tracking any metadata for a particular client that might need to be persisted across connections (i.e. the sendBuffer, ack, seq)\n * - This will only be considered disconnected if\n * - the server tells the client that we’ve reconnected but it doesn’t recognize us anymore (server definitely died) or\n * - we hit a grace period after a connection disconnect\n */\nexport class Session<ConnType extends Connection> {\n private codec: Codec;\n private options: SessionOptions;\n readonly telemetry: TelemetryInfo;\n\n /**\n * The buffer of messages that have been sent but not yet acknowledged.\n */\n private sendBuffer: Array<OpaqueTransportMessage> = [];\n\n /**\n * The active connection associated with this session\n */\n connection?: ConnType;\n /**\n * A connection that is currently undergoing handshaking. Used to distinguish between the active\n * connection, but still be able to close it if needed.\n */\n private handshakingConnection?: ConnType;\n readonly from: TransportClientId;\n readonly to: TransportClientId;\n\n /**\n * The unique ID of this session.\n */\n readonly id: string;\n\n /**\n * What the other side advertised as their session ID\n * for this session.\n */\n advertisedSessionId?: string;\n\n /**\n * Number of messages we've sent along this session (excluding handshake and acks)\n */\n private seq: SequenceNumber = 0;\n\n /**\n * Number of unique messages we've received this session (excluding handshake and acks)\n */\n private ack: SequenceNumber = 0;\n\n /**\n * The grace period between when the inner connection is disconnected\n * and when we should consider the entire session disconnected.\n */\n private disconnectionGrace?: ReturnType<typeof setTimeout>;\n\n /**\n * Number of heartbeats we've sent without a response.\n */\n private heartbeatMisses: number;\n\n /**\n * The interval for sending heartbeats.\n */\n private heartbeat: ReturnType<typeof setInterval>;\n private log?: Logger;\n\n constructor(\n conn: ConnType | undefined,\n from: TransportClientId,\n to: TransportClientId,\n options: SessionOptions,\n propagationCtx?: PropagationContext,\n ) {\n this.id = `session-${nanoid(12)}`;\n this.options = options;\n this.from = from;\n this.to = to;\n this.connection = conn;\n this.codec = options.codec;\n\n // setup heartbeat\n this.heartbeatMisses = 0;\n this.heartbeat = setInterval(\n () => this.sendHeartbeat(),\n options.heartbeatIntervalMs,\n );\n this.telemetry = createSessionTelemetryInfo(this, propagationCtx);\n }\n\n bindLogger(log: Logger) {\n this.log = log;\n }\n\n get loggingMetadata(): MessageMetadata {\n const spanContext = this.telemetry.span.spanContext();\n\n return {\n clientId: this.from,\n connectedTo: this.to,\n sessionId: this.id,\n connId: this.connection?.id,\n telemetry: {\n traceId: spanContext.traceId,\n spanId: spanContext.spanId,\n },\n };\n }\n\n /**\n * Sends a message over the session's connection.\n * If the connection is not ready or the message fails to send, the message can be buffered for retry unless skipped.\n *\n * @param msg The partial message to be sent, which will be constructed into a full message.\n * @param addToSendBuff Whether to add the message to the send buffer for retry.\n * @returns The full transport ID of the message that was attempted to be sent.\n */\n send(msg: PartialTransportMessage): string {\n const fullMsg: TransportMessage = this.constructMsg(msg);\n this.log?.debug(`sending msg`, {\n ...this.loggingMetadata,\n transportMessage: fullMsg,\n });\n\n if (this.connection) {\n const ok = this.connection.send(this.codec.toBuffer(fullMsg));\n if (ok) return fullMsg.id;\n this.log?.info(\n `failed to send msg to ${fullMsg.to}, connection is probably dead`,\n {\n ...this.loggingMetadata,\n transportMessage: fullMsg,\n },\n );\n } else {\n this.log?.debug(\n `buffering msg to ${fullMsg.to}, connection not ready yet`,\n { ...this.loggingMetadata, transportMessage: fullMsg },\n );\n }\n\n return fullMsg.id;\n }\n\n sendHeartbeat() {\n const misses = this.heartbeatMisses;\n const missDuration = misses * this.options.heartbeatIntervalMs;\n if (misses > this.options.heartbeatsUntilDead) {\n if (this.connection) {\n this.log?.info(\n `closing connection to ${this.to} due to inactivity (missed ${misses} heartbeats which is ${missDuration}ms)`,\n this.loggingMetadata,\n );\n this.telemetry.span.addEvent('closing connection due to inactivity');\n this.closeStaleConnection();\n }\n return;\n }\n\n this.send({\n streamId: 'heartbeat',\n controlFlags: ControlFlags.AckBit,\n payload: {\n type: 'ACK',\n } satisfies Static<typeof ControlMessageAckSchema>,\n });\n this.heartbeatMisses++;\n }\n\n resetBufferedMessages() {\n this.sendBuffer = [];\n this.seq = 0;\n this.ack = 0;\n }\n\n sendBufferedMessages(conn: ConnType) {\n this.log?.info(`resending ${this.sendBuffer.length} buffered messages`, {\n ...this.loggingMetadata,\n connId: conn.id,\n });\n for (const msg of this.sendBuffer) {\n this.log?.debug(`resending msg`, {\n ...this.loggingMetadata,\n transportMessage: msg,\n connId: conn.id,\n });\n const ok = conn.send(this.codec.toBuffer(msg));\n if (!ok) {\n // this should never happen unless the transport has an\n // incorrect implementation of `createNewOutgoingConnection`\n const errMsg = `failed to send buffered message to ${this.to} (sus, this is a fresh connection)`;\n conn.telemetry?.span.setStatus({\n code: SpanStatusCode.ERROR,\n message: errMsg,\n });\n\n this.log?.error(errMsg, {\n ...this.loggingMetadata,\n transportMessage: msg,\n connId: conn.id,\n tags: ['invariant-violation'],\n });\n conn.close();\n return;\n }\n }\n }\n\n updateBookkeeping(ack: number, seq: number) {\n if (seq + 1 < this.ack) {\n this.log?.error(`received stale seq ${seq} + 1 < ${this.ack}`, {\n ...this.loggingMetadata,\n tags: ['invariant-violation'],\n });\n return;\n }\n\n this.sendBuffer = this.sendBuffer.filter((unacked) => unacked.seq >= ack);\n this.ack = seq + 1;\n }\n\n private closeStaleConnection(conn?: ConnType) {\n if (this.connection === undefined || this.connection === conn) return;\n this.log?.info(\n `closing old inner connection from session to ${this.to}`,\n this.loggingMetadata,\n );\n this.connection.close();\n this.connection = undefined;\n }\n\n replaceWithNewConnection(newConn: ConnType, isTransparentReconnect: boolean) {\n this.closeStaleConnection(newConn);\n this.cancelGrace();\n if (isTransparentReconnect) {\n // only send the buffered messages if this is considered a transparent reconnect. there are\n // cases where the cient reconnects but with a different session id. for those cases we should\n // not send messages from a previous session.\n\n this.sendBufferedMessages(newConn);\n }\n this.connection = newConn;\n\n // we only call replaceWithNewConnection after\n // having successfully completed a handshake so we clear\n // it here\n this.handshakingConnection = undefined;\n }\n\n replaceWithNewHandshakingConnection(newConn: ConnType) {\n this.handshakingConnection = newConn;\n }\n\n beginGrace(cb: () => void) {\n this.log?.info(\n `starting ${this.options.sessionDisconnectGraceMs}ms grace period until session to ${this.to} is closed`,\n this.loggingMetadata,\n );\n\n // Replace any old timeouts to prevent this from firing twice.\n this.cancelGrace();\n this.disconnectionGrace = setTimeout(() => {\n this.log?.info(\n `grace period for ${this.to} elapsed`,\n this.loggingMetadata,\n );\n cb();\n }, this.options.sessionDisconnectGraceMs);\n }\n\n // called on reconnect of the underlying session\n cancelGrace() {\n this.heartbeatMisses = 0;\n clearTimeout(this.disconnectionGrace);\n this.disconnectionGrace = undefined;\n }\n\n /**\n * Used to close the handshaking connection, if set.\n */\n closeHandshakingConnection(expectedHandshakingConn?: ConnType) {\n if (this.handshakingConnection === undefined) return;\n if (\n expectedHandshakingConn !== undefined &&\n this.handshakingConnection === expectedHandshakingConn\n ) {\n // If the handshaking connection is the expected one, don't close it.\n return;\n }\n this.handshakingConnection.close();\n this.handshakingConnection = undefined;\n }\n\n // closed when we want to discard the whole session\n // (i.e. shutdown or session disconnect)\n close() {\n this.closeStaleConnection();\n this.cancelGrace();\n this.resetBufferedMessages();\n clearInterval(this.heartbeat);\n }\n\n get connected() {\n return this.connection !== undefined;\n }\n\n get nextExpectedAck() {\n return this.seq;\n }\n\n get nextExpectedSeq() {\n return this.ack;\n }\n\n // This is only used in tests to make the session misbehave.\n /* @internal */ advanceAckForTesting(by: number) {\n this.ack += by;\n }\n\n constructMsg<Payload>(\n partialMsg: PartialTransportMessage<Payload>,\n ): TransportMessage<Payload> {\n const msg = {\n ...partialMsg,\n id: unsafeId(),\n to: this.to,\n from: this.from,\n seq: this.seq,\n ack: this.ack,\n };\n\n this.seq++;\n this.sendBuffer.push(msg);\n return msg;\n }\n\n inspectSendBuffer(): ReadonlyArray<OpaqueTransportMessage> {\n return this.sendBuffer;\n }\n}\n","import { NaiveJsonCodec } from '../codec/json';\nimport { ConnectionRetryOptions } from './rateLimit';\nimport { SessionOptions } from './session';\n\nexport type TransportOptions = SessionOptions;\n\nexport type ProvidedTransportOptions = Partial<TransportOptions>;\n\nexport const defaultTransportOptions: TransportOptions = {\n heartbeatIntervalMs: 1_000,\n heartbeatsUntilDead: 2,\n sessionDisconnectGraceMs: 5_000,\n codec: NaiveJsonCodec,\n};\n\nexport type ClientTransportOptions = TransportOptions & ConnectionRetryOptions;\n\nexport type ProvidedClientTransportOptions = Partial<ClientTransportOptions>;\n\nconst defaultConnectionRetryOptions: ConnectionRetryOptions = {\n baseIntervalMs: 250,\n maxJitterMs: 200,\n maxBackoffMs: 32_000,\n attemptBudgetCapacity: 5,\n budgetRestoreIntervalMs: 200,\n};\n\nexport const defaultClientTransportOptions: ClientTransportOptions = {\n ...defaultTransportOptions,\n ...defaultConnectionRetryOptions,\n};\n\nexport type ServerTransportOptions = TransportOptions;\n\nexport type ProvidedServerTransportOptions = Partial<ServerTransportOptions>;\n\nexport const defaultServerTransportOptions: ServerTransportOptions = {\n ...defaultTransportOptions,\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../transport/session.ts","../transport/options.ts"],"sourcesContent":["import { customAlphabet } from 'nanoid';\nimport {\n ControlFlags,\n ControlMessageAckSchema,\n OpaqueTransportMessage,\n PartialTransportMessage,\n TransportClientId,\n TransportMessage,\n} from './message';\nimport { Codec } from '../codec';\nimport { Logger, MessageMetadata } from '../logging/log';\nimport { Static } from '@sinclair/typebox';\nimport {\n PropagationContext,\n TelemetryInfo,\n createSessionTelemetryInfo,\n} from '../tracing';\nimport { SpanStatusCode } from '@opentelemetry/api';\n\nconst nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvxyz', 6);\nexport const unsafeId = () => nanoid();\n\ntype SequenceNumber = number;\n\n/**\n * A connection is the actual raw underlying transport connection.\n * It’s responsible for dispatching to/from the actual connection itself\n * This should be instantiated as soon as the client/server has a connection\n * It’s tied to the lifecycle of the underlying transport connection (i.e. if the WS drops, this connection should be deleted)\n */\nexport abstract class Connection {\n id: string;\n telemetry?: TelemetryInfo;\n constructor() {\n this.id = `conn-${nanoid(12)}`; // for debugging, no collision safety needed\n }\n\n get loggingMetadata(): MessageMetadata {\n const metadata: MessageMetadata = { connId: this.id };\n const spanContext = this.telemetry?.span.spanContext();\n\n if (this.telemetry?.span.isRecording() && spanContext) {\n metadata.telemetry = {\n traceId: spanContext.traceId,\n spanId: spanContext.spanId,\n };\n }\n\n return metadata;\n }\n\n /**\n * Handle adding a callback for when a message is received.\n * @param msg The message that was received.\n */\n abstract addDataListener(cb: (msg: Uint8Array) => void): void;\n abstract removeDataListener(cb: (msg: Uint8Array) => void): void;\n\n /**\n * Handle adding a callback for when the connection is closed.\n * This should also be called if an error happens.\n * @param cb The callback to call when the connection is closed.\n */\n abstract addCloseListener(cb: () => void): void;\n\n /**\n * Handle adding a callback for when an error is received.\n * This should only be used for this.logging errors, all cleanup\n * should be delegated to addCloseListener.\n *\n * The implementer should take care such that the implemented\n * connection will call both the close and error callbacks\n * on an error.\n *\n * @param cb The callback to call when an error is received.\n */\n abstract addErrorListener(cb: (err: Error) => void): void;\n\n /**\n * Sends a message over the connection.\n * @param msg The message to send.\n * @returns true if the message was sent, false otherwise.\n */\n abstract send(msg: Uint8Array): boolean;\n\n /**\n * Closes the connection.\n */\n abstract close(): void;\n}\n\nexport interface SessionOptions {\n /**\n * Frequency at which to send heartbeat acknowledgements\n */\n heartbeatIntervalMs: number;\n /**\n * Number of elapsed heartbeats without a response message before we consider\n * the connection dead.\n */\n heartbeatsUntilDead: number;\n /**\n * Duration to wait between connection disconnect and actual session disconnect\n */\n sessionDisconnectGraceMs: number;\n /**\n * The codec to use for encoding/decoding messages over the wire\n */\n codec: Codec;\n}\n\n/**\n * A session is a higher-level abstraction that operates over the span of potentially multiple transport-level connections\n * - It’s responsible for tracking any metadata for a particular client that might need to be persisted across connections (i.e. the sendBuffer, ack, seq)\n * - This will only be considered disconnected if\n * - the server tells the client that we’ve reconnected but it doesn’t recognize us anymore (server definitely died) or\n * - we hit a grace period after a connection disconnect\n */\nexport class Session<ConnType extends Connection> {\n private codec: Codec;\n private options: SessionOptions;\n readonly telemetry: TelemetryInfo;\n\n /**\n * The buffer of messages that have been sent but not yet acknowledged.\n */\n private sendBuffer: Array<OpaqueTransportMessage> = [];\n\n /**\n * The active connection associated with this session\n */\n connection?: ConnType;\n /**\n * A connection that is currently undergoing handshaking. Used to distinguish between the active\n * connection, but still be able to close it if needed.\n */\n private handshakingConnection?: ConnType;\n readonly from: TransportClientId;\n readonly to: TransportClientId;\n\n /**\n * The unique ID of this session.\n */\n readonly id: string;\n\n /**\n * What the other side advertised as their session ID\n * for this session.\n */\n advertisedSessionId?: string;\n\n /**\n * Number of messages we've sent along this session (excluding handshake and acks)\n */\n private seq: SequenceNumber = 0;\n\n /**\n * Number of unique messages we've received this session (excluding handshake and acks)\n */\n private ack: SequenceNumber = 0;\n\n /**\n * The grace period between when the inner connection is disconnected\n * and when we should consider the entire session disconnected.\n */\n private disconnectionGrace?: ReturnType<typeof setTimeout>;\n\n /**\n * Number of heartbeats we've sent without a response.\n */\n private heartbeatMisses: number;\n\n /**\n * The interval for sending heartbeats.\n */\n private heartbeat: ReturnType<typeof setInterval>;\n private log?: Logger;\n\n constructor(\n conn: ConnType | undefined,\n from: TransportClientId,\n to: TransportClientId,\n options: SessionOptions,\n propagationCtx?: PropagationContext,\n ) {\n this.id = `session-${nanoid(12)}`;\n this.options = options;\n this.from = from;\n this.to = to;\n this.connection = conn;\n this.codec = options.codec;\n\n // setup heartbeat\n this.heartbeatMisses = 0;\n this.heartbeat = setInterval(\n () => this.sendHeartbeat(),\n options.heartbeatIntervalMs,\n );\n this.telemetry = createSessionTelemetryInfo(this, propagationCtx);\n }\n\n bindLogger(log: Logger) {\n this.log = log;\n }\n\n get loggingMetadata(): MessageMetadata {\n const spanContext = this.telemetry.span.spanContext();\n\n return {\n clientId: this.from,\n connectedTo: this.to,\n sessionId: this.id,\n connId: this.connection?.id,\n telemetry: {\n traceId: spanContext.traceId,\n spanId: spanContext.spanId,\n },\n };\n }\n\n /**\n * Sends a message over the session's connection.\n * If the connection is not ready or the message fails to send, the message can be buffered for retry unless skipped.\n *\n * @param msg The partial message to be sent, which will be constructed into a full message.\n * @param addToSendBuff Whether to add the message to the send buffer for retry.\n * @returns The full transport ID of the message that was attempted to be sent.\n */\n send(msg: PartialTransportMessage): string {\n const fullMsg: TransportMessage = this.constructMsg(msg);\n this.log?.debug(`sending msg`, {\n ...this.loggingMetadata,\n transportMessage: fullMsg,\n });\n\n if (this.connection) {\n const ok = this.connection.send(this.codec.toBuffer(fullMsg));\n if (ok) return fullMsg.id;\n this.log?.info(\n `failed to send msg to ${fullMsg.to}, connection is probably dead`,\n {\n ...this.loggingMetadata,\n transportMessage: fullMsg,\n },\n );\n } else {\n this.log?.debug(\n `buffering msg to ${fullMsg.to}, connection not ready yet`,\n { ...this.loggingMetadata, transportMessage: fullMsg },\n );\n }\n\n return fullMsg.id;\n }\n\n sendHeartbeat() {\n const misses = this.heartbeatMisses;\n const missDuration = misses * this.options.heartbeatIntervalMs;\n if (misses > this.options.heartbeatsUntilDead) {\n if (this.connection) {\n this.log?.info(\n `closing connection to ${this.to} due to inactivity (missed ${misses} heartbeats which is ${missDuration}ms)`,\n this.loggingMetadata,\n );\n this.telemetry.span.addEvent('closing connection due to inactivity');\n this.closeStaleConnection();\n }\n return;\n }\n\n this.send({\n streamId: 'heartbeat',\n controlFlags: ControlFlags.AckBit,\n payload: {\n type: 'ACK',\n } satisfies Static<typeof ControlMessageAckSchema>,\n });\n this.heartbeatMisses++;\n }\n\n resetBufferedMessages() {\n this.sendBuffer = [];\n this.seq = 0;\n this.ack = 0;\n }\n\n sendBufferedMessages(conn: ConnType) {\n this.log?.info(`resending ${this.sendBuffer.length} buffered messages`, {\n ...this.loggingMetadata,\n connId: conn.id,\n });\n for (const msg of this.sendBuffer) {\n this.log?.debug(`resending msg`, {\n ...this.loggingMetadata,\n transportMessage: msg,\n connId: conn.id,\n });\n const ok = conn.send(this.codec.toBuffer(msg));\n if (!ok) {\n // this should never happen unless the transport has an\n // incorrect implementation of `createNewOutgoingConnection`\n const errMsg = `failed to send buffered message to ${this.to} (sus, this is a fresh connection)`;\n conn.telemetry?.span.setStatus({\n code: SpanStatusCode.ERROR,\n message: errMsg,\n });\n\n this.log?.error(errMsg, {\n ...this.loggingMetadata,\n transportMessage: msg,\n connId: conn.id,\n tags: ['invariant-violation'],\n });\n conn.close();\n return;\n }\n }\n }\n\n updateBookkeeping(ack: number, seq: number) {\n if (seq + 1 < this.ack) {\n this.log?.error(`received stale seq ${seq} + 1 < ${this.ack}`, {\n ...this.loggingMetadata,\n tags: ['invariant-violation'],\n });\n return;\n }\n\n this.sendBuffer = this.sendBuffer.filter((unacked) => unacked.seq >= ack);\n this.ack = seq + 1;\n }\n\n private closeStaleConnection(conn?: ConnType) {\n if (this.connection === undefined || this.connection === conn) return;\n this.log?.info(\n `closing old inner connection from session to ${this.to}`,\n this.loggingMetadata,\n );\n this.connection.close();\n this.connection = undefined;\n }\n\n replaceWithNewConnection(newConn: ConnType, isTransparentReconnect: boolean) {\n this.closeStaleConnection(newConn);\n this.cancelGrace();\n if (isTransparentReconnect) {\n // only send the buffered messages if this is considered a transparent reconnect. there are\n // cases where the cient reconnects but with a different session id. for those cases we should\n // not send messages from a previous session.\n\n this.sendBufferedMessages(newConn);\n }\n this.connection = newConn;\n\n // we only call replaceWithNewConnection after\n // having successfully completed a handshake so we clear\n // it here\n this.handshakingConnection = undefined;\n }\n\n replaceWithNewHandshakingConnection(newConn: ConnType) {\n this.handshakingConnection = newConn;\n }\n\n beginGrace(cb: () => void) {\n this.log?.info(\n `starting ${this.options.sessionDisconnectGraceMs}ms grace period until session to ${this.to} is closed`,\n this.loggingMetadata,\n );\n\n // Replace any old timeouts to prevent this from firing twice.\n this.cancelGrace();\n this.disconnectionGrace = setTimeout(() => {\n this.log?.info(\n `grace period for ${this.to} elapsed`,\n this.loggingMetadata,\n );\n cb();\n }, this.options.sessionDisconnectGraceMs);\n }\n\n // called on reconnect of the underlying session\n cancelGrace() {\n this.heartbeatMisses = 0;\n clearTimeout(this.disconnectionGrace);\n this.disconnectionGrace = undefined;\n }\n\n /**\n * Used to close the handshaking connection, if set.\n */\n closeHandshakingConnection(expectedHandshakingConn?: ConnType) {\n if (this.handshakingConnection === undefined) return;\n if (\n expectedHandshakingConn !== undefined &&\n this.handshakingConnection === expectedHandshakingConn\n ) {\n // If the handshaking connection is the expected one, don't close it.\n return;\n }\n this.handshakingConnection.close();\n this.handshakingConnection = undefined;\n }\n\n // closed when we want to discard the whole session\n // (i.e. shutdown or session disconnect)\n close() {\n this.closeStaleConnection();\n this.cancelGrace();\n this.resetBufferedMessages();\n clearInterval(this.heartbeat);\n }\n\n get connected() {\n return this.connection !== undefined;\n }\n\n get nextExpectedAck() {\n return this.seq;\n }\n\n get nextExpectedSeq() {\n return this.ack;\n }\n\n /**\n * Check that the peer's next expected seq number matches something that is in our send buffer\n * _or_ matches our actual next seq.\n */\n nextExpectedSeqInRange(nextExpectedSeq: number) {\n for (const msg of this.sendBuffer) {\n if (nextExpectedSeq === msg.seq) {\n return true;\n }\n }\n return nextExpectedSeq === this.seq;\n }\n\n // This is only used in tests to make the session misbehave.\n /* @internal */ advanceAckForTesting(by: number) {\n this.ack += by;\n }\n\n constructMsg<Payload>(\n partialMsg: PartialTransportMessage<Payload>,\n ): TransportMessage<Payload> {\n const msg = {\n ...partialMsg,\n id: unsafeId(),\n to: this.to,\n from: this.from,\n seq: this.seq,\n ack: this.ack,\n };\n\n this.seq++;\n this.sendBuffer.push(msg);\n return msg;\n }\n\n inspectSendBuffer(): ReadonlyArray<OpaqueTransportMessage> {\n return this.sendBuffer;\n }\n}\n","import { NaiveJsonCodec } from '../codec/json';\nimport { ConnectionRetryOptions } from './rateLimit';\nimport { SessionOptions } from './session';\n\nexport type TransportOptions = SessionOptions;\n\nexport type ProvidedTransportOptions = Partial<TransportOptions>;\n\nexport const defaultTransportOptions: TransportOptions = {\n heartbeatIntervalMs: 1_000,\n heartbeatsUntilDead: 2,\n sessionDisconnectGraceMs: 5_000,\n codec: NaiveJsonCodec,\n};\n\nexport type ClientTransportOptions = TransportOptions & ConnectionRetryOptions;\n\nexport type ProvidedClientTransportOptions = Partial<ClientTransportOptions>;\n\nconst defaultConnectionRetryOptions: ConnectionRetryOptions = {\n baseIntervalMs: 250,\n maxJitterMs: 200,\n maxBackoffMs: 32_000,\n attemptBudgetCapacity: 5,\n budgetRestoreIntervalMs: 200,\n};\n\nexport const defaultClientTransportOptions: ClientTransportOptions = {\n ...defaultTransportOptions,\n ...defaultConnectionRetryOptions,\n};\n\nexport type ServerTransportOptions = TransportOptions;\n\nexport type ProvidedServerTransportOptions = Partial<ServerTransportOptions>;\n\nexport const defaultServerTransportOptions: ServerTransportOptions = {\n ...defaultTransportOptions,\n};\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Connection
3
- } from "./chunk-5HK7ZQYH.js";
3
+ } from "./chunk-3FALN7ZG.js";
4
4
 
5
5
  // transport/impls/ws/connection.ts
6
6
  var WebSocketConnection = class extends Connection {
@@ -56,4 +56,4 @@ var WebSocketConnection = class extends Connection {
56
56
  export {
57
57
  WebSocketConnection
58
58
  };
59
- //# sourceMappingURL=chunk-RQQZUQGE.js.map
59
+ //# sourceMappingURL=chunk-6GK2IIDP.js.map
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  ProtocolError,
3
3
  Transport
4
- } from "./chunk-MD4S7GO2.js";
4
+ } from "./chunk-YUY37VAK.js";
5
5
  import {
6
6
  defaultServerTransportOptions
7
- } from "./chunk-5HK7ZQYH.js";
7
+ } from "./chunk-3FALN7ZG.js";
8
8
  import {
9
9
  ControlMessageHandshakeRequestSchema,
10
10
  PROTOCOL_VERSION,
11
11
  SESSION_STATE_MISMATCH,
12
12
  coerceErrorString,
13
13
  handshakeResponseMessage
14
- } from "./chunk-OXVWMLID.js";
14
+ } from "./chunk-LK74ZG7M.js";
15
15
 
16
16
  // transport/server.ts
17
17
  import { SpanStatusCode } from "@opentelemetry/api";
@@ -332,4 +332,4 @@ var ServerTransport = class extends Transport {
332
332
  export {
333
333
  ServerTransport
334
334
  };
335
- //# sourceMappingURL=chunk-JMVKSGND.js.map
335
+ //# sourceMappingURL=chunk-6RKO3DDG.js.map