@replit/river 0.209.6 → 0.209.8

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.
package/README.md CHANGED
@@ -1,9 +1,5 @@
1
1
  # River
2
2
 
3
- ⚠️ Not production ready, while Replit is using parts of River in production, we are still going through rapid breaking changes. First production ready version will be `1.x.x` ⚠️
4
-
5
- River allows multiple clients to connect to and make remote procedure calls to a remote server as if they were local procedures.
6
-
7
3
  ## Long-lived streaming remote procedure calls
8
4
 
9
5
  River provides a framework for long-lived streaming Remote Procedure Calls (RPCs) in modern web applications, featuring advanced error handling and customizable retry policies to ensure seamless communication between clients and servers.
@@ -16,7 +12,8 @@ River provides a framework similar to [tRPC](https://trpc.io/) and [gRPC](https:
16
12
  - result types and error handling
17
13
  - snappy DX (no code generation)
18
14
  - transparent reconnect support for long-lived sessions
19
- - over any transport (WebSockets and Unix Domain Socket out of the box)
15
+ - over any transport (WebSockets out of the box)
16
+ - full OpenTelemetry integration (distributed tracing for connections, sessions, procedure calls)
20
17
 
21
18
  See [PROTOCOL.md](./PROTOCOL.md) for more information on the protocol.
22
19
 
@@ -29,13 +26,7 @@ Before proceeding, ensure you have TypeScript 5 installed and configured appropr
29
26
  You must verify that:
30
27
 
31
28
  - `compilerOptions.moduleResolution` is set to `"bundler"`
32
- - `compilerOptions.strictFunctionTypes` is set to `true`
33
- - `compilerOptions.strictNullChecks` is set to `true`
34
-
35
- or, preferably, that:
36
-
37
- - `compilerOptions.moduleResolution` is set to `"bundler"`
38
- - `compilerOptions.strict` is set to `true`
29
+ - `compilerOptions.strict` is set to true (or at least `compilerOptions.strictFunctionTypes` and `compilerOptions.strictNullChecks`)
39
30
 
40
31
  Like so:
41
32
 
@@ -49,7 +40,7 @@ Before proceeding, ensure you have TypeScript 5 installed and configured appropr
49
40
  }
50
41
  ```
51
42
 
52
- If these options already exist in your `tsconfig.json` and don't match what is shown above, modify them. River is designed for `"strict": true`, but technically only `strictFunctionTypes` and `strictNullChecks` being set to `true` is required. Failing to set these will cause unresolvable type errors when defining services.
43
+ If these options already exist in your `tsconfig.json` and don't match what is shown above, modify them. Failing to set these will cause unresolvable type errors when defining services.
53
44
 
54
45
  2. Install River and Dependencies:
55
46
 
@@ -77,14 +68,15 @@ Before proceeding, ensure you have TypeScript 5 installed and configured appropr
77
68
 
78
69
  ### A basic router
79
70
 
80
- First, we create a service using `ServiceSchema`:
71
+ First, we create a service:
81
72
 
82
73
  ```ts
83
- import { ServiceSchema, Procedure, Ok } from '@replit/river';
74
+ import { createServiceSchema, Procedure, Ok } from '@replit/river';
84
75
  import { Type } from '@sinclair/typebox';
85
76
 
77
+ const ServiceSchema = createServiceSchema();
86
78
  export const ExampleService = ServiceSchema.define(
87
- // configuration
79
+ // optional configuration parameter
88
80
  {
89
81
  // initializer for shared state
90
82
  initializeState: () => ({ count: 0 }),
@@ -92,10 +84,13 @@ export const ExampleService = ServiceSchema.define(
92
84
  // procedures
93
85
  {
94
86
  add: Procedure.rpc({
87
+ // input type
95
88
  requestInit: Type.Object({ n: Type.Number() }),
89
+ // response data type
96
90
  responseData: Type.Object({ result: Type.Number() }),
97
- requestErrors: Type.Never(),
98
- // note that a handler is unique per user RPC
91
+ // any error results (other than the uncaught) that this procedure can return
92
+ responseError: Type.Never(),
93
+ // note that a handler is unique per user
99
94
  async handler({ ctx, reqInit: { n } }) {
100
95
  // access and mutate shared state
101
96
  ctx.state.count += n;
@@ -120,11 +115,13 @@ const port = 3000;
120
115
  const wss = new WebSocketServer({ server: httpServer });
121
116
  const transport = new WebSocketServerTransport(wss, 'SERVER');
122
117
 
123
- export const server = createServer(transport, {
118
+ const services = {
124
119
  example: ExampleService,
125
- });
120
+ };
121
+
122
+ export type ServiceSurface = typeof services;
126
123
 
127
- export type ServiceSurface = typeof server;
124
+ const server = createServer(transport, services);
128
125
 
129
126
  httpServer.listen(port);
130
127
  ```
@@ -135,13 +132,15 @@ In another file for the client (to create a separate entrypoint),
135
132
  import { WebSocketClientTransport } from '@replit/river/transport/ws/client';
136
133
  import { createClient } from '@replit/river';
137
134
  import { WebSocket } from 'ws';
135
+ import type { ServiceSurface } from './server';
136
+ // ^ type only import to avoid bundling the server!
138
137
 
139
138
  const transport = new WebSocketClientTransport(
140
139
  async () => new WebSocket('ws://localhost:3000'),
141
140
  'my-client-id',
142
141
  );
143
142
 
144
- const client = createClient(
143
+ const client = createClient<ServiceSurface>(
145
144
  transport,
146
145
  'SERVER', // transport id of the server in the previous step
147
146
  { eagerlyConnect: true }, // whether to eagerly connect to the server on creation (optional argument)
@@ -157,6 +156,88 @@ if (result.ok) {
157
156
  }
158
157
  ```
159
158
 
159
+ ### Error Handling
160
+
161
+ River uses a Result pattern for error handling. All procedure responses are wrapped in `Ok()` for success or `Err()` for errors:
162
+
163
+ ```ts
164
+ import { Ok, Err } from '@replit/river';
165
+
166
+ // success
167
+ return Ok({ result: 42 });
168
+
169
+ // error
170
+ return Err({ code: 'INVALID_INPUT', message: 'Value must be positive' });
171
+ ```
172
+
173
+ #### Custom Error Types
174
+
175
+ You can define custom error schemas for your procedures:
176
+
177
+ ```ts
178
+ const MathService = ServiceSchema.define({
179
+ divide: Procedure.rpc({
180
+ requestInit: Type.Object({ a: Type.Number(), b: Type.Number() }),
181
+ responseData: Type.Object({ result: Type.Number() }),
182
+ responseError: Type.Union([
183
+ Type.Object({
184
+ code: Type.Literal('DIVISION_BY_ZERO'),
185
+ message: Type.String(),
186
+ extras: Type.Object({ dividend: Type.Number() }),
187
+ }),
188
+ Type.Object({
189
+ code: Type.Literal('INVALID_INPUT'),
190
+ message: Type.String(),
191
+ }),
192
+ ]),
193
+ async handler({ reqInit: { a, b } }) {
194
+ if (b === 0) {
195
+ return Err({
196
+ code: 'DIVISION_BY_ZERO',
197
+ message: 'Cannot divide by zero',
198
+ extras: { dividend: a },
199
+ });
200
+ }
201
+
202
+ if (!Number.isFinite(a) || !Number.isFinite(b)) {
203
+ return Err({
204
+ code: 'INVALID_INPUT',
205
+ message: 'Inputs must be finite numbers',
206
+ });
207
+ }
208
+
209
+ return Ok({ result: a / b });
210
+ },
211
+ }),
212
+ });
213
+ ```
214
+
215
+ #### Uncaught Errors
216
+
217
+ When a procedure handler throws an uncaught error, River automatically handles it:
218
+
219
+ ```ts
220
+ const ExampleService = ServiceSchema.define({
221
+ maybeThrow: Procedure.rpc({
222
+ requestInit: Type.Object({ shouldThrow: Type.Boolean() }),
223
+ responseData: Type.Object({ result: Type.String() }),
224
+ async handler({ reqInit: { shouldThrow } }) {
225
+ if (shouldThrow) {
226
+ throw new Error('Something went wrong!');
227
+ }
228
+
229
+ return Ok({ result: 'success' });
230
+ },
231
+ }),
232
+ });
233
+
234
+ // client will receive an error with code 'UNCAUGHT_ERROR'
235
+ const result = await client.example.maybeThrow.rpc({ shouldThrow: true });
236
+ if (!result.ok && result.payload.code === 'UNCAUGHT_ERROR') {
237
+ console.log('Handler threw an error:', result.payload.message);
238
+ }
239
+ ```
240
+
160
241
  ### Logging
161
242
 
162
243
  To add logging, you can bind a logging function to a transport.
@@ -210,7 +291,380 @@ transport.addEventListener('sessionTransition', (evt) => {
210
291
  });
211
292
  ```
212
293
 
213
- ### Custom Handshake
294
+ ### Advanced Patterns
295
+
296
+ #### All Procedure Types
297
+
298
+ River supports four types of procedures, each with different message patterns:
299
+
300
+ ##### Unary RPC Procedures (1:1)
301
+
302
+ Single request, single response:
303
+
304
+ ```ts
305
+ const ExampleService = ServiceSchema.define({
306
+ add: Procedure.rpc({
307
+ requestInit: Type.Object({ a: Type.Number(), b: Type.Number() }),
308
+ responseData: Type.Object({ result: Type.Number() }),
309
+ async handler({ reqInit: { a, b } }) {
310
+ return Ok({ result: a + b });
311
+ },
312
+ }),
313
+ });
314
+
315
+ // client usage
316
+ const result = await client.example.add.rpc({ a: 1, b: 2 });
317
+ if (result.ok) {
318
+ console.log(result.payload.result); // 3
319
+ }
320
+ ```
321
+
322
+ ##### Upload Procedures (n:1)
323
+
324
+ Multiple requests, single response:
325
+
326
+ ```ts
327
+ const ExampleService = ServiceSchema.define({
328
+ sum: Procedure.upload({
329
+ requestInit: Type.Object({ multiplier: Type.Number() }),
330
+ requestData: Type.Object({ value: Type.Number() }),
331
+ responseData: Type.Object({ total: Type.Number() }),
332
+ responseError: Type.Object({
333
+ code: Type.Literal('INVALID_INPUT'),
334
+ message: Type.String(),
335
+ }),
336
+ async handler({ ctx, reqInit, reqReadable }) {
337
+ let sum = 0;
338
+ for await (const msg of reqReadable) {
339
+ if (!msg.ok) {
340
+ return ctx.cancel('client disconnected');
341
+ }
342
+
343
+ sum += msg.payload.value;
344
+ }
345
+ return Ok({ total: sum * reqInit.multiplier });
346
+ },
347
+ }),
348
+ });
349
+
350
+ // client usage
351
+ const { reqWritable, finalize } = client.example.sum.upload({ multiplier: 2 });
352
+ reqWritable.write({ value: 1 });
353
+ reqWritable.write({ value: 2 });
354
+ reqWritable.write({ value: 3 });
355
+
356
+ const result = await finalize();
357
+ if (result.ok) {
358
+ console.log(result.payload.total); // 12 (6 * 2)
359
+ } else {
360
+ console.error('Upload failed:', result.payload.message);
361
+ }
362
+ ```
363
+
364
+ ##### Subscription Procedures (1:n)
365
+
366
+ Single request, multiple responses:
367
+
368
+ ```ts
369
+ const ExampleService = ServiceSchema.define(
370
+ { initializeState: () => ({ count: 0 }) },
371
+ {
372
+ counter: Procedure.subscription({
373
+ requestInit: Type.Object({ interval: Type.Number() }),
374
+ responseData: Type.Object({ count: Type.Number() }),
375
+ async handler({ ctx, reqInit, resWritable }) {
376
+ const intervalId = setInterval(() => {
377
+ ctx.state.count++;
378
+ resWritable.write(Ok({ count: ctx.state.count }));
379
+ }, reqInit.interval);
380
+
381
+ ctx.signal.addEventListener('abort', () => {
382
+ clearInterval(intervalId);
383
+ });
384
+ },
385
+ }),
386
+ },
387
+ );
388
+
389
+ // client usage
390
+ const { resReadable } = client.example.counter.subscribe({ interval: 1000 });
391
+ for await (const msg of resReadable) {
392
+ if (msg.ok) {
393
+ console.log('Count:', msg.payload.count);
394
+ } else {
395
+ console.error('Subscription error:', msg.payload.message);
396
+ break; // exit on error for subscriptions
397
+ }
398
+ }
399
+ ```
400
+
401
+ ##### Stream Procedures (n:n)
402
+
403
+ Multiple requests, multiple responses:
404
+
405
+ ```ts
406
+ const ExampleService = ServiceSchema.define({
407
+ echo: Procedure.stream({
408
+ requestInit: Type.Object({ prefix: Type.String() }),
409
+ requestData: Type.Object({ message: Type.String() }),
410
+ responseData: Type.Object({ echo: Type.String() }),
411
+ async handler({ reqInit, reqReadable, resWritable, ctx }) {
412
+ for await (const msg of reqReadable) {
413
+ if (!msg.ok) {
414
+ return;
415
+ }
416
+
417
+ const { message } = msg.payload;
418
+ resWritable.write(
419
+ Ok({
420
+ echo: `${reqInit.prefix}: ${message}`,
421
+ }),
422
+ );
423
+ }
424
+
425
+ // client ended their side, we can close ours
426
+ resWritable.close();
427
+ },
428
+ }),
429
+ });
430
+
431
+ // client usage
432
+ const { reqWritable, resReadable } = client.example.echo.stream({
433
+ prefix: 'Server',
434
+ });
435
+
436
+ // send messages
437
+ reqWritable.write({ message: 'Hello' });
438
+ reqWritable.write({ message: 'World' });
439
+ reqWritable.close();
440
+
441
+ // read responses
442
+ for await (const msg of resReadable) {
443
+ if (msg.ok) {
444
+ console.log(msg.payload.echo); // "Server: Hello", "Server: World"
445
+ } else {
446
+ console.error('Stream error:', msg.payload.message);
447
+ }
448
+ }
449
+ ```
450
+
451
+ #### Client Cancellation
452
+
453
+ River supports client-side cancellation using AbortController. All procedure calls accept an optional `signal` parameter:
454
+
455
+ ```ts
456
+ const controller = new AbortController();
457
+ const rpcResult = client.example.longRunning.rpc(
458
+ { data: 'hello world' },
459
+ { signal: controller.signal },
460
+ );
461
+
462
+ // cancel the operation
463
+ controller.abort();
464
+
465
+ // all cancelled operations will receive an error with CANCEL_CODE
466
+ const result = await rpcResult;
467
+ if (!result.ok && result.payload.code === 'CANCEL_CODE') {
468
+ console.log('Operation was cancelled');
469
+ }
470
+ ```
471
+
472
+ When a client cancels an operation, the server handler receives the cancellation via the `ctx.signal`:
473
+
474
+ ```ts
475
+ const ExampleService = ServiceSchema.define({
476
+ longRunning: Procedure.rpc({
477
+ requestInit: Type.Object({}),
478
+ responseData: Type.Object({ result: Type.String() }),
479
+ async handler({ ctx }) {
480
+ ctx.signal.addEventListener('abort', () => {
481
+ // do something
482
+ });
483
+
484
+ // long running operation
485
+ await new Promise((resolve) => setTimeout(resolve, 10000));
486
+ return Ok({ result: 'completed' });
487
+ },
488
+ }),
489
+
490
+ streamingExample: Procedure.stream({
491
+ requestInit: Type.Object({}),
492
+ requestData: Type.Object({ message: Type.String() }),
493
+ responseData: Type.Object({ echo: Type.String() }),
494
+ async handler({ ctx, reqReadable, resWritable }) {
495
+ // for streams, cancellation closes both readable and writable
496
+ // in addition to triggering the abort signal.
497
+ for await (const msg of reqReadable) {
498
+ if (!msg.ok) {
499
+ // msg.payload.code === CANCEL_CODE error if client cancelled
500
+ break;
501
+ }
502
+
503
+ resWritable.write(Ok({ echo: msg.payload.message }));
504
+ }
505
+
506
+ resWritable.close();
507
+ },
508
+ }),
509
+ });
510
+ ```
511
+
512
+ Worth noting that the `ctx.signal` is triggered regardless of the reason the procedure has ended.
513
+
514
+ #### Codecs
515
+
516
+ River provides two built-in codecs:
517
+
518
+ - `NaiveJsonCodec`: Simple JSON serialization
519
+ - `BinaryCodec`: Efficient msgpack serialization (recommended for production)
520
+
521
+ ```ts
522
+ import { BinaryCodec, NaiveJsonCodec } from '@replit/river/codec';
523
+
524
+ // use binary codec for better performance
525
+ const transport = new WebSocketClientTransport(
526
+ async () => new WebSocket('ws://localhost:3000'),
527
+ 'my-client-id',
528
+ { codec: BinaryCodec },
529
+ );
530
+ ```
531
+
532
+ You can also create custom codecs for message serialization:
533
+
534
+ ```ts
535
+ import { Codec } from '@replit/river/codec';
536
+
537
+ class CustomCodec implements Codec {
538
+ toBuffer(obj: object): Uint8Array {
539
+ // custom serialization logic
540
+ }
541
+
542
+ fromBuffer(buf: Uint8Array): object {
543
+ // custom deserialization logic
544
+ }
545
+ }
546
+
547
+ // use with transports
548
+ const transport = new WebSocketClientTransport(
549
+ async () => new WebSocket('ws://localhost:3000'),
550
+ 'my-client-id',
551
+ { codec: new CustomCodec() },
552
+ );
553
+ ```
554
+
555
+ #### Custom Transports
556
+
557
+ You can implement custom transports by extending the base Transport classes:
558
+
559
+ ```ts
560
+ import { ClientTransport, ServerTransport } from '@replit/river/transport';
561
+ import { Connection } from '@replit/river/transport';
562
+
563
+ // custom connection implementation
564
+ class MyCustomConnection extends Connection {
565
+ private socket: MyCustomSocket;
566
+
567
+ constructor(socket: MyCustomSocket) {
568
+ super();
569
+ this.socket = socket;
570
+
571
+ this.socket.onMessage = (data: Uint8Array) => {
572
+ this.dataListener?.(data);
573
+ };
574
+
575
+ this.socket.onClose = () => {
576
+ this.closeListener?.();
577
+ };
578
+
579
+ this.socket.onError = (err: Error) => {
580
+ this.errorListener?.(err);
581
+ };
582
+ }
583
+
584
+ send(msg: Uint8Array): boolean {
585
+ return this.socket.send(msg);
586
+ }
587
+
588
+ close(): void {
589
+ this.socket.close();
590
+ }
591
+ }
592
+
593
+ // custom client transport
594
+ class MyCustomClientTransport extends ClientTransport<MyCustomConnection> {
595
+ constructor(
596
+ private connectFn: () => Promise<MyCustomSocket>,
597
+ clientId: string,
598
+ ) {
599
+ super(clientId);
600
+ }
601
+
602
+ async createNewOutgoingConnection(): Promise<MyCustomConnection> {
603
+ const socket = await this.connectFn();
604
+ return new MyCustomConnection(socket);
605
+ }
606
+ }
607
+
608
+ // custom server transport
609
+ class MyCustomServerTransport extends ServerTransport<MyCustomConnection> {
610
+ constructor(
611
+ private server: MyCustomServer,
612
+ clientId: string,
613
+ ) {
614
+ super(clientId);
615
+
616
+ server.onConnection = (socket: MyCustomSocket) => {
617
+ const connection = new MyCustomConnection(socket);
618
+ this.handleConnection(connection);
619
+ };
620
+ }
621
+ }
622
+
623
+ // usage
624
+ const clientTransport = new MyCustomClientTransport(
625
+ () => connectToMyCustomServer(),
626
+ 'client-id',
627
+ );
628
+
629
+ const client = createClient<ServiceSurface>(clientTransport, 'SERVER');
630
+ ```
631
+
632
+ #### Testing
633
+
634
+ River provides utilities for testing your services:
635
+
636
+ ```ts
637
+ import { createMockTransportNetwork } from '@replit/river/testUtil';
638
+
639
+ describe('My Service', () => {
640
+ // create mock transport network
641
+ const { getClientTransport, getServerTransport, cleanup } =
642
+ createMockTransportNetwork();
643
+ afterEach(cleanup);
644
+
645
+ test('should add numbers correctly', async () => {
646
+ // setup server
647
+ const serverTransport = getServerTransport('SERVER');
648
+ const services = {
649
+ math: MathService,
650
+ };
651
+ const server = createServer(serverTransport, services);
652
+
653
+ // setup client
654
+ const clientTransport = getClientTransport('client');
655
+ const client = createClient<typeof services>(clientTransport, 'SERVER');
656
+
657
+ // test the service
658
+ const result = await client.math.add.rpc({ a: 1, b: 2 });
659
+ expect(result.ok).toBe(true);
660
+ if (result.ok) {
661
+ expect(result.payload.result).toBe(3);
662
+ }
663
+ });
664
+ });
665
+ ```
666
+
667
+ #### Custom Handshake
214
668
 
215
669
  River allows you to extend the protocol-level handshake so you can add additional logic to
216
670
  validate incoming connections.
@@ -218,32 +672,33 @@ validate incoming connections.
218
672
  You can do this by passing extra options to `createClient` and `createServer` and extending the `ParsedMetadata` interface:
219
673
 
220
674
  ```ts
221
- declare module '@replit/river' {
222
- interface ParsedMetadata {
223
- userId: number;
224
- }
225
- }
675
+ type ContextType = { ... }; // has to extend object
676
+ type ParsedMetadata = { parsedToken: string };
677
+ const ServiceSchema = createServiceSchema<ContextType, ParsedMetadata>();
678
+
679
+ const services = { ... }; // use custom ServiceSchema builder here
226
680
 
227
- const schema = Type.Object({ token: Type.String() });
681
+ const handshakeSchema = Type.Object({ token: Type.String() });
228
682
  createClient<typeof services>(new MockClientTransport('client'), 'SERVER', {
229
683
  eagerlyConnect: false,
230
- handshakeOptions: createClientHandshakeOptions(schema, async () => ({
684
+ handshakeOptions: createClientHandshakeOptions(handshakeSchema, async () => ({
231
685
  // the type of this function is
232
- // () => Static<typeof schema> | Promise<Static<typeof schema>>
686
+ // () => Static<typeof handshakeSchema> | Promise<Static<typeof handshakeSchema>>
233
687
  token: '123',
234
688
  })),
235
689
  });
236
690
 
237
691
  createServer(new MockServerTransport('SERVER'), services, {
238
692
  handshakeOptions: createServerHandshakeOptions(
239
- schema,
693
+ handshakeSchema,
240
694
  (metadata, previousMetadata) => {
241
695
  // the type of this function is
242
- // (metadata: Static<typeof<schema>, previousMetadata?: ParsedMetadata) =>
696
+ // (metadata: Static<typeof<handshakeSchema>, previousMetadata?: ParsedMetadata) =>
243
697
  // | false | Promise<false> (if you reject it)
244
698
  // | ParsedMetadata | Promise<ParsedMetadata> (if you allow it)
245
699
  // next time a connection happens on the same session, previousMetadata will
246
700
  // be populated with the last returned value
701
+ return { parsedToken: metadata.token };
247
702
  },
248
703
  ),
249
704
  });
@@ -20,7 +20,7 @@ import {
20
20
  handshakeResponseMessage,
21
21
  isAcceptedProtocolVersion,
22
22
  isAck
23
- } from "./chunk-LTSD2AMH.js";
23
+ } from "./chunk-DOUYY7FU.js";
24
24
 
25
25
  // transport/events.ts
26
26
  var ProtocolError = {
@@ -2327,4 +2327,4 @@ export {
2327
2327
  WebSocketConnection,
2328
2328
  CodecMessageAdapter
2329
2329
  };
2330
- //# sourceMappingURL=chunk-V2YMCSBX.js.map
2330
+ //# sourceMappingURL=chunk-6NMRASPI.js.map
@@ -583,10 +583,13 @@ var WritableImpl = class {
583
583
  isWritable() {
584
584
  return !this.closed;
585
585
  }
586
- close() {
586
+ close(value) {
587
587
  if (this.closed) {
588
588
  return;
589
589
  }
590
+ if (value !== void 0) {
591
+ this.writeCb(value);
592
+ }
590
593
  this.closed = true;
591
594
  this.writeCb = () => void 0;
592
595
  this.closeCb();
@@ -1994,7 +1997,7 @@ function createServerHandshakeOptions(schema, validate) {
1994
1997
  }
1995
1998
 
1996
1999
  // package.json
1997
- var version = "0.209.6";
2000
+ var version = "0.209.8";
1998
2001
 
1999
2002
  export {
2000
2003
  generateId,
@@ -2035,4 +2038,4 @@ export {
2035
2038
  createConnectionTelemetryInfo,
2036
2039
  getTracer
2037
2040
  };
2038
- //# sourceMappingURL=chunk-LTSD2AMH.js.map
2041
+ //# sourceMappingURL=chunk-DOUYY7FU.js.map