@trpc/server 11.0.0-rc.417 → 11.0.0-rc.419

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 (95) hide show
  1. package/dist/@trpc/server/index.d.ts +1 -1
  2. package/dist/@trpc/server/index.d.ts.map +1 -1
  3. package/dist/adapters/aws-lambda/getPlanner.d.ts.map +1 -1
  4. package/dist/adapters/next-app-dir/redirect.d.ts.map +1 -1
  5. package/dist/adapters/node-http/incomingMessageToRequest.d.ts +0 -1
  6. package/dist/adapters/node-http/incomingMessageToRequest.d.ts.map +1 -1
  7. package/dist/adapters/node-http/incomingMessageToRequest.js +3 -1
  8. package/dist/adapters/node-http/incomingMessageToRequest.mjs +3 -1
  9. package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts.map +1 -1
  10. package/dist/adapters/node-http/nodeHTTPRequestHandler.js +30 -7
  11. package/dist/adapters/node-http/nodeHTTPRequestHandler.mjs +30 -7
  12. package/dist/adapters/node-http/types.d.ts +0 -1
  13. package/dist/adapters/node-http/types.d.ts.map +1 -1
  14. package/dist/adapters/standalone.d.ts +0 -1
  15. package/dist/adapters/standalone.d.ts.map +1 -1
  16. package/dist/adapters/ws.d.ts +1 -2
  17. package/dist/adapters/ws.d.ts.map +1 -1
  18. package/dist/adapters/ws.js +98 -81
  19. package/dist/adapters/ws.mjs +98 -81
  20. package/dist/bundle-analysis.json +196 -137
  21. package/dist/index.js +5 -3
  22. package/dist/index.mjs +2 -1
  23. package/dist/observable/observable.d.ts +1 -0
  24. package/dist/observable/observable.d.ts.map +1 -1
  25. package/dist/observable/observable.js +55 -0
  26. package/dist/observable/observable.mjs +55 -1
  27. package/dist/unstable-core-do-not-import/createProxy.d.ts.map +1 -1
  28. package/dist/unstable-core-do-not-import/http/contentType.d.ts +7 -4
  29. package/dist/unstable-core-do-not-import/http/contentType.d.ts.map +1 -1
  30. package/dist/unstable-core-do-not-import/http/contentType.js +55 -17
  31. package/dist/unstable-core-do-not-import/http/contentType.mjs +56 -18
  32. package/dist/unstable-core-do-not-import/http/resolveResponse.d.ts.map +1 -1
  33. package/dist/unstable-core-do-not-import/http/resolveResponse.js +302 -149
  34. package/dist/unstable-core-do-not-import/http/resolveResponse.mjs +301 -148
  35. package/dist/unstable-core-do-not-import/http/types.d.ts +34 -5
  36. package/dist/unstable-core-do-not-import/http/types.d.ts.map +1 -1
  37. package/dist/unstable-core-do-not-import/initTRPC.d.ts +12 -12
  38. package/dist/unstable-core-do-not-import/initTRPC.d.ts.map +1 -1
  39. package/dist/unstable-core-do-not-import/middleware.d.ts +3 -3
  40. package/dist/unstable-core-do-not-import/middleware.d.ts.map +1 -1
  41. package/dist/unstable-core-do-not-import/procedureBuilder.d.ts +3 -1
  42. package/dist/unstable-core-do-not-import/procedureBuilder.d.ts.map +1 -1
  43. package/dist/unstable-core-do-not-import/rootConfig.d.ts +12 -0
  44. package/dist/unstable-core-do-not-import/rootConfig.d.ts.map +1 -1
  45. package/dist/unstable-core-do-not-import/router.d.ts +2 -2
  46. package/dist/unstable-core-do-not-import/router.d.ts.map +1 -1
  47. package/dist/unstable-core-do-not-import/router.js +6 -0
  48. package/dist/unstable-core-do-not-import/router.mjs +6 -0
  49. package/dist/unstable-core-do-not-import/stream/{stream.d.ts → jsonl.d.ts} +5 -5
  50. package/dist/unstable-core-do-not-import/stream/jsonl.d.ts.map +1 -0
  51. package/dist/unstable-core-do-not-import/stream/{stream.js → jsonl.js} +90 -89
  52. package/dist/unstable-core-do-not-import/stream/{stream.mjs → jsonl.mjs} +89 -88
  53. package/dist/unstable-core-do-not-import/stream/sse.d.ts +95 -0
  54. package/dist/unstable-core-do-not-import/stream/sse.d.ts.map +1 -0
  55. package/dist/unstable-core-do-not-import/stream/sse.js +175 -0
  56. package/dist/unstable-core-do-not-import/stream/sse.mjs +169 -0
  57. package/dist/unstable-core-do-not-import/stream/utils/createDeferred.d.ts +18 -0
  58. package/dist/unstable-core-do-not-import/stream/utils/createDeferred.d.ts.map +1 -0
  59. package/dist/unstable-core-do-not-import/stream/utils/createDeferred.js +46 -0
  60. package/dist/unstable-core-do-not-import/stream/utils/createDeferred.mjs +43 -0
  61. package/dist/unstable-core-do-not-import/stream/utils/createReadableStream.d.ts +10 -0
  62. package/dist/unstable-core-do-not-import/stream/utils/createReadableStream.d.ts.map +1 -0
  63. package/dist/unstable-core-do-not-import/stream/utils/createReadableStream.js +31 -0
  64. package/dist/unstable-core-do-not-import/stream/utils/createReadableStream.mjs +29 -0
  65. package/dist/unstable-core-do-not-import/stream/utils/createServer.d.ts +7 -0
  66. package/dist/unstable-core-do-not-import/stream/utils/createServer.d.ts.map +1 -0
  67. package/dist/unstable-core-do-not-import/transformer.d.ts +5 -5
  68. package/dist/unstable-core-do-not-import/utils.d.ts +4 -0
  69. package/dist/unstable-core-do-not-import/utils.d.ts.map +1 -1
  70. package/dist/unstable-core-do-not-import/utils.js +4 -0
  71. package/dist/unstable-core-do-not-import/utils.mjs +4 -1
  72. package/dist/unstable-core-do-not-import.d.ts +2 -1
  73. package/dist/unstable-core-do-not-import.d.ts.map +1 -1
  74. package/dist/unstable-core-do-not-import.js +11 -4
  75. package/dist/unstable-core-do-not-import.mjs +3 -2
  76. package/package.json +3 -3
  77. package/src/@trpc/server/index.ts +1 -0
  78. package/src/adapters/node-http/incomingMessageToRequest.ts +3 -2
  79. package/src/adapters/node-http/nodeHTTPRequestHandler.ts +32 -7
  80. package/src/adapters/ws.ts +101 -75
  81. package/src/observable/observable.ts +63 -0
  82. package/src/unstable-core-do-not-import/http/contentType.ts +78 -21
  83. package/src/unstable-core-do-not-import/http/resolveResponse.ts +331 -164
  84. package/src/unstable-core-do-not-import/http/types.ts +42 -5
  85. package/src/unstable-core-do-not-import/procedureBuilder.ts +8 -1
  86. package/src/unstable-core-do-not-import/rootConfig.ts +12 -0
  87. package/src/unstable-core-do-not-import/router.ts +12 -0
  88. package/src/unstable-core-do-not-import/stream/{stream.ts → jsonl.ts} +99 -85
  89. package/src/unstable-core-do-not-import/stream/sse.ts +291 -0
  90. package/src/unstable-core-do-not-import/stream/utils/createDeferred.ts +48 -0
  91. package/src/unstable-core-do-not-import/stream/utils/createReadableStream.ts +31 -0
  92. package/src/unstable-core-do-not-import/stream/utils/createServer.ts +46 -0
  93. package/src/unstable-core-do-not-import/utils.ts +5 -0
  94. package/src/unstable-core-do-not-import.ts +2 -1
  95. package/dist/unstable-core-do-not-import/stream/stream.d.ts.map +0 -1
@@ -1,5 +1,9 @@
1
1
  import type { TRPCError } from '../error/TRPCError';
2
- import type { ErrorHandlerOptions, ProcedureType } from '../procedure';
2
+ import type {
3
+ AnyProcedure,
4
+ ErrorHandlerOptions,
5
+ ProcedureType,
6
+ } from '../procedure';
3
7
  import type {
4
8
  AnyRouter,
5
9
  inferRouterContext,
@@ -51,6 +55,8 @@ export interface HTTPBaseHandlerOptions<TRouter extends AnyRouter, TRequest>
51
55
  responseMeta?: ResponseMetaFn<TRouter>;
52
56
  }
53
57
 
58
+ export type TRPCAcceptHeader = 'application/jsonl';
59
+
54
60
  interface TRPCRequestInfoProcedureCall {
55
61
  path: string;
56
62
  /**
@@ -61,16 +67,47 @@ interface TRPCRequestInfoProcedureCall {
61
67
  * Get already parsed inputs - won't trigger reading the body or parsing the inputs
62
68
  */
63
69
  result: () => unknown;
70
+ /**
71
+ * The procedure being called, `null` if not found
72
+ * @internal
73
+ */
74
+ procedure: AnyProcedure | null;
75
+ }
76
+
77
+ export interface TRPCRequestInfoBase {
78
+ /**
79
+ * The `trpc-accept` header
80
+ */
81
+ accept: TRPCAcceptHeader | null;
82
+ /**
83
+ * The type of the request
84
+ */
85
+ type: ProcedureType | 'unknown';
86
+ /**
87
+ * If the content type handler has detected that this is a batch call
88
+ */
89
+ isBatchCall: boolean;
90
+ /**
91
+ * The calls being made
92
+ */
93
+ calls: TRPCRequestInfoProcedureCall[];
94
+ }
95
+ interface TRPCRequestInfoBatchCall extends TRPCRequestInfoBase {
96
+ isBatchCall: true;
97
+ calls: TRPCRequestInfoProcedureCall[];
98
+ }
99
+ interface TRPCRequestInfoSingleCall extends TRPCRequestInfoBase {
100
+ isBatchCall: false;
101
+ calls: [TRPCRequestInfoProcedureCall];
64
102
  }
65
103
 
66
104
  /**
67
105
  * Information about the incoming request
68
106
  * @public
69
107
  */
70
- export interface TRPCRequestInfo {
71
- isBatchCall: boolean;
72
- calls: TRPCRequestInfoProcedureCall[];
73
- }
108
+ export type TRPCRequestInfo =
109
+ | TRPCRequestInfoBatchCall
110
+ | TRPCRequestInfoSingleCall;
74
111
 
75
112
  /**
76
113
  * Inner createContext function for `resolveResponse` used to forward `TRPCRequestInfo` to `createContext`
@@ -23,6 +23,7 @@ import type {
23
23
  QueryProcedure,
24
24
  SubscriptionProcedure,
25
25
  } from './procedure';
26
+ import type { inferSSEOutput } from './stream/sse';
26
27
  import type {
27
28
  GetRawInputFn,
28
29
  MaybePromise,
@@ -43,6 +44,12 @@ type DefaultValue<TValue, TFallback> = TValue extends UnsetMarker
43
44
  ? TFallback
44
45
  : TValue;
45
46
 
47
+ type inferSubscriptionOutput<TOutput> = TOutput extends AsyncIterable<
48
+ infer $Output
49
+ >
50
+ ? inferSSEOutput<$Output>
51
+ : inferObservableValue<TOutput>;
52
+
46
53
  export type CallerOverride<TContext> = (opts: {
47
54
  args: unknown[];
48
55
  invoke: (opts: ProcedureCallOptions<TContext>) => Promise<unknown>;
@@ -347,7 +354,7 @@ export interface ProcedureBuilder<
347
354
  ? TypeError<'Not implemented'>
348
355
  : SubscriptionProcedure<{
349
356
  input: DefaultValue<TInputIn, void>;
350
- output: DefaultValue<TOutputOut, inferObservableValue<$Output>>;
357
+ output: DefaultValue<TOutputOut, inferSubscriptionOutput<$Output>>;
351
358
  }>;
352
359
 
353
360
  /**
@@ -1,5 +1,6 @@
1
1
  import type { CombinedDataTransformer } from '../unstable-core-do-not-import';
2
2
  import type { DefaultErrorShape, ErrorFormatter } from './error/formatter';
3
+ import type { SSEStreamProducerOptions } from './stream/sse';
3
4
 
4
5
  /**
5
6
  * The initial generics that are used in the init function
@@ -67,8 +68,19 @@ export interface RootConfig<TTypes extends RootTypes> {
67
68
  experimental?: {
68
69
  /**
69
70
  * Enable support for returning async iterables and returning deferred promises when using `httpBatchStreamLink`
71
+ * @default true
70
72
  */
71
73
  iterablesAndDeferreds?: boolean;
74
+ /**
75
+ * Enable support for server-sent events (SSE) subscriptions
76
+ */
77
+ sseSubscriptions?: {
78
+ /**
79
+ * Enable server-sent events (SSE) subscriptions
80
+ * @default true
81
+ */
82
+ enabled: boolean;
83
+ } & Omit<SSEStreamProducerOptions, 'maxDepth' | 'data' | 'serialize'>;
72
84
  };
73
85
  }
74
86
 
@@ -248,6 +248,18 @@ export function callProcedure(
248
248
  });
249
249
  }
250
250
 
251
+ /* istanbul ignore if -- @preserve */
252
+ if (
253
+ proc._def.type !== type &&
254
+ opts.allowMethodOverride &&
255
+ proc._def.type === 'subscription'
256
+ ) {
257
+ throw new TRPCError({
258
+ code: 'METHOD_NOT_SUPPORTED',
259
+ message: `Method override is not supported for subscriptions`,
260
+ });
261
+ }
262
+
251
263
  return proc(opts);
252
264
  }
253
265
 
@@ -1,19 +1,8 @@
1
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
- import { isAsyncIterable, isFunction, isObject } from '../utils';
3
-
4
- // ---------- utils
5
-
6
- function createReadableStream<TValue = unknown>() {
7
- let controller: ReadableStreamDefaultController<TValue> =
8
- null as unknown as ReadableStreamDefaultController<TValue>;
9
- const stream = new ReadableStream<TValue>({
10
- start(c) {
11
- controller = c;
12
- },
13
- });
14
-
15
- return [stream, controller] as const;
16
- }
1
+ import { getTRPCErrorFromUnknown } from '../error/TRPCError';
2
+ import { isAsyncIterable, isFunction, isObject, run } from '../utils';
3
+ import type { Deferred } from './utils/createDeferred';
4
+ import { createDeferred } from './utils/createDeferred';
5
+ import { createReadableStream } from './utils/createReadableStream';
17
6
 
18
7
  /**
19
8
  * A subset of the standard ReadableStream properties needed by tRPC internally.
@@ -65,19 +54,19 @@ type ChunkDefinition = [
65
54
  type: ChunkValueType,
66
55
  chunkId: ChunkIndex,
67
56
  ];
68
- type HydratedValue = [
57
+ type DehydratedValue = [
69
58
  // data
70
59
  [unknown],
71
60
  // chunk descriptions
72
61
  ...ChunkDefinition[],
73
62
  ];
74
63
 
75
- type Head = Record<string, HydratedValue>;
64
+ type Head = Record<string, DehydratedValue>;
76
65
  type PromiseChunk =
77
66
  | [
78
67
  chunkIndex: ChunkIndex,
79
68
  status: PROMISE_STATUS_FULFILLED,
80
- value: HydratedValue,
69
+ value: DehydratedValue,
81
70
  ]
82
71
  | [chunkIndex: ChunkIndex, status: PROMISE_STATUS_REJECTED, error: unknown];
83
72
  type IterableChunk =
@@ -85,7 +74,7 @@ type IterableChunk =
85
74
  | [
86
75
  chunkIndex: ChunkIndex,
87
76
  status: ASYNC_ITERABLE_STATUS_VALUE,
88
- value: HydratedValue,
77
+ value: DehydratedValue,
89
78
  ]
90
79
  | [
91
80
  chunkIndex: ChunkIndex,
@@ -111,7 +100,7 @@ export type ProducerOnError = (opts: {
111
100
  }) => void;
112
101
  export interface ProducerOptions {
113
102
  serialize?: Serialize;
114
- data: Record<number, unknown>;
103
+ data: Record<string, unknown> | unknown[];
115
104
  onError?: ProducerOnError;
116
105
  formatError?: (opts: {
117
106
  error: unknown;
@@ -131,14 +120,15 @@ function createBatchStreamProducer(opts: ProducerOptions) {
131
120
  let counter = 0 as ChunkIndex;
132
121
  const placeholder = 0 as PlaceholderValue;
133
122
 
134
- const [stream, controller] = createReadableStream<ChunkData>();
123
+ const stream = createReadableStream<ChunkData>();
135
124
  const pending = new Set<ChunkIndex>();
125
+
136
126
  function maybeClose() {
137
- if (pending.size === 0) {
138
- controller.close();
127
+ if (pending.size === 0 && !stream.cancelled()) {
128
+ stream.controller.close();
139
129
  }
140
130
  }
141
- function hydratePromise(
131
+ function dehydratePromise(
142
132
  promise: Promise<unknown>,
143
133
  path: (string | number)[],
144
134
  ) {
@@ -152,19 +142,24 @@ function createBatchStreamProducer(opts: ProducerOptions) {
152
142
  }
153
143
  const idx = counter++ as ChunkIndex;
154
144
  pending.add(idx);
155
- const enqueue = (value: PromiseChunk) => {
156
- controller.enqueue(value);
157
- };
158
- promise
145
+
146
+ Promise.race([promise, stream.cancelledPromise])
159
147
  .then((it) => {
160
- enqueue([idx, PROMISE_STATUS_FULFILLED, hydrate(it, path)]);
148
+ if (it === null) {
149
+ return;
150
+ }
151
+ stream.controller.enqueue([
152
+ idx,
153
+ PROMISE_STATUS_FULFILLED,
154
+ dehydrate(it, path),
155
+ ]);
161
156
  })
162
- .catch((error) => {
163
- opts.onError?.({ error, path });
164
- enqueue([
157
+ .catch((cause) => {
158
+ opts.onError?.({ error: cause, path });
159
+ stream.controller.enqueue([
165
160
  idx,
166
161
  PROMISE_STATUS_REJECTED,
167
- opts.formatError?.({ error, path }),
162
+ opts.formatError?.({ error: cause, path }),
168
163
  ]);
169
164
  })
170
165
  .finally(() => {
@@ -173,7 +168,7 @@ function createBatchStreamProducer(opts: ProducerOptions) {
173
168
  });
174
169
  return idx;
175
170
  }
176
- function hydrateAsyncIterable(
171
+ function dehydrateAsyncIterable(
177
172
  iterable: AsyncIterable<unknown>,
178
173
  path: (string | number)[],
179
174
  ) {
@@ -187,28 +182,56 @@ function createBatchStreamProducer(opts: ProducerOptions) {
187
182
  }
188
183
  const idx = counter++ as ChunkIndex;
189
184
  pending.add(idx);
190
- void (async () => {
191
- try {
192
- for await (const item of iterable) {
193
- controller.enqueue([
185
+ run(async () => {
186
+ const iterator = iterable[Symbol.asyncIterator]();
187
+
188
+ while (true) {
189
+ const next = await Promise.race([
190
+ iterator.next().catch(getTRPCErrorFromUnknown),
191
+ stream.cancelledPromise,
192
+ ]);
193
+
194
+ if (next instanceof Error) {
195
+ opts.onError?.({ error: next, path });
196
+
197
+ stream.controller.enqueue([
194
198
  idx,
195
- ASYNC_ITERABLE_STATUS_VALUE,
196
- hydrate(item, path),
199
+ ASYNC_ITERABLE_STATUS_ERROR,
200
+ opts.formatError?.({ error: next, path }),
197
201
  ]);
202
+ return;
198
203
  }
199
- controller.enqueue([idx, ASYNC_ITERABLE_STATUS_DONE]);
200
- } catch (error) {
201
- opts.onError?.({ error, path });
202
- controller.enqueue([
204
+ if (next === 'cancelled') {
205
+ await iterator.return?.();
206
+ break;
207
+ }
208
+ if (next.done) {
209
+ stream.controller.enqueue([idx, ASYNC_ITERABLE_STATUS_DONE]);
210
+ break;
211
+ }
212
+ stream.controller.enqueue([
203
213
  idx,
204
- ASYNC_ITERABLE_STATUS_ERROR,
205
- opts.formatError?.({ error, path }),
214
+ ASYNC_ITERABLE_STATUS_VALUE,
215
+ dehydrate(next.value, path),
206
216
  ]);
207
- } finally {
208
- pending.delete(idx);
209
- maybeClose();
210
217
  }
211
- })();
218
+
219
+ pending.delete(idx);
220
+ maybeClose();
221
+ }).catch((cause) => {
222
+ // this shouldn't happen, but node crashes if we don't catch it
223
+ opts.onError?.({
224
+ error: new Error(
225
+ 'You found a bug - please report it on https://github.com/trpc/trpc',
226
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
227
+ // @ts-ignore https://github.com/tc39/proposal-error-cause
228
+ {
229
+ cause,
230
+ },
231
+ ),
232
+ path,
233
+ });
234
+ });
212
235
  return idx;
213
236
  }
214
237
  function checkMaxDepth(path: (string | number)[]) {
@@ -217,12 +240,12 @@ function createBatchStreamProducer(opts: ProducerOptions) {
217
240
  }
218
241
  return null;
219
242
  }
220
- function hydrateChunk(
243
+ function dehydrateChunk(
221
244
  value: unknown,
222
245
  path: (string | number)[],
223
246
  ): null | [type: ChunkValueType, chunkId: ChunkIndex] {
224
247
  if (isPromise(value)) {
225
- return [CHUNK_VALUE_TYPE_PROMISE, hydratePromise(value, path)];
248
+ return [CHUNK_VALUE_TYPE_PROMISE, dehydratePromise(value, path)];
226
249
  }
227
250
  if (isAsyncIterable(value)) {
228
251
  if (opts.maxDepth && path.length >= opts.maxDepth) {
@@ -230,13 +253,16 @@ function createBatchStreamProducer(opts: ProducerOptions) {
230
253
  }
231
254
  return [
232
255
  CHUNK_VALUE_TYPE_ASYNC_ITERABLE,
233
- hydrateAsyncIterable(value, path),
256
+ dehydrateAsyncIterable(value, path),
234
257
  ];
235
258
  }
236
259
  return null;
237
260
  }
238
- function hydrate(value: unknown, path: (string | number)[]): HydratedValue {
239
- const reg = hydrateChunk(value, path);
261
+ function dehydrate(
262
+ value: unknown,
263
+ path: (string | number)[],
264
+ ): DehydratedValue {
265
+ const reg = dehydrateChunk(value, path);
240
266
  if (reg) {
241
267
  return [[placeholder], [null, ...reg]];
242
268
  }
@@ -246,7 +272,7 @@ function createBatchStreamProducer(opts: ProducerOptions) {
246
272
  const newObj = {} as Record<string, unknown>;
247
273
  const asyncValues: ChunkDefinition[] = [];
248
274
  for (const [key, item] of Object.entries(value)) {
249
- const transformed = hydrateChunk(item, [...path, key]);
275
+ const transformed = dehydrateChunk(item, [...path, key]);
250
276
  if (!transformed) {
251
277
  newObj[key] = item;
252
278
  continue;
@@ -259,10 +285,10 @@ function createBatchStreamProducer(opts: ProducerOptions) {
259
285
 
260
286
  const newHead: Head = {};
261
287
  for (const [key, item] of Object.entries(data)) {
262
- newHead[key] = hydrate(item, [key]);
288
+ newHead[key] = dehydrate(item, [key]);
263
289
  }
264
290
 
265
- return [newHead, stream] as const;
291
+ return [newHead, stream.readable] as const;
266
292
  }
267
293
  /**
268
294
  * JSON Lines stream producer
@@ -296,6 +322,7 @@ export function jsonlStreamProducer(opts: ProducerOptions) {
296
322
  )
297
323
  .pipeThrough(new TextEncoderStream());
298
324
  }
325
+
299
326
  class StreamInterruptedError extends Error {
300
327
  constructor(cause?: unknown) {
301
328
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -313,7 +340,7 @@ export type ConsumerOnError = (opts: { error: unknown }) => void;
313
340
  const nodeJsStreamToReaderEsque = (source: NodeJSReadableStreamEsque) => {
314
341
  return {
315
342
  getReader() {
316
- const [stream, controller] = createReadableStream<Uint8Array>();
343
+ const { readable, controller } = createReadableStream<Uint8Array>();
317
344
  source.on('data', (chunk) => {
318
345
  controller.enqueue(chunk);
319
346
  });
@@ -323,7 +350,7 @@ const nodeJsStreamToReaderEsque = (source: NodeJSReadableStreamEsque) => {
323
350
  source.on('error', (error) => {
324
351
  controller.error(error);
325
352
  });
326
- return stream.getReader();
353
+ return readable.getReader();
327
354
  },
328
355
  };
329
356
  };
@@ -388,19 +415,6 @@ function createConsumerStream<THead>(
388
415
  );
389
416
  }
390
417
 
391
- function createDeferred<TValue>() {
392
- let resolve: (value: TValue) => void;
393
- let reject: (error: unknown) => void;
394
- const promise = new Promise<TValue>((res, rej) => {
395
- resolve = res;
396
- reject = rej;
397
- });
398
-
399
- return { promise, resolve: resolve!, reject: reject! };
400
- }
401
-
402
- type Deferred<TValue> = ReturnType<typeof createDeferred<TValue>>;
403
-
404
418
  /**
405
419
  * JSON Lines stream consumer
406
420
  * @see https://jsonlines.org/
@@ -430,10 +444,10 @@ export async function jsonlStreamConsumer<THead>(opts: {
430
444
  const chunkDeferred = new Map<ChunkIndex, Deferred<ChunkController>>();
431
445
  const controllers = new Map<ChunkIndex, ChunkController>();
432
446
 
433
- function dehydrateChunkDefinition(value: ChunkDefinition) {
447
+ function hydrateChunkDefinition(value: ChunkDefinition) {
434
448
  const [_path, type, chunkId] = value;
435
449
 
436
- const [stream, controller] = createReadableStream<ChunkData>();
450
+ const { readable, controller } = createReadableStream<ChunkData>();
437
451
  controllers.set(chunkId, controller);
438
452
 
439
453
  // resolve chunk deferred if it exists
@@ -447,7 +461,7 @@ export async function jsonlStreamConsumer<THead>(opts: {
447
461
  case CHUNK_VALUE_TYPE_PROMISE: {
448
462
  return new Promise((resolve, reject) => {
449
463
  // listen for next value in the stream
450
- const reader = stream.getReader();
464
+ const reader = readable.getReader();
451
465
  reader
452
466
  .read()
453
467
  .then((it) => {
@@ -463,7 +477,7 @@ export async function jsonlStreamConsumer<THead>(opts: {
463
477
  const [_chunkId, status, data] = value as PromiseChunk;
464
478
  switch (status) {
465
479
  case PROMISE_STATUS_FULFILLED:
466
- resolve(dehydrate(data));
480
+ resolve(hydrate(data));
467
481
  break;
468
482
  case PROMISE_STATUS_REJECTED:
469
483
  reject(
@@ -482,7 +496,7 @@ export async function jsonlStreamConsumer<THead>(opts: {
482
496
  case CHUNK_VALUE_TYPE_ASYNC_ITERABLE: {
483
497
  return {
484
498
  [Symbol.asyncIterator]: async function* () {
485
- const reader = stream.getReader();
499
+ const reader = readable.getReader();
486
500
  while (true) {
487
501
  const { done, value } = await reader.read();
488
502
  if (done) {
@@ -496,7 +510,7 @@ export async function jsonlStreamConsumer<THead>(opts: {
496
510
 
497
511
  switch (status) {
498
512
  case ASYNC_ITERABLE_STATUS_VALUE:
499
- yield dehydrate(data);
513
+ yield hydrate(data);
500
514
  break;
501
515
  case ASYNC_ITERABLE_STATUS_DONE:
502
516
  controllers.delete(chunkId);
@@ -514,18 +528,18 @@ export async function jsonlStreamConsumer<THead>(opts: {
514
528
  }
515
529
  }
516
530
 
517
- function dehydrate(value: HydratedValue): unknown {
531
+ function hydrate(value: DehydratedValue): unknown {
518
532
  const [[data], ...asyncProps] = value;
519
533
 
520
534
  for (const value of asyncProps) {
521
- const dehydrated = dehydrateChunkDefinition(value);
535
+ const hydrated = hydrateChunkDefinition(value);
522
536
 
523
537
  const [path] = value;
524
538
  if (path === null) {
525
- return dehydrated;
539
+ return hydrated;
526
540
  }
527
541
 
528
- (data as any)[path] = dehydrated;
542
+ (data as any)[path] = hydrated;
529
543
  }
530
544
  return data;
531
545
  }
@@ -552,7 +566,7 @@ export async function jsonlStreamConsumer<THead>(opts: {
552
566
  const head = chunkOrHead as Record<number | string, unknown>;
553
567
 
554
568
  for (const [key, value] of Object.entries(chunkOrHead)) {
555
- const parsed = dehydrate(value as any);
569
+ const parsed = hydrate(value as any);
556
570
  head[key] = parsed;
557
571
  }
558
572
  headDeferred.resolve(head as THead);