@replit/river 0.215.1 → 0.216.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 (70) hide show
  1. package/README.md +47 -0
  2. package/dist/{adapter-Dtt4bYL-.d.ts → adapter-BXCk-dmy.d.ts} +3 -21
  3. package/dist/{adapter-CjgmjtUJ.d.cts → adapter-D5X11kmP.d.cts} +3 -21
  4. package/dist/{chunk-3DDZCLJM.js → chunk-75ZMPCKC.js} +22 -6
  5. package/dist/{chunk-3DDZCLJM.js.map → chunk-75ZMPCKC.js.map} +1 -1
  6. package/dist/chunk-SHND2JG6.js +86 -0
  7. package/dist/chunk-SHND2JG6.js.map +1 -0
  8. package/dist/{chunk-NUGV5QWU.js → chunk-ZLMQQI43.js} +12 -2
  9. package/dist/chunk-ZLMQQI43.js.map +1 -0
  10. package/dist/{client-BOc8blGj.d.ts → client-BNc5Pj_4.d.ts} +2 -2
  11. package/dist/{client-B9aKi9Li.d.cts → client-BZUvFL6B.d.cts} +2 -2
  12. package/dist/codec/index.cjs.map +1 -1
  13. package/dist/codec/index.d.cts +3 -3
  14. package/dist/codec/index.d.ts +3 -3
  15. package/dist/codec/index.js +2 -2
  16. package/dist/{connection-DnMYvolf.d.ts → connection-ou9w2dSY.d.ts} +3 -3
  17. package/dist/{connection-1hFoyxuX.d.cts → connection-xxgJHs2o.d.cts} +3 -3
  18. package/dist/{index-Bf9PGbS4.d.cts → index-BAGGleT3.d.cts} +1 -1
  19. package/dist/{index-DiAq34gk.d.ts → index-ZWkoesQD.d.ts} +1 -1
  20. package/dist/logging/index.d.cts +2 -2
  21. package/dist/logging/index.d.ts +2 -2
  22. package/dist/{message-DL74OqsX.d.cts → message-CpXWqmJw.d.cts} +1 -1
  23. package/dist/{message-DL74OqsX.d.ts → message-CpXWqmJw.d.ts} +1 -1
  24. package/dist/protobuf/codec.cjs +107 -0
  25. package/dist/protobuf/codec.cjs.map +1 -0
  26. package/dist/protobuf/codec.d.cts +13 -0
  27. package/dist/protobuf/codec.d.ts +13 -0
  28. package/dist/protobuf/codec.js +7 -0
  29. package/dist/protobuf/codec.js.map +1 -0
  30. package/dist/protobuf/index.cjs +1877 -0
  31. package/dist/protobuf/index.cjs.map +1 -0
  32. package/dist/protobuf/index.d.cts +488 -0
  33. package/dist/protobuf/index.d.ts +488 -0
  34. package/dist/protobuf/index.js +1260 -0
  35. package/dist/protobuf/index.js.map +1 -0
  36. package/dist/router/index.cjs +1 -1
  37. package/dist/router/index.cjs.map +1 -1
  38. package/dist/router/index.d.cts +11 -10
  39. package/dist/router/index.d.ts +11 -10
  40. package/dist/router/index.js +1 -1
  41. package/dist/{server-_bfE7LYc.d.ts → server-BPu7Td80.d.ts} +4 -4
  42. package/dist/{server-BkEzDYIv.d.cts → server-JdnoVO11.d.cts} +4 -4
  43. package/dist/{services-KdKBWdJr.d.ts → services-BrTFTO5Q.d.ts} +104 -93
  44. package/dist/{services-zaansuuR.d.cts → services-cwGAC2rB.d.cts} +104 -93
  45. package/dist/testUtil/index.cjs +21 -5
  46. package/dist/testUtil/index.cjs.map +1 -1
  47. package/dist/testUtil/index.d.cts +8 -7
  48. package/dist/testUtil/index.d.ts +8 -7
  49. package/dist/testUtil/index.js +2 -2
  50. package/dist/transport/impls/ws/client.cjs +1 -1
  51. package/dist/transport/impls/ws/client.cjs.map +1 -1
  52. package/dist/transport/impls/ws/client.d.cts +7 -6
  53. package/dist/transport/impls/ws/client.d.ts +7 -6
  54. package/dist/transport/impls/ws/client.js +2 -2
  55. package/dist/transport/impls/ws/server.cjs +21 -5
  56. package/dist/transport/impls/ws/server.cjs.map +1 -1
  57. package/dist/transport/impls/ws/server.d.cts +7 -6
  58. package/dist/transport/impls/ws/server.d.ts +7 -6
  59. package/dist/transport/impls/ws/server.js +2 -2
  60. package/dist/transport/index.cjs +21 -5
  61. package/dist/transport/index.cjs.map +1 -1
  62. package/dist/transport/index.d.cts +8 -7
  63. package/dist/transport/index.d.ts +8 -7
  64. package/dist/transport/index.js +2 -2
  65. package/dist/{transport-CCBNESLA.d.cts → transport-B1MUtXL7.d.ts} +5 -4
  66. package/dist/{transport-kW92H6x-.d.ts → transport-BnU3Zb0Q.d.cts} +5 -4
  67. package/dist/types-BGGvYIJM.d.cts +20 -0
  68. package/dist/types-BGGvYIJM.d.ts +20 -0
  69. package/package.json +12 -1
  70. package/dist/chunk-NUGV5QWU.js.map +0 -1
@@ -0,0 +1,1877 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // protobuf/index.ts
21
+ var protobuf_exports = {};
22
+ __export(protobuf_exports, {
23
+ CANCEL_CODE: () => CANCEL_CODE,
24
+ Err: () => Err,
25
+ INVALID_REQUEST_CODE: () => INVALID_REQUEST_CODE,
26
+ Ok: () => Ok,
27
+ ProtoCodec: () => ProtoCodec,
28
+ ReadableBrokenError: () => ReadableBrokenError,
29
+ RiverErrorCode: () => RiverErrorCode,
30
+ UNCAUGHT_ERROR_CODE: () => UNCAUGHT_ERROR_CODE,
31
+ UNEXPECTED_DISCONNECT_CODE: () => UNEXPECTED_DISCONNECT_CODE,
32
+ createClient: () => createClient,
33
+ createClientHandshakeOptions: () => createClientHandshakeOptions2,
34
+ createProtoService: () => createProtoService,
35
+ createServer: () => createServer,
36
+ createServerHandshakeOptions: () => createServerHandshakeOptions2,
37
+ isClientError: () => isClientError,
38
+ isProtocolError: () => isProtocolError,
39
+ isRiverError: () => isRiverError,
40
+ isSerializedClientErrorResult: () => isSerializedClientErrorResult,
41
+ isSerializedProtocolErrorResult: () => isSerializedProtocolErrorResult
42
+ });
43
+ module.exports = __toCommonJS(protobuf_exports);
44
+
45
+ // protobuf/codec.ts
46
+ var import_protobuf = require("@bufbuild/protobuf");
47
+ var import_msgpack = require("@msgpack/msgpack");
48
+
49
+ // protobuf/gen/transport_pb.ts
50
+ var import_codegenv2 = require("@bufbuild/protobuf/codegenv2");
51
+ var file_transport = /* @__PURE__ */ (0, import_codegenv2.fileDesc)("Cg90cmFuc3BvcnQucHJvdG8SGHJlcGxpdC5yaXZlci5pbnRlcm5hbC52MSI9ChJQcm9wYWdhdGlvbkNvbnRleHQSEwoLdHJhY2VwYXJlbnQYASABKAkSEgoKdHJhY2VzdGF0ZRgCIAEoCSKuAgoRVHJhbnNwb3J0RW52ZWxvcGUSCgoCaWQYASABKAkSDAoEZnJvbRgCIAEoCRIKCgJ0bxgDIAEoCRILCgNzZXEYBCABKA0SCwoDYWNrGAUgASgNEhEKCXN0cmVhbV9pZBgGIAEoCRIVCg1jb250cm9sX2ZsYWdzGAcgASgNEhQKDHNlcnZpY2VfbmFtZRgIIAEoCRIWCg5wcm9jZWR1cmVfbmFtZRgJIAEoCRI9Cgd0cmFjaW5nGAogASgLMiwucmVwbGl0LnJpdmVyLmludGVybmFsLnYxLlByb3BhZ2F0aW9uQ29udGV4dBIXCg1wYXlsb2FkX2J5dGVzGAsgASgMSAASGQoPcGF5bG9hZF9tc2dwYWNrGAwgASgMSABCDgoMcGF5bG9hZF9raW5kYgZwcm90bzM");
52
+ var TransportEnvelopeSchema = /* @__PURE__ */ (0, import_codegenv2.messageDesc)(file_transport, 1);
53
+
54
+ // protobuf/codec.ts
55
+ var ProtoCodec = {
56
+ toBuffer(obj) {
57
+ const message = coerceTransportMessage(obj);
58
+ return (0, import_protobuf.toBinary)(
59
+ TransportEnvelopeSchema,
60
+ (0, import_protobuf.create)(TransportEnvelopeSchema, toEnvelopeInit(message))
61
+ );
62
+ },
63
+ fromBuffer(buff) {
64
+ const bytes = buff instanceof Uint8Array ? buff : new Uint8Array(buff);
65
+ return fromEnvelope((0, import_protobuf.fromBinary)(TransportEnvelopeSchema, bytes));
66
+ }
67
+ };
68
+ function coerceTransportMessage(obj) {
69
+ const candidate = obj;
70
+ if (typeof candidate.id !== "string" || typeof candidate.from !== "string" || typeof candidate.to !== "string" || typeof candidate.seq !== "number" || typeof candidate.ack !== "number" || typeof candidate.streamId !== "string" || typeof candidate.controlFlags !== "number" || !("payload" in candidate)) {
71
+ throw new Error("ProtoCodec expects an opaque transport message");
72
+ }
73
+ return candidate;
74
+ }
75
+ function toEnvelopeInit(message) {
76
+ return {
77
+ id: message.id,
78
+ from: message.from,
79
+ to: message.to,
80
+ seq: message.seq,
81
+ ack: message.ack,
82
+ streamId: message.streamId,
83
+ controlFlags: message.controlFlags,
84
+ serviceName: message.serviceName ?? "",
85
+ procedureName: message.procedureName ?? "",
86
+ tracing: message.tracing ? {
87
+ traceparent: message.tracing.traceparent,
88
+ tracestate: message.tracing.tracestate
89
+ } : void 0,
90
+ payloadKind: message.payload instanceof Uint8Array ? { case: "payloadBytes", value: message.payload } : { case: "payloadMsgpack", value: (0, import_msgpack.encode)(message.payload) }
91
+ };
92
+ }
93
+ function fromEnvelope(envelope) {
94
+ return {
95
+ id: envelope.id,
96
+ from: envelope.from,
97
+ to: envelope.to,
98
+ seq: envelope.seq,
99
+ ack: envelope.ack,
100
+ streamId: envelope.streamId,
101
+ controlFlags: envelope.controlFlags,
102
+ payload: decodePayloadKind(envelope),
103
+ ...envelope.serviceName === "" ? {} : { serviceName: envelope.serviceName },
104
+ ...envelope.procedureName === "" ? {} : { procedureName: envelope.procedureName },
105
+ ...envelope.tracing ? {
106
+ tracing: {
107
+ traceparent: envelope.tracing.traceparent,
108
+ tracestate: envelope.tracing.tracestate
109
+ }
110
+ } : {}
111
+ };
112
+ }
113
+ function decodePayloadKind(envelope) {
114
+ switch (envelope.payloadKind.case) {
115
+ case "payloadBytes":
116
+ return envelope.payloadKind.value;
117
+ case "payloadMsgpack":
118
+ return (0, import_msgpack.decode)(envelope.payloadKind.value);
119
+ default:
120
+ throw new Error("invalid protobuf transport envelope: missing payload");
121
+ }
122
+ }
123
+
124
+ // protobuf/client.ts
125
+ var import_value = require("@sinclair/typebox/value");
126
+
127
+ // transport/message.ts
128
+ var import_typebox = require("@sinclair/typebox");
129
+
130
+ // transport/id.ts
131
+ var import_nanoid = require("nanoid");
132
+ var alphabet = (0, import_nanoid.customAlphabet)(
133
+ "1234567890abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZ"
134
+ );
135
+ var generateId = () => alphabet(12);
136
+
137
+ // transport/message.ts
138
+ var TransportMessageSchema = (t) => import_typebox.Type.Object({
139
+ id: import_typebox.Type.String(),
140
+ from: import_typebox.Type.String(),
141
+ to: import_typebox.Type.String(),
142
+ seq: import_typebox.Type.Integer(),
143
+ ack: import_typebox.Type.Integer(),
144
+ serviceName: import_typebox.Type.Optional(import_typebox.Type.String()),
145
+ procedureName: import_typebox.Type.Optional(import_typebox.Type.String()),
146
+ streamId: import_typebox.Type.String(),
147
+ controlFlags: import_typebox.Type.Integer(),
148
+ tracing: import_typebox.Type.Optional(
149
+ import_typebox.Type.Object({
150
+ traceparent: import_typebox.Type.String(),
151
+ tracestate: import_typebox.Type.String()
152
+ })
153
+ ),
154
+ payload: t
155
+ });
156
+ var ControlMessageAckSchema = import_typebox.Type.Object({
157
+ type: import_typebox.Type.Literal("ACK")
158
+ });
159
+ var ControlMessageCloseSchema = import_typebox.Type.Object({
160
+ type: import_typebox.Type.Literal("CLOSE")
161
+ });
162
+ var ControlMessageHandshakeRequestSchema = import_typebox.Type.Object({
163
+ type: import_typebox.Type.Literal("HANDSHAKE_REQ"),
164
+ protocolVersion: import_typebox.Type.String(),
165
+ sessionId: import_typebox.Type.String(),
166
+ /**
167
+ * Specifies what the server's expected session state (from the pov of the client). This can be
168
+ * used by the server to know whether this is a new or a reestablished connection, and whether it
169
+ * is compatible with what it already has.
170
+ */
171
+ expectedSessionState: import_typebox.Type.Object({
172
+ // what the client expects the server to send next
173
+ nextExpectedSeq: import_typebox.Type.Integer(),
174
+ nextSentSeq: import_typebox.Type.Integer()
175
+ }),
176
+ metadata: import_typebox.Type.Optional(import_typebox.Type.Unknown())
177
+ });
178
+ var HandshakeErrorRetriableResponseCodes = import_typebox.Type.Union([
179
+ import_typebox.Type.Literal("SESSION_STATE_MISMATCH")
180
+ ]);
181
+ var HandshakeErrorCustomHandlerFatalResponseCodes = import_typebox.Type.Union([
182
+ // The custom validation handler rejected the handler because the client is unsupported.
183
+ import_typebox.Type.Literal("REJECTED_UNSUPPORTED_CLIENT"),
184
+ // The custom validation handler rejected the handshake.
185
+ import_typebox.Type.Literal("REJECTED_BY_CUSTOM_HANDLER")
186
+ ]);
187
+ var HandshakeErrorFatalResponseCodes = import_typebox.Type.Union([
188
+ HandshakeErrorCustomHandlerFatalResponseCodes,
189
+ // The ciient sent a handshake that doesn't comply with the extended handshake metadata.
190
+ import_typebox.Type.Literal("MALFORMED_HANDSHAKE_META"),
191
+ // The ciient sent a handshake that doesn't comply with ControlMessageHandshakeRequestSchema.
192
+ import_typebox.Type.Literal("MALFORMED_HANDSHAKE"),
193
+ // The client's protocol version does not match the server's.
194
+ import_typebox.Type.Literal("PROTOCOL_VERSION_MISMATCH")
195
+ ]);
196
+ var HandshakeErrorResponseCodes = import_typebox.Type.Union([
197
+ HandshakeErrorRetriableResponseCodes,
198
+ HandshakeErrorFatalResponseCodes
199
+ ]);
200
+ var ControlMessageHandshakeResponseSchema = import_typebox.Type.Object({
201
+ type: import_typebox.Type.Literal("HANDSHAKE_RESP"),
202
+ status: import_typebox.Type.Union([
203
+ import_typebox.Type.Object({
204
+ ok: import_typebox.Type.Literal(true),
205
+ sessionId: import_typebox.Type.String()
206
+ }),
207
+ import_typebox.Type.Object({
208
+ ok: import_typebox.Type.Literal(false),
209
+ reason: import_typebox.Type.String(),
210
+ code: HandshakeErrorResponseCodes
211
+ })
212
+ ])
213
+ });
214
+ var ControlMessagePayloadSchema = import_typebox.Type.Union([
215
+ ControlMessageCloseSchema,
216
+ ControlMessageAckSchema,
217
+ ControlMessageHandshakeRequestSchema,
218
+ ControlMessageHandshakeResponseSchema
219
+ ]);
220
+ var OpaqueTransportMessageSchema = TransportMessageSchema(
221
+ import_typebox.Type.Unknown()
222
+ );
223
+ function closeStreamMessage(streamId) {
224
+ return {
225
+ streamId,
226
+ controlFlags: 8 /* StreamClosedBit */,
227
+ payload: {
228
+ type: "CLOSE"
229
+ }
230
+ };
231
+ }
232
+ function cancelMessage(streamId, payload) {
233
+ return {
234
+ streamId,
235
+ controlFlags: 4 /* StreamCancelBit */,
236
+ payload
237
+ };
238
+ }
239
+ function isStreamOpen(controlFlag) {
240
+ return (
241
+ /* eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison */
242
+ (controlFlag & 2 /* StreamOpenBit */) === 2 /* StreamOpenBit */
243
+ );
244
+ }
245
+ function isStreamClose(controlFlag) {
246
+ return (
247
+ /* eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison */
248
+ (controlFlag & 8 /* StreamClosedBit */) === 8 /* StreamClosedBit */
249
+ );
250
+ }
251
+ function isStreamCancel(controlFlag) {
252
+ return (
253
+ /* eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison */
254
+ (controlFlag & 4 /* StreamCancelBit */) === 4 /* StreamCancelBit */
255
+ );
256
+ }
257
+
258
+ // router/result.ts
259
+ var import_typebox2 = require("@sinclair/typebox");
260
+ var AnyResultSchema = import_typebox2.Type.Union([
261
+ import_typebox2.Type.Object({
262
+ ok: import_typebox2.Type.Literal(false),
263
+ payload: import_typebox2.Type.Object({
264
+ code: import_typebox2.Type.String(),
265
+ message: import_typebox2.Type.String(),
266
+ extras: import_typebox2.Type.Optional(import_typebox2.Type.Unknown())
267
+ })
268
+ }),
269
+ import_typebox2.Type.Object({
270
+ ok: import_typebox2.Type.Literal(true),
271
+ payload: import_typebox2.Type.Unknown()
272
+ })
273
+ ]);
274
+ function Ok(payload) {
275
+ return {
276
+ ok: true,
277
+ payload
278
+ };
279
+ }
280
+ function Err(error) {
281
+ return {
282
+ ok: false,
283
+ payload: error
284
+ };
285
+ }
286
+
287
+ // router/streams.ts
288
+ var ReadableBrokenError = {
289
+ code: "READABLE_BROKEN",
290
+ message: "Readable was broken before it is fully consumed"
291
+ };
292
+ function createPromiseWithResolvers() {
293
+ let resolve;
294
+ let reject;
295
+ const promise = new Promise((res, rej) => {
296
+ resolve = res;
297
+ reject = rej;
298
+ });
299
+ return {
300
+ promise,
301
+ // @ts-expect-error promise callbacks are sync
302
+ resolve,
303
+ // @ts-expect-error promise callbacks are sync
304
+ reject
305
+ };
306
+ }
307
+ var ReadableImpl = class {
308
+ /**
309
+ * Whether the {@link Readable} is closed.
310
+ *
311
+ * Closed {@link Readable}s are done receiving values, but that doesn't affect
312
+ * any other aspect of the {@link Readable} such as it's consumability.
313
+ */
314
+ closed = false;
315
+ /**
316
+ * Whether the {@link Readable} is locked.
317
+ *
318
+ * @see {@link Readable}'s typedoc to understand locking
319
+ */
320
+ locked = false;
321
+ /**
322
+ * Whether {@link break} was called.
323
+ *
324
+ * @see {@link break} for more information
325
+ */
326
+ broken = false;
327
+ /**
328
+ * This flag allows us to avoid emitting a {@link ReadableBrokenError} after {@link break} was called
329
+ * in cases where the {@link queue} is fully consumed and {@link ReadableImpl} is {@link closed}. This is just an
330
+ * ergonomic feature to avoid emitting an error in our iteration when we don't have to.
331
+ */
332
+ brokenWithValuesLeftToRead = false;
333
+ /**
334
+ * A list of values that have been pushed to the {@link ReadableImpl} but not yet emitted to the user.
335
+ */
336
+ queue = [];
337
+ /**
338
+ * Used by methods in the class to signal to the iterator that it
339
+ * should check for the next value.
340
+ */
341
+ next = null;
342
+ /**
343
+ * Consumes the {@link Readable} and returns an {@link AsyncIterator} that can be used
344
+ * to iterate over the values in the {@link Readable}.
345
+ */
346
+ [Symbol.asyncIterator]() {
347
+ if (this.locked) {
348
+ throw new TypeError("Readable is already locked");
349
+ }
350
+ this.locked = true;
351
+ let didSignalBreak = false;
352
+ return {
353
+ next: async () => {
354
+ if (didSignalBreak) {
355
+ return {
356
+ done: true,
357
+ value: void 0
358
+ };
359
+ }
360
+ while (this.queue.length === 0) {
361
+ if (this.closed && !this.brokenWithValuesLeftToRead) {
362
+ return {
363
+ done: true,
364
+ value: void 0
365
+ };
366
+ }
367
+ if (this.broken) {
368
+ didSignalBreak = true;
369
+ return {
370
+ done: false,
371
+ value: Err(ReadableBrokenError)
372
+ };
373
+ }
374
+ if (!this.next) {
375
+ this.next = createPromiseWithResolvers();
376
+ }
377
+ await this.next.promise;
378
+ this.next = null;
379
+ }
380
+ const value = this.queue.shift();
381
+ return { done: false, value };
382
+ },
383
+ return: async () => {
384
+ this.break();
385
+ return { done: true, value: void 0 };
386
+ }
387
+ };
388
+ }
389
+ /**
390
+ * Collects all the values from the {@link Readable} into an array.
391
+ *
392
+ * @see {@link Readable}'s typedoc for more information
393
+ */
394
+ async collect() {
395
+ const array = [];
396
+ for await (const value of this) {
397
+ array.push(value);
398
+ }
399
+ return array;
400
+ }
401
+ /**
402
+ * Breaks the {@link Readable} and signals an error to any iterators waiting for the next value.
403
+ *
404
+ * @see {@link Readable}'s typedoc for more information
405
+ */
406
+ break() {
407
+ if (this.broken) {
408
+ return;
409
+ }
410
+ this.locked = true;
411
+ this.broken = true;
412
+ this.brokenWithValuesLeftToRead = this.queue.length > 0;
413
+ this.queue.length = 0;
414
+ this.next?.resolve();
415
+ }
416
+ /**
417
+ * Whether the {@link Readable} is readable.
418
+ *
419
+ * @see {@link Readable}'s typedoc for more information
420
+ */
421
+ isReadable() {
422
+ return !this.locked && !this.broken;
423
+ }
424
+ /**
425
+ * Pushes a value to be read.
426
+ */
427
+ _pushValue(value) {
428
+ if (this.broken) {
429
+ return;
430
+ }
431
+ if (this.closed) {
432
+ throw new Error("Cannot push to closed Readable");
433
+ }
434
+ this.queue.push(value);
435
+ this.next?.resolve();
436
+ }
437
+ /**
438
+ * Triggers the close of the {@link Readable}. Make sure to push all remaining
439
+ * values before calling this method.
440
+ */
441
+ _triggerClose() {
442
+ if (this.closed) {
443
+ throw new Error("Unexpected closing multiple times");
444
+ }
445
+ this.closed = true;
446
+ this.next?.resolve();
447
+ }
448
+ /**
449
+ * @internal meant for use within river, not exposed as a public API
450
+ */
451
+ _hasValuesInQueue() {
452
+ return this.queue.length > 0;
453
+ }
454
+ /**
455
+ * Whether the {@link Readable} is closed.
456
+ */
457
+ isClosed() {
458
+ return this.closed;
459
+ }
460
+ };
461
+ var WritableImpl = class {
462
+ /**
463
+ * Passed via constructor to pass on calls to {@link write}
464
+ */
465
+ writeCb;
466
+ /**
467
+ * Passed via constructor to pass on calls to {@link close}
468
+ */
469
+ closeCb;
470
+ /**
471
+ * Whether {@link close} was called, and {@link Writable} is not writable anymore.
472
+ */
473
+ closed = false;
474
+ constructor(callbacks) {
475
+ this.writeCb = callbacks.writeCb;
476
+ this.closeCb = callbacks.closeCb;
477
+ }
478
+ write(value) {
479
+ if (this.closed) {
480
+ throw new Error("Cannot write to closed Writable");
481
+ }
482
+ this.writeCb(value);
483
+ }
484
+ isWritable() {
485
+ return !this.closed;
486
+ }
487
+ close(value) {
488
+ if (this.closed) {
489
+ return;
490
+ }
491
+ if (value !== void 0) {
492
+ this.writeCb(value);
493
+ }
494
+ this.closed = true;
495
+ this.writeCb = () => void 0;
496
+ this.closeCb();
497
+ this.closeCb = () => void 0;
498
+ }
499
+ /**
500
+ * @internal meant for use within river, not exposed as a public API
501
+ */
502
+ isClosed() {
503
+ return this.closed;
504
+ }
505
+ };
506
+
507
+ // tracing/index.ts
508
+ var import_api = require("@opentelemetry/api");
509
+
510
+ // router/errors.ts
511
+ var import_typebox3 = require("@sinclair/typebox");
512
+ var UNCAUGHT_ERROR_CODE = "UNCAUGHT_ERROR";
513
+ var UNEXPECTED_DISCONNECT_CODE = "UNEXPECTED_DISCONNECT";
514
+ var INVALID_REQUEST_CODE = "INVALID_REQUEST";
515
+ var CANCEL_CODE = "CANCEL";
516
+ var ErrResultSchema = (t) => import_typebox3.Type.Object({
517
+ ok: import_typebox3.Type.Literal(false),
518
+ payload: t
519
+ });
520
+ var ValidationErrorDetails = import_typebox3.Type.Object({
521
+ path: import_typebox3.Type.String(),
522
+ message: import_typebox3.Type.String()
523
+ });
524
+ var ValidationErrors = import_typebox3.Type.Array(ValidationErrorDetails);
525
+ var CancelErrorSchema = import_typebox3.Type.Object({
526
+ code: import_typebox3.Type.Literal(CANCEL_CODE),
527
+ message: import_typebox3.Type.String()
528
+ });
529
+ var CancelResultSchema = ErrResultSchema(CancelErrorSchema);
530
+ var ReaderErrorSchema = import_typebox3.Type.Union([
531
+ import_typebox3.Type.Object({
532
+ code: import_typebox3.Type.Literal(UNCAUGHT_ERROR_CODE),
533
+ message: import_typebox3.Type.String()
534
+ }),
535
+ import_typebox3.Type.Object({
536
+ code: import_typebox3.Type.Literal(UNEXPECTED_DISCONNECT_CODE),
537
+ message: import_typebox3.Type.String()
538
+ }),
539
+ import_typebox3.Type.Object({
540
+ code: import_typebox3.Type.Literal(INVALID_REQUEST_CODE),
541
+ message: import_typebox3.Type.String(),
542
+ extras: import_typebox3.Type.Optional(
543
+ import_typebox3.Type.Object({
544
+ firstValidationErrors: import_typebox3.Type.Array(ValidationErrorDetails),
545
+ totalErrors: import_typebox3.Type.Number()
546
+ })
547
+ )
548
+ }),
549
+ CancelErrorSchema
550
+ ]);
551
+ var ReaderErrorResultSchema = ErrResultSchema(ReaderErrorSchema);
552
+
553
+ // transport/stringifyError.ts
554
+ function coerceErrorString(err) {
555
+ if (err instanceof Error) {
556
+ return err.message || "unknown reason";
557
+ }
558
+ return `[coerced to error] ${String(err)}`;
559
+ }
560
+
561
+ // router/handshake.ts
562
+ function createClientHandshakeOptions(schema, construct) {
563
+ return { schema, construct };
564
+ }
565
+ function createServerHandshakeOptions(schema, validate) {
566
+ return { schema, validate };
567
+ }
568
+
569
+ // package.json
570
+ var version = "0.216.0";
571
+
572
+ // tracing/index.ts
573
+ function getPropagationContext(ctx) {
574
+ const tracing = {
575
+ traceparent: "",
576
+ tracestate: ""
577
+ };
578
+ import_api.propagation.inject(ctx, tracing);
579
+ return tracing;
580
+ }
581
+ function createProcTelemetryInfo(tracer, session, kind, serviceName, procedureName, streamId) {
582
+ const baseCtx = import_api.context.active();
583
+ const span = tracer.startSpan(
584
+ `river.client.${serviceName}.${procedureName}`,
585
+ {
586
+ attributes: {
587
+ component: "river",
588
+ "river.method.kind": kind,
589
+ "river.method.service": serviceName,
590
+ "river.method.name": procedureName,
591
+ "river.streamId": streamId,
592
+ "span.kind": "client"
593
+ },
594
+ links: [{ context: session.telemetry.span.spanContext() }],
595
+ kind: import_api.SpanKind.CLIENT
596
+ },
597
+ baseCtx
598
+ );
599
+ const ctx = import_api.trace.setSpan(baseCtx, span);
600
+ const metadata = {
601
+ ...session.loggingMetadata,
602
+ transportMessage: {
603
+ procedureName,
604
+ serviceName
605
+ }
606
+ };
607
+ if (span.isRecording()) {
608
+ metadata.telemetry = {
609
+ traceId: span.spanContext().traceId,
610
+ spanId: span.spanContext().spanId
611
+ };
612
+ }
613
+ session.log?.info(`invoked ${serviceName}.${procedureName}`, metadata);
614
+ return { span, ctx };
615
+ }
616
+ function createHandlerSpan(tracer, session, kind, serviceName, procedureName, streamId, tracing, fn) {
617
+ const ctx = tracing ? import_api.propagation.extract(import_api.context.active(), tracing) : import_api.context.active();
618
+ return tracer.startActiveSpan(
619
+ `river.server.${serviceName}.${procedureName}`,
620
+ {
621
+ attributes: {
622
+ component: "river",
623
+ "river.method.kind": kind,
624
+ "river.method.service": serviceName,
625
+ "river.method.name": procedureName,
626
+ "river.streamId": streamId,
627
+ "span.kind": "server"
628
+ },
629
+ links: [{ context: session.telemetry.span.spanContext() }],
630
+ kind: import_api.SpanKind.SERVER
631
+ },
632
+ ctx,
633
+ fn
634
+ );
635
+ }
636
+ function recordRiverError(span, error) {
637
+ span.setStatus({
638
+ code: import_api.SpanStatusCode.ERROR,
639
+ message: error.message
640
+ });
641
+ span.setAttributes({
642
+ "river.error_code": error.code,
643
+ "river.error_message": error.message
644
+ });
645
+ }
646
+ function getTracer() {
647
+ return import_api.trace.getTracer("river", version);
648
+ }
649
+
650
+ // protobuf/errors.ts
651
+ var RiverErrorCode = /* @__PURE__ */ ((RiverErrorCode2) => {
652
+ RiverErrorCode2["OK"] = "OK";
653
+ RiverErrorCode2["CANCELED"] = "CANCELED";
654
+ RiverErrorCode2["UNKNOWN"] = "UNKNOWN";
655
+ RiverErrorCode2["INVALID_ARGUMENT"] = "INVALID_ARGUMENT";
656
+ RiverErrorCode2["DEADLINE_EXCEEDED"] = "DEADLINE_EXCEEDED";
657
+ RiverErrorCode2["NOT_FOUND"] = "NOT_FOUND";
658
+ RiverErrorCode2["ALREADY_EXISTS"] = "ALREADY_EXISTS";
659
+ RiverErrorCode2["PERMISSION_DENIED"] = "PERMISSION_DENIED";
660
+ RiverErrorCode2["RESOURCE_EXHAUSTED"] = "RESOURCE_EXHAUSTED";
661
+ RiverErrorCode2["FAILED_PRECONDITION"] = "FAILED_PRECONDITION";
662
+ RiverErrorCode2["ABORTED"] = "ABORTED";
663
+ RiverErrorCode2["OUT_OF_RANGE"] = "OUT_OF_RANGE";
664
+ RiverErrorCode2["UNIMPLEMENTED"] = "UNIMPLEMENTED";
665
+ RiverErrorCode2["INTERNAL"] = "INTERNAL";
666
+ RiverErrorCode2["UNAVAILABLE"] = "UNAVAILABLE";
667
+ RiverErrorCode2["DATA_LOSS"] = "DATA_LOSS";
668
+ RiverErrorCode2["UNAUTHENTICATED"] = "UNAUTHENTICATED";
669
+ return RiverErrorCode2;
670
+ })(RiverErrorCode || {});
671
+ var riverErrorCodeSet = new Set(Object.values(RiverErrorCode));
672
+ var protocolErrorCodeSet = /* @__PURE__ */ new Set([
673
+ CANCEL_CODE,
674
+ INVALID_REQUEST_CODE,
675
+ UNCAUGHT_ERROR_CODE,
676
+ UNEXPECTED_DISCONNECT_CODE
677
+ ]);
678
+ function isRiverError(value) {
679
+ if (!(typeof value === "object" && value !== null)) {
680
+ return false;
681
+ }
682
+ const candidate = value;
683
+ return isRiverErrorCode(candidate.code) && typeof candidate.message === "string";
684
+ }
685
+ function isProtocolError(value) {
686
+ if (!(typeof value === "object" && value !== null)) {
687
+ return false;
688
+ }
689
+ const candidate = value;
690
+ return isProtocolErrorCode(candidate.code) && typeof candidate.message === "string";
691
+ }
692
+ function isClientError(value) {
693
+ return isRiverError(value) || isProtocolError(value);
694
+ }
695
+ function isSerializedClientErrorResult(value) {
696
+ return isErrResultWithPayload(value, isClientError);
697
+ }
698
+ function isSerializedProtocolErrorResult(value) {
699
+ return isErrResultWithPayload(value, isProtocolError);
700
+ }
701
+ function isRiverErrorCode(value) {
702
+ return typeof value === "string" && riverErrorCodeSet.has(value);
703
+ }
704
+ function isProtocolErrorCode(value) {
705
+ return typeof value === "string" && protocolErrorCodeSet.has(value);
706
+ }
707
+ function isErrResultWithPayload(value, predicate) {
708
+ if (!(typeof value === "object" && value !== null)) {
709
+ return false;
710
+ }
711
+ const candidate = value;
712
+ return candidate.ok === false && predicate(candidate.payload);
713
+ }
714
+
715
+ // protobuf/shared.ts
716
+ var import_protobuf2 = require("@bufbuild/protobuf");
717
+ var EMPTY_PROTO_BYTES = new Uint8Array(0);
718
+ function methodKindToProcType(methodKind) {
719
+ switch (methodKind) {
720
+ case "unary":
721
+ return "rpc";
722
+ case "server_streaming":
723
+ return "subscription";
724
+ case "client_streaming":
725
+ return "upload";
726
+ case "bidi_streaming":
727
+ return "stream";
728
+ }
729
+ }
730
+ function methodKey(serviceName, methodName) {
731
+ return `${serviceName}/${methodName}`;
732
+ }
733
+ function encodeMessageBytes(schema, message) {
734
+ return (0, import_protobuf2.toBinary)(schema, (0, import_protobuf2.create)(schema, message));
735
+ }
736
+ function decodeMessageBytes(schema, payload) {
737
+ return (0, import_protobuf2.fromBinary)(schema, payload);
738
+ }
739
+
740
+ // protobuf/client.ts
741
+ var defaultClientOptions = {
742
+ connectOnInvoke: true,
743
+ eagerlyConnect: true
744
+ };
745
+ function createClient(service, transport, serverId, providedClientOptions = {}) {
746
+ if (providedClientOptions.handshakeOptions) {
747
+ transport.extendHandshake(providedClientOptions.handshakeOptions);
748
+ }
749
+ const clientOptions = { ...defaultClientOptions, ...providedClientOptions };
750
+ if (clientOptions.eagerlyConnect) {
751
+ transport.connect(serverId);
752
+ }
753
+ const client = {};
754
+ for (const methodName of Object.keys(service.method)) {
755
+ const method = service.method[methodName];
756
+ client[methodName] = createMethodCaller(
757
+ service,
758
+ method,
759
+ transport,
760
+ serverId,
761
+ clientOptions
762
+ );
763
+ }
764
+ return client;
765
+ }
766
+ function createMethodCaller(service, method, transport, serverId, clientOptions) {
767
+ switch (method.methodKind) {
768
+ case "unary":
769
+ return ((request, options) => {
770
+ if (transport.getStatus() === "closed") {
771
+ return Promise.resolve(
772
+ Err({
773
+ code: UNEXPECTED_DISCONNECT_CODE,
774
+ message: "transport is closed"
775
+ })
776
+ );
777
+ }
778
+ connectOnInvokeIfNeeded(clientOptions, transport, serverId);
779
+ const { resReadable } = startMethodCall(
780
+ service,
781
+ method,
782
+ transport,
783
+ serverId,
784
+ encodeMessageBytes(method.input, request),
785
+ true,
786
+ options?.signal
787
+ );
788
+ return getSingleMessage(resReadable, transport.log);
789
+ });
790
+ case "server_streaming":
791
+ return ((request, options) => {
792
+ if (transport.getStatus() === "closed") {
793
+ return createPreClosedReadable({
794
+ code: UNEXPECTED_DISCONNECT_CODE,
795
+ message: "transport is closed"
796
+ });
797
+ }
798
+ connectOnInvokeIfNeeded(clientOptions, transport, serverId);
799
+ return startMethodCall(
800
+ service,
801
+ method,
802
+ transport,
803
+ serverId,
804
+ encodeMessageBytes(method.input, request),
805
+ true,
806
+ options?.signal
807
+ ).resReadable;
808
+ });
809
+ case "client_streaming":
810
+ return ((options) => {
811
+ if (transport.getStatus() === "closed") {
812
+ return createPreClosedClientStreamingCall();
813
+ }
814
+ connectOnInvokeIfNeeded(clientOptions, transport, serverId);
815
+ const { reqWritable, resReadable } = startMethodCall(
816
+ service,
817
+ method,
818
+ transport,
819
+ serverId,
820
+ EMPTY_PROTO_BYTES,
821
+ false,
822
+ options?.signal
823
+ );
824
+ let didFinalize = false;
825
+ return {
826
+ reqWritable,
827
+ finalize: () => {
828
+ if (didFinalize) {
829
+ throw new Error("client streaming call already finalized");
830
+ }
831
+ didFinalize = true;
832
+ if (!reqWritable.isClosed()) {
833
+ reqWritable.close();
834
+ }
835
+ return getSingleMessage(resReadable, transport.log);
836
+ }
837
+ };
838
+ });
839
+ case "bidi_streaming":
840
+ return ((options) => {
841
+ if (transport.getStatus() === "closed") {
842
+ return createPreClosedBiDiStreamingCall();
843
+ }
844
+ connectOnInvokeIfNeeded(clientOptions, transport, serverId);
845
+ return startMethodCall(
846
+ service,
847
+ method,
848
+ transport,
849
+ serverId,
850
+ EMPTY_PROTO_BYTES,
851
+ false,
852
+ options?.signal
853
+ );
854
+ });
855
+ }
856
+ }
857
+ function connectOnInvokeIfNeeded(clientOptions, transport, serverId) {
858
+ if (clientOptions.connectOnInvoke && !transport.sessions.has(serverId)) {
859
+ transport.connect(serverId);
860
+ }
861
+ }
862
+ function startMethodCall(service, method, transport, serverId, initialPayload, procClosesWithInit, abortSignal) {
863
+ const session = transport.sessions.get(serverId) ?? transport.createUnconnectedSession(serverId);
864
+ const sessionScopedSend = transport.getSessionBoundSendFn(
865
+ serverId,
866
+ session.id
867
+ );
868
+ const streamId = generateId();
869
+ const { span, ctx } = createProcTelemetryInfo(
870
+ transport.tracer,
871
+ session,
872
+ methodKindToProcType(method.methodKind),
873
+ service.typeName,
874
+ method.name,
875
+ streamId
876
+ );
877
+ let cleanClose = true;
878
+ const reqWritable = new WritableImpl({
879
+ writeCb: (value) => {
880
+ sessionScopedSend({
881
+ streamId,
882
+ payload: encodeMessageBytes(method.input, value),
883
+ controlFlags: 0
884
+ });
885
+ },
886
+ closeCb: () => {
887
+ span.addEvent("reqWritable closed");
888
+ if (!procClosesWithInit && cleanClose) {
889
+ sessionScopedSend(closeStreamMessage(streamId));
890
+ }
891
+ if (resReadable.isClosed()) {
892
+ cleanup();
893
+ }
894
+ }
895
+ });
896
+ const resReadable = new ReadableImpl();
897
+ const closeReadable = () => {
898
+ if (resReadable.isClosed()) {
899
+ return;
900
+ }
901
+ resReadable._triggerClose();
902
+ span.addEvent("resReadable closed");
903
+ if (reqWritable.isClosed()) {
904
+ cleanup();
905
+ }
906
+ };
907
+ function cleanup() {
908
+ transport.removeEventListener("message", onMessage);
909
+ transport.removeEventListener("sessionStatus", onSessionStatus);
910
+ abortSignal?.removeEventListener("abort", onClientCancel);
911
+ span.end();
912
+ }
913
+ function pushResponseError(error) {
914
+ if (!resReadable.isClosed()) {
915
+ resReadable._pushValue(Err(error));
916
+ closeReadable();
917
+ }
918
+ reqWritable.close();
919
+ }
920
+ function onClientCancel() {
921
+ if (resReadable.isClosed() && reqWritable.isClosed()) {
922
+ return;
923
+ }
924
+ span.addEvent("sending cancel");
925
+ cleanClose = false;
926
+ const error = {
927
+ code: CANCEL_CODE,
928
+ message: "cancelled by client"
929
+ };
930
+ pushResponseError(error);
931
+ sessionScopedSend(cancelMessage(streamId, Err(error)));
932
+ }
933
+ function onMessage(msg) {
934
+ if (msg.streamId !== streamId) {
935
+ return;
936
+ }
937
+ if (msg.to !== transport.clientId) {
938
+ transport.log?.error("got stream message from unexpected client", {
939
+ clientId: transport.clientId,
940
+ transportMessage: msg
941
+ });
942
+ return;
943
+ }
944
+ if (isStreamCancel(msg.controlFlags)) {
945
+ cleanClose = false;
946
+ span.addEvent("received cancel");
947
+ const error = isSerializedClientErrorResult(msg.payload) ? msg.payload.payload : {
948
+ code: CANCEL_CODE,
949
+ message: "stream cancelled with invalid payload"
950
+ };
951
+ pushResponseError(error);
952
+ return;
953
+ }
954
+ if (resReadable.isClosed()) {
955
+ transport.log?.error("received message after response stream is closed", {
956
+ clientId: transport.clientId,
957
+ transportMessage: msg
958
+ });
959
+ return;
960
+ }
961
+ if (!import_value.Value.Check(ControlMessageCloseSchema, msg.payload)) {
962
+ if (msg.payload instanceof Uint8Array) {
963
+ try {
964
+ resReadable._pushValue(
965
+ Ok(
966
+ decodeMessageBytes(method.output, msg.payload)
967
+ )
968
+ );
969
+ } catch (err) {
970
+ pushResponseError({
971
+ code: INVALID_REQUEST_CODE,
972
+ message: "failed to decode protobuf response payload",
973
+ extras: { cause: err }
974
+ });
975
+ return;
976
+ }
977
+ } else if (isSerializedClientErrorResult(msg.payload)) {
978
+ resReadable._pushValue(msg.payload);
979
+ } else {
980
+ pushResponseError({
981
+ code: INVALID_REQUEST_CODE,
982
+ message: "received invalid protobuf response payload"
983
+ });
984
+ return;
985
+ }
986
+ }
987
+ if (isStreamClose(msg.controlFlags)) {
988
+ span.addEvent("received response close");
989
+ closeReadable();
990
+ }
991
+ }
992
+ function onSessionStatus(evt) {
993
+ if (evt.status !== "closing" || evt.session.to !== serverId || session.id !== evt.session.id) {
994
+ return;
995
+ }
996
+ cleanClose = false;
997
+ pushResponseError({
998
+ code: UNEXPECTED_DISCONNECT_CODE,
999
+ message: `${serverId} unexpectedly disconnected`
1000
+ });
1001
+ }
1002
+ abortSignal?.addEventListener("abort", onClientCancel);
1003
+ transport.addEventListener("message", onMessage);
1004
+ transport.addEventListener("sessionStatus", onSessionStatus);
1005
+ try {
1006
+ sessionScopedSend({
1007
+ streamId,
1008
+ serviceName: service.typeName,
1009
+ procedureName: method.name,
1010
+ tracing: getPropagationContext(ctx),
1011
+ payload: initialPayload,
1012
+ controlFlags: procClosesWithInit ? 2 /* StreamOpenBit */ | 8 /* StreamClosedBit */ : 2 /* StreamOpenBit */
1013
+ });
1014
+ } catch (err) {
1015
+ cleanup();
1016
+ throw err;
1017
+ }
1018
+ if (procClosesWithInit) {
1019
+ reqWritable.close();
1020
+ }
1021
+ return { reqWritable, resReadable };
1022
+ }
1023
+ function createPreClosedReadable(error) {
1024
+ const readable = new ReadableImpl();
1025
+ readable._pushValue(Err(error));
1026
+ readable._triggerClose();
1027
+ return readable;
1028
+ }
1029
+ function createPreClosedWritable() {
1030
+ const writable = new WritableImpl({
1031
+ writeCb: () => void 0,
1032
+ closeCb: () => void 0
1033
+ });
1034
+ writable.close();
1035
+ return writable;
1036
+ }
1037
+ function createPreClosedClientStreamingCall() {
1038
+ return {
1039
+ reqWritable: createPreClosedWritable(),
1040
+ finalize: () => Promise.resolve(
1041
+ Err({
1042
+ code: UNEXPECTED_DISCONNECT_CODE,
1043
+ message: "transport is closed"
1044
+ })
1045
+ )
1046
+ };
1047
+ }
1048
+ function createPreClosedBiDiStreamingCall() {
1049
+ return {
1050
+ reqWritable: createPreClosedWritable(),
1051
+ resReadable: createPreClosedReadable({
1052
+ code: UNEXPECTED_DISCONNECT_CODE,
1053
+ message: "transport is closed"
1054
+ })
1055
+ };
1056
+ }
1057
+ async function getSingleMessage(resReadable, log) {
1058
+ const ret = await resReadable.collect();
1059
+ if (ret.length === 0) {
1060
+ return Err({
1061
+ code: INVALID_REQUEST_CODE,
1062
+ message: "expected single response from server, got none"
1063
+ });
1064
+ }
1065
+ if (ret.length > 1) {
1066
+ log?.error("expected single protobuf response from server, got multiple");
1067
+ }
1068
+ const first = ret[0];
1069
+ if (!first.ok) {
1070
+ if (first.payload.code === ReadableBrokenError.code) {
1071
+ return Err({
1072
+ code: UNEXPECTED_DISCONNECT_CODE,
1073
+ message: first.payload.message
1074
+ });
1075
+ }
1076
+ return Err(first.payload);
1077
+ }
1078
+ return first;
1079
+ }
1080
+
1081
+ // protobuf/handshake.ts
1082
+ var import_typebox4 = require("@sinclair/typebox");
1083
+ var HandshakeBytesSchema = import_typebox4.Type.Uint8Array();
1084
+ function createClientHandshakeOptions2(schema, construct) {
1085
+ return createClientHandshakeOptions(
1086
+ HandshakeBytesSchema,
1087
+ async () => {
1088
+ const metadata = await construct();
1089
+ return encodeMessageBytes(schema, metadata);
1090
+ }
1091
+ );
1092
+ }
1093
+ function createServerHandshakeOptions2(schema, validate) {
1094
+ return createServerHandshakeOptions(
1095
+ HandshakeBytesSchema,
1096
+ async (metadata, previousParsedMetadata) => {
1097
+ let decoded;
1098
+ try {
1099
+ decoded = decodeMessageBytes(schema, metadata);
1100
+ } catch {
1101
+ return "REJECTED_BY_CUSTOM_HANDLER";
1102
+ }
1103
+ return await validate(decoded, previousParsedMetadata);
1104
+ }
1105
+ );
1106
+ }
1107
+
1108
+ // protobuf/service.ts
1109
+ function buildMethodMap(descriptor, handlers) {
1110
+ const methods = /* @__PURE__ */ new Map();
1111
+ const typedMethods = descriptor.method;
1112
+ for (const methodName of Object.keys(handlers)) {
1113
+ const handler = handlers[methodName];
1114
+ if (handler === void 0) {
1115
+ continue;
1116
+ }
1117
+ const method = typedMethods[methodName];
1118
+ if (!method) {
1119
+ throw new Error(`unknown method ${methodName} on ${descriptor.typeName}`);
1120
+ }
1121
+ methods.set(method.name, {
1122
+ service: descriptor,
1123
+ method,
1124
+ impl: handler
1125
+ });
1126
+ }
1127
+ return methods;
1128
+ }
1129
+ var ProtoServiceScaffold = class {
1130
+ descriptor;
1131
+ config;
1132
+ constructor(descriptor, config) {
1133
+ this.descriptor = descriptor;
1134
+ this.config = config;
1135
+ }
1136
+ /**
1137
+ * Type-check a partial set of handler implementations against this
1138
+ * service's types. Returns the input unchanged -- this is purely a
1139
+ * type-level helper for splitting handlers across files.
1140
+ *
1141
+ * @param handlers - A partial set of method implementations.
1142
+ */
1143
+ procedures(handlers) {
1144
+ return handlers;
1145
+ }
1146
+ /**
1147
+ * Finalize the scaffold into a service definition. Provide all handlers
1148
+ * here (or spread in handler objects from {@link procedures}).
1149
+ *
1150
+ * @param handlers - Method implementations (missing methods return
1151
+ * UNIMPLEMENTED at runtime).
1152
+ */
1153
+ finalize(handlers) {
1154
+ return createProtoService().define(
1155
+ this.descriptor,
1156
+ this.config,
1157
+ handlers
1158
+ );
1159
+ }
1160
+ };
1161
+ function createProtoService() {
1162
+ return class ProtoServiceSchema {
1163
+ descriptor;
1164
+ methods;
1165
+ /** @internal */
1166
+ initializeStateFn;
1167
+ constructor(descriptor, initializeStateFn, methods) {
1168
+ this.descriptor = descriptor;
1169
+ this.initializeStateFn = initializeStateFn;
1170
+ this.methods = methods;
1171
+ }
1172
+ /**
1173
+ * Create a live service instance with initialized state.
1174
+ *
1175
+ * @param ctx - The user-provided context, passed to `initializeState`.
1176
+ */
1177
+ instantiate(ctx) {
1178
+ const state = this.initializeStateFn ? this.initializeStateFn(ctx) : {};
1179
+ return Object.freeze({
1180
+ descriptor: this.descriptor,
1181
+ state,
1182
+ methods: this.methods,
1183
+ async [Symbol.asyncDispose]() {
1184
+ await state[Symbol.asyncDispose]?.();
1185
+ state[Symbol.dispose]?.();
1186
+ }
1187
+ });
1188
+ }
1189
+ static define(descriptor, configOrHandlers, maybeHandlers) {
1190
+ let initializeStateFn;
1191
+ let handlers;
1192
+ if ("initializeState" in configOrHandlers && typeof configOrHandlers.initializeState === "function") {
1193
+ if (!maybeHandlers) {
1194
+ throw new Error("expected handlers as third argument");
1195
+ }
1196
+ initializeStateFn = configOrHandlers.initializeState;
1197
+ handlers = maybeHandlers;
1198
+ } else {
1199
+ initializeStateFn = void 0;
1200
+ handlers = configOrHandlers;
1201
+ }
1202
+ return new ProtoServiceSchema(
1203
+ descriptor,
1204
+ initializeStateFn,
1205
+ buildMethodMap(descriptor, handlers)
1206
+ );
1207
+ }
1208
+ /**
1209
+ * Create a scaffold for splitting handler implementations across files.
1210
+ *
1211
+ * @param descriptor - The generated protobuf service descriptor.
1212
+ * @param config - Service configuration including `initializeState`.
1213
+ */
1214
+ static scaffold(descriptor, config) {
1215
+ return new ProtoServiceScaffold(
1216
+ descriptor,
1217
+ config
1218
+ );
1219
+ }
1220
+ };
1221
+ }
1222
+
1223
+ // protobuf/server.ts
1224
+ var import_value2 = require("@sinclair/typebox/value");
1225
+ var import_api2 = require("@opentelemetry/api");
1226
+ var ProtobufServer = class {
1227
+ streams;
1228
+ transport;
1229
+ methods;
1230
+ serviceInstances;
1231
+ userContext;
1232
+ log;
1233
+ middlewares;
1234
+ serverCancelledStreams;
1235
+ maxCancelledStreamTombstonesPerSession;
1236
+ unregisterTransportListeners;
1237
+ constructor(transport, services, options = {}) {
1238
+ this.transport = transport;
1239
+ this.log = transport.log;
1240
+ this.middlewares = options.middlewares ?? [];
1241
+ this.maxCancelledStreamTombstonesPerSession = options.maxCancelledStreamTombstonesPerSession ?? 200;
1242
+ this.serverCancelledStreams = /* @__PURE__ */ new Map();
1243
+ this.streams = /* @__PURE__ */ new Map();
1244
+ this.userContext = options.extendedContext ?? {};
1245
+ this.methods = /* @__PURE__ */ new Map();
1246
+ this.serviceInstances = /* @__PURE__ */ new Map();
1247
+ for (const svc of services) {
1248
+ if (this.serviceInstances.has(svc.descriptor.typeName)) {
1249
+ throw new Error(
1250
+ `duplicate protobuf service registration for ${svc.descriptor.typeName}`
1251
+ );
1252
+ }
1253
+ const instance = svc.instantiate(this.userContext);
1254
+ this.serviceInstances.set(svc.descriptor.typeName, instance);
1255
+ for (const [, reg] of instance.methods) {
1256
+ this.methods.set(
1257
+ methodKey(svc.descriptor.typeName, reg.method.name),
1258
+ reg
1259
+ );
1260
+ }
1261
+ }
1262
+ if (options.handshakeOptions) {
1263
+ transport.extendHandshake(options.handshakeOptions);
1264
+ }
1265
+ const handleCreatingNewStreams = (message) => {
1266
+ if (message.to !== this.transport.clientId) {
1267
+ this.log?.info(
1268
+ `got msg with destination that isn't this server, ignoring`,
1269
+ {
1270
+ clientId: this.transport.clientId,
1271
+ transportMessage: message
1272
+ }
1273
+ );
1274
+ return;
1275
+ }
1276
+ const stream = this.streams.get(message.streamId);
1277
+ if (stream) {
1278
+ stream.handleMsg(message);
1279
+ return;
1280
+ }
1281
+ if (this.serverCancelledStreams.get(message.from)?.has(message.streamId)) {
1282
+ return;
1283
+ }
1284
+ const newStreamProps = this.validateNewProcStream(message);
1285
+ if (!newStreamProps) {
1286
+ return;
1287
+ }
1288
+ createHandlerSpan(
1289
+ transport.tracer,
1290
+ newStreamProps.initialSession,
1291
+ methodKindToProcType(newStreamProps.method.methodKind),
1292
+ newStreamProps.service.typeName,
1293
+ newStreamProps.method.name,
1294
+ newStreamProps.streamId,
1295
+ newStreamProps.tracingCtx,
1296
+ (span) => {
1297
+ this.createNewProcStream(span, newStreamProps);
1298
+ }
1299
+ );
1300
+ };
1301
+ const handleSessionStatus = (evt) => {
1302
+ if (evt.status !== "closing") {
1303
+ return;
1304
+ }
1305
+ const disconnectedClientId = evt.session.to;
1306
+ this.log?.info(
1307
+ `got session disconnect from ${disconnectedClientId}, cleaning up protobuf streams`,
1308
+ evt.session.loggingMetadata
1309
+ );
1310
+ for (const stream of this.streams.values()) {
1311
+ if (stream.from === disconnectedClientId) {
1312
+ stream.handleSessionDisconnect();
1313
+ }
1314
+ }
1315
+ this.serverCancelledStreams.delete(disconnectedClientId);
1316
+ };
1317
+ const handleTransportStatus = (evt) => {
1318
+ if (evt.status === "closed") {
1319
+ this.unregisterTransportListeners();
1320
+ }
1321
+ };
1322
+ this.unregisterTransportListeners = () => {
1323
+ this.transport.removeEventListener("message", handleCreatingNewStreams);
1324
+ this.transport.removeEventListener("sessionStatus", handleSessionStatus);
1325
+ this.transport.removeEventListener(
1326
+ "transportStatus",
1327
+ handleTransportStatus
1328
+ );
1329
+ };
1330
+ this.transport.addEventListener("message", handleCreatingNewStreams);
1331
+ this.transport.addEventListener("sessionStatus", handleSessionStatus);
1332
+ this.transport.addEventListener("transportStatus", handleTransportStatus);
1333
+ }
1334
+ async close() {
1335
+ this.unregisterTransportListeners();
1336
+ for (const instance of this.serviceInstances.values()) {
1337
+ await instance[Symbol.asyncDispose]();
1338
+ }
1339
+ const ctx = this.userContext;
1340
+ if (ctx[Symbol.asyncDispose]) {
1341
+ await ctx[Symbol.asyncDispose]?.();
1342
+ } else if (ctx[Symbol.dispose]) {
1343
+ ctx[Symbol.dispose]?.();
1344
+ } else {
1345
+ for (const value of Object.values(ctx)) {
1346
+ if (value && typeof value === "object") {
1347
+ const v = value;
1348
+ if (v[Symbol.asyncDispose]) {
1349
+ await v[Symbol.asyncDispose]?.();
1350
+ } else if (v[Symbol.dispose]) {
1351
+ v[Symbol.dispose]?.();
1352
+ }
1353
+ }
1354
+ }
1355
+ }
1356
+ }
1357
+ createNewProcStream(span, props) {
1358
+ const {
1359
+ streamId,
1360
+ service,
1361
+ method,
1362
+ impl,
1363
+ serviceContext,
1364
+ serviceState,
1365
+ sessionMetadata,
1366
+ initialSession,
1367
+ initialRequest,
1368
+ closeRequestOnStart
1369
+ } = props;
1370
+ const { to: from, loggingMetadata, id: sessionId } = initialSession;
1371
+ loggingMetadata.telemetry = {
1372
+ traceId: span.spanContext().traceId,
1373
+ spanId: span.spanContext().spanId
1374
+ };
1375
+ let cleanClose = true;
1376
+ const finishedController = new AbortController();
1377
+ const sessionScopedSend = this.transport.getSessionBoundSendFn(
1378
+ from,
1379
+ sessionId
1380
+ );
1381
+ const deferredCleanups = [];
1382
+ let cleanupsHaveRun = false;
1383
+ const runCleanupSafe = async (fn) => {
1384
+ try {
1385
+ await fn();
1386
+ } catch (err) {
1387
+ span.recordException(
1388
+ err instanceof Error ? err : new Error(String(err))
1389
+ );
1390
+ }
1391
+ };
1392
+ const deferCleanup = (fn) => {
1393
+ if (cleanupsHaveRun) {
1394
+ void runCleanupSafe(fn);
1395
+ return;
1396
+ }
1397
+ deferredCleanups.push(fn);
1398
+ };
1399
+ const runDeferredCleanups = async () => {
1400
+ if (deferredCleanups.length === 0) {
1401
+ cleanupsHaveRun = true;
1402
+ span.end();
1403
+ return;
1404
+ }
1405
+ const cleanupSpan = getTracer().startSpan(
1406
+ "river.cleanup",
1407
+ {},
1408
+ import_api2.trace.setSpan(import_api2.context.active(), span)
1409
+ );
1410
+ try {
1411
+ for (let fn = deferredCleanups.pop(); fn; fn = deferredCleanups.pop()) {
1412
+ await runCleanupSafe(fn);
1413
+ }
1414
+ } finally {
1415
+ cleanupsHaveRun = true;
1416
+ cleanupSpan.end();
1417
+ span.end();
1418
+ }
1419
+ };
1420
+ const cleanup = () => {
1421
+ finishedController.abort();
1422
+ this.streams.delete(streamId);
1423
+ void runDeferredCleanups();
1424
+ };
1425
+ const reqReadable = new ReadableImpl();
1426
+ const closeReadable = () => {
1427
+ if (reqReadable.isClosed()) {
1428
+ return;
1429
+ }
1430
+ reqReadable._triggerClose();
1431
+ if (resWritable.isClosed()) {
1432
+ cleanup();
1433
+ }
1434
+ };
1435
+ const procClosesWithResponse = method.methodKind === "unary" || method.methodKind === "client_streaming";
1436
+ const resWritable = new WritableImpl({
1437
+ writeCb: (response) => {
1438
+ const payload = response.ok ? encodeMessageBytes(method.output, response.payload) : Err(response.payload);
1439
+ if (!response.ok) {
1440
+ recordRiverError(span, response.payload);
1441
+ }
1442
+ sessionScopedSend({
1443
+ streamId,
1444
+ controlFlags: procClosesWithResponse ? 8 /* StreamClosedBit */ : 0,
1445
+ payload
1446
+ });
1447
+ if (procClosesWithResponse) {
1448
+ resWritable.close();
1449
+ }
1450
+ },
1451
+ closeCb: () => {
1452
+ if (!procClosesWithResponse && cleanClose) {
1453
+ sessionScopedSend(closeStreamMessage(streamId));
1454
+ }
1455
+ if (reqReadable.isClosed()) {
1456
+ cleanup();
1457
+ }
1458
+ }
1459
+ });
1460
+ const cancelStream = (error) => {
1461
+ this.cancelStream(from, sessionScopedSend, streamId, error);
1462
+ };
1463
+ const pushRequestError = (error) => {
1464
+ if (!reqReadable.isClosed()) {
1465
+ reqReadable._pushValue(Err(error));
1466
+ closeReadable();
1467
+ }
1468
+ resWritable.close();
1469
+ };
1470
+ const onServerCancel = (error) => {
1471
+ recordRiverError(span, error);
1472
+ if (reqReadable.isClosed() && resWritable.isClosed()) {
1473
+ return;
1474
+ }
1475
+ cleanClose = false;
1476
+ pushRequestError(error);
1477
+ cancelStream(error);
1478
+ };
1479
+ const onHandlerError = (err) => {
1480
+ const errorMsg = coerceErrorString(err);
1481
+ span.recordException(err instanceof Error ? err : new Error(errorMsg));
1482
+ this.log?.error(
1483
+ `${service.typeName}.${method.name} handler threw an uncaught error`,
1484
+ {
1485
+ ...loggingMetadata,
1486
+ transportMessage: {
1487
+ procedureName: method.name,
1488
+ serviceName: service.typeName
1489
+ },
1490
+ extras: {
1491
+ error: errorMsg,
1492
+ originalException: err
1493
+ },
1494
+ tags: ["uncaught-handler-error"]
1495
+ }
1496
+ );
1497
+ const error = {
1498
+ code: UNCAUGHT_ERROR_CODE,
1499
+ message: errorMsg
1500
+ };
1501
+ recordRiverError(span, error);
1502
+ if (reqReadable.isClosed() && resWritable.isClosed()) {
1503
+ return;
1504
+ }
1505
+ if (!resWritable.isClosed()) {
1506
+ resWritable.write(Err(error));
1507
+ if (!procClosesWithResponse) {
1508
+ resWritable.close();
1509
+ }
1510
+ }
1511
+ if (!reqReadable.isClosed()) {
1512
+ closeReadable();
1513
+ }
1514
+ };
1515
+ const onMessage = (msg) => {
1516
+ if (msg.from !== from) {
1517
+ this.log?.error("got stream message from unexpected client", {
1518
+ ...loggingMetadata,
1519
+ transportMessage: msg,
1520
+ tags: ["invariant-violation"]
1521
+ });
1522
+ return;
1523
+ }
1524
+ if (isStreamCancel(msg.controlFlags)) {
1525
+ const error = isSerializedProtocolErrorResult(
1526
+ msg.payload
1527
+ ) ? msg.payload.payload : {
1528
+ code: CANCEL_CODE,
1529
+ message: "stream cancelled, client sent invalid payload"
1530
+ };
1531
+ pushRequestError(error);
1532
+ return;
1533
+ }
1534
+ if (reqReadable.isClosed()) {
1535
+ this.log?.warn("received message after request stream is closed", {
1536
+ ...loggingMetadata,
1537
+ transportMessage: msg,
1538
+ tags: ["invalid-request"]
1539
+ });
1540
+ onServerCancel({
1541
+ code: INVALID_REQUEST_CODE,
1542
+ message: "received message after request stream is closed"
1543
+ });
1544
+ return;
1545
+ }
1546
+ if (msg.payload instanceof Uint8Array) {
1547
+ try {
1548
+ reqReadable._pushValue(
1549
+ Ok(decodeMessageBytes(method.input, msg.payload))
1550
+ );
1551
+ } catch {
1552
+ onServerCancel({
1553
+ code: INVALID_REQUEST_CODE,
1554
+ message: "failed to decode protobuf request payload"
1555
+ });
1556
+ return;
1557
+ }
1558
+ if (isStreamClose(msg.controlFlags)) {
1559
+ closeReadable();
1560
+ }
1561
+ return;
1562
+ }
1563
+ if (import_value2.Value.Check(ControlMessageCloseSchema, msg.payload) && isStreamClose(msg.controlFlags)) {
1564
+ closeReadable();
1565
+ return;
1566
+ }
1567
+ onServerCancel({
1568
+ code: INVALID_REQUEST_CODE,
1569
+ message: "received invalid protobuf request payload"
1570
+ });
1571
+ };
1572
+ const procStream = {
1573
+ from,
1574
+ streamId,
1575
+ service,
1576
+ method,
1577
+ handleMsg: onMessage,
1578
+ handleSessionDisconnect: () => {
1579
+ cleanClose = false;
1580
+ pushRequestError({
1581
+ code: UNEXPECTED_DISCONNECT_CODE,
1582
+ message: "client unexpectedly disconnected"
1583
+ });
1584
+ }
1585
+ };
1586
+ const handlerContext = {
1587
+ ...serviceContext,
1588
+ state: serviceState,
1589
+ from,
1590
+ sessionId,
1591
+ metadata: sessionMetadata,
1592
+ span,
1593
+ service,
1594
+ method,
1595
+ deferCleanup,
1596
+ cancel: (message) => {
1597
+ const error = {
1598
+ code: CANCEL_CODE,
1599
+ message: message ?? "cancelled by server procedure handler"
1600
+ };
1601
+ onServerCancel(error);
1602
+ return Err(error);
1603
+ },
1604
+ signal: finishedController.signal
1605
+ };
1606
+ const middlewareContext = {
1607
+ ...handlerContext,
1608
+ streamId,
1609
+ procedureName: method.name,
1610
+ serviceName: service.typeName
1611
+ };
1612
+ if (initialRequest !== null) {
1613
+ reqReadable._pushValue(Ok(initialRequest));
1614
+ }
1615
+ if (closeRequestOnStart) {
1616
+ closeReadable();
1617
+ }
1618
+ const handler = impl;
1619
+ const runProcedureHandler = async () => {
1620
+ try {
1621
+ switch (method.methodKind) {
1622
+ case "unary": {
1623
+ const response = await handler(
1624
+ requireInitialRequest(initialRequest, method),
1625
+ handlerContext
1626
+ );
1627
+ if (!resWritable.isClosed()) {
1628
+ resWritable.write(response);
1629
+ }
1630
+ break;
1631
+ }
1632
+ case "server_streaming":
1633
+ await handler({
1634
+ request: requireInitialRequest(initialRequest, method),
1635
+ ctx: handlerContext,
1636
+ resWritable
1637
+ });
1638
+ break;
1639
+ case "client_streaming": {
1640
+ const response = await handler({
1641
+ ctx: handlerContext,
1642
+ reqReadable
1643
+ });
1644
+ if (!resWritable.isClosed()) {
1645
+ resWritable.write(response);
1646
+ }
1647
+ break;
1648
+ }
1649
+ case "bidi_streaming":
1650
+ await handler({
1651
+ ctx: handlerContext,
1652
+ reqReadable,
1653
+ resWritable
1654
+ });
1655
+ break;
1656
+ }
1657
+ } catch (err) {
1658
+ onHandlerError(err);
1659
+ }
1660
+ };
1661
+ this.middlewares.reduceRight(
1662
+ (next, middleware) => {
1663
+ return () => {
1664
+ middleware({
1665
+ ctx: middlewareContext,
1666
+ reqInit: initialRequest,
1667
+ next
1668
+ });
1669
+ };
1670
+ },
1671
+ () => {
1672
+ void runProcedureHandler();
1673
+ }
1674
+ )();
1675
+ if (!finishedController.signal.aborted) {
1676
+ this.streams.set(streamId, procStream);
1677
+ }
1678
+ }
1679
+ validateNewProcStream(initMessage) {
1680
+ const session = this.transport.sessions.get(initMessage.from);
1681
+ if (!session) {
1682
+ this.log?.error(`couldn't find session for ${initMessage.from}`, {
1683
+ clientId: this.transport.clientId,
1684
+ transportMessage: initMessage,
1685
+ tags: ["invariant-violation"]
1686
+ });
1687
+ return null;
1688
+ }
1689
+ const sessionScopedSend = this.transport.getSessionBoundSendFn(
1690
+ initMessage.from,
1691
+ session.id
1692
+ );
1693
+ const sendCancel = (error) => {
1694
+ this.cancelStream(
1695
+ initMessage.from,
1696
+ sessionScopedSend,
1697
+ initMessage.streamId,
1698
+ error
1699
+ );
1700
+ };
1701
+ const sessionMetadata = this.transport.sessionHandshakeMetadata.get(
1702
+ session.to
1703
+ );
1704
+ if (!sessionMetadata) {
1705
+ sendCancel({
1706
+ code: UNCAUGHT_ERROR_CODE,
1707
+ message: `session doesn't have handshake metadata`
1708
+ });
1709
+ return null;
1710
+ }
1711
+ if (!isStreamOpen(initMessage.controlFlags)) {
1712
+ sendCancel({
1713
+ code: INVALID_REQUEST_CODE,
1714
+ message: `can't create a new procedure stream from a message without the stream open bit set`
1715
+ });
1716
+ return null;
1717
+ }
1718
+ if (!initMessage.serviceName) {
1719
+ sendCancel({
1720
+ code: INVALID_REQUEST_CODE,
1721
+ message: `missing service name in stream open message`
1722
+ });
1723
+ return null;
1724
+ }
1725
+ if (!initMessage.procedureName) {
1726
+ sendCancel({
1727
+ code: INVALID_REQUEST_CODE,
1728
+ message: `missing procedure name in stream open message`
1729
+ });
1730
+ return null;
1731
+ }
1732
+ const route = this.methods.get(
1733
+ methodKey(initMessage.serviceName, initMessage.procedureName)
1734
+ );
1735
+ if (!route) {
1736
+ sendCancel({
1737
+ code: "UNIMPLEMENTED" /* UNIMPLEMENTED */,
1738
+ message: `${initMessage.serviceName}.${initMessage.procedureName} is not implemented`
1739
+ });
1740
+ return null;
1741
+ }
1742
+ const serviceInstance = this.serviceInstances.get(initMessage.serviceName);
1743
+ let initialRequest = null;
1744
+ let closeRequestOnStart = false;
1745
+ if (route.method.methodKind === "unary" || route.method.methodKind === "server_streaming") {
1746
+ if (!(initMessage.payload instanceof Uint8Array)) {
1747
+ sendCancel({
1748
+ code: INVALID_REQUEST_CODE,
1749
+ message: "expected protobuf request payload in opening frame"
1750
+ });
1751
+ return null;
1752
+ }
1753
+ try {
1754
+ initialRequest = decodeMessageBytes(
1755
+ route.method.input,
1756
+ initMessage.payload
1757
+ );
1758
+ } catch {
1759
+ sendCancel({
1760
+ code: INVALID_REQUEST_CODE,
1761
+ message: "failed to decode protobuf request payload"
1762
+ });
1763
+ return null;
1764
+ }
1765
+ if (!isStreamClose(initMessage.controlFlags)) {
1766
+ sendCancel({
1767
+ code: INVALID_REQUEST_CODE,
1768
+ message: "protobuf unary and server-streaming calls must close the request stream in the opening frame"
1769
+ });
1770
+ return null;
1771
+ }
1772
+ closeRequestOnStart = true;
1773
+ } else if (initMessage.payload instanceof Uint8Array) {
1774
+ if (initMessage.payload.byteLength > 0) {
1775
+ try {
1776
+ initialRequest = decodeMessageBytes(
1777
+ route.method.input,
1778
+ initMessage.payload
1779
+ );
1780
+ } catch {
1781
+ sendCancel({
1782
+ code: INVALID_REQUEST_CODE,
1783
+ message: "failed to decode protobuf request payload"
1784
+ });
1785
+ return null;
1786
+ }
1787
+ }
1788
+ closeRequestOnStart = isStreamClose(initMessage.controlFlags);
1789
+ } else if (import_value2.Value.Check(ControlMessageCloseSchema, initMessage.payload) && isStreamClose(initMessage.controlFlags)) {
1790
+ closeRequestOnStart = true;
1791
+ } else {
1792
+ sendCancel({
1793
+ code: INVALID_REQUEST_CODE,
1794
+ message: "received invalid protobuf request payload"
1795
+ });
1796
+ return null;
1797
+ }
1798
+ return {
1799
+ streamId: initMessage.streamId,
1800
+ service: route.service,
1801
+ method: route.method,
1802
+ impl: route.impl,
1803
+ serviceContext: this.userContext,
1804
+ serviceState: serviceInstance?.state ?? {},
1805
+ sessionMetadata,
1806
+ initialSession: session,
1807
+ initialRequest,
1808
+ closeRequestOnStart,
1809
+ tracingCtx: initMessage.tracing
1810
+ };
1811
+ }
1812
+ cancelStream(to, sessionScopedSend, streamId, error) {
1813
+ let cancelledStreamsInSession = this.serverCancelledStreams.get(to);
1814
+ if (!cancelledStreamsInSession) {
1815
+ cancelledStreamsInSession = new LRUSet(
1816
+ this.maxCancelledStreamTombstonesPerSession
1817
+ );
1818
+ this.serverCancelledStreams.set(to, cancelledStreamsInSession);
1819
+ }
1820
+ cancelledStreamsInSession.add(streamId);
1821
+ sessionScopedSend(cancelMessage(streamId, Err(error)));
1822
+ }
1823
+ };
1824
+ function requireInitialRequest(initialRequest, method) {
1825
+ if (initialRequest === null) {
1826
+ throw new Error(
1827
+ `missing initial request for protobuf ${method.parent.typeName}.${method.name}`
1828
+ );
1829
+ }
1830
+ return initialRequest;
1831
+ }
1832
+ var LRUSet = class {
1833
+ constructor(maxItems) {
1834
+ this.maxItems = maxItems;
1835
+ }
1836
+ items = /* @__PURE__ */ new Set();
1837
+ add(item) {
1838
+ if (this.items.has(item)) {
1839
+ this.items.delete(item);
1840
+ } else if (this.items.size >= this.maxItems) {
1841
+ const first = this.items.values().next();
1842
+ if (!first.done) {
1843
+ this.items.delete(first.value);
1844
+ }
1845
+ }
1846
+ this.items.add(item);
1847
+ }
1848
+ has(item) {
1849
+ return this.items.has(item);
1850
+ }
1851
+ };
1852
+ function createServer(transport, services, options) {
1853
+ return new ProtobufServer(transport, services, options);
1854
+ }
1855
+ // Annotate the CommonJS export names for ESM import in node:
1856
+ 0 && (module.exports = {
1857
+ CANCEL_CODE,
1858
+ Err,
1859
+ INVALID_REQUEST_CODE,
1860
+ Ok,
1861
+ ProtoCodec,
1862
+ ReadableBrokenError,
1863
+ RiverErrorCode,
1864
+ UNCAUGHT_ERROR_CODE,
1865
+ UNEXPECTED_DISCONNECT_CODE,
1866
+ createClient,
1867
+ createClientHandshakeOptions,
1868
+ createProtoService,
1869
+ createServer,
1870
+ createServerHandshakeOptions,
1871
+ isClientError,
1872
+ isProtocolError,
1873
+ isRiverError,
1874
+ isSerializedClientErrorResult,
1875
+ isSerializedProtocolErrorResult
1876
+ });
1877
+ //# sourceMappingURL=index.cjs.map