@trpc/server 11.0.0-rc.553 → 11.0.0-rc.561

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.
@@ -1,7 +1,7 @@
1
1
  {
2
- "bundleSize": 136392,
3
- "bundleOrigSize": 182813,
4
- "bundleReduction": 25.39,
2
+ "bundleSize": 139502,
3
+ "bundleOrigSize": 186355,
4
+ "bundleReduction": 25.14,
5
5
  "modules": [
6
6
  {
7
7
  "id": "/src/unstable-core-do-not-import/http/resolveResponse.ts",
@@ -14,13 +14,13 @@
14
14
  "dependents": [
15
15
  "/src/unstable-core-do-not-import.ts"
16
16
  ],
17
- "percent": 13.52,
17
+ "percent": 13.22,
18
18
  "reduction": 0
19
19
  },
20
20
  {
21
21
  "id": "/src/unstable-core-do-not-import/stream/jsonl.ts",
22
22
  "size": 17567,
23
- "origSize": 18359,
23
+ "origSize": 18465,
24
24
  "renderedExports": [
25
25
  "isPromise",
26
26
  "jsonlStreamProducer",
@@ -31,8 +31,8 @@
31
31
  "/src/unstable-core-do-not-import.ts",
32
32
  "/src/unstable-core-do-not-import/http/resolveResponse.ts"
33
33
  ],
34
- "percent": 12.88,
35
- "reduction": 4.31
34
+ "percent": 12.59,
35
+ "reduction": 4.86
36
36
  },
37
37
  {
38
38
  "id": "/src/adapters/ws.ts",
@@ -47,9 +47,26 @@
47
47
  "dependents": [
48
48
  "/src/adapters/fastify/fastifyTRPCPlugin.ts"
49
49
  ],
50
- "percent": 11.94,
50
+ "percent": 11.67,
51
51
  "reduction": 0
52
52
  },
53
+ {
54
+ "id": "/src/unstable-core-do-not-import/stream/sse.ts",
55
+ "size": 9020,
56
+ "origSize": 10407,
57
+ "renderedExports": [
58
+ "sseStreamProducer",
59
+ "sseStreamConsumer",
60
+ "sseHeaders"
61
+ ],
62
+ "removedExports": [],
63
+ "dependents": [
64
+ "/src/unstable-core-do-not-import.ts",
65
+ "/src/unstable-core-do-not-import/http/resolveResponse.ts"
66
+ ],
67
+ "percent": 6.47,
68
+ "reduction": 13.33
69
+ },
53
70
  {
54
71
  "id": "/src/unstable-core-do-not-import/http/contentType.ts",
55
72
  "size": 7688,
@@ -62,7 +79,7 @@
62
79
  "/src/unstable-core-do-not-import.ts",
63
80
  "/src/unstable-core-do-not-import/http/resolveResponse.ts"
64
81
  ],
65
- "percent": 5.64,
82
+ "percent": 5.51,
66
83
  "reduction": 0
67
84
  },
68
85
  {
@@ -80,26 +97,9 @@
80
97
  "/src/unstable-core-do-not-import.ts",
81
98
  "/src/unstable-core-do-not-import/initTRPC.ts"
82
99
  ],
83
- "percent": 4.71,
100
+ "percent": 4.6,
84
101
  "reduction": 40.09
85
102
  },
86
- {
87
- "id": "/src/unstable-core-do-not-import/stream/sse.ts",
88
- "size": 5910,
89
- "origSize": 6971,
90
- "renderedExports": [
91
- "sseStreamProducer",
92
- "sseStreamConsumer",
93
- "sseHeaders"
94
- ],
95
- "removedExports": [],
96
- "dependents": [
97
- "/src/unstable-core-do-not-import.ts",
98
- "/src/unstable-core-do-not-import/http/resolveResponse.ts"
99
- ],
100
- "percent": 4.33,
101
- "reduction": 15.22
102
- },
103
103
  {
104
104
  "id": "/src/unstable-core-do-not-import/procedureBuilder.ts",
105
105
  "size": 5795,
@@ -112,7 +112,7 @@
112
112
  "/src/unstable-core-do-not-import.ts",
113
113
  "/src/unstable-core-do-not-import/initTRPC.ts"
114
114
  ],
115
- "percent": 4.25,
115
+ "percent": 4.15,
116
116
  "reduction": 64.74
117
117
  },
118
118
  {
@@ -126,7 +126,7 @@
126
126
  "dependents": [
127
127
  "/src/adapters/aws-lambda/index.ts"
128
128
  ],
129
- "percent": 3.97,
129
+ "percent": 3.88,
130
130
  "reduction": 11.38
131
131
  },
132
132
  {
@@ -146,7 +146,7 @@
146
146
  "/src/unstable-core-do-not-import/http/resolveResponse.ts",
147
147
  "/src/observable/operators.ts"
148
148
  ],
149
- "percent": 3.02,
149
+ "percent": 2.95,
150
150
  "reduction": 0
151
151
  },
152
152
  {
@@ -160,7 +160,7 @@
160
160
  "dependents": [
161
161
  "/src/adapters/next-app-dir.ts"
162
162
  ],
163
- "percent": 2.36,
163
+ "percent": 2.31,
164
164
  "reduction": 22.57
165
165
  },
166
166
  {
@@ -174,7 +174,7 @@
174
174
  "dependents": [
175
175
  "/src/adapters/node-http/index.ts"
176
176
  ],
177
- "percent": 2.1,
177
+ "percent": 2.05,
178
178
  "reduction": 6.07
179
179
  },
180
180
  {
@@ -190,7 +190,7 @@
190
190
  "dependents": [
191
191
  "/src/observable/index.ts"
192
192
  ],
193
- "percent": 2.02,
193
+ "percent": 1.98,
194
194
  "reduction": 0
195
195
  },
196
196
  {
@@ -210,7 +210,7 @@
210
210
  "/src/unstable-core-do-not-import/initTRPC.ts",
211
211
  "/src/unstable-core-do-not-import/router.ts"
212
212
  ],
213
- "percent": 2.01,
213
+ "percent": 1.97,
214
214
  "reduction": 45.94
215
215
  },
216
216
  {
@@ -224,7 +224,7 @@
224
224
  "dependents": [
225
225
  "/src/unstable-core-do-not-import.ts"
226
226
  ],
227
- "percent": 1.98,
227
+ "percent": 1.93,
228
228
  "reduction": 40.98
229
229
  },
230
230
  {
@@ -244,7 +244,7 @@
244
244
  "/src/unstable-core-do-not-import/initTRPC.ts",
245
245
  "/src/unstable-core-do-not-import/procedureBuilder.ts"
246
246
  ],
247
- "percent": 1.93,
247
+ "percent": 1.88,
248
248
  "reduction": 55.78
249
249
  },
250
250
  {
@@ -260,7 +260,7 @@
260
260
  "/src/unstable-core-do-not-import.ts",
261
261
  "/src/unstable-core-do-not-import/router.ts"
262
262
  ],
263
- "percent": 1.71,
263
+ "percent": 1.67,
264
264
  "reduction": 0
265
265
  },
266
266
  {
@@ -274,7 +274,7 @@
274
274
  "dependents": [
275
275
  "/src/adapters/fetch/index.ts"
276
276
  ],
277
- "percent": 1.65,
277
+ "percent": 1.62,
278
278
  "reduction": 2.17
279
279
  },
280
280
  {
@@ -289,7 +289,7 @@
289
289
  "/src/adapters/node-http/index.ts",
290
290
  "/src/adapters/node-http/nodeHTTPRequestHandler.ts"
291
291
  ],
292
- "percent": 1.61,
292
+ "percent": 1.57,
293
293
  "reduction": 13.79
294
294
  },
295
295
  {
@@ -303,7 +303,7 @@
303
303
  "dependents": [
304
304
  "/src/adapters/next-app-dir/nextAppDirCaller.ts"
305
305
  ],
306
- "percent": 1.5,
306
+ "percent": 1.47,
307
307
  "reduction": 5.79
308
308
  },
309
309
  {
@@ -317,7 +317,7 @@
317
317
  "dependents": [
318
318
  "/src/adapters/fastify/index.ts"
319
319
  ],
320
- "percent": 1.3,
320
+ "percent": 1.28,
321
321
  "reduction": 29.88
322
322
  },
323
323
  {
@@ -341,7 +341,7 @@
341
341
  "/src/unstable-core-do-not-import/stream/jsonl.ts",
342
342
  "/src/unstable-core-do-not-import/stream/sse.ts"
343
343
  ],
344
- "percent": 1.27,
344
+ "percent": 1.24,
345
345
  "reduction": 19.47
346
346
  },
347
347
  {
@@ -353,7 +353,7 @@
353
353
  ],
354
354
  "removedExports": [],
355
355
  "dependents": [],
356
- "percent": 1.25,
356
+ "percent": 1.22,
357
357
  "reduction": 19.29
358
358
  },
359
359
  {
@@ -366,7 +366,7 @@
366
366
  ],
367
367
  "removedExports": [],
368
368
  "dependents": [],
369
- "percent": 1.18,
369
+ "percent": 1.15,
370
370
  "reduction": 27.47
371
371
  },
372
372
  {
@@ -378,7 +378,7 @@
378
378
  ],
379
379
  "removedExports": [],
380
380
  "dependents": [],
381
- "percent": 1.13,
381
+ "percent": 1.11,
382
382
  "reduction": 26.94
383
383
  },
384
384
  {
@@ -395,7 +395,7 @@
395
395
  "/src/unstable-core-do-not-import/http/resolveResponse.ts",
396
396
  "/src/unstable-core-do-not-import/error/getErrorShape.ts"
397
397
  ],
398
- "percent": 1.05,
398
+ "percent": 1.03,
399
399
  "reduction": 16.73
400
400
  },
401
401
  {
@@ -410,7 +410,7 @@
410
410
  "/src/unstable-core-do-not-import.ts",
411
411
  "/src/unstable-core-do-not-import/procedureBuilder.ts"
412
412
  ],
413
- "percent": 0.95,
413
+ "percent": 0.93,
414
414
  "reduction": 55.21
415
415
  },
416
416
  {
@@ -442,7 +442,7 @@
442
442
  "/src/unstable-core-do-not-import/stream/jsonl.ts",
443
443
  "/src/unstable-core-do-not-import/stream/sse.ts"
444
444
  ],
445
- "percent": 0.87,
445
+ "percent": 0.85,
446
446
  "reduction": 28.34
447
447
  },
448
448
  {
@@ -457,7 +457,7 @@
457
457
  "/src/adapters/fastify/index.ts",
458
458
  "/src/adapters/fastify/fastifyTRPCPlugin.ts"
459
459
  ],
460
- "percent": 0.83,
460
+ "percent": 0.81,
461
461
  "reduction": 47.59
462
462
  },
463
463
  {
@@ -473,7 +473,7 @@
473
473
  "/src/unstable-core-do-not-import.ts",
474
474
  "/src/unstable-core-do-not-import/http/contentType.ts"
475
475
  ],
476
- "percent": 0.81,
476
+ "percent": 0.79,
477
477
  "reduction": 15.08
478
478
  },
479
479
  {
@@ -487,7 +487,7 @@
487
487
  "dependents": [
488
488
  "/src/unstable-core-do-not-import.ts"
489
489
  ],
490
- "percent": 0.78,
490
+ "percent": 0.76,
491
491
  "reduction": 0
492
492
  },
493
493
  {
@@ -504,7 +504,7 @@
504
504
  "/src/adapters/next-app-dir/nextAppDirCaller.ts",
505
505
  "/src/adapters/next-app-dir/rethrowNextErrors.ts"
506
506
  ],
507
- "percent": 0.72,
507
+ "percent": 0.71,
508
508
  "reduction": 13.65
509
509
  },
510
510
  {
@@ -522,7 +522,7 @@
522
522
  "/src/unstable-core-do-not-import/stream/sse.ts",
523
523
  "/src/unstable-core-do-not-import/stream/utils/createReadableStream.ts"
524
524
  ],
525
- "percent": 0.72,
525
+ "percent": 0.7,
526
526
  "reduction": 15.69
527
527
  },
528
528
  {
@@ -539,7 +539,7 @@
539
539
  "/src/unstable-core-do-not-import.ts",
540
540
  "/src/unstable-core-do-not-import/stream/sse.ts"
541
541
  ],
542
- "percent": 0.57,
542
+ "percent": 0.56,
543
543
  "reduction": 44.37
544
544
  },
545
545
  {
@@ -551,7 +551,7 @@
551
551
  ],
552
552
  "removedExports": [],
553
553
  "dependents": [],
554
- "percent": 0.56,
554
+ "percent": 0.54,
555
555
  "reduction": 66.9
556
556
  },
557
557
  {
@@ -567,7 +567,7 @@
567
567
  "/src/unstable-core-do-not-import/stream/jsonl.ts",
568
568
  "/src/unstable-core-do-not-import/stream/sse.ts"
569
569
  ],
570
- "percent": 0.52,
570
+ "percent": 0.51,
571
571
  "reduction": 21.32
572
572
  },
573
573
  {
@@ -581,7 +581,7 @@
581
581
  "dependents": [
582
582
  "/src/unstable-core-do-not-import.ts"
583
583
  ],
584
- "percent": 0.49,
584
+ "percent": 0.48,
585
585
  "reduction": 0.6
586
586
  },
587
587
  {
@@ -596,7 +596,7 @@
596
596
  "/src/unstable-core-do-not-import.ts",
597
597
  "/src/unstable-core-do-not-import/http/resolveResponse.ts"
598
598
  ],
599
- "percent": 0.46,
599
+ "percent": 0.45,
600
600
  "reduction": 43.49
601
601
  },
602
602
  {
@@ -609,7 +609,7 @@
609
609
  ],
610
610
  "removedExports": [],
611
611
  "dependents": [],
612
- "percent": 0.38,
612
+ "percent": 0.37,
613
613
  "reduction": 67.09
614
614
  },
615
615
  {
@@ -636,7 +636,7 @@
636
636
  ],
637
637
  "removedExports": [],
638
638
  "dependents": [],
639
- "percent": 0.21,
639
+ "percent": 0.2,
640
640
  "reduction": 72.92
641
641
  },
642
642
  {
@@ -678,7 +678,7 @@
678
678
  "dependents": [
679
679
  "/src/unstable-core-do-not-import.ts"
680
680
  ],
681
- "percent": 0.12,
681
+ "percent": 0.11,
682
682
  "reduction": 14.13
683
683
  },
684
684
  {
@@ -735,9 +735,9 @@
735
735
  "reduction": 100
736
736
  },
737
737
  {
738
- "id": "/src/shared.ts",
738
+ "id": "/src/rpc.ts",
739
739
  "size": 0,
740
- "origSize": 653,
740
+ "origSize": 36,
741
741
  "renderedExports": [],
742
742
  "removedExports": [],
743
743
  "dependents": [],
@@ -745,9 +745,9 @@
745
745
  "reduction": 100
746
746
  },
747
747
  {
748
- "id": "/src/rpc.ts",
748
+ "id": "/src/shared.ts",
749
749
  "size": 0,
750
- "origSize": 36,
750
+ "origSize": 653,
751
751
  "renderedExports": [],
752
752
  "removedExports": [],
753
753
  "dependents": [],
@@ -789,6 +789,16 @@
789
789
  "percent": 0,
790
790
  "reduction": 100
791
791
  },
792
+ {
793
+ "id": "/src/adapters/fastify/index.ts",
794
+ "size": 0,
795
+ "origSize": 78,
796
+ "renderedExports": [],
797
+ "removedExports": [],
798
+ "dependents": [],
799
+ "percent": 0,
800
+ "reduction": 100
801
+ },
792
802
  {
793
803
  "id": "/src/adapters/fetch/index.ts",
794
804
  "size": 0,
@@ -813,16 +823,6 @@
813
823
  ],
814
824
  "percent": 0,
815
825
  "reduction": 100
816
- },
817
- {
818
- "id": "/src/adapters/fastify/index.ts",
819
- "size": 0,
820
- "origSize": 78,
821
- "renderedExports": [],
822
- "removedExports": [],
823
- "dependents": [],
824
- "percent": 0,
825
- "reduction": 100
826
826
  }
827
827
  ],
828
828
  "moduleCount": 55
@@ -97,6 +97,9 @@ export declare function jsonlStreamConsumer<THead>(opts: {
97
97
  formatError?: (opts: {
98
98
  error: unknown;
99
99
  }) => Error;
100
+ /**
101
+ * This `AbortController` will be triggered when there are no more listeners to the stream.
102
+ */
100
103
  abortController: AbortController | null;
101
104
  }): Promise<readonly [Awaited<THead>, {
102
105
  readonly controllers: Map<ChunkIndex, {
@@ -1 +1 @@
1
- {"version":3,"file":"jsonl.d.ts","sourceRoot":"","sources":["../../../src/unstable-core-do-not-import/stream/jsonl.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"jsonl.d.ts","sourceRoot":"","sources":["../../../src/unstable-core-do-not-import/stream/jsonl.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { ConsumerOnError } from './jsonl';
1
+ import type { MaybePromise } from '../types';
2
2
  import type { inferTrackedOutput } from './tracked';
3
3
  type Serialize = (value: any) => any;
4
4
  type Deserialize = (value: any) => any;
@@ -43,21 +43,41 @@ export interface SSEStreamProducerOptions {
43
43
  * @see https://html.spec.whatwg.org/multipage/server-sent-events.html
44
44
  */
45
45
  export declare function sseStreamProducer(opts: SSEStreamProducerOptions): ReadableStream<string>;
46
- type ConsumerStreamResult<TData> = {
47
- ok: true;
46
+ interface ConsumerStreamResultBase {
47
+ eventSource: EventSource;
48
+ }
49
+ interface ConsumerStreamResultData<TData> extends ConsumerStreamResultBase {
50
+ type: 'data';
48
51
  data: inferTrackedOutput<TData>;
49
- } | {
50
- ok: false;
52
+ }
53
+ interface ConsumerStreamResultError extends ConsumerStreamResultBase {
54
+ type: 'error';
51
55
  error: unknown;
52
- };
56
+ }
57
+ interface ConsumerStreamResultOpened extends ConsumerStreamResultBase {
58
+ type: 'opened';
59
+ }
60
+ interface ConsumerStreamResultConnecting extends ConsumerStreamResultBase {
61
+ type: 'connecting';
62
+ }
63
+ type ConsumerStreamResult<TData> = ConsumerStreamResultData<TData> | ConsumerStreamResultError | ConsumerStreamResultOpened | ConsumerStreamResultConnecting;
64
+ export interface SSEStreamConsumerOptions {
65
+ url: () => MaybePromise<string>;
66
+ init: () => MaybePromise<EventSourceInit> | undefined;
67
+ signal: AbortSignal;
68
+ shouldRecreateOnError?: (opts: {
69
+ type: 'event';
70
+ event: Event;
71
+ } | {
72
+ type: 'serialized-error';
73
+ error: unknown;
74
+ }) => boolean | Promise<boolean>;
75
+ deserialize?: Deserialize;
76
+ }
53
77
  /**
54
78
  * @see https://html.spec.whatwg.org/multipage/server-sent-events.html
55
79
  */
56
- export declare function sseStreamConsumer<TData>(opts: {
57
- from: EventSource;
58
- onError?: ConsumerOnError;
59
- deserialize?: Deserialize;
60
- }): AsyncIterable<ConsumerStreamResult<TData>>;
80
+ export declare function sseStreamConsumer<TData>(opts: SSEStreamConsumerOptions): AsyncIterable<ConsumerStreamResult<TData>>;
61
81
  export declare const sseHeaders: {
62
82
  readonly 'Content-Type': "text/event-stream";
63
83
  readonly 'Cache-Control': "no-cache, no-transform";
@@ -1 +1 @@
1
- {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/unstable-core-do-not-import/stream/sse.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAKpD,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC;AACrC,KAAK,WAAW,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC;CACrD;AAUD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,0BAoH/D;AAED,KAAK,oBAAoB,CAAC,KAAK,IAC3B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC;CACjC,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEN;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE;IAC7C,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,GAAG,aAAa,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CA6E7C;AAED,eAAO,MAAM,UAAU;;;;;CAKb,CAAC"}
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/unstable-core-do-not-import/stream/sse.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAKpD,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC;AACrC,KAAK,WAAW,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC;CACrD;AAUD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,0BAoH/D;AAED,UAAU,wBAAwB;IAChC,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,UAAU,wBAAwB,CAAC,KAAK,CAAE,SAAQ,wBAAwB;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC;CACjC;AAED,UAAU,yBAA0B,SAAQ,wBAAwB;IAClE,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,0BAA2B,SAAQ,wBAAwB;IACnE,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,UAAU,8BAA+B,SAAQ,wBAAwB;IACvE,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,KAAK,oBAAoB,CAAC,KAAK,IAC3B,wBAAwB,CAAC,KAAK,CAAC,GAC/B,yBAAyB,GACzB,0BAA0B,GAC1B,8BAA8B,CAAC;AAEnC,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,YAAY,CAAC,eAAe,CAAC,GAAG,SAAS,CAAC;IACtD,MAAM,EAAE,WAAW,CAAC;IACpB,qBAAqB,CAAC,EAAE,CACtB,IAAI,EACA;QACE,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,EAAE,KAAK,CAAC;KACd,GACD;QACE,IAAI,EAAE,kBAAkB,CAAC;QACzB,KAAK,EAAE,OAAO,CAAC;KAChB,KACF,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AACD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EACrC,IAAI,EAAE,wBAAwB,GAC7B,aAAa,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAkL5C;AAED,eAAO,MAAM,UAAU;;;;;CAKb,CAAC"}
@@ -105,47 +105,141 @@ const SERIALIZED_ERROR_EVENT = 'serialized-error';
105
105
  /**
106
106
  * @see https://html.spec.whatwg.org/multipage/server-sent-events.html
107
107
  */ function sseStreamConsumer(opts) {
108
- const { deserialize =(v)=>v } = opts;
109
- const eventSource = opts.from;
108
+ const { deserialize =(v)=>v , shouldRecreateOnError } = opts;
109
+ const signal = opts.signal;
110
+ let eventSource = null;
111
+ let lock = null;
110
112
  const stream = createReadableStream.createReadableStream();
111
- const transform = new TransformStream({
112
- async transform (chunk, controller) {
113
- const data = deserialize(JSON.parse(chunk.data));
114
- if (chunk.type === SERIALIZED_ERROR_EVENT) {
115
- controller.enqueue({
116
- ok: false,
117
- error: data
118
- });
113
+ function createEventSource(...args) {
114
+ const es = new EventSource(...args);
115
+ if (signal.aborted) {
116
+ es.close();
117
+ } else {
118
+ signal.addEventListener('abort', ()=>es.close());
119
+ }
120
+ /**
121
+ * Dispatch an event to the stream controller
122
+ *
123
+ * Will be a no-op if the event source has been replaced
124
+ */ const dispatch = (fn)=>{
125
+ utils.run(async ()=>{
126
+ while(lock){
127
+ await lock;
128
+ }
129
+ if (es === eventSource) {
130
+ await fn(stream.controller);
131
+ }
132
+ }).catch((error)=>{
133
+ stream.controller.error(error);
134
+ });
135
+ };
136
+ const pauseDispatch = async (fn)=>{
137
+ while(lock){
138
+ await lock;
139
+ }
140
+ if (es !== eventSource) {
119
141
  return;
120
142
  }
121
- // console.debug('transforming', chunk.type, chunk.data);
122
- const def = {
123
- data
124
- };
125
- if (chunk.lastEventId) {
126
- def.id = chunk.lastEventId;
143
+ const deferred = createDeferred.createDeferred();
144
+ lock = deferred.promise;
145
+ try {
146
+ await fn();
147
+ } finally{
148
+ lock = null;
149
+ deferred.resolve();
127
150
  }
128
- controller.enqueue({
129
- ok: true,
130
- data: def
151
+ };
152
+ es.addEventListener('open', ()=>{
153
+ dispatch((controller)=>{
154
+ controller.enqueue({
155
+ type: 'opened',
156
+ eventSource: es
157
+ });
131
158
  });
132
- }
133
- });
134
- eventSource.addEventListener('message', (msg)=>{
135
- stream.controller.enqueue(msg);
136
- });
137
- eventSource.addEventListener(SERIALIZED_ERROR_EVENT, (msg)=>{
138
- stream.controller.enqueue(msg);
139
- });
140
- eventSource.addEventListener('error', (cause)=>{
141
- if (eventSource.readyState === EventSource.CLOSED) {
142
- stream.controller.error(cause);
143
- }
159
+ });
160
+ es.addEventListener(SERIALIZED_ERROR_EVENT, (msg)=>{
161
+ dispatch(async ()=>{
162
+ if (shouldRecreateOnError) {
163
+ await pauseDispatch(async ()=>{
164
+ const recreate = await shouldRecreateOnError({
165
+ type: SERIALIZED_ERROR_EVENT,
166
+ error: deserialize(JSON.parse(msg.data))
167
+ });
168
+ if (recreate) {
169
+ await recreateEventSource();
170
+ }
171
+ });
172
+ }
173
+ dispatch((controller)=>{
174
+ controller.enqueue({
175
+ type: 'error',
176
+ error: deserialize(JSON.parse(msg.data)),
177
+ eventSource: es
178
+ });
179
+ });
180
+ });
181
+ });
182
+ es.addEventListener('error', (event)=>{
183
+ dispatch(async ()=>{
184
+ if (shouldRecreateOnError) {
185
+ await pauseDispatch(async ()=>{
186
+ const recreate = await shouldRecreateOnError({
187
+ type: 'event',
188
+ event
189
+ });
190
+ if (recreate) {
191
+ await recreateEventSource();
192
+ }
193
+ });
194
+ }
195
+ dispatch((controller)=>{
196
+ if (es.readyState === EventSource.CLOSED) {
197
+ controller.error(event);
198
+ } else {
199
+ controller.enqueue({
200
+ type: 'connecting',
201
+ eventSource: es
202
+ });
203
+ }
204
+ });
205
+ });
206
+ });
207
+ es.addEventListener('message', (msg)=>{
208
+ dispatch((controller)=>{
209
+ const chunk = deserialize(JSON.parse(msg.data));
210
+ const def = {
211
+ data: chunk
212
+ };
213
+ if (msg.lastEventId) {
214
+ def.id = msg.lastEventId;
215
+ }
216
+ controller.enqueue({
217
+ type: 'data',
218
+ data: def,
219
+ eventSource: es
220
+ });
221
+ });
222
+ });
223
+ return es;
224
+ }
225
+ async function recreateEventSource() {
226
+ eventSource?.close();
227
+ const [url, init] = await Promise.all([
228
+ opts.url(),
229
+ opts.init()
230
+ ]);
231
+ eventSource = createEventSource(url, init);
232
+ stream.controller.enqueue({
233
+ type: 'connecting',
234
+ eventSource
235
+ });
236
+ }
237
+ recreateEventSource().catch(()=>{
238
+ // prevent unhandled promise rejection
144
239
  });
145
- const readable = stream.readable.pipeThrough(transform);
146
240
  return {
147
241
  [Symbol.asyncIterator] () {
148
- const reader = readable.getReader();
242
+ const reader = stream.readable.getReader();
149
243
  const iterator = {
150
244
  async next () {
151
245
  const value = await reader.read();
@@ -1,7 +1,7 @@
1
1
  import { getTRPCErrorFromUnknown } from '../error/TRPCError.mjs';
2
2
  import { run } from '../utils.mjs';
3
3
  import { isTrackedEnvelope } from './tracked.mjs';
4
- import { createTimeoutPromise } from './utils/createDeferred.mjs';
4
+ import { createTimeoutPromise, createDeferred } from './utils/createDeferred.mjs';
5
5
  import { createReadableStream } from './utils/createReadableStream.mjs';
6
6
 
7
7
  const SERIALIZED_ERROR_EVENT = 'serialized-error';
@@ -103,47 +103,141 @@ const SERIALIZED_ERROR_EVENT = 'serialized-error';
103
103
  /**
104
104
  * @see https://html.spec.whatwg.org/multipage/server-sent-events.html
105
105
  */ function sseStreamConsumer(opts) {
106
- const { deserialize =(v)=>v } = opts;
107
- const eventSource = opts.from;
106
+ const { deserialize =(v)=>v , shouldRecreateOnError } = opts;
107
+ const signal = opts.signal;
108
+ let eventSource = null;
109
+ let lock = null;
108
110
  const stream = createReadableStream();
109
- const transform = new TransformStream({
110
- async transform (chunk, controller) {
111
- const data = deserialize(JSON.parse(chunk.data));
112
- if (chunk.type === SERIALIZED_ERROR_EVENT) {
113
- controller.enqueue({
114
- ok: false,
115
- error: data
116
- });
111
+ function createEventSource(...args) {
112
+ const es = new EventSource(...args);
113
+ if (signal.aborted) {
114
+ es.close();
115
+ } else {
116
+ signal.addEventListener('abort', ()=>es.close());
117
+ }
118
+ /**
119
+ * Dispatch an event to the stream controller
120
+ *
121
+ * Will be a no-op if the event source has been replaced
122
+ */ const dispatch = (fn)=>{
123
+ run(async ()=>{
124
+ while(lock){
125
+ await lock;
126
+ }
127
+ if (es === eventSource) {
128
+ await fn(stream.controller);
129
+ }
130
+ }).catch((error)=>{
131
+ stream.controller.error(error);
132
+ });
133
+ };
134
+ const pauseDispatch = async (fn)=>{
135
+ while(lock){
136
+ await lock;
137
+ }
138
+ if (es !== eventSource) {
117
139
  return;
118
140
  }
119
- // console.debug('transforming', chunk.type, chunk.data);
120
- const def = {
121
- data
122
- };
123
- if (chunk.lastEventId) {
124
- def.id = chunk.lastEventId;
141
+ const deferred = createDeferred();
142
+ lock = deferred.promise;
143
+ try {
144
+ await fn();
145
+ } finally{
146
+ lock = null;
147
+ deferred.resolve();
125
148
  }
126
- controller.enqueue({
127
- ok: true,
128
- data: def
149
+ };
150
+ es.addEventListener('open', ()=>{
151
+ dispatch((controller)=>{
152
+ controller.enqueue({
153
+ type: 'opened',
154
+ eventSource: es
155
+ });
129
156
  });
130
- }
131
- });
132
- eventSource.addEventListener('message', (msg)=>{
133
- stream.controller.enqueue(msg);
134
- });
135
- eventSource.addEventListener(SERIALIZED_ERROR_EVENT, (msg)=>{
136
- stream.controller.enqueue(msg);
137
- });
138
- eventSource.addEventListener('error', (cause)=>{
139
- if (eventSource.readyState === EventSource.CLOSED) {
140
- stream.controller.error(cause);
141
- }
157
+ });
158
+ es.addEventListener(SERIALIZED_ERROR_EVENT, (msg)=>{
159
+ dispatch(async ()=>{
160
+ if (shouldRecreateOnError) {
161
+ await pauseDispatch(async ()=>{
162
+ const recreate = await shouldRecreateOnError({
163
+ type: SERIALIZED_ERROR_EVENT,
164
+ error: deserialize(JSON.parse(msg.data))
165
+ });
166
+ if (recreate) {
167
+ await recreateEventSource();
168
+ }
169
+ });
170
+ }
171
+ dispatch((controller)=>{
172
+ controller.enqueue({
173
+ type: 'error',
174
+ error: deserialize(JSON.parse(msg.data)),
175
+ eventSource: es
176
+ });
177
+ });
178
+ });
179
+ });
180
+ es.addEventListener('error', (event)=>{
181
+ dispatch(async ()=>{
182
+ if (shouldRecreateOnError) {
183
+ await pauseDispatch(async ()=>{
184
+ const recreate = await shouldRecreateOnError({
185
+ type: 'event',
186
+ event
187
+ });
188
+ if (recreate) {
189
+ await recreateEventSource();
190
+ }
191
+ });
192
+ }
193
+ dispatch((controller)=>{
194
+ if (es.readyState === EventSource.CLOSED) {
195
+ controller.error(event);
196
+ } else {
197
+ controller.enqueue({
198
+ type: 'connecting',
199
+ eventSource: es
200
+ });
201
+ }
202
+ });
203
+ });
204
+ });
205
+ es.addEventListener('message', (msg)=>{
206
+ dispatch((controller)=>{
207
+ const chunk = deserialize(JSON.parse(msg.data));
208
+ const def = {
209
+ data: chunk
210
+ };
211
+ if (msg.lastEventId) {
212
+ def.id = msg.lastEventId;
213
+ }
214
+ controller.enqueue({
215
+ type: 'data',
216
+ data: def,
217
+ eventSource: es
218
+ });
219
+ });
220
+ });
221
+ return es;
222
+ }
223
+ async function recreateEventSource() {
224
+ eventSource?.close();
225
+ const [url, init] = await Promise.all([
226
+ opts.url(),
227
+ opts.init()
228
+ ]);
229
+ eventSource = createEventSource(url, init);
230
+ stream.controller.enqueue({
231
+ type: 'connecting',
232
+ eventSource
233
+ });
234
+ }
235
+ recreateEventSource().catch(()=>{
236
+ // prevent unhandled promise rejection
142
237
  });
143
- const readable = stream.readable.pipeThrough(transform);
144
238
  return {
145
239
  [Symbol.asyncIterator] () {
146
- const reader = readable.getReader();
240
+ const reader = stream.readable.getReader();
147
241
  const iterator = {
148
242
  async next () {
149
243
  const value = await reader.read();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trpc/server",
3
- "version": "11.0.0-rc.553+9b629cc67",
3
+ "version": "11.0.0-rc.561+c50cd4308",
4
4
  "description": "The tRPC server library",
5
5
  "author": "KATT",
6
6
  "license": "MIT",
@@ -149,5 +149,5 @@
149
149
  "funding": [
150
150
  "https://trpc.io/sponsor"
151
151
  ],
152
- "gitHead": "9b629cc672aad7908af1d5355e3f2dd8f03f048d"
152
+ "gitHead": "c50cd4308223508184310103938d1fee50046989"
153
153
  }
@@ -436,6 +436,9 @@ export async function jsonlStreamConsumer<THead>(opts: {
436
436
  deserialize?: Deserialize;
437
437
  onError?: ConsumerOnError;
438
438
  formatError?: (opts: { error: unknown }) => Error;
439
+ /**
440
+ * This `AbortController` will be triggered when there are no more listeners to the stream.
441
+ */
439
442
  abortController: AbortController | null;
440
443
  }) {
441
444
  const { deserialize = (v) => v } = opts;
@@ -1,9 +1,9 @@
1
1
  import { getTRPCErrorFromUnknown } from '../error/TRPCError';
2
+ import type { MaybePromise } from '../types';
2
3
  import { run } from '../utils';
3
- import type { ConsumerOnError } from './jsonl';
4
4
  import type { inferTrackedOutput } from './tracked';
5
5
  import { isTrackedEnvelope } from './tracked';
6
- import { createTimeoutPromise } from './utils/createDeferred';
6
+ import { createDeferred, createTimeoutPromise } from './utils/createDeferred';
7
7
  import { createReadableStream } from './utils/createReadableStream';
8
8
 
9
9
  type Serialize = (value: any) => any;
@@ -175,78 +175,212 @@ export function sseStreamProducer(opts: SSEStreamProducerOptions) {
175
175
  );
176
176
  }
177
177
 
178
+ interface ConsumerStreamResultBase {
179
+ eventSource: EventSource;
180
+ }
181
+
182
+ interface ConsumerStreamResultData<TData> extends ConsumerStreamResultBase {
183
+ type: 'data';
184
+ data: inferTrackedOutput<TData>;
185
+ }
186
+
187
+ interface ConsumerStreamResultError extends ConsumerStreamResultBase {
188
+ type: 'error';
189
+ error: unknown;
190
+ }
191
+
192
+ interface ConsumerStreamResultOpened extends ConsumerStreamResultBase {
193
+ type: 'opened';
194
+ }
195
+
196
+ interface ConsumerStreamResultConnecting extends ConsumerStreamResultBase {
197
+ type: 'connecting';
198
+ }
199
+
178
200
  type ConsumerStreamResult<TData> =
179
- | {
180
- ok: true;
181
- data: inferTrackedOutput<TData>;
182
- }
183
- | {
184
- ok: false;
185
- error: unknown;
186
- };
201
+ | ConsumerStreamResultData<TData>
202
+ | ConsumerStreamResultError
203
+ | ConsumerStreamResultOpened
204
+ | ConsumerStreamResultConnecting;
187
205
 
206
+ export interface SSEStreamConsumerOptions {
207
+ url: () => MaybePromise<string>;
208
+ init: () => MaybePromise<EventSourceInit> | undefined;
209
+ signal: AbortSignal;
210
+ shouldRecreateOnError?: (
211
+ opts:
212
+ | {
213
+ type: 'event';
214
+ event: Event;
215
+ }
216
+ | {
217
+ type: 'serialized-error';
218
+ error: unknown;
219
+ },
220
+ ) => boolean | Promise<boolean>;
221
+ deserialize?: Deserialize;
222
+ }
188
223
  /**
189
224
  * @see https://html.spec.whatwg.org/multipage/server-sent-events.html
190
225
  */
191
- export function sseStreamConsumer<TData>(opts: {
192
- from: EventSource;
193
- onError?: ConsumerOnError;
194
- deserialize?: Deserialize;
195
- }): AsyncIterable<ConsumerStreamResult<TData>> {
196
- const { deserialize = (v) => v } = opts;
197
- const eventSource = opts.from;
198
-
199
- const stream = createReadableStream<MessageEvent>();
200
-
201
- const transform = new TransformStream<
202
- MessageEvent,
203
- ConsumerStreamResult<TData>
204
- >({
205
- async transform(chunk, controller) {
206
- const data = deserialize(JSON.parse(chunk.data));
207
- if (chunk.type === SERIALIZED_ERROR_EVENT) {
208
- controller.enqueue({
209
- ok: false,
210
- error: data,
211
- });
226
+ export function sseStreamConsumer<TData>(
227
+ opts: SSEStreamConsumerOptions,
228
+ ): AsyncIterable<ConsumerStreamResult<TData>> {
229
+ const { deserialize = (v) => v, shouldRecreateOnError } = opts;
230
+
231
+ const signal = opts.signal;
232
+
233
+ let eventSource: EventSource | null = null;
234
+ let lock: Promise<void> | null = null;
235
+
236
+ const stream = createReadableStream<ConsumerStreamResult<TData>>();
237
+
238
+ function createEventSource(
239
+ ...args: ConstructorParameters<typeof EventSource>
240
+ ) {
241
+ const es = new EventSource(...args);
242
+
243
+ if (signal.aborted) {
244
+ es.close();
245
+ } else {
246
+ signal.addEventListener('abort', () => es.close());
247
+ }
248
+
249
+ /**
250
+ * Dispatch an event to the stream controller
251
+ *
252
+ * Will be a no-op if the event source has been replaced
253
+ */
254
+ const dispatch = (
255
+ fn: (controller: typeof stream.controller) => void | Promise<void>,
256
+ ): void => {
257
+ run(async () => {
258
+ while (lock) {
259
+ await lock;
260
+ }
261
+ if (es === eventSource) {
262
+ await fn(stream.controller);
263
+ }
264
+ }).catch((error) => {
265
+ stream.controller.error(error);
266
+ });
267
+ };
268
+
269
+ const pauseDispatch = async (fn: () => Promise<void>): Promise<void> => {
270
+ while (lock) {
271
+ await lock;
272
+ }
273
+ if (es !== eventSource) {
212
274
  return;
213
275
  }
214
- // console.debug('transforming', chunk.type, chunk.data);
215
- const def: SSEvent = {
216
- data,
217
- };
218
276
 
219
- if (chunk.lastEventId) {
220
- def.id = chunk.lastEventId;
277
+ const deferred = createDeferred<void>();
278
+ lock = deferred.promise;
279
+ try {
280
+ await fn();
281
+ } finally {
282
+ lock = null;
283
+ deferred.resolve();
221
284
  }
285
+ };
222
286
 
223
- controller.enqueue({
224
- ok: true,
225
- data: def as inferTrackedOutput<TData>,
287
+ es.addEventListener('open', () => {
288
+ dispatch((controller) => {
289
+ controller.enqueue({
290
+ type: 'opened',
291
+ eventSource: es,
292
+ });
226
293
  });
227
- },
228
- });
294
+ });
229
295
 
230
- eventSource.addEventListener('message', (msg) => {
231
- stream.controller.enqueue(msg);
232
- });
233
- eventSource.addEventListener(SERIALIZED_ERROR_EVENT, (msg) => {
234
- stream.controller.enqueue(msg);
235
- });
236
- eventSource.addEventListener('error', (cause) => {
237
- if (eventSource.readyState === EventSource.CLOSED) {
238
- stream.controller.error(cause);
239
- }
240
- });
296
+ es.addEventListener(SERIALIZED_ERROR_EVENT, (msg) => {
297
+ dispatch(async () => {
298
+ if (shouldRecreateOnError) {
299
+ await pauseDispatch(async () => {
300
+ const recreate = await shouldRecreateOnError({
301
+ type: SERIALIZED_ERROR_EVENT,
302
+ error: deserialize(JSON.parse(msg.data)),
303
+ });
304
+ if (recreate) {
305
+ await recreateEventSource();
306
+ }
307
+ });
308
+ }
309
+ dispatch((controller) => {
310
+ controller.enqueue({
311
+ type: 'error',
312
+ error: deserialize(JSON.parse(msg.data)),
313
+ eventSource: es,
314
+ });
315
+ });
316
+ });
317
+ });
318
+ es.addEventListener('error', (event) => {
319
+ dispatch(async () => {
320
+ if (shouldRecreateOnError) {
321
+ await pauseDispatch(async () => {
322
+ const recreate = await shouldRecreateOnError({
323
+ type: 'event',
324
+ event,
325
+ });
326
+ if (recreate) {
327
+ await recreateEventSource();
328
+ }
329
+ });
330
+ }
331
+
332
+ dispatch((controller) => {
333
+ if (es.readyState === EventSource.CLOSED) {
334
+ controller.error(event);
335
+ } else {
336
+ controller.enqueue({
337
+ type: 'connecting',
338
+ eventSource: es,
339
+ });
340
+ }
341
+ });
342
+ });
343
+ });
344
+ es.addEventListener('message', (msg) => {
345
+ dispatch((controller) => {
346
+ const chunk = deserialize(JSON.parse(msg.data));
241
347
 
242
- const readable = stream.readable.pipeThrough(transform);
348
+ const def: SSEvent = {
349
+ data: chunk,
350
+ };
351
+ if (msg.lastEventId) {
352
+ def.id = msg.lastEventId;
353
+ }
354
+ controller.enqueue({
355
+ type: 'data',
356
+ data: def as inferTrackedOutput<TData>,
357
+ eventSource: es,
358
+ });
359
+ });
360
+ });
361
+ return es;
362
+ }
363
+ async function recreateEventSource() {
364
+ eventSource?.close();
365
+ const [url, init] = await Promise.all([opts.url(), opts.init()]);
366
+ eventSource = createEventSource(url, init);
367
+ stream.controller.enqueue({
368
+ type: 'connecting',
369
+ eventSource,
370
+ });
371
+ }
372
+
373
+ recreateEventSource().catch(() => {
374
+ // prevent unhandled promise rejection
375
+ });
243
376
  return {
244
377
  [Symbol.asyncIterator]() {
245
- const reader = readable.getReader();
378
+ const reader = stream.readable.getReader();
246
379
 
247
380
  const iterator: AsyncIterator<ConsumerStreamResult<TData>> = {
248
381
  async next() {
249
382
  const value = await reader.read();
383
+
250
384
  if (value.done) {
251
385
  return {
252
386
  value: undefined,