@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
@@ -1,377 +0,0 @@
1
- import {
2
- ProtocolError,
3
- ServerSessionStateGraph,
4
- Transport,
5
- defaultServerTransportOptions
6
- } from "./chunk-24EWYOGK.js";
7
- import {
8
- ControlMessageHandshakeRequestSchema,
9
- HandshakeErrorCustomHandlerFatalResponseCodes,
10
- acceptedProtocolVersions,
11
- coerceErrorString,
12
- currentProtocolVersion,
13
- handshakeResponseMessage,
14
- isAcceptedProtocolVersion
15
- } from "./chunk-46IVOKJU.js";
16
-
17
- // transport/server.ts
18
- import { SpanStatusCode } from "@opentelemetry/api";
19
- import { Value } from "@sinclair/typebox/value";
20
- var ServerTransport = class extends Transport {
21
- /**
22
- * The options for this transport.
23
- */
24
- options;
25
- /**
26
- * Optional handshake options for the server.
27
- */
28
- handshakeExtensions;
29
- /**
30
- * A map of session handshake data for each session.
31
- */
32
- sessionHandshakeMetadata = /* @__PURE__ */ new Map();
33
- sessions = /* @__PURE__ */ new Map();
34
- pendingSessions = /* @__PURE__ */ new Set();
35
- constructor(clientId, providedOptions) {
36
- super(clientId, providedOptions);
37
- this.sessions = /* @__PURE__ */ new Map();
38
- this.options = {
39
- ...defaultServerTransportOptions,
40
- ...providedOptions
41
- };
42
- this.log?.info(`initiated server transport`, {
43
- clientId: this.clientId,
44
- protocolVersion: currentProtocolVersion
45
- });
46
- }
47
- extendHandshake(options) {
48
- this.handshakeExtensions = options;
49
- }
50
- deletePendingSession(pendingSession) {
51
- pendingSession.close();
52
- this.pendingSessions.delete(pendingSession);
53
- }
54
- deleteSession(session, options) {
55
- this.sessionHandshakeMetadata.delete(session.to);
56
- super.deleteSession(session, options);
57
- }
58
- handleConnection(conn) {
59
- if (this.getStatus() !== "open")
60
- return;
61
- this.log?.info(`new incoming connection`, {
62
- ...conn.loggingMetadata,
63
- clientId: this.clientId
64
- });
65
- let receivedHandshake = false;
66
- const pendingSession = ServerSessionStateGraph.entrypoint(
67
- this.clientId,
68
- conn,
69
- {
70
- onConnectionClosed: () => {
71
- this.log?.warn(
72
- `connection from unknown closed before handshake finished`,
73
- pendingSession.loggingMetadata
74
- );
75
- this.deletePendingSession(pendingSession);
76
- },
77
- onConnectionErrored: (err) => {
78
- const errorString = coerceErrorString(err);
79
- this.log?.warn(
80
- `connection from unknown errored before handshake finished: ${errorString}`,
81
- pendingSession.loggingMetadata
82
- );
83
- this.deletePendingSession(pendingSession);
84
- },
85
- onHandshakeTimeout: () => {
86
- this.log?.warn(
87
- `connection from unknown timed out before handshake finished`,
88
- pendingSession.loggingMetadata
89
- );
90
- this.deletePendingSession(pendingSession);
91
- },
92
- onHandshake: (msg) => {
93
- if (receivedHandshake) {
94
- this.log?.error(
95
- `received multiple handshake messages from pending session`,
96
- {
97
- ...pendingSession.loggingMetadata,
98
- connectedTo: msg.from,
99
- transportMessage: msg
100
- }
101
- );
102
- this.deletePendingSession(pendingSession);
103
- return;
104
- }
105
- receivedHandshake = true;
106
- void this.onHandshakeRequest(pendingSession, msg);
107
- },
108
- onInvalidHandshake: (reason, code) => {
109
- this.log?.error(
110
- `invalid handshake: ${reason}`,
111
- pendingSession.loggingMetadata
112
- );
113
- this.deletePendingSession(pendingSession);
114
- this.protocolError({
115
- type: ProtocolError.HandshakeFailed,
116
- code,
117
- message: reason
118
- });
119
- }
120
- },
121
- this.options,
122
- this.tracer,
123
- this.log
124
- );
125
- this.pendingSessions.add(pendingSession);
126
- }
127
- rejectHandshakeRequest(session, to, reason, code, metadata) {
128
- session.conn.telemetry?.span.setStatus({
129
- code: SpanStatusCode.ERROR,
130
- message: reason
131
- });
132
- this.log?.warn(reason, metadata);
133
- session.sendHandshake(
134
- handshakeResponseMessage({
135
- from: this.clientId,
136
- to,
137
- status: {
138
- ok: false,
139
- code,
140
- reason
141
- }
142
- })
143
- );
144
- this.protocolError({
145
- type: ProtocolError.HandshakeFailed,
146
- code,
147
- message: reason
148
- });
149
- this.deletePendingSession(session);
150
- }
151
- async onHandshakeRequest(session, msg) {
152
- if (!Value.Check(ControlMessageHandshakeRequestSchema, msg.payload)) {
153
- this.rejectHandshakeRequest(
154
- session,
155
- msg.from,
156
- "received invalid handshake request",
157
- "MALFORMED_HANDSHAKE",
158
- {
159
- ...session.loggingMetadata,
160
- transportMessage: msg,
161
- connectedTo: msg.from,
162
- validationErrors: [
163
- ...Value.Errors(ControlMessageHandshakeRequestSchema, msg.payload)
164
- ]
165
- }
166
- );
167
- return;
168
- }
169
- const gotVersion = msg.payload.protocolVersion;
170
- if (!isAcceptedProtocolVersion(gotVersion)) {
171
- this.rejectHandshakeRequest(
172
- session,
173
- msg.from,
174
- `expected protocol version oneof [${acceptedProtocolVersions.toString()}], got ${gotVersion}`,
175
- "PROTOCOL_VERSION_MISMATCH",
176
- {
177
- ...session.loggingMetadata,
178
- connectedTo: msg.from,
179
- transportMessage: msg
180
- }
181
- );
182
- return;
183
- }
184
- let parsedMetadata = {};
185
- if (this.handshakeExtensions) {
186
- if (!Value.Check(this.handshakeExtensions.schema, msg.payload.metadata)) {
187
- this.rejectHandshakeRequest(
188
- session,
189
- msg.from,
190
- "received malformed handshake metadata",
191
- "MALFORMED_HANDSHAKE_META",
192
- {
193
- ...session.loggingMetadata,
194
- connectedTo: msg.from,
195
- validationErrors: [
196
- ...Value.Errors(
197
- this.handshakeExtensions.schema,
198
- msg.payload.metadata
199
- )
200
- ]
201
- }
202
- );
203
- return;
204
- }
205
- const previousParsedMetadata = this.sessionHandshakeMetadata.get(
206
- msg.from
207
- );
208
- const parsedMetadataOrFailureCode = await this.handshakeExtensions.validate(
209
- msg.payload.metadata,
210
- previousParsedMetadata
211
- );
212
- if (session._isConsumed) {
213
- return;
214
- }
215
- if (Value.Check(
216
- HandshakeErrorCustomHandlerFatalResponseCodes,
217
- parsedMetadataOrFailureCode
218
- )) {
219
- this.rejectHandshakeRequest(
220
- session,
221
- msg.from,
222
- "rejected by handshake handler",
223
- parsedMetadataOrFailureCode,
224
- {
225
- ...session.loggingMetadata,
226
- connectedTo: msg.from,
227
- clientId: this.clientId
228
- }
229
- );
230
- return;
231
- }
232
- parsedMetadata = parsedMetadataOrFailureCode;
233
- }
234
- let connectCase = "new session";
235
- const clientNextExpectedSeq = msg.payload.expectedSessionState.nextExpectedSeq;
236
- const clientNextSentSeq = msg.payload.expectedSessionState.nextSentSeq;
237
- let oldSession = this.sessions.get(msg.from);
238
- if (this.options.enableTransparentSessionReconnects && oldSession && oldSession.id === msg.payload.sessionId) {
239
- connectCase = "transparent reconnection";
240
- const ourNextSeq = oldSession.nextSeq();
241
- const ourAck = oldSession.ack;
242
- if (clientNextSentSeq > ourAck) {
243
- this.rejectHandshakeRequest(
244
- session,
245
- msg.from,
246
- `client is in the future: server wanted next message to be ${ourAck} but client would have sent ${clientNextSentSeq}`,
247
- "SESSION_STATE_MISMATCH",
248
- {
249
- ...session.loggingMetadata,
250
- connectedTo: msg.from,
251
- transportMessage: msg
252
- }
253
- );
254
- return;
255
- }
256
- if (ourNextSeq > clientNextExpectedSeq) {
257
- this.rejectHandshakeRequest(
258
- session,
259
- msg.from,
260
- `server is in the future: client wanted next message to be ${clientNextExpectedSeq} but server would have sent ${ourNextSeq}`,
261
- "SESSION_STATE_MISMATCH",
262
- {
263
- ...session.loggingMetadata,
264
- connectedTo: msg.from,
265
- transportMessage: msg
266
- }
267
- );
268
- return;
269
- }
270
- if (oldSession.state !== "NoConnection" /* NoConnection */) {
271
- const noConnectionSession = ServerSessionStateGraph.transition.ConnectedToNoConnection(
272
- oldSession,
273
- {
274
- onSessionGracePeriodElapsed: () => {
275
- this.onSessionGracePeriodElapsed(noConnectionSession);
276
- }
277
- }
278
- );
279
- oldSession = noConnectionSession;
280
- this.updateSession(oldSession);
281
- }
282
- } else if (oldSession) {
283
- connectCase = "hard reconnection";
284
- this.log?.info(
285
- `client is reconnecting to a new session (${msg.payload.sessionId}) with an old session (${oldSession.id}) already existing, closing old session`,
286
- {
287
- ...session.loggingMetadata,
288
- connectedTo: msg.from,
289
- sessionId: msg.payload.sessionId
290
- }
291
- );
292
- this.deleteSession(oldSession);
293
- oldSession = void 0;
294
- }
295
- if (!oldSession && (clientNextSentSeq > 0 || clientNextExpectedSeq > 0)) {
296
- connectCase = "unknown session";
297
- const rejectionMessage = this.options.enableTransparentSessionReconnects ? `client is trying to reconnect to a session the server don't know about: ${msg.payload.sessionId}` : `client is attempting a transparent reconnect to a session but the server does not support it: ${msg.payload.sessionId}`;
298
- this.rejectHandshakeRequest(
299
- session,
300
- msg.from,
301
- rejectionMessage,
302
- "SESSION_STATE_MISMATCH",
303
- {
304
- ...session.loggingMetadata,
305
- connectedTo: msg.from,
306
- transportMessage: msg
307
- }
308
- );
309
- return;
310
- }
311
- const sessionId = msg.payload.sessionId;
312
- this.log?.info(
313
- `handshake from ${msg.from} ok (${connectCase}), responding with handshake success`,
314
- {
315
- ...session.loggingMetadata,
316
- connectedTo: msg.from
317
- }
318
- );
319
- const responseMsg = handshakeResponseMessage({
320
- from: this.clientId,
321
- to: msg.from,
322
- status: {
323
- ok: true,
324
- sessionId
325
- }
326
- });
327
- session.sendHandshake(responseMsg);
328
- const connectedSession = ServerSessionStateGraph.transition.WaitingForHandshakeToConnected(
329
- session,
330
- // by this point oldSession is either no connection or we dont have an old session
331
- oldSession,
332
- sessionId,
333
- msg.from,
334
- msg.tracing,
335
- {
336
- onConnectionErrored: (err) => {
337
- const errStr = coerceErrorString(err);
338
- this.log?.warn(
339
- `connection to ${connectedSession.to} errored: ${errStr}`,
340
- connectedSession.loggingMetadata
341
- );
342
- },
343
- onConnectionClosed: () => {
344
- this.log?.info(
345
- `connection to ${connectedSession.to} closed`,
346
- connectedSession.loggingMetadata
347
- );
348
- this.onConnClosed(connectedSession);
349
- },
350
- onMessage: (msg2) => {
351
- this.handleMsg(msg2);
352
- },
353
- onInvalidMessage: (reason) => {
354
- this.protocolError({
355
- type: ProtocolError.InvalidMessage,
356
- message: reason
357
- });
358
- this.deleteSession(connectedSession, { unhealthy: true });
359
- }
360
- },
361
- gotVersion
362
- );
363
- this.sessionHandshakeMetadata.set(connectedSession.to, parsedMetadata);
364
- if (oldSession) {
365
- this.updateSession(connectedSession);
366
- } else {
367
- this.createSession(connectedSession);
368
- }
369
- this.pendingSessions.delete(session);
370
- connectedSession.startActiveHeartbeat();
371
- }
372
- };
373
-
374
- export {
375
- ServerTransport
376
- };
377
- //# sourceMappingURL=chunk-XV4RQ62N.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../transport/server.ts"],"sourcesContent":["import { SpanStatusCode } from '@opentelemetry/api';\nimport { ParsedMetadata } from '../router/context';\nimport { ServerHandshakeOptions } from '../router/handshake';\nimport {\n ControlMessageHandshakeRequestSchema,\n HandshakeErrorCustomHandlerFatalResponseCodes,\n HandshakeErrorResponseCodes,\n OpaqueTransportMessage,\n acceptedProtocolVersions,\n TransportClientId,\n handshakeResponseMessage,\n currentProtocolVersion,\n isAcceptedProtocolVersion,\n} from './message';\nimport {\n ProvidedServerTransportOptions,\n ServerTransportOptions,\n defaultServerTransportOptions,\n} from './options';\nimport { DeleteSessionOptions, Transport } from './transport';\nimport { coerceErrorString } from './stringifyError';\nimport { Static } from '@sinclair/typebox';\nimport { Value } from '@sinclair/typebox/value';\nimport { ProtocolError } from './events';\nimport { Connection } from './connection';\nimport { MessageMetadata } from '../logging';\nimport { SessionWaitingForHandshake } from './sessionStateMachine/SessionWaitingForHandshake';\nimport { SessionState } from './sessionStateMachine/common';\nimport {\n ServerSession,\n ServerSessionStateGraph,\n} from './sessionStateMachine/transitions';\n\nexport abstract class ServerTransport<\n ConnType extends Connection,\n> extends Transport<ConnType> {\n /**\n * The options for this transport.\n */\n protected options: ServerTransportOptions;\n\n /**\n * Optional handshake options for the server.\n */\n handshakeExtensions?: ServerHandshakeOptions;\n\n /**\n * A map of session handshake data for each session.\n */\n sessionHandshakeMetadata = new Map<TransportClientId, ParsedMetadata>();\n\n sessions = new Map<TransportClientId, ServerSession<ConnType>>();\n pendingSessions = new Set<SessionWaitingForHandshake<ConnType>>();\n\n constructor(\n clientId: TransportClientId,\n providedOptions?: ProvidedServerTransportOptions,\n ) {\n super(clientId, providedOptions);\n this.sessions = new Map();\n this.options = {\n ...defaultServerTransportOptions,\n ...providedOptions,\n };\n this.log?.info(`initiated server transport`, {\n clientId: this.clientId,\n protocolVersion: currentProtocolVersion,\n });\n }\n\n extendHandshake(options: ServerHandshakeOptions) {\n this.handshakeExtensions = options;\n }\n\n protected deletePendingSession(\n pendingSession: SessionWaitingForHandshake<ConnType>,\n ) {\n pendingSession.close();\n // we don't dispatch a session disconnect event\n // for a non-identified session, just delete directly\n\n this.pendingSessions.delete(pendingSession);\n }\n\n protected deleteSession(\n session: ServerSession<ConnType>,\n options?: DeleteSessionOptions,\n ): void {\n this.sessionHandshakeMetadata.delete(session.to);\n super.deleteSession(session, options);\n }\n\n protected handleConnection(conn: ConnType) {\n if (this.getStatus() !== 'open') return;\n\n this.log?.info(`new incoming connection`, {\n ...conn.loggingMetadata,\n clientId: this.clientId,\n });\n\n let receivedHandshake = false;\n const pendingSession = ServerSessionStateGraph.entrypoint(\n this.clientId,\n conn,\n {\n onConnectionClosed: () => {\n this.log?.warn(\n `connection from unknown closed before handshake finished`,\n pendingSession.loggingMetadata,\n );\n\n this.deletePendingSession(pendingSession);\n },\n onConnectionErrored: (err) => {\n const errorString = coerceErrorString(err);\n this.log?.warn(\n `connection from unknown errored before handshake finished: ${errorString}`,\n pendingSession.loggingMetadata,\n );\n\n this.deletePendingSession(pendingSession);\n },\n onHandshakeTimeout: () => {\n this.log?.warn(\n `connection from unknown timed out before handshake finished`,\n pendingSession.loggingMetadata,\n );\n\n this.deletePendingSession(pendingSession);\n },\n onHandshake: (msg) => {\n if (receivedHandshake) {\n this.log?.error(\n `received multiple handshake messages from pending session`,\n {\n ...pendingSession.loggingMetadata,\n connectedTo: msg.from,\n transportMessage: msg,\n },\n );\n\n this.deletePendingSession(pendingSession);\n\n return;\n }\n\n // let this resolve async, we just need to make sure its only\n // called once so we don't race while transitioning to connected\n // onHandshakeRequest is async as custom validation may be async\n receivedHandshake = true;\n void this.onHandshakeRequest(pendingSession, msg);\n },\n onInvalidHandshake: (reason, code) => {\n this.log?.error(\n `invalid handshake: ${reason}`,\n pendingSession.loggingMetadata,\n );\n this.deletePendingSession(pendingSession);\n this.protocolError({\n type: ProtocolError.HandshakeFailed,\n code,\n message: reason,\n });\n },\n },\n this.options,\n this.tracer,\n this.log,\n );\n\n this.pendingSessions.add(pendingSession);\n }\n\n private rejectHandshakeRequest(\n session: SessionWaitingForHandshake<ConnType>,\n to: TransportClientId,\n reason: string,\n code: Static<typeof HandshakeErrorResponseCodes>,\n metadata: MessageMetadata,\n ) {\n session.conn.telemetry?.span.setStatus({\n code: SpanStatusCode.ERROR,\n message: reason,\n });\n\n this.log?.warn(reason, metadata);\n\n session.sendHandshake(\n handshakeResponseMessage({\n from: this.clientId,\n to,\n status: {\n ok: false,\n code,\n reason,\n },\n }),\n );\n\n this.protocolError({\n type: ProtocolError.HandshakeFailed,\n code,\n message: reason,\n });\n this.deletePendingSession(session);\n }\n\n protected async onHandshakeRequest(\n session: SessionWaitingForHandshake<ConnType>,\n msg: OpaqueTransportMessage,\n ) {\n // invariant: msg is a handshake request\n if (!Value.Check(ControlMessageHandshakeRequestSchema, msg.payload)) {\n this.rejectHandshakeRequest(\n session,\n msg.from,\n 'received invalid handshake request',\n 'MALFORMED_HANDSHAKE',\n {\n ...session.loggingMetadata,\n transportMessage: msg,\n connectedTo: msg.from,\n validationErrors: [\n ...Value.Errors(ControlMessageHandshakeRequestSchema, msg.payload),\n ],\n },\n );\n\n return;\n }\n\n // invariant: handshake request passes all the validation\n const gotVersion = msg.payload.protocolVersion;\n if (!isAcceptedProtocolVersion(gotVersion)) {\n this.rejectHandshakeRequest(\n session,\n msg.from,\n `expected protocol version oneof [${acceptedProtocolVersions.toString()}], got ${gotVersion}`,\n 'PROTOCOL_VERSION_MISMATCH',\n {\n ...session.loggingMetadata,\n connectedTo: msg.from,\n transportMessage: msg,\n },\n );\n\n return;\n }\n\n // invariant: must pass custom validation if defined\n let parsedMetadata: ParsedMetadata = {};\n if (this.handshakeExtensions) {\n if (!Value.Check(this.handshakeExtensions.schema, msg.payload.metadata)) {\n this.rejectHandshakeRequest(\n session,\n msg.from,\n 'received malformed handshake metadata',\n 'MALFORMED_HANDSHAKE_META',\n {\n ...session.loggingMetadata,\n connectedTo: msg.from,\n validationErrors: [\n ...Value.Errors(\n this.handshakeExtensions.schema,\n msg.payload.metadata,\n ),\n ],\n },\n );\n\n return;\n }\n\n const previousParsedMetadata = this.sessionHandshakeMetadata.get(\n msg.from,\n );\n\n const parsedMetadataOrFailureCode =\n await this.handshakeExtensions.validate(\n msg.payload.metadata,\n previousParsedMetadata,\n );\n\n // double-check to make sure we haven't transitioned the session yet\n if (session._isConsumed) {\n // bail out, don't need to do anything\n return;\n }\n\n // handler rejected the connection\n if (\n Value.Check(\n HandshakeErrorCustomHandlerFatalResponseCodes,\n parsedMetadataOrFailureCode,\n )\n ) {\n this.rejectHandshakeRequest(\n session,\n msg.from,\n 'rejected by handshake handler',\n parsedMetadataOrFailureCode,\n {\n ...session.loggingMetadata,\n connectedTo: msg.from,\n clientId: this.clientId,\n },\n );\n\n return;\n }\n\n // success!\n parsedMetadata = parsedMetadataOrFailureCode;\n }\n\n // 4 connect cases\n // 1. new session\n // we dont have a session and the client is requesting a new one\n // we can create the session as normal\n // 2. client is reconnecting to an existing session but we don't have it\n // reject this handshake, there's nothing we can do to salvage it\n // 3. transparent reconnect (old session exists and is the same as the client wants)\n // assign to old session\n // 4. hard reconnect (oldSession exists but but the client wants a new one)\n // we close the old session and create a new one\n let connectCase:\n | 'new session'\n | 'unknown session'\n | 'transparent reconnection'\n | 'hard reconnection' = 'new session';\n const clientNextExpectedSeq =\n msg.payload.expectedSessionState.nextExpectedSeq;\n const clientNextSentSeq = msg.payload.expectedSessionState.nextSentSeq;\n\n let oldSession = this.sessions.get(msg.from);\n if (\n this.options.enableTransparentSessionReconnects &&\n oldSession &&\n oldSession.id === msg.payload.sessionId\n ) {\n connectCase = 'transparent reconnection';\n\n // invariant: ordering must be correct\n const ourNextSeq = oldSession.nextSeq();\n const ourAck = oldSession.ack;\n\n // two incorrect cases where we cannot permit a reconnect:\n // - if the client is about to send a message in the future w.r.t to the server\n // - client.seq > server.ack => nextSentSeq > oldSession.ack\n if (clientNextSentSeq > ourAck) {\n this.rejectHandshakeRequest(\n session,\n msg.from,\n `client is in the future: server wanted next message to be ${ourAck} but client would have sent ${clientNextSentSeq}`,\n 'SESSION_STATE_MISMATCH',\n {\n ...session.loggingMetadata,\n connectedTo: msg.from,\n transportMessage: msg,\n },\n );\n\n return;\n }\n\n // - if the server is about to send a message in the future w.r.t to the client\n // - server.seq > client.ack => oldSession.nextSeq() > nextExpectedSeq\n if (ourNextSeq > clientNextExpectedSeq) {\n this.rejectHandshakeRequest(\n session,\n msg.from,\n `server is in the future: client wanted next message to be ${clientNextExpectedSeq} but server would have sent ${ourNextSeq}`,\n 'SESSION_STATE_MISMATCH',\n {\n ...session.loggingMetadata,\n connectedTo: msg.from,\n transportMessage: msg,\n },\n );\n\n return;\n }\n\n // transparent reconnect seems ok, proceed by transitioning old session\n // to not connected\n if (oldSession.state !== SessionState.NoConnection) {\n const noConnectionSession =\n ServerSessionStateGraph.transition.ConnectedToNoConnection(\n oldSession,\n {\n onSessionGracePeriodElapsed: () => {\n this.onSessionGracePeriodElapsed(noConnectionSession);\n },\n },\n );\n\n oldSession = noConnectionSession;\n this.updateSession(oldSession);\n }\n } else if (oldSession) {\n connectCase = 'hard reconnection';\n\n // just nuke the old session entirely and proceed as if this was new\n this.log?.info(\n `client is reconnecting to a new session (${msg.payload.sessionId}) with an old session (${oldSession.id}) already existing, closing old session`,\n {\n ...session.loggingMetadata,\n connectedTo: msg.from,\n sessionId: msg.payload.sessionId,\n },\n );\n this.deleteSession(oldSession);\n oldSession = undefined;\n }\n\n if (!oldSession && (clientNextSentSeq > 0 || clientNextExpectedSeq > 0)) {\n // we don't have a session, but the client is trying to reconnect\n // to an old session. we can't do anything about this, so we reject\n connectCase = 'unknown session';\n\n const rejectionMessage = this.options.enableTransparentSessionReconnects\n ? `client is trying to reconnect to a session the server don't know about: ${msg.payload.sessionId}`\n : `client is attempting a transparent reconnect to a session but the server does not support it: ${msg.payload.sessionId}`;\n\n this.rejectHandshakeRequest(\n session,\n msg.from,\n rejectionMessage,\n 'SESSION_STATE_MISMATCH',\n {\n ...session.loggingMetadata,\n connectedTo: msg.from,\n transportMessage: msg,\n },\n );\n\n return;\n }\n\n // from this point on, we're committed to connecting\n const sessionId = msg.payload.sessionId;\n this.log?.info(\n `handshake from ${msg.from} ok (${connectCase}), responding with handshake success`,\n {\n ...session.loggingMetadata,\n connectedTo: msg.from,\n },\n );\n\n const responseMsg = handshakeResponseMessage({\n from: this.clientId,\n to: msg.from,\n status: {\n ok: true,\n sessionId,\n },\n });\n\n session.sendHandshake(responseMsg);\n\n // transition\n const connectedSession =\n ServerSessionStateGraph.transition.WaitingForHandshakeToConnected(\n session,\n // by this point oldSession is either no connection or we dont have an old session\n oldSession,\n sessionId,\n msg.from,\n msg.tracing,\n {\n onConnectionErrored: (err) => {\n // just log, when we error we also emit close\n const errStr = coerceErrorString(err);\n this.log?.warn(\n `connection to ${connectedSession.to} errored: ${errStr}`,\n connectedSession.loggingMetadata,\n );\n },\n onConnectionClosed: () => {\n this.log?.info(\n `connection to ${connectedSession.to} closed`,\n connectedSession.loggingMetadata,\n );\n this.onConnClosed(connectedSession);\n },\n onMessage: (msg) => {\n this.handleMsg(msg);\n },\n onInvalidMessage: (reason) => {\n this.protocolError({\n type: ProtocolError.InvalidMessage,\n message: reason,\n });\n this.deleteSession(connectedSession, { unhealthy: true });\n },\n },\n gotVersion,\n );\n\n this.sessionHandshakeMetadata.set(connectedSession.to, parsedMetadata);\n if (oldSession) {\n this.updateSession(connectedSession);\n } else {\n this.createSession(connectedSession);\n }\n\n this.pendingSessions.delete(session);\n connectedSession.startActiveHeartbeat();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA,SAAS,sBAAsB;AAsB/B,SAAS,aAAa;AAWf,IAAe,kBAAf,cAEG,UAAoB;AAAA;AAAA;AAAA;AAAA,EAIlB;AAAA;AAAA;AAAA;AAAA,EAKV;AAAA;AAAA;AAAA;AAAA,EAKA,2BAA2B,oBAAI,IAAuC;AAAA,EAEtE,WAAW,oBAAI,IAAgD;AAAA,EAC/D,kBAAkB,oBAAI,IAA0C;AAAA,EAEhE,YACE,UACA,iBACA;AACA,UAAM,UAAU,eAAe;AAC/B,SAAK,WAAW,oBAAI,IAAI;AACxB,SAAK,UAAU;AAAA,MACb,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AACA,SAAK,KAAK,KAAK,8BAA8B;AAAA,MAC3C,UAAU,KAAK;AAAA,MACf,iBAAiB;AAAA,IACnB,CAAC;AAAA,EACH;AAAA,EAEA,gBAAgB,SAAiC;AAC/C,SAAK,sBAAsB;AAAA,EAC7B;AAAA,EAEU,qBACR,gBACA;AACA,mBAAe,MAAM;AAIrB,SAAK,gBAAgB,OAAO,cAAc;AAAA,EAC5C;AAAA,EAEU,cACR,SACA,SACM;AACN,SAAK,yBAAyB,OAAO,QAAQ,EAAE;AAC/C,UAAM,cAAc,SAAS,OAAO;AAAA,EACtC;AAAA,EAEU,iBAAiB,MAAgB;AACzC,QAAI,KAAK,UAAU,MAAM;AAAQ;AAEjC,SAAK,KAAK,KAAK,2BAA2B;AAAA,MACxC,GAAG,KAAK;AAAA,MACR,UAAU,KAAK;AAAA,IACjB,CAAC;AAED,QAAI,oBAAoB;AACxB,UAAM,iBAAiB,wBAAwB;AAAA,MAC7C,KAAK;AAAA,MACL;AAAA,MACA;AAAA,QACE,oBAAoB,MAAM;AACxB,eAAK,KAAK;AAAA,YACR;AAAA,YACA,eAAe;AAAA,UACjB;AAEA,eAAK,qBAAqB,cAAc;AAAA,QAC1C;AAAA,QACA,qBAAqB,CAAC,QAAQ;AAC5B,gBAAM,cAAc,kBAAkB,GAAG;AACzC,eAAK,KAAK;AAAA,YACR,8DAA8D,WAAW;AAAA,YACzE,eAAe;AAAA,UACjB;AAEA,eAAK,qBAAqB,cAAc;AAAA,QAC1C;AAAA,QACA,oBAAoB,MAAM;AACxB,eAAK,KAAK;AAAA,YACR;AAAA,YACA,eAAe;AAAA,UACjB;AAEA,eAAK,qBAAqB,cAAc;AAAA,QAC1C;AAAA,QACA,aAAa,CAAC,QAAQ;AACpB,cAAI,mBAAmB;AACrB,iBAAK,KAAK;AAAA,cACR;AAAA,cACA;AAAA,gBACE,GAAG,eAAe;AAAA,gBAClB,aAAa,IAAI;AAAA,gBACjB,kBAAkB;AAAA,cACpB;AAAA,YACF;AAEA,iBAAK,qBAAqB,cAAc;AAExC;AAAA,UACF;AAKA,8BAAoB;AACpB,eAAK,KAAK,mBAAmB,gBAAgB,GAAG;AAAA,QAClD;AAAA,QACA,oBAAoB,CAAC,QAAQ,SAAS;AACpC,eAAK,KAAK;AAAA,YACR,sBAAsB,MAAM;AAAA,YAC5B,eAAe;AAAA,UACjB;AACA,eAAK,qBAAqB,cAAc;AACxC,eAAK,cAAc;AAAA,YACjB,MAAM,cAAc;AAAA,YACpB;AAAA,YACA,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAEA,SAAK,gBAAgB,IAAI,cAAc;AAAA,EACzC;AAAA,EAEQ,uBACN,SACA,IACA,QACA,MACA,UACA;AACA,YAAQ,KAAK,WAAW,KAAK,UAAU;AAAA,MACrC,MAAM,eAAe;AAAA,MACrB,SAAS;AAAA,IACX,CAAC;AAED,SAAK,KAAK,KAAK,QAAQ,QAAQ;AAE/B,YAAQ;AAAA,MACN,yBAAyB;AAAA,QACvB,MAAM,KAAK;AAAA,QACX;AAAA,QACA,QAAQ;AAAA,UACN,IAAI;AAAA,UACJ;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,SAAK,cAAc;AAAA,MACjB,MAAM,cAAc;AAAA,MACpB;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AACD,SAAK,qBAAqB,OAAO;AAAA,EACnC;AAAA,EAEA,MAAgB,mBACd,SACA,KACA;AAEA,QAAI,CAAC,MAAM,MAAM,sCAAsC,IAAI,OAAO,GAAG;AACnE,WAAK;AAAA,QACH;AAAA,QACA,IAAI;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,UACE,GAAG,QAAQ;AAAA,UACX,kBAAkB;AAAA,UAClB,aAAa,IAAI;AAAA,UACjB,kBAAkB;AAAA,YAChB,GAAG,MAAM,OAAO,sCAAsC,IAAI,OAAO;AAAA,UACnE;AAAA,QACF;AAAA,MACF;AAEA;AAAA,IACF;AAGA,UAAM,aAAa,IAAI,QAAQ;AAC/B,QAAI,CAAC,0BAA0B,UAAU,GAAG;AAC1C,WAAK;AAAA,QACH;AAAA,QACA,IAAI;AAAA,QACJ,oCAAoC,yBAAyB,SAAS,CAAC,UAAU,UAAU;AAAA,QAC3F;AAAA,QACA;AAAA,UACE,GAAG,QAAQ;AAAA,UACX,aAAa,IAAI;AAAA,UACjB,kBAAkB;AAAA,QACpB;AAAA,MACF;AAEA;AAAA,IACF;AAGA,QAAI,iBAAiC,CAAC;AACtC,QAAI,KAAK,qBAAqB;AAC5B,UAAI,CAAC,MAAM,MAAM,KAAK,oBAAoB,QAAQ,IAAI,QAAQ,QAAQ,GAAG;AACvE,aAAK;AAAA,UACH;AAAA,UACA,IAAI;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,YACE,GAAG,QAAQ;AAAA,YACX,aAAa,IAAI;AAAA,YACjB,kBAAkB;AAAA,cAChB,GAAG,MAAM;AAAA,gBACP,KAAK,oBAAoB;AAAA,gBACzB,IAAI,QAAQ;AAAA,cACd;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA;AAAA,MACF;AAEA,YAAM,yBAAyB,KAAK,yBAAyB;AAAA,QAC3D,IAAI;AAAA,MACN;AAEA,YAAM,8BACJ,MAAM,KAAK,oBAAoB;AAAA,QAC7B,IAAI,QAAQ;AAAA,QACZ;AAAA,MACF;AAGF,UAAI,QAAQ,aAAa;AAEvB;AAAA,MACF;AAGA,UACE,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,MACF,GACA;AACA,aAAK;AAAA,UACH;AAAA,UACA,IAAI;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,YACE,GAAG,QAAQ;AAAA,YACX,aAAa,IAAI;AAAA,YACjB,UAAU,KAAK;AAAA,UACjB;AAAA,QACF;AAEA;AAAA,MACF;AAGA,uBAAiB;AAAA,IACnB;AAYA,QAAI,cAIsB;AAC1B,UAAM,wBACJ,IAAI,QAAQ,qBAAqB;AACnC,UAAM,oBAAoB,IAAI,QAAQ,qBAAqB;AAE3D,QAAI,aAAa,KAAK,SAAS,IAAI,IAAI,IAAI;AAC3C,QACE,KAAK,QAAQ,sCACb,cACA,WAAW,OAAO,IAAI,QAAQ,WAC9B;AACA,oBAAc;AAGd,YAAM,aAAa,WAAW,QAAQ;AACtC,YAAM,SAAS,WAAW;AAK1B,UAAI,oBAAoB,QAAQ;AAC9B,aAAK;AAAA,UACH;AAAA,UACA,IAAI;AAAA,UACJ,6DAA6D,MAAM,+BAA+B,iBAAiB;AAAA,UACnH;AAAA,UACA;AAAA,YACE,GAAG,QAAQ;AAAA,YACX,aAAa,IAAI;AAAA,YACjB,kBAAkB;AAAA,UACpB;AAAA,QACF;AAEA;AAAA,MACF;AAIA,UAAI,aAAa,uBAAuB;AACtC,aAAK;AAAA,UACH;AAAA,UACA,IAAI;AAAA,UACJ,6DAA6D,qBAAqB,+BAA+B,UAAU;AAAA,UAC3H;AAAA,UACA;AAAA,YACE,GAAG,QAAQ;AAAA,YACX,aAAa,IAAI;AAAA,YACjB,kBAAkB;AAAA,UACpB;AAAA,QACF;AAEA;AAAA,MACF;AAIA,UAAI,WAAW,6CAAqC;AAClD,cAAM,sBACJ,wBAAwB,WAAW;AAAA,UACjC;AAAA,UACA;AAAA,YACE,6BAA6B,MAAM;AACjC,mBAAK,4BAA4B,mBAAmB;AAAA,YACtD;AAAA,UACF;AAAA,QACF;AAEF,qBAAa;AACb,aAAK,cAAc,UAAU;AAAA,MAC/B;AAAA,IACF,WAAW,YAAY;AACrB,oBAAc;AAGd,WAAK,KAAK;AAAA,QACR,4CAA4C,IAAI,QAAQ,SAAS,0BAA0B,WAAW,EAAE;AAAA,QACxG;AAAA,UACE,GAAG,QAAQ;AAAA,UACX,aAAa,IAAI;AAAA,UACjB,WAAW,IAAI,QAAQ;AAAA,QACzB;AAAA,MACF;AACA,WAAK,cAAc,UAAU;AAC7B,mBAAa;AAAA,IACf;AAEA,QAAI,CAAC,eAAe,oBAAoB,KAAK,wBAAwB,IAAI;AAGvE,oBAAc;AAEd,YAAM,mBAAmB,KAAK,QAAQ,qCAClC,2EAA2E,IAAI,QAAQ,SAAS,KAChG,iGAAiG,IAAI,QAAQ,SAAS;AAE1H,WAAK;AAAA,QACH;AAAA,QACA,IAAI;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,UACE,GAAG,QAAQ;AAAA,UACX,aAAa,IAAI;AAAA,UACjB,kBAAkB;AAAA,QACpB;AAAA,MACF;AAEA;AAAA,IACF;AAGA,UAAM,YAAY,IAAI,QAAQ;AAC9B,SAAK,KAAK;AAAA,MACR,kBAAkB,IAAI,IAAI,QAAQ,WAAW;AAAA,MAC7C;AAAA,QACE,GAAG,QAAQ;AAAA,QACX,aAAa,IAAI;AAAA,MACnB;AAAA,IACF;AAEA,UAAM,cAAc,yBAAyB;AAAA,MAC3C,MAAM,KAAK;AAAA,MACX,IAAI,IAAI;AAAA,MACR,QAAQ;AAAA,QACN,IAAI;AAAA,QACJ;AAAA,MACF;AAAA,IACF,CAAC;AAED,YAAQ,cAAc,WAAW;AAGjC,UAAM,mBACJ,wBAAwB,WAAW;AAAA,MACjC;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ;AAAA,QACE,qBAAqB,CAAC,QAAQ;AAE5B,gBAAM,SAAS,kBAAkB,GAAG;AACpC,eAAK,KAAK;AAAA,YACR,iBAAiB,iBAAiB,EAAE,aAAa,MAAM;AAAA,YACvD,iBAAiB;AAAA,UACnB;AAAA,QACF;AAAA,QACA,oBAAoB,MAAM;AACxB,eAAK,KAAK;AAAA,YACR,iBAAiB,iBAAiB,EAAE;AAAA,YACpC,iBAAiB;AAAA,UACnB;AACA,eAAK,aAAa,gBAAgB;AAAA,QACpC;AAAA,QACA,WAAW,CAACA,SAAQ;AAClB,eAAK,UAAUA,IAAG;AAAA,QACpB;AAAA,QACA,kBAAkB,CAAC,WAAW;AAC5B,eAAK,cAAc;AAAA,YACjB,MAAM,cAAc;AAAA,YACpB,SAAS;AAAA,UACX,CAAC;AACD,eAAK,cAAc,kBAAkB,EAAE,WAAW,KAAK,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAEF,SAAK,yBAAyB,IAAI,iBAAiB,IAAI,cAAc;AACrE,QAAI,YAAY;AACd,WAAK,cAAc,gBAAgB;AAAA,IACrC,OAAO;AACL,WAAK,cAAc,gBAAgB;AAAA,IACrC;AAEA,SAAK,gBAAgB,OAAO,OAAO;AACnC,qBAAiB,qBAAqB;AAAA,EACxC;AACF;","names":["msg"]}
@@ -1,20 +0,0 @@
1
- /**
2
- * Codec interface for encoding and decoding objects to and from Uint8 buffers.
3
- * Used to prepare messages for use by the transport layer.
4
- */
5
- interface Codec {
6
- /**
7
- * Encodes an object to a Uint8 buffer.
8
- * @param obj - The object to encode.
9
- * @returns The encoded Uint8 buffer.
10
- */
11
- toBuffer(obj: object): Uint8Array;
12
- /**
13
- * Decodes an object from a Uint8 buffer.
14
- * @param buf - The Uint8 buffer to decode.
15
- * @returns The decoded object, or null if decoding failed.
16
- */
17
- fromBuffer(buf: Uint8Array): object | null;
18
- }
19
-
20
- export { Codec as C };