@replit/river 0.200.0-rc.9 → 0.200.2

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/README.md +8 -8
  2. package/dist/{chunk-42Z2FQIU.js → chunk-6BH2CXVE.js} +21 -13
  3. package/dist/chunk-6BH2CXVE.js.map +1 -0
  4. package/dist/{chunk-4HT6P2ZG.js → chunk-A4JKES5A.js} +22 -30
  5. package/dist/chunk-A4JKES5A.js.map +1 -0
  6. package/dist/{chunk-4PVU7J25.js → chunk-AJGIY2UB.js} +1 -1
  7. package/dist/chunk-AJGIY2UB.js.map +1 -0
  8. package/dist/{chunk-EETL2L77.js → chunk-GJUUVID2.js} +14 -32
  9. package/dist/chunk-GJUUVID2.js.map +1 -0
  10. package/dist/{chunk-GR3AQKHL.js → chunk-HRKM7BIE.js} +14 -4
  11. package/dist/chunk-HRKM7BIE.js.map +1 -0
  12. package/dist/{chunk-ZXZE253M.js → chunk-PJB2Y2AV.js} +24 -37
  13. package/dist/chunk-PJB2Y2AV.js.map +1 -0
  14. package/dist/{chunk-I75XYO5W.js → chunk-QIDEN5PP.js} +82 -20
  15. package/dist/chunk-QIDEN5PP.js.map +1 -0
  16. package/dist/{chunk-VXYHC666.js → chunk-YTMS7OP6.js} +1 -1
  17. package/dist/chunk-YTMS7OP6.js.map +1 -0
  18. package/dist/chunk-Z4PX66JO.js +307 -0
  19. package/dist/chunk-Z4PX66JO.js.map +1 -0
  20. package/dist/{client-22a47343.d.ts → client-9292552a.d.ts} +3 -4
  21. package/dist/codec/index.cjs.map +1 -1
  22. package/dist/codec/index.js +1 -1
  23. package/dist/connection-94dea547.d.ts +32 -0
  24. package/dist/{context-b4aff18f.d.ts → context-69f37ac1.d.ts} +48 -43
  25. package/dist/logging/index.cjs.map +1 -1
  26. package/dist/logging/index.d.cts +1 -1
  27. package/dist/logging/index.d.ts +1 -1
  28. package/dist/logging/index.js +1 -1
  29. package/dist/{message-7d135e38.d.ts → message-57bb8187.d.ts} +5 -3
  30. package/dist/router/index.cjs +649 -709
  31. package/dist/router/index.cjs.map +1 -1
  32. package/dist/router/index.d.cts +22 -12
  33. package/dist/router/index.d.ts +22 -12
  34. package/dist/router/index.js +502 -404
  35. package/dist/router/index.js.map +1 -1
  36. package/dist/{server-dd6a9853.d.ts → server-8fdd7fb2.d.ts} +5 -5
  37. package/dist/{services-1b5ac5bc.d.ts → services-259f39a3.d.ts} +191 -194
  38. package/dist/transport/impls/ws/client.cjs +129 -62
  39. package/dist/transport/impls/ws/client.cjs.map +1 -1
  40. package/dist/transport/impls/ws/client.d.cts +4 -4
  41. package/dist/transport/impls/ws/client.d.ts +4 -4
  42. package/dist/transport/impls/ws/client.js +7 -7
  43. package/dist/transport/impls/ws/client.js.map +1 -1
  44. package/dist/transport/impls/ws/server.cjs +146 -70
  45. package/dist/transport/impls/ws/server.cjs.map +1 -1
  46. package/dist/transport/impls/ws/server.d.cts +6 -5
  47. package/dist/transport/impls/ws/server.d.ts +6 -5
  48. package/dist/transport/impls/ws/server.js +21 -9
  49. package/dist/transport/impls/ws/server.js.map +1 -1
  50. package/dist/transport/index.cjs +138 -92
  51. package/dist/transport/index.cjs.map +1 -1
  52. package/dist/transport/index.d.cts +4 -4
  53. package/dist/transport/index.d.ts +4 -4
  54. package/dist/transport/index.js +7 -7
  55. package/dist/util/testHelpers.cjs +265 -327
  56. package/dist/util/testHelpers.cjs.map +1 -1
  57. package/dist/util/testHelpers.d.cts +36 -31
  58. package/dist/util/testHelpers.d.ts +36 -31
  59. package/dist/util/testHelpers.js +82 -52
  60. package/dist/util/testHelpers.js.map +1 -1
  61. package/package.json +4 -3
  62. package/dist/chunk-42Z2FQIU.js.map +0 -1
  63. package/dist/chunk-4HT6P2ZG.js.map +0 -1
  64. package/dist/chunk-4PVU7J25.js.map +0 -1
  65. package/dist/chunk-EETL2L77.js.map +0 -1
  66. package/dist/chunk-GR3AQKHL.js.map +0 -1
  67. package/dist/chunk-I75XYO5W.js.map +0 -1
  68. package/dist/chunk-MQ6ANR3H.js +0 -451
  69. package/dist/chunk-MQ6ANR3H.js.map +0 -1
  70. package/dist/chunk-VXYHC666.js.map +0 -1
  71. package/dist/chunk-ZXZE253M.js.map +0 -1
  72. package/dist/connection-260e45a8.d.ts +0 -11
@@ -39,12 +39,15 @@ __export(testHelpers_exports, {
39
39
  createLocalWebSocketClient: () => createLocalWebSocketClient,
40
40
  createWebSocketServer: () => createWebSocketServer,
41
41
  dummySession: () => dummySession,
42
- getIteratorFromStream: () => getIteratorFromStream,
42
+ getClientSendFn: () => getClientSendFn,
43
+ getReadableIterator: () => getReadableIterator,
44
+ getServerSendFn: () => getServerSendFn,
43
45
  getTransportConnections: () => getTransportConnections,
44
- iterNext: () => iterNext,
46
+ isReadableDone: () => isReadableDone,
45
47
  numberOfConnections: () => numberOfConnections,
46
48
  onWsServerReady: () => onWsServerReady,
47
49
  payloadToTransportMessage: () => payloadToTransportMessage,
50
+ readNextResult: () => readNextResult,
48
51
  testingClientSessionOptions: () => testingClientSessionOptions,
49
52
  testingSessionOptions: () => testingSessionOptions,
50
53
  waitForMessage: () => waitForMessage
@@ -81,35 +84,8 @@ function Err(error) {
81
84
  };
82
85
  }
83
86
 
84
- // router/procedures.ts
85
- var import_typebox2 = require("@sinclair/typebox");
86
- var INTERNAL_RIVER_ERROR_CODE = "INTERNAL_RIVER_ERROR";
87
- var UNCAUGHT_ERROR_CODE = "UNCAUGHT_ERROR";
88
- var UNEXPECTED_DISCONNECT_CODE = "UNEXPECTED_DISCONNECT";
89
- var INVALID_REQUEST_CODE = "INVALID_REQUEST";
90
- var ABORT_CODE = "ABORT";
91
- var ResponseReaderErrorSchema = import_typebox2.Type.Object({
92
- code: import_typebox2.Type.Union([
93
- import_typebox2.Type.Literal(INTERNAL_RIVER_ERROR_CODE),
94
- import_typebox2.Type.Literal(UNCAUGHT_ERROR_CODE),
95
- import_typebox2.Type.Literal(UNEXPECTED_DISCONNECT_CODE),
96
- import_typebox2.Type.Literal(INVALID_REQUEST_CODE),
97
- import_typebox2.Type.Literal(ABORT_CODE)
98
- ]),
99
- message: import_typebox2.Type.String()
100
- });
101
- var RequestReaderErrorSchema = import_typebox2.Type.Object({
102
- code: import_typebox2.Type.Union([
103
- import_typebox2.Type.Literal(UNCAUGHT_ERROR_CODE),
104
- import_typebox2.Type.Literal(UNEXPECTED_DISCONNECT_CODE),
105
- import_typebox2.Type.Literal(INVALID_REQUEST_CODE),
106
- import_typebox2.Type.Literal(ABORT_CODE)
107
- ]),
108
- message: import_typebox2.Type.String()
109
- });
110
-
111
87
  // transport/message.ts
112
- var import_typebox3 = require("@sinclair/typebox");
88
+ var import_typebox2 = require("@sinclair/typebox");
113
89
 
114
90
  // transport/id.ts
115
91
  var import_nanoid = require("nanoid");
@@ -119,96 +95,91 @@ var alphabet = (0, import_nanoid.customAlphabet)(
119
95
  var generateId = () => alphabet(12);
120
96
 
121
97
  // transport/message.ts
122
- var TransportMessageSchema = (t) => import_typebox3.Type.Object({
123
- id: import_typebox3.Type.String(),
124
- from: import_typebox3.Type.String(),
125
- to: import_typebox3.Type.String(),
126
- seq: import_typebox3.Type.Integer(),
127
- ack: import_typebox3.Type.Integer(),
128
- serviceName: import_typebox3.Type.Optional(import_typebox3.Type.String()),
129
- procedureName: import_typebox3.Type.Optional(import_typebox3.Type.String()),
130
- streamId: import_typebox3.Type.String(),
131
- controlFlags: import_typebox3.Type.Integer(),
132
- tracing: import_typebox3.Type.Optional(
133
- import_typebox3.Type.Object({
134
- traceparent: import_typebox3.Type.String(),
135
- tracestate: import_typebox3.Type.String()
98
+ var TransportMessageSchema = (t) => import_typebox2.Type.Object({
99
+ id: import_typebox2.Type.String(),
100
+ from: import_typebox2.Type.String(),
101
+ to: import_typebox2.Type.String(),
102
+ seq: import_typebox2.Type.Integer(),
103
+ ack: import_typebox2.Type.Integer(),
104
+ serviceName: import_typebox2.Type.Optional(import_typebox2.Type.String()),
105
+ procedureName: import_typebox2.Type.Optional(import_typebox2.Type.String()),
106
+ streamId: import_typebox2.Type.String(),
107
+ controlFlags: import_typebox2.Type.Integer(),
108
+ tracing: import_typebox2.Type.Optional(
109
+ import_typebox2.Type.Object({
110
+ traceparent: import_typebox2.Type.String(),
111
+ tracestate: import_typebox2.Type.String()
136
112
  })
137
113
  ),
138
114
  payload: t
139
115
  });
140
- var ControlMessageAckSchema = import_typebox3.Type.Object({
141
- type: import_typebox3.Type.Literal("ACK")
116
+ var ControlMessageAckSchema = import_typebox2.Type.Object({
117
+ type: import_typebox2.Type.Literal("ACK")
142
118
  });
143
- var ControlMessageCloseSchema = import_typebox3.Type.Object({
144
- type: import_typebox3.Type.Literal("CLOSE")
119
+ var ControlMessageCloseSchema = import_typebox2.Type.Object({
120
+ type: import_typebox2.Type.Literal("CLOSE")
145
121
  });
146
122
  var currentProtocolVersion = "v2.0";
147
- var ControlMessageHandshakeRequestSchema = import_typebox3.Type.Object({
148
- type: import_typebox3.Type.Literal("HANDSHAKE_REQ"),
149
- protocolVersion: import_typebox3.Type.String(),
150
- sessionId: import_typebox3.Type.String(),
123
+ var ControlMessageHandshakeRequestSchema = import_typebox2.Type.Object({
124
+ type: import_typebox2.Type.Literal("HANDSHAKE_REQ"),
125
+ protocolVersion: import_typebox2.Type.String(),
126
+ sessionId: import_typebox2.Type.String(),
151
127
  /**
152
128
  * Specifies what the server's expected session state (from the pov of the client). This can be
153
129
  * used by the server to know whether this is a new or a reestablished connection, and whether it
154
130
  * is compatible with what it already has.
155
131
  */
156
- expectedSessionState: import_typebox3.Type.Object({
132
+ expectedSessionState: import_typebox2.Type.Object({
157
133
  // what the client expects the server to send next
158
- nextExpectedSeq: import_typebox3.Type.Integer(),
159
- // TODO: remove optional once we know all servers
160
- // are nextSentSeq here
161
- // what the server expects the client to send next
162
- nextSentSeq: import_typebox3.Type.Optional(import_typebox3.Type.Integer())
134
+ nextExpectedSeq: import_typebox2.Type.Integer(),
135
+ nextSentSeq: import_typebox2.Type.Integer()
163
136
  }),
164
- metadata: import_typebox3.Type.Optional(import_typebox3.Type.Unknown())
137
+ metadata: import_typebox2.Type.Optional(import_typebox2.Type.Unknown())
165
138
  });
166
- var HandshakeErrorRetriableResponseCodes = import_typebox3.Type.Union([
167
- import_typebox3.Type.Literal("SESSION_STATE_MISMATCH")
139
+ var HandshakeErrorRetriableResponseCodes = import_typebox2.Type.Union([
140
+ import_typebox2.Type.Literal("SESSION_STATE_MISMATCH")
168
141
  ]);
169
- var HandshakeErrorCustomHandlerFatalResponseCodes = import_typebox3.Type.Union([
142
+ var HandshakeErrorCustomHandlerFatalResponseCodes = import_typebox2.Type.Union([
170
143
  // The custom validation handler rejected the handler because the client is unsupported.
171
- import_typebox3.Type.Literal("REJECTED_UNSUPPORTED_CLIENT"),
144
+ import_typebox2.Type.Literal("REJECTED_UNSUPPORTED_CLIENT"),
172
145
  // The custom validation handler rejected the handshake.
173
- import_typebox3.Type.Literal("REJECTED_BY_CUSTOM_HANDLER")
146
+ import_typebox2.Type.Literal("REJECTED_BY_CUSTOM_HANDLER")
174
147
  ]);
175
- var HandshakeErrorFatalResponseCodes = import_typebox3.Type.Union([
148
+ var HandshakeErrorFatalResponseCodes = import_typebox2.Type.Union([
176
149
  HandshakeErrorCustomHandlerFatalResponseCodes,
177
150
  // The ciient sent a handshake that doesn't comply with the extended handshake metadata.
178
- import_typebox3.Type.Literal("MALFORMED_HANDSHAKE_META"),
151
+ import_typebox2.Type.Literal("MALFORMED_HANDSHAKE_META"),
179
152
  // The ciient sent a handshake that doesn't comply with ControlMessageHandshakeRequestSchema.
180
- import_typebox3.Type.Literal("MALFORMED_HANDSHAKE"),
153
+ import_typebox2.Type.Literal("MALFORMED_HANDSHAKE"),
181
154
  // The client's protocol version does not match the server's.
182
- import_typebox3.Type.Literal("PROTOCOL_VERSION_MISMATCH")
155
+ import_typebox2.Type.Literal("PROTOCOL_VERSION_MISMATCH")
183
156
  ]);
184
- var HandshakeErrorResponseCodes = import_typebox3.Type.Union([
157
+ var HandshakeErrorResponseCodes = import_typebox2.Type.Union([
185
158
  HandshakeErrorRetriableResponseCodes,
186
159
  HandshakeErrorFatalResponseCodes
187
160
  ]);
188
- var ControlMessageHandshakeResponseSchema = import_typebox3.Type.Object({
189
- type: import_typebox3.Type.Literal("HANDSHAKE_RESP"),
190
- status: import_typebox3.Type.Union([
191
- import_typebox3.Type.Object({
192
- ok: import_typebox3.Type.Literal(true),
193
- sessionId: import_typebox3.Type.String()
161
+ var ControlMessageHandshakeResponseSchema = import_typebox2.Type.Object({
162
+ type: import_typebox2.Type.Literal("HANDSHAKE_RESP"),
163
+ status: import_typebox2.Type.Union([
164
+ import_typebox2.Type.Object({
165
+ ok: import_typebox2.Type.Literal(true),
166
+ sessionId: import_typebox2.Type.String()
194
167
  }),
195
- import_typebox3.Type.Object({
196
- ok: import_typebox3.Type.Literal(false),
197
- reason: import_typebox3.Type.String(),
198
- // TODO: remove optional once we know all servers
199
- // are sending code here
200
- code: import_typebox3.Type.Optional(HandshakeErrorResponseCodes)
168
+ import_typebox2.Type.Object({
169
+ ok: import_typebox2.Type.Literal(false),
170
+ reason: import_typebox2.Type.String(),
171
+ code: HandshakeErrorResponseCodes
201
172
  })
202
173
  ])
203
174
  });
204
- var ControlMessagePayloadSchema = import_typebox3.Type.Union([
175
+ var ControlMessagePayloadSchema = import_typebox2.Type.Union([
205
176
  ControlMessageCloseSchema,
206
177
  ControlMessageAckSchema,
207
178
  ControlMessageHandshakeRequestSchema,
208
179
  ControlMessageHandshakeResponseSchema
209
180
  ]);
210
181
  var OpaqueTransportMessageSchema = TransportMessageSchema(
211
- import_typebox3.Type.Unknown()
182
+ import_typebox2.Type.Unknown()
212
183
  );
213
184
  function isAck(controlFlag) {
214
185
  return (controlFlag & 1 /* AckBit */) === 1 /* AckBit */;
@@ -223,300 +194,204 @@ function coerceErrorString(err) {
223
194
  }
224
195
 
225
196
  // router/streams.ts
226
- var StreamDrainedError = {
227
- code: "STREAM_DRAINED",
228
- message: "Stream was drained"
197
+ var ReadableBrokenError = {
198
+ code: "READABLE_BROKEN",
199
+ message: "Readable was broken before it is fully consumed"
229
200
  };
230
- var ReadStreamImpl = class {
201
+ function createPromiseWithResolvers() {
202
+ let resolve;
203
+ let reject;
204
+ const promise = new Promise((res, rej) => {
205
+ resolve = res;
206
+ reject = rej;
207
+ });
208
+ return {
209
+ promise,
210
+ // @ts-expect-error promise callbacks are sync
211
+ resolve,
212
+ // @ts-expect-error promise callbacks are sync
213
+ reject
214
+ };
215
+ }
216
+ var ReadableImpl = class {
231
217
  /**
232
- * Whether the stream is closed.
218
+ * Whether the {@link Readable} is closed.
219
+ *
220
+ * Closed {@link Readable}s are done receiving values, but that doesn't affect
221
+ * any other aspect of the {@link Readable} such as it's consumability.
233
222
  */
234
223
  closed = false;
235
224
  /**
236
- * A list of listeners that will be called when the stream is closed.
237
- */
238
- onCloseListeners;
239
- /**
240
- * Whether the user has requested to close the stream.
241
- */
242
- closeRequested = false;
243
- /**
244
- * Used to signal to the outside world that the user has requested to close the stream.
245
- */
246
- closeRequestCallback;
247
- /**
248
- * Whether the stream is locked.
225
+ * Whether the {@link Readable} is locked.
226
+ *
227
+ * @see {@link Readable}'s typedoc to understand locking
249
228
  */
250
229
  locked = false;
251
230
  /**
252
- * Whether drain was called.
231
+ * Whether {@link break} was called.
232
+ *
233
+ * @see {@link break} for more information
253
234
  */
254
- drained = false;
235
+ broken = false;
255
236
  /**
256
- * This flag allows us to avoid cases where drain was called,
257
- * but the stream is fully consumed and closed. We don't need
258
- * to signal that drain was called.
237
+ * This flag allows us to avoid emitting a {@link ReadableBrokenError} after {@link break} was called
238
+ * in cases where the {@link queue} is fully consumed and {@link ReadableImpl} is {@link closed}. This is just an
239
+ * ergonomic feature to avoid emitting an error in our iteration when we don't have to.
259
240
  */
260
- didDrainDisposeValues = false;
241
+ brokenWithValuesLeftToRead = false;
261
242
  /**
262
- * A list of values that have been pushed to the stream but not yet emitted to the user.
243
+ * A list of values that have been pushed to the {@link ReadableImpl} but not yet emitted to the user.
263
244
  */
264
245
  queue = [];
265
246
  /**
266
247
  * Used by methods in the class to signal to the iterator that it
267
248
  * should check for the next value.
268
249
  */
269
- nextPromise = null;
270
- /**
271
- * Resolves nextPromise
272
- */
273
- resolveNextPromise = null;
274
- constructor(closeRequestCallback) {
275
- this.closeRequestCallback = closeRequestCallback;
276
- this.onCloseListeners = /* @__PURE__ */ new Set();
277
- }
250
+ next = null;
278
251
  [Symbol.asyncIterator]() {
279
- if (this.isLocked()) {
280
- throw new TypeError("ReadStream is already locked");
252
+ if (this.locked) {
253
+ throw new TypeError("Readable is already locked");
281
254
  }
282
- let didSignalDrain = false;
283
255
  this.locked = true;
256
+ let didSignalBreak = false;
284
257
  return {
285
258
  next: async () => {
286
- if (this.drained && didSignalDrain) {
259
+ if (didSignalBreak) {
287
260
  return {
288
261
  done: true,
289
262
  value: void 0
290
263
  };
291
264
  }
292
265
  while (this.queue.length === 0) {
293
- if (this.isClosed() && !this.didDrainDisposeValues) {
266
+ if (this.closed && !this.brokenWithValuesLeftToRead) {
294
267
  return {
295
268
  done: true,
296
269
  value: void 0
297
270
  };
298
271
  }
299
- if (this.drained) {
300
- didSignalDrain = true;
272
+ if (this.broken) {
273
+ didSignalBreak = true;
301
274
  return {
302
275
  done: false,
303
- value: Err(StreamDrainedError)
276
+ value: Err(ReadableBrokenError)
304
277
  };
305
278
  }
306
- if (!this.nextPromise) {
307
- this.nextPromise = new Promise((resolve) => {
308
- this.resolveNextPromise = resolve;
309
- });
279
+ if (!this.next) {
280
+ this.next = createPromiseWithResolvers();
310
281
  }
311
- await this.nextPromise;
312
- this.nextPromise = null;
313
- this.resolveNextPromise = null;
282
+ await this.next.promise;
283
+ this.next = null;
314
284
  }
315
285
  const value = this.queue.shift();
316
286
  return { done: false, value };
317
287
  },
318
288
  return: () => {
319
- this.drain();
289
+ this.break();
320
290
  return { done: true, value: void 0 };
321
291
  }
322
292
  };
323
293
  }
324
- unwrappedIter() {
325
- const iterator = this[Symbol.asyncIterator]();
326
- let unwrappedLock = false;
327
- return {
328
- [Symbol.asyncIterator]() {
329
- if (unwrappedLock) {
330
- throw new TypeError("ReadStream is already locked");
331
- }
332
- unwrappedLock = true;
333
- return {
334
- next: async () => {
335
- const next = await iterator.next();
336
- if (next.done) {
337
- return next;
338
- }
339
- if (next.value.ok) {
340
- return { done: false, value: next.value.payload };
341
- }
342
- iterator.return();
343
- throw new Error(
344
- `Got err result in unwrappedIter: ${next.value.payload.code} - ${next.value.payload.message}`
345
- );
346
- },
347
- return: () => iterator.return()
348
- };
349
- }
350
- };
351
- }
352
- async asArray() {
294
+ async collect() {
353
295
  const array = [];
354
296
  for await (const value of this) {
355
297
  array.push(value);
356
298
  }
357
299
  return array;
358
300
  }
359
- drain() {
360
- if (this.drained) {
301
+ break() {
302
+ if (this.broken) {
361
303
  return;
362
304
  }
363
305
  this.locked = true;
364
- this.drained = true;
365
- this.didDrainDisposeValues = this.queue.length > 0;
306
+ this.broken = true;
307
+ this.brokenWithValuesLeftToRead = this.queue.length > 0;
366
308
  this.queue.length = 0;
367
- this.resolveNextPromise?.();
368
- }
369
- isClosed() {
370
- return this.closed;
371
- }
372
- isLocked() {
373
- return this.locked;
309
+ this.next?.resolve();
374
310
  }
375
- onClose(cb) {
376
- if (this.isClosed()) {
377
- throw new Error("Stream is already closed");
378
- }
379
- this.onCloseListeners.add(cb);
380
- return () => {
381
- this.onCloseListeners.delete(cb);
382
- };
383
- }
384
- requestClose() {
385
- if (this.isClosed()) {
386
- throw new Error("Cannot request close after stream already closed");
387
- }
388
- if (!this.closeRequested) {
389
- this.closeRequested = true;
390
- this.closeRequestCallback();
391
- }
392
- return new Promise((resolve) => {
393
- this.onClose(() => {
394
- resolve(void 0);
395
- });
396
- });
397
- }
398
- isCloseRequested() {
399
- return this.closeRequested;
311
+ isReadable() {
312
+ return !this.locked && !this.broken;
400
313
  }
401
314
  /**
402
315
  * @internal meant for use within river, not exposed as a public API
403
316
  *
404
- * Pushes a value to the stream.
317
+ * Pushes a value to be read.
405
318
  */
406
- pushValue(value) {
407
- if (this.drained) {
319
+ _pushValue(value) {
320
+ if (this.broken) {
408
321
  return;
409
322
  }
410
323
  if (this.closed) {
411
- throw new Error("Cannot push to closed stream");
324
+ throw new Error("Cannot push to closed Readable");
412
325
  }
413
326
  this.queue.push(value);
414
- this.resolveNextPromise?.();
327
+ this.next?.resolve();
415
328
  }
416
329
  /**
417
330
  * @internal meant for use within river, not exposed as a public API
418
331
  *
419
- * Triggers the close of the stream. Make sure to push all remaining
332
+ * Triggers the close of the {@link Readable}. Make sure to push all remaining
420
333
  * values before calling this method.
421
334
  */
422
- triggerClose() {
423
- if (this.isClosed()) {
335
+ _triggerClose() {
336
+ if (this.closed) {
424
337
  throw new Error("Unexpected closing multiple times");
425
338
  }
426
339
  this.closed = true;
427
- this.resolveNextPromise?.();
428
- this.onCloseListeners.forEach((cb) => cb());
429
- this.onCloseListeners.clear();
340
+ this.next?.resolve();
430
341
  }
431
342
  /**
432
343
  * @internal meant for use within river, not exposed as a public API
433
344
  */
434
- hasValuesInQueue() {
345
+ _hasValuesInQueue() {
435
346
  return this.queue.length > 0;
436
347
  }
437
- };
438
- var WriteStreamImpl = class {
439
348
  /**
440
- * Passed via constructor to pass on write requests
441
- */
442
- writeCb;
443
- /**
444
- * Whether the stream is closed.
349
+ * @internal meant for use within river, not exposed as a public API
445
350
  */
446
- closed = false;
351
+ isClosed() {
352
+ return this.closed;
353
+ }
354
+ };
355
+ var WritableImpl = class {
447
356
  /**
448
- * A list of listeners that will be called when the stream is closed.
357
+ * Passed via constructor to pass on calls to {@link write}
449
358
  */
450
- onCloseListeners;
359
+ writeCb;
451
360
  /**
452
- * Whether the reader has requested to close the stream.
361
+ * Passed via constructor to pass on calls to {@link close}
453
362
  */
454
- closeRequested = false;
363
+ closeCb;
455
364
  /**
456
- * A list of listeners that will be called when a close request is triggered.
365
+ * Whether {@link close} was called, and {@link Writable} is not writable anymore.
457
366
  */
458
- onCloseRequestListeners;
459
- constructor(writeCb) {
460
- this.writeCb = writeCb;
461
- this.onCloseListeners = /* @__PURE__ */ new Set();
462
- this.onCloseRequestListeners = /* @__PURE__ */ new Set();
367
+ closed = false;
368
+ constructor(callbacks) {
369
+ this.writeCb = callbacks.writeCb;
370
+ this.closeCb = callbacks.closeCb;
463
371
  }
464
372
  write(value) {
465
- if (this.isClosed()) {
466
- throw new Error("Cannot write to closed stream");
373
+ if (this.closed) {
374
+ throw new Error("Cannot write to closed Writable");
467
375
  }
468
376
  this.writeCb(value);
469
377
  }
470
- isClosed() {
471
- return this.closed;
472
- }
473
- onClose(cb) {
474
- if (this.isClosed()) {
475
- cb();
476
- return () => void 0;
477
- }
478
- this.onCloseListeners.add(cb);
479
- return () => this.onCloseListeners.delete(cb);
378
+ isWritable() {
379
+ return !this.closed;
480
380
  }
481
381
  close() {
482
- if (this.isClosed()) {
382
+ if (this.closed) {
483
383
  return;
484
384
  }
485
385
  this.closed = true;
486
- this.onCloseListeners.forEach((cb) => cb());
487
- this.onCloseListeners.clear();
488
- this.onCloseRequestListeners.clear();
489
386
  this.writeCb = () => void 0;
490
- }
491
- isCloseRequested() {
492
- return this.closeRequested;
493
- }
494
- onCloseRequest(cb) {
495
- if (this.isClosed()) {
496
- throw new Error("Stream is already closed");
497
- }
498
- if (this.isCloseRequested()) {
499
- cb();
500
- return () => void 0;
501
- }
502
- this.onCloseRequestListeners.add(cb);
503
- return () => this.onCloseRequestListeners.delete(cb);
387
+ this.closeCb();
388
+ this.closeCb = () => void 0;
504
389
  }
505
390
  /**
506
391
  * @internal meant for use within river, not exposed as a public API
507
- *
508
- * Triggers a close request.
509
392
  */
510
- triggerCloseRequest() {
511
- if (this.isCloseRequested()) {
512
- throw new Error("Cannot trigger close request multiple times");
513
- }
514
- if (this.isClosed()) {
515
- throw new Error("Cannot trigger close request on closed stream");
516
- }
517
- this.closeRequested = true;
518
- this.onCloseRequestListeners.forEach((cb) => cb());
519
- this.onCloseRequestListeners.clear();
393
+ isClosed() {
394
+ return this.closed;
520
395
  }
521
396
  };
522
397
 
@@ -842,7 +717,7 @@ var SessionNoConnection = class extends IdentifiedSessionWithGracePeriod {
842
717
  var import_api = require("@opentelemetry/api");
843
718
 
844
719
  // package.json
845
- var version = "0.200.0-rc.9";
720
+ var version = "0.200.2";
846
721
 
847
722
  // tracing/index.ts
848
723
  function createSessionTelemetryInfo(sessionId, to, from, propagationCtx) {
@@ -995,13 +870,13 @@ var SessionConnected = class extends IdentifiedSession {
995
870
  this.conn.addCloseListener(this.listeners.onConnectionClosed);
996
871
  this.conn.addErrorListener(this.listeners.onConnectionErrored);
997
872
  if (this.sendBuffer.length > 0) {
998
- this.log?.debug(
999
- `sending ${this.sendBuffer.length} buffered messages`,
873
+ this.log?.info(
874
+ `sending ${this.sendBuffer.length} buffered messages, starting at seq ${this.nextSeq()}`,
1000
875
  this.loggingMetadata
1001
876
  );
1002
- }
1003
- for (const msg of this.sendBuffer) {
1004
- this.conn.send(this.options.codec.toBuffer(msg));
877
+ for (const msg of this.sendBuffer) {
878
+ this.conn.send(this.options.codec.toBuffer(msg));
879
+ }
1005
880
  }
1006
881
  this.isActivelyHeartbeating = false;
1007
882
  this.heartbeatHandle = setInterval(() => {
@@ -1043,6 +918,12 @@ var SessionConnected = class extends IdentifiedSession {
1043
918
  }
1044
919
  });
1045
920
  }
921
+ closeConnection() {
922
+ this.conn.removeDataListener(this.onMessageData);
923
+ this.conn.removeCloseListener(this.listeners.onConnectionClosed);
924
+ this.conn.removeErrorListener(this.listeners.onConnectionErrored);
925
+ this.conn.close();
926
+ }
1046
927
  onMessageData = (msg) => {
1047
928
  const parsedMsg = this.parseMsg(msg);
1048
929
  if (parsedMsg === null) {
@@ -1059,8 +940,8 @@ var SessionConnected = class extends IdentifiedSession {
1059
940
  }
1060
941
  );
1061
942
  } else {
1062
- const reason = `received out-of-order msg (got seq: ${parsedMsg.seq}, wanted seq: ${this.ack})`;
1063
- this.log?.error(reason, {
943
+ const reason = `received out-of-order msg, closing connection (got seq: ${parsedMsg.seq}, wanted seq: ${this.ack})`;
944
+ this.log?.warn(reason, {
1064
945
  ...this.loggingMetadata,
1065
946
  transportMessage: parsedMsg,
1066
947
  tags: ["invariant-violation"]
@@ -1069,7 +950,7 @@ var SessionConnected = class extends IdentifiedSession {
1069
950
  code: import_api2.SpanStatusCode.ERROR,
1070
951
  message: reason
1071
952
  });
1072
- this.listeners.onInvalidMessage(reason);
953
+ this.closeConnection();
1073
954
  }
1074
955
  return;
1075
956
  }
@@ -1095,8 +976,10 @@ var SessionConnected = class extends IdentifiedSession {
1095
976
  this.conn.removeDataListener(this.onMessageData);
1096
977
  this.conn.removeCloseListener(this.listeners.onConnectionClosed);
1097
978
  this.conn.removeErrorListener(this.listeners.onConnectionErrored);
1098
- clearInterval(this.heartbeatHandle);
1099
- this.heartbeatHandle = void 0;
979
+ if (this.heartbeatHandle) {
980
+ clearInterval(this.heartbeatHandle);
981
+ this.heartbeatHandle = void 0;
982
+ }
1100
983
  }
1101
984
  _handleClose() {
1102
985
  super._handleClose();
@@ -1421,6 +1304,31 @@ var ServerSessionStateGraph = {
1421
1304
  }
1422
1305
  };
1423
1306
 
1307
+ // router/errors.ts
1308
+ var import_typebox3 = require("@sinclair/typebox");
1309
+ var UNCAUGHT_ERROR_CODE = "UNCAUGHT_ERROR";
1310
+ var UNEXPECTED_DISCONNECT_CODE = "UNEXPECTED_DISCONNECT";
1311
+ var INVALID_REQUEST_CODE = "INVALID_REQUEST";
1312
+ var CANCEL_CODE = "CANCEL";
1313
+ var ReaderErrorSchema = import_typebox3.Type.Union([
1314
+ import_typebox3.Type.Object({
1315
+ code: import_typebox3.Type.Literal(UNCAUGHT_ERROR_CODE),
1316
+ message: import_typebox3.Type.String()
1317
+ }),
1318
+ import_typebox3.Type.Object({
1319
+ code: import_typebox3.Type.Literal(UNEXPECTED_DISCONNECT_CODE),
1320
+ message: import_typebox3.Type.String()
1321
+ }),
1322
+ import_typebox3.Type.Object({
1323
+ code: import_typebox3.Type.Literal(INVALID_REQUEST_CODE),
1324
+ message: import_typebox3.Type.String()
1325
+ }),
1326
+ import_typebox3.Type.Object({
1327
+ code: import_typebox3.Type.Literal(CANCEL_CODE),
1328
+ message: import_typebox3.Type.String()
1329
+ })
1330
+ ]);
1331
+
1424
1332
  // util/testHelpers.ts
1425
1333
  function createLocalWebSocketClient(port) {
1426
1334
  const sock = new import_ws.default(`ws://localhost:${port}`);
@@ -1442,11 +1350,25 @@ function onWsServerReady(server) {
1442
1350
  });
1443
1351
  });
1444
1352
  }
1445
- function getIteratorFromStream(readStream) {
1446
- return readStream[Symbol.asyncIterator]();
1353
+ var readableIterators = /* @__PURE__ */ new WeakMap();
1354
+ function getReadableIterator(readable) {
1355
+ let iter = readableIterators.get(readable);
1356
+ if (!iter) {
1357
+ iter = readable[Symbol.asyncIterator]();
1358
+ readableIterators.set(readable, iter);
1359
+ }
1360
+ return iter;
1447
1361
  }
1448
- async function iterNext(iter) {
1449
- return await iter.next().then((res) => res.value);
1362
+ async function readNextResult(readable) {
1363
+ const res = await getReadableIterator(readable).next();
1364
+ if (res.done) {
1365
+ throw new Error("readNext from a done Readable");
1366
+ }
1367
+ return res.value;
1368
+ }
1369
+ async function isReadableDone(readable) {
1370
+ const res = await getReadableIterator(readable).next();
1371
+ return res.done;
1450
1372
  }
1451
1373
  function payloadToTransportMessage(payload) {
1452
1374
  return {
@@ -1496,6 +1418,23 @@ function dummySession() {
1496
1418
  currentProtocolVersion
1497
1419
  );
1498
1420
  }
1421
+ function getClientSendFn(clientTransport, serverTransport) {
1422
+ const session = clientTransport.sessions.get(serverTransport.clientId) ?? clientTransport.createUnconnectedSession(serverTransport.clientId);
1423
+ return clientTransport.getSessionBoundSendFn(
1424
+ serverTransport.clientId,
1425
+ session.id
1426
+ );
1427
+ }
1428
+ function getServerSendFn(serverTransport, clientTransport) {
1429
+ const session = serverTransport.sessions.get(clientTransport.clientId);
1430
+ if (!session) {
1431
+ throw new Error("session not found");
1432
+ }
1433
+ return serverTransport.getSessionBoundSendFn(
1434
+ clientTransport.clientId,
1435
+ session.id
1436
+ );
1437
+ }
1499
1438
  function dummyCtx(state, session, extendedContext) {
1500
1439
  return {
1501
1440
  ...extendedContext,
@@ -1503,9 +1442,9 @@ function dummyCtx(state, session, extendedContext) {
1503
1442
  sessionId: session.id,
1504
1443
  from: session.from,
1505
1444
  metadata: {},
1506
- abortController: new AbortController(),
1507
- clientAbortSignal: new AbortController().signal,
1508
- onRequestFinished: () => void 0
1445
+ // TODO might wanna hook these up!
1446
+ cancel: () => void 0,
1447
+ signal: new AbortController().signal
1509
1448
  };
1510
1449
  }
1511
1450
  function asClientRpc(state, proc, extendedContext, session = dummySession()) {
@@ -1517,38 +1456,32 @@ function asClientRpc(state, proc, extendedContext, session = dummySession()) {
1517
1456
  };
1518
1457
  }
1519
1458
  function createResponsePipe() {
1520
- const reader = new ReadStreamImpl(() => {
1521
- void Promise.resolve().then(() => {
1522
- writer.triggerCloseRequest();
1523
- });
1524
- });
1525
- const writer = new WriteStreamImpl(
1526
- (v) => {
1527
- reader.pushValue(v);
1459
+ const readable = new ReadableImpl();
1460
+ const writable = new WritableImpl({
1461
+ writeCb: (v) => {
1462
+ readable._pushValue(v);
1463
+ },
1464
+ closeCb: () => {
1465
+ void Promise.resolve().then(() => {
1466
+ readable._triggerClose();
1467
+ });
1528
1468
  }
1529
- );
1530
- writer.onClose(() => {
1531
- void Promise.resolve().then(() => {
1532
- reader.triggerClose();
1533
- });
1534
1469
  });
1535
- return { reader, writer };
1470
+ return { readable, writable };
1536
1471
  }
1537
1472
  function createRequestPipe() {
1538
- const reader = new ReadStreamImpl(() => {
1539
- void Promise.resolve().then(() => {
1540
- writer.triggerCloseRequest();
1541
- });
1542
- });
1543
- const writer = new WriteStreamImpl((v) => {
1544
- reader.pushValue(Ok(v));
1545
- });
1546
- writer.onClose(() => {
1547
- void Promise.resolve().then(() => {
1548
- reader.triggerClose();
1549
- });
1473
+ const readable = new ReadableImpl();
1474
+ const writable = new WritableImpl({
1475
+ writeCb: (v) => {
1476
+ readable._pushValue(Ok(v));
1477
+ },
1478
+ closeCb: () => {
1479
+ void Promise.resolve().then(() => {
1480
+ readable._triggerClose();
1481
+ });
1482
+ }
1550
1483
  });
1551
- return { reader, writer };
1484
+ return { readable, writable };
1552
1485
  }
1553
1486
  function asClientStream(state, proc, reqInit, extendedContext, session = dummySession()) {
1554
1487
  const requestPipe = createRequestPipe();
@@ -1556,12 +1489,12 @@ function asClientStream(state, proc, reqInit, extendedContext, session = dummySe
1556
1489
  void proc.handler({
1557
1490
  ctx: dummyCtx(state, session, extendedContext),
1558
1491
  reqInit: reqInit ?? {},
1559
- reqReader: requestPipe.reader,
1560
- resWriter: responsePipe.writer
1561
- }).catch((err) => responsePipe.writer.write(catchProcError(err)));
1492
+ reqReadable: requestPipe.readable,
1493
+ resWritable: responsePipe.writable
1494
+ }).catch((err) => responsePipe.writable.write(catchProcError(err)));
1562
1495
  return {
1563
- reqWriter: requestPipe.writer,
1564
- resReader: responsePipe.reader
1496
+ reqWritable: requestPipe.writable,
1497
+ resReadable: responsePipe.readable
1565
1498
  };
1566
1499
  }
1567
1500
  function asClientSubscription(state, proc, extendedContext, session = dummySession()) {
@@ -1570,9 +1503,11 @@ function asClientSubscription(state, proc, extendedContext, session = dummySessi
1570
1503
  void proc.handler({
1571
1504
  ctx: dummyCtx(state, session, extendedContext),
1572
1505
  reqInit: msg,
1573
- resWriter: responsePipe.writer
1574
- }).catch((err) => responsePipe.writer.write(catchProcError(err)));
1575
- return { resReader: responsePipe.reader };
1506
+ resWritable: responsePipe.writable
1507
+ }).catch(
1508
+ (err) => responsePipe.writable.write(catchProcError(err))
1509
+ );
1510
+ return { resReadable: responsePipe.readable };
1576
1511
  };
1577
1512
  }
1578
1513
  function asClientUpload(state, proc, reqInit, extendedContext, session = dummySession()) {
@@ -1580,9 +1515,9 @@ function asClientUpload(state, proc, reqInit, extendedContext, session = dummySe
1580
1515
  const result = proc.handler({
1581
1516
  ctx: dummyCtx(state, session, extendedContext),
1582
1517
  reqInit: reqInit ?? {},
1583
- reqReader: requestPipe.reader
1518
+ reqReadable: requestPipe.readable
1584
1519
  }).catch(catchProcError);
1585
- return [requestPipe.writer, () => result];
1520
+ return { reqWritable: requestPipe.writable, finalize: () => result };
1586
1521
  }
1587
1522
  function getTransportConnections(transport) {
1588
1523
  const connections = [];
@@ -1612,12 +1547,15 @@ function closeAllConnections(transport) {
1612
1547
  createLocalWebSocketClient,
1613
1548
  createWebSocketServer,
1614
1549
  dummySession,
1615
- getIteratorFromStream,
1550
+ getClientSendFn,
1551
+ getReadableIterator,
1552
+ getServerSendFn,
1616
1553
  getTransportConnections,
1617
- iterNext,
1554
+ isReadableDone,
1618
1555
  numberOfConnections,
1619
1556
  onWsServerReady,
1620
1557
  payloadToTransportMessage,
1558
+ readNextResult,
1621
1559
  testingClientSessionOptions,
1622
1560
  testingSessionOptions,
1623
1561
  waitForMessage