@trpc/server 11.0.0-rc.370 → 11.0.0-rc.374
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/dist/adapters/node-http/incomingMessageToRequest.js +21 -19
- package/dist/adapters/node-http/incomingMessageToRequest.mjs +21 -19
- package/dist/bundle-analysis.json +122 -103
- package/dist/unstable-core-do-not-import/clientish/serialize.d.ts +1 -1
- package/dist/unstable-core-do-not-import/clientish/serialize.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/http/resolveResponse.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/http/resolveResponse.js +79 -52
- package/dist/unstable-core-do-not-import/http/resolveResponse.mjs +78 -51
- package/dist/unstable-core-do-not-import/initTRPC.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/initTRPC.js +2 -1
- package/dist/unstable-core-do-not-import/initTRPC.mjs +2 -1
- package/dist/unstable-core-do-not-import/rootConfig.d.ts +6 -0
- package/dist/unstable-core-do-not-import/rootConfig.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/stream/stream.d.ts +94 -0
- package/dist/unstable-core-do-not-import/stream/stream.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/stream/stream.js +466 -0
- package/dist/unstable-core-do-not-import/stream/stream.mjs +462 -0
- package/dist/unstable-core-do-not-import/utils.d.ts +2 -1
- package/dist/unstable-core-do-not-import/utils.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/utils.js +4 -0
- package/dist/unstable-core-do-not-import/utils.mjs +4 -1
- package/dist/unstable-core-do-not-import.d.ts +1 -0
- package/dist/unstable-core-do-not-import.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import.js +5 -0
- package/dist/unstable-core-do-not-import.mjs +2 -1
- package/package.json +2 -2
- package/src/adapters/node-http/incomingMessageToRequest.ts +23 -23
- package/src/unstable-core-do-not-import/clientish/serialize.ts +1 -0
- package/src/unstable-core-do-not-import/http/resolveResponse.ts +83 -52
- package/src/unstable-core-do-not-import/initTRPC.ts +1 -0
- package/src/unstable-core-do-not-import/rootConfig.ts +7 -0
- package/src/unstable-core-do-not-import/stream/stream.ts +580 -0
- package/src/unstable-core-do-not-import/utils.ts +7 -1
- package/src/unstable-core-do-not-import.ts +1 -0
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
import { isObject, isFunction, isAsyncIterable } from '../utils.mjs';
|
|
2
|
+
|
|
3
|
+
// ---------- utils
|
|
4
|
+
function createReadableStream() {
|
|
5
|
+
let controller = null;
|
|
6
|
+
const stream = new ReadableStream({
|
|
7
|
+
start (c) {
|
|
8
|
+
controller = c;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
return [
|
|
12
|
+
stream,
|
|
13
|
+
controller
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
// ---------- types
|
|
17
|
+
const CHUNK_VALUE_TYPE_PROMISE = 0;
|
|
18
|
+
const CHUNK_VALUE_TYPE_ASYNC_ITERABLE = 1;
|
|
19
|
+
const PROMISE_STATUS_FULFILLED = 0;
|
|
20
|
+
const PROMISE_STATUS_REJECTED = 1;
|
|
21
|
+
const ASYNC_ITERABLE_STATUS_DONE = 0;
|
|
22
|
+
const ASYNC_ITERABLE_STATUS_VALUE = 1;
|
|
23
|
+
const ASYNC_ITERABLE_STATUS_ERROR = 2;
|
|
24
|
+
function isPromise(value) {
|
|
25
|
+
return (isObject(value) || isFunction(value)) && typeof value?.['then'] === 'function' && typeof value?.['catch'] === 'function';
|
|
26
|
+
}
|
|
27
|
+
class MaxDepthError extends Error {
|
|
28
|
+
constructor(path){
|
|
29
|
+
super('Max depth reached at path: ' + path.join('.'));
|
|
30
|
+
this.path = path;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function createBatchStreamProducer(opts) {
|
|
34
|
+
const { data } = opts;
|
|
35
|
+
let counter = 0;
|
|
36
|
+
const placeholder = 0;
|
|
37
|
+
const [stream, controller] = createReadableStream();
|
|
38
|
+
const pending = new Set();
|
|
39
|
+
function maybeClose() {
|
|
40
|
+
if (pending.size === 0) {
|
|
41
|
+
controller.close();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function hydratePromise(promise, path) {
|
|
45
|
+
//
|
|
46
|
+
const error = checkMaxDepth(path);
|
|
47
|
+
if (error) {
|
|
48
|
+
promise.catch(()=>{
|
|
49
|
+
// ignore
|
|
50
|
+
});
|
|
51
|
+
promise = Promise.reject(error);
|
|
52
|
+
}
|
|
53
|
+
const idx = counter++;
|
|
54
|
+
pending.add(idx);
|
|
55
|
+
const enqueue = (value)=>{
|
|
56
|
+
controller.enqueue(value);
|
|
57
|
+
};
|
|
58
|
+
promise.then((it)=>{
|
|
59
|
+
enqueue([
|
|
60
|
+
idx,
|
|
61
|
+
PROMISE_STATUS_FULFILLED,
|
|
62
|
+
hydrate(it, path)
|
|
63
|
+
]);
|
|
64
|
+
}).catch((err)=>{
|
|
65
|
+
opts.onError?.({
|
|
66
|
+
error: err,
|
|
67
|
+
path
|
|
68
|
+
});
|
|
69
|
+
enqueue([
|
|
70
|
+
idx,
|
|
71
|
+
PROMISE_STATUS_REJECTED
|
|
72
|
+
]);
|
|
73
|
+
}).finally(()=>{
|
|
74
|
+
pending.delete(idx);
|
|
75
|
+
maybeClose();
|
|
76
|
+
});
|
|
77
|
+
return idx;
|
|
78
|
+
}
|
|
79
|
+
function hydrateAsyncIterable(iterable, path) {
|
|
80
|
+
const error = checkMaxDepth(path);
|
|
81
|
+
if (error) {
|
|
82
|
+
iterable = {
|
|
83
|
+
[Symbol.asyncIterator] () {
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const idx = counter++;
|
|
89
|
+
pending.add(idx);
|
|
90
|
+
void (async ()=>{
|
|
91
|
+
try {
|
|
92
|
+
for await (const item of iterable){
|
|
93
|
+
controller.enqueue([
|
|
94
|
+
idx,
|
|
95
|
+
ASYNC_ITERABLE_STATUS_VALUE,
|
|
96
|
+
hydrate(item, path)
|
|
97
|
+
]);
|
|
98
|
+
}
|
|
99
|
+
controller.enqueue([
|
|
100
|
+
idx,
|
|
101
|
+
ASYNC_ITERABLE_STATUS_DONE
|
|
102
|
+
]);
|
|
103
|
+
} catch (error) {
|
|
104
|
+
opts.onError?.({
|
|
105
|
+
error,
|
|
106
|
+
path
|
|
107
|
+
});
|
|
108
|
+
controller.enqueue([
|
|
109
|
+
idx,
|
|
110
|
+
ASYNC_ITERABLE_STATUS_ERROR
|
|
111
|
+
]);
|
|
112
|
+
} finally{
|
|
113
|
+
pending.delete(idx);
|
|
114
|
+
maybeClose();
|
|
115
|
+
}
|
|
116
|
+
})();
|
|
117
|
+
return idx;
|
|
118
|
+
}
|
|
119
|
+
function checkMaxDepth(path) {
|
|
120
|
+
if (opts.maxDepth && path.length > opts.maxDepth) {
|
|
121
|
+
return new MaxDepthError(path);
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
function hydrateChunk(value, path) {
|
|
126
|
+
if (isPromise(value)) {
|
|
127
|
+
return [
|
|
128
|
+
CHUNK_VALUE_TYPE_PROMISE,
|
|
129
|
+
hydratePromise(value, path)
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
if (isAsyncIterable(value)) {
|
|
133
|
+
if (opts.maxDepth && path.length >= opts.maxDepth) {
|
|
134
|
+
throw new Error('Max depth reached');
|
|
135
|
+
}
|
|
136
|
+
return [
|
|
137
|
+
CHUNK_VALUE_TYPE_ASYNC_ITERABLE,
|
|
138
|
+
hydrateAsyncIterable(value, path)
|
|
139
|
+
];
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
function hydrate(value, path) {
|
|
144
|
+
const reg = hydrateChunk(value, path);
|
|
145
|
+
if (reg) {
|
|
146
|
+
return [
|
|
147
|
+
[
|
|
148
|
+
placeholder
|
|
149
|
+
],
|
|
150
|
+
[
|
|
151
|
+
null,
|
|
152
|
+
...reg
|
|
153
|
+
]
|
|
154
|
+
];
|
|
155
|
+
}
|
|
156
|
+
if (!isObject(value)) {
|
|
157
|
+
return [
|
|
158
|
+
[
|
|
159
|
+
value
|
|
160
|
+
]
|
|
161
|
+
];
|
|
162
|
+
}
|
|
163
|
+
const newObj = {};
|
|
164
|
+
const asyncValues = [];
|
|
165
|
+
for (const [key, item] of Object.entries(value)){
|
|
166
|
+
const transformed = hydrateChunk(item, [
|
|
167
|
+
...path,
|
|
168
|
+
key
|
|
169
|
+
]);
|
|
170
|
+
if (!transformed) {
|
|
171
|
+
newObj[key] = item;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
newObj[key] = placeholder;
|
|
175
|
+
asyncValues.push([
|
|
176
|
+
key,
|
|
177
|
+
...transformed
|
|
178
|
+
]);
|
|
179
|
+
}
|
|
180
|
+
return [
|
|
181
|
+
[
|
|
182
|
+
newObj
|
|
183
|
+
],
|
|
184
|
+
...asyncValues
|
|
185
|
+
];
|
|
186
|
+
}
|
|
187
|
+
const newHead = {};
|
|
188
|
+
for (const [key, item] of Object.entries(data)){
|
|
189
|
+
newHead[key] = hydrate(item, [
|
|
190
|
+
key
|
|
191
|
+
]);
|
|
192
|
+
}
|
|
193
|
+
return [
|
|
194
|
+
newHead,
|
|
195
|
+
stream
|
|
196
|
+
];
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* JSON Lines stream producer
|
|
200
|
+
* @see https://jsonlines.org/
|
|
201
|
+
*/ function jsonlStreamProducer(opts) {
|
|
202
|
+
let [head, stream] = createBatchStreamProducer(opts);
|
|
203
|
+
const { serialize } = opts;
|
|
204
|
+
if (serialize) {
|
|
205
|
+
head = serialize(head);
|
|
206
|
+
stream = stream.pipeThrough(new TransformStream({
|
|
207
|
+
transform (chunk, controller) {
|
|
208
|
+
controller.enqueue(serialize(chunk));
|
|
209
|
+
}
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
return stream.pipeThrough(new TransformStream({
|
|
213
|
+
start (controller) {
|
|
214
|
+
controller.enqueue(JSON.stringify(head) + '\n');
|
|
215
|
+
},
|
|
216
|
+
transform (chunk, controller) {
|
|
217
|
+
controller.enqueue(JSON.stringify(chunk) + '\n');
|
|
218
|
+
}
|
|
219
|
+
})).pipeThrough(new TextEncoderStream());
|
|
220
|
+
}
|
|
221
|
+
class StreamInterruptedError extends Error {
|
|
222
|
+
constructor(cause){
|
|
223
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
224
|
+
// @ts-ignore https://github.com/tc39/proposal-error-cause
|
|
225
|
+
super('Invalid response or stream interrupted', {
|
|
226
|
+
cause
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
class AsyncError extends Error {
|
|
231
|
+
constructor(data){
|
|
232
|
+
super('Received error from server');
|
|
233
|
+
this.data = data;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const nodeJsStreamToReaderEsque = (source)=>{
|
|
237
|
+
return {
|
|
238
|
+
getReader () {
|
|
239
|
+
const [stream, controller] = createReadableStream();
|
|
240
|
+
source.on('data', (chunk)=>{
|
|
241
|
+
controller.enqueue(chunk);
|
|
242
|
+
});
|
|
243
|
+
source.on('end', ()=>{
|
|
244
|
+
controller.close();
|
|
245
|
+
});
|
|
246
|
+
source.on('error', (error)=>{
|
|
247
|
+
controller.error(error);
|
|
248
|
+
});
|
|
249
|
+
return stream.getReader();
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
function createLineAccumulator(from) {
|
|
254
|
+
const reader = 'getReader' in from ? from.getReader() : nodeJsStreamToReaderEsque(from).getReader();
|
|
255
|
+
let lineAggregate = '';
|
|
256
|
+
return new ReadableStream({
|
|
257
|
+
async pull (controller) {
|
|
258
|
+
const { done , value } = await reader.read();
|
|
259
|
+
if (done) {
|
|
260
|
+
controller.close();
|
|
261
|
+
} else {
|
|
262
|
+
controller.enqueue(value);
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
cancel () {
|
|
266
|
+
return reader.cancel();
|
|
267
|
+
}
|
|
268
|
+
}).pipeThrough(new TextDecoderStream()).pipeThrough(new TransformStream({
|
|
269
|
+
transform (chunk, controller) {
|
|
270
|
+
lineAggregate += chunk;
|
|
271
|
+
const parts = lineAggregate.split('\n');
|
|
272
|
+
lineAggregate = parts.pop() ?? '';
|
|
273
|
+
for (const part of parts){
|
|
274
|
+
controller.enqueue(part);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}));
|
|
278
|
+
}
|
|
279
|
+
function createConsumerStream(from) {
|
|
280
|
+
const stream = createLineAccumulator(from);
|
|
281
|
+
let sentHead = false;
|
|
282
|
+
return stream.pipeThrough(new TransformStream({
|
|
283
|
+
transform (line, controller) {
|
|
284
|
+
if (!sentHead) {
|
|
285
|
+
const head = JSON.parse(line);
|
|
286
|
+
controller.enqueue(head);
|
|
287
|
+
sentHead = true;
|
|
288
|
+
} else {
|
|
289
|
+
const chunk = JSON.parse(line);
|
|
290
|
+
controller.enqueue(chunk);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}));
|
|
294
|
+
}
|
|
295
|
+
function createDeferred() {
|
|
296
|
+
let resolve;
|
|
297
|
+
let reject;
|
|
298
|
+
const promise = new Promise((res, rej)=>{
|
|
299
|
+
resolve = res;
|
|
300
|
+
reject = rej;
|
|
301
|
+
});
|
|
302
|
+
return {
|
|
303
|
+
promise,
|
|
304
|
+
resolve: resolve,
|
|
305
|
+
reject: reject
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* JSON Lines stream consumer
|
|
310
|
+
* @see https://jsonlines.org/
|
|
311
|
+
*/ async function jsonlStreamConsumer(opts) {
|
|
312
|
+
const { deserialize =(v)=>v } = opts;
|
|
313
|
+
let source = createConsumerStream(opts.from);
|
|
314
|
+
if (deserialize) {
|
|
315
|
+
source = source.pipeThrough(new TransformStream({
|
|
316
|
+
transform (chunk, controller) {
|
|
317
|
+
controller.enqueue(deserialize(chunk));
|
|
318
|
+
}
|
|
319
|
+
}));
|
|
320
|
+
}
|
|
321
|
+
let headDeferred = createDeferred();
|
|
322
|
+
const chunkDeferred = new Map();
|
|
323
|
+
const controllers = new Map();
|
|
324
|
+
function dehydrateChunkDefinition(value) {
|
|
325
|
+
const [_path, type, chunkId] = value;
|
|
326
|
+
const [stream, controller] = createReadableStream();
|
|
327
|
+
controllers.set(chunkId, controller);
|
|
328
|
+
// resolve chunk deferred if it exists
|
|
329
|
+
const deferred = chunkDeferred.get(chunkId);
|
|
330
|
+
if (deferred) {
|
|
331
|
+
deferred.resolve(controller);
|
|
332
|
+
chunkDeferred.delete(chunkId);
|
|
333
|
+
}
|
|
334
|
+
switch(type){
|
|
335
|
+
case CHUNK_VALUE_TYPE_PROMISE:
|
|
336
|
+
{
|
|
337
|
+
return new Promise((resolve, reject)=>{
|
|
338
|
+
// listen for next value in the stream
|
|
339
|
+
const reader = stream.getReader();
|
|
340
|
+
reader.read().then((it)=>{
|
|
341
|
+
if (it.done) {
|
|
342
|
+
reject(new Error('Promise chunk ended without value'));
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
if (it.value instanceof StreamInterruptedError) {
|
|
346
|
+
reject(it.value);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
const value = it.value;
|
|
350
|
+
const [_chunkId, status, data] = value;
|
|
351
|
+
switch(status){
|
|
352
|
+
case PROMISE_STATUS_FULFILLED:
|
|
353
|
+
resolve(dehydrate(data));
|
|
354
|
+
break;
|
|
355
|
+
case PROMISE_STATUS_REJECTED:
|
|
356
|
+
reject(new AsyncError(data));
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
}).catch(reject).finally(()=>{
|
|
360
|
+
// reader.releaseLock();
|
|
361
|
+
controllers.delete(chunkId);
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
case CHUNK_VALUE_TYPE_ASYNC_ITERABLE:
|
|
366
|
+
{
|
|
367
|
+
return {
|
|
368
|
+
[Symbol.asyncIterator]: async function*() {
|
|
369
|
+
const reader = stream.getReader();
|
|
370
|
+
while(true){
|
|
371
|
+
const { done , value } = await reader.read();
|
|
372
|
+
if (done) {
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
if (value instanceof StreamInterruptedError) {
|
|
376
|
+
throw value;
|
|
377
|
+
}
|
|
378
|
+
const [_chunkId, status, data] = value;
|
|
379
|
+
switch(status){
|
|
380
|
+
case ASYNC_ITERABLE_STATUS_VALUE:
|
|
381
|
+
yield dehydrate(data);
|
|
382
|
+
break;
|
|
383
|
+
case ASYNC_ITERABLE_STATUS_DONE:
|
|
384
|
+
controllers.delete(chunkId);
|
|
385
|
+
return;
|
|
386
|
+
case ASYNC_ITERABLE_STATUS_ERROR:
|
|
387
|
+
controllers.delete(chunkId);
|
|
388
|
+
throw new AsyncError(data);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
function dehydrate(value) {
|
|
397
|
+
const [[data], ...asyncProps] = value;
|
|
398
|
+
for (const value1 of asyncProps){
|
|
399
|
+
const dehydrated = dehydrateChunkDefinition(value1);
|
|
400
|
+
const [path] = value1;
|
|
401
|
+
if (path === null) {
|
|
402
|
+
return dehydrated;
|
|
403
|
+
}
|
|
404
|
+
data[path] = dehydrated;
|
|
405
|
+
}
|
|
406
|
+
return data;
|
|
407
|
+
}
|
|
408
|
+
const closeOrAbort = (reason)=>{
|
|
409
|
+
const error = new StreamInterruptedError(reason);
|
|
410
|
+
headDeferred?.reject(error);
|
|
411
|
+
for (const deferred of chunkDeferred.values()){
|
|
412
|
+
deferred.reject(error);
|
|
413
|
+
}
|
|
414
|
+
chunkDeferred.clear();
|
|
415
|
+
for (const controller of controllers.values()){
|
|
416
|
+
controller.enqueue(error);
|
|
417
|
+
controller.close();
|
|
418
|
+
}
|
|
419
|
+
controllers.clear();
|
|
420
|
+
};
|
|
421
|
+
source.pipeTo(new WritableStream({
|
|
422
|
+
async write (chunkOrHead) {
|
|
423
|
+
if (headDeferred) {
|
|
424
|
+
const head = chunkOrHead;
|
|
425
|
+
for (const [key, value] of Object.entries(chunkOrHead)){
|
|
426
|
+
const parsed = dehydrate(value);
|
|
427
|
+
head[key] = parsed;
|
|
428
|
+
}
|
|
429
|
+
headDeferred.resolve(head);
|
|
430
|
+
headDeferred = null;
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
const chunk = chunkOrHead;
|
|
434
|
+
const [idx] = chunk;
|
|
435
|
+
let controller = controllers.get(idx);
|
|
436
|
+
if (!controller) {
|
|
437
|
+
let deferred = chunkDeferred.get(idx);
|
|
438
|
+
if (!deferred) {
|
|
439
|
+
deferred = createDeferred();
|
|
440
|
+
chunkDeferred.set(idx, deferred);
|
|
441
|
+
}
|
|
442
|
+
controller = await deferred.promise;
|
|
443
|
+
}
|
|
444
|
+
controller.enqueue(chunk);
|
|
445
|
+
},
|
|
446
|
+
close: closeOrAbort,
|
|
447
|
+
abort: closeOrAbort
|
|
448
|
+
})).catch((error)=>{
|
|
449
|
+
opts.onError?.({
|
|
450
|
+
error
|
|
451
|
+
});
|
|
452
|
+
closeOrAbort(error);
|
|
453
|
+
});
|
|
454
|
+
return [
|
|
455
|
+
await headDeferred.promise,
|
|
456
|
+
{
|
|
457
|
+
controllers
|
|
458
|
+
}
|
|
459
|
+
];
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
export { isPromise, jsonlStreamConsumer, jsonlStreamProducer };
|
|
@@ -11,12 +11,13 @@ export declare function mergeWithoutOverrides<TType extends Record<string, unkno
|
|
|
11
11
|
* @internal
|
|
12
12
|
*/
|
|
13
13
|
export declare function isObject(value: unknown): value is Record<string, unknown>;
|
|
14
|
-
type AnyFn = (...args: any[]) => unknown
|
|
14
|
+
type AnyFn = ((...args: any[]) => unknown) & Record<keyof any, unknown>;
|
|
15
15
|
export declare function isFunction(fn: unknown): fn is AnyFn;
|
|
16
16
|
/**
|
|
17
17
|
* Create an object without inheriting anything from `Object.prototype`
|
|
18
18
|
* @internal
|
|
19
19
|
*/
|
|
20
20
|
export declare function omitPrototype<TObj extends Record<string, unknown>>(obj: TObj): TObj;
|
|
21
|
+
export declare function isAsyncIterable<TValue>(value: unknown): value is AsyncIterable<TValue>;
|
|
21
22
|
export {};
|
|
22
23
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/unstable-core-do-not-import/utils.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,eAAO,MAAM,WAAW,eAAwB,CAAC;AACjD,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC;AAE7C;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzE,IAAI,EAAE,KAAK,EACX,GAAG,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,GACxB,KAAK,CAYP;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED,KAAK,KAAK,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/unstable-core-do-not-import/utils.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,eAAO,MAAM,WAAW,eAAwB,CAAC;AACjD,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC;AAE7C;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzE,IAAI,EAAE,KAAK,EACX,GAAG,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,GACxB,KAAK,CAYP;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED,KAAK,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC;AACxE,wBAAgB,UAAU,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,IAAI,KAAK,CAEnD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,GAAG,EAAE,IAAI,GACR,IAAI,CAEN;AAED,wBAAgB,eAAe,CAAC,MAAM,EACpC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,aAAa,CAAC,MAAM,CAAC,CAEhC"}
|
|
@@ -31,7 +31,11 @@ function isFunction(fn) {
|
|
|
31
31
|
*/ function omitPrototype(obj) {
|
|
32
32
|
return Object.assign(Object.create(null), obj);
|
|
33
33
|
}
|
|
34
|
+
function isAsyncIterable(value) {
|
|
35
|
+
return isObject(value) && Symbol.asyncIterator in value;
|
|
36
|
+
}
|
|
34
37
|
|
|
38
|
+
exports.isAsyncIterable = isAsyncIterable;
|
|
35
39
|
exports.isFunction = isFunction;
|
|
36
40
|
exports.isObject = isObject;
|
|
37
41
|
exports.mergeWithoutOverrides = mergeWithoutOverrides;
|
|
@@ -29,5 +29,8 @@ function isFunction(fn) {
|
|
|
29
29
|
*/ function omitPrototype(obj) {
|
|
30
30
|
return Object.assign(Object.create(null), obj);
|
|
31
31
|
}
|
|
32
|
+
function isAsyncIterable(value) {
|
|
33
|
+
return isObject(value) && Symbol.asyncIterator in value;
|
|
34
|
+
}
|
|
32
35
|
|
|
33
|
-
export { isFunction, isObject, mergeWithoutOverrides, omitPrototype, unsetMarker };
|
|
36
|
+
export { isAsyncIterable, isFunction, isObject, mergeWithoutOverrides, omitPrototype, unsetMarker };
|
|
@@ -33,4 +33,5 @@ export * from './unstable-core-do-not-import/rpc';
|
|
|
33
33
|
export * from './unstable-core-do-not-import/transformer';
|
|
34
34
|
export * from './unstable-core-do-not-import/types';
|
|
35
35
|
export * from './unstable-core-do-not-import/utils';
|
|
36
|
+
export * from './unstable-core-do-not-import/stream/stream';
|
|
36
37
|
//# sourceMappingURL=unstable-core-do-not-import.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unstable-core-do-not-import.d.ts","sourceRoot":"","sources":["../src/unstable-core-do-not-import.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,mDAAmD,CAAC;AAClE,cAAc,oDAAoD,CAAC;AACnE,cAAc,mDAAmD,CAAC;AAClE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,mDAAmD,CAAC;AAClE,cAAc,yDAAyD,CAAC;AACxE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,uDAAuD,CAAC;AACtE,cAAc,sDAAsD,CAAC;AACrE,cAAc,oDAAoD,CAAC;AACnE,cAAc,0CAA0C,CAAC;AACzD,cAAc,0CAA0C,CAAC;AACzD,cAAc,wCAAwC,CAAC;AACvD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,yCAAyC,CAAC;AACxD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC"}
|
|
1
|
+
{"version":3,"file":"unstable-core-do-not-import.d.ts","sourceRoot":"","sources":["../src/unstable-core-do-not-import.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,mDAAmD,CAAC;AAClE,cAAc,oDAAoD,CAAC;AACnE,cAAc,mDAAmD,CAAC;AAClE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,mDAAmD,CAAC;AAClE,cAAc,yDAAyD,CAAC;AACxE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,uDAAuD,CAAC;AACtE,cAAc,sDAAsD,CAAC;AACrE,cAAc,oDAAoD,CAAC;AACnE,cAAc,0CAA0C,CAAC;AACzD,cAAc,0CAA0C,CAAC;AACzD,cAAc,wCAAwC,CAAC;AACvD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,yCAAyC,CAAC;AACxD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,6CAA6C,CAAC"}
|
|
@@ -22,6 +22,7 @@ var parseTRPCMessage = require('./unstable-core-do-not-import/rpc/parseTRPCMessa
|
|
|
22
22
|
var transformer = require('./unstable-core-do-not-import/transformer.js');
|
|
23
23
|
var types = require('./unstable-core-do-not-import/types.js');
|
|
24
24
|
var utils = require('./unstable-core-do-not-import/utils.js');
|
|
25
|
+
var stream = require('./unstable-core-do-not-import/stream/stream.js');
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
|
|
@@ -61,8 +62,12 @@ exports.getDataTransformer = transformer.getDataTransformer;
|
|
|
61
62
|
exports.transformResult = transformer.transformResult;
|
|
62
63
|
exports.transformTRPCResponse = transformer.transformTRPCResponse;
|
|
63
64
|
exports.ERROR_SYMBOL = types.ERROR_SYMBOL;
|
|
65
|
+
exports.isAsyncIterable = utils.isAsyncIterable;
|
|
64
66
|
exports.isFunction = utils.isFunction;
|
|
65
67
|
exports.isObject = utils.isObject;
|
|
66
68
|
exports.mergeWithoutOverrides = utils.mergeWithoutOverrides;
|
|
67
69
|
exports.omitPrototype = utils.omitPrototype;
|
|
68
70
|
exports.unsetMarker = utils.unsetMarker;
|
|
71
|
+
exports.isPromise = stream.isPromise;
|
|
72
|
+
exports.jsonlStreamConsumer = stream.jsonlStreamConsumer;
|
|
73
|
+
exports.jsonlStreamProducer = stream.jsonlStreamProducer;
|
|
@@ -19,4 +19,5 @@ export { TRPC_ERROR_CODES_BY_KEY, TRPC_ERROR_CODES_BY_NUMBER } from './unstable-
|
|
|
19
19
|
export { parseTRPCMessage } from './unstable-core-do-not-import/rpc/parseTRPCMessage.mjs';
|
|
20
20
|
export { defaultTransformer, getDataTransformer, transformResult, transformTRPCResponse } from './unstable-core-do-not-import/transformer.mjs';
|
|
21
21
|
export { ERROR_SYMBOL } from './unstable-core-do-not-import/types.mjs';
|
|
22
|
-
export { isFunction, isObject, mergeWithoutOverrides, omitPrototype, unsetMarker } from './unstable-core-do-not-import/utils.mjs';
|
|
22
|
+
export { isAsyncIterable, isFunction, isObject, mergeWithoutOverrides, omitPrototype, unsetMarker } from './unstable-core-do-not-import/utils.mjs';
|
|
23
|
+
export { isPromise, jsonlStreamConsumer, jsonlStreamProducer } from './unstable-core-do-not-import/stream/stream.mjs';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trpc/server",
|
|
3
|
-
"version": "11.0.0-rc.
|
|
3
|
+
"version": "11.0.0-rc.374+5027209bc",
|
|
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": "
|
|
152
|
+
"gitHead": "5027209bc300d299224ecef764adeac09b8cab8d"
|
|
153
153
|
}
|
|
@@ -17,32 +17,32 @@ function incomingMessageToBodyStream(
|
|
|
17
17
|
type Value = Buffer | Uint8Array | string | null;
|
|
18
18
|
let size = 0;
|
|
19
19
|
const maxBodySize = opts.maxBodySize;
|
|
20
|
+
let hasClosed = false;
|
|
20
21
|
|
|
21
|
-
let controller: ReadableStreamDefaultController<Value> =
|
|
22
|
-
null as unknown as ReadableStreamDefaultController<Value>;
|
|
23
22
|
const stream = new ReadableStream<Value>({
|
|
24
|
-
start(
|
|
25
|
-
|
|
26
|
-
},
|
|
27
|
-
async pull(c) {
|
|
28
|
-
const chunk: Value = req.read();
|
|
29
|
-
|
|
30
|
-
if (chunk) {
|
|
23
|
+
start(controller) {
|
|
24
|
+
req.on('data', (chunk) => {
|
|
31
25
|
size += chunk.length;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
26
|
+
if (maxBodySize != null && size > maxBodySize) {
|
|
27
|
+
controller.error(
|
|
28
|
+
new TRPCError({
|
|
29
|
+
code: 'PAYLOAD_TOO_LARGE',
|
|
30
|
+
}),
|
|
31
|
+
);
|
|
32
|
+
// an error is thrown if we try to close the controller after
|
|
33
|
+
// erroring, so track the closure
|
|
34
|
+
hasClosed = true;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
controller.enqueue(chunk);
|
|
38
|
+
});
|
|
39
|
+
req.once('end', () => {
|
|
40
|
+
if (hasClosed) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
hasClosed = true;
|
|
44
|
+
controller.close();
|
|
45
|
+
});
|
|
46
46
|
},
|
|
47
47
|
cancel() {
|
|
48
48
|
req.destroy();
|
|
@@ -26,6 +26,7 @@ type IsRecord<T extends object> = keyof WithoutIndexSignature<T> extends never
|
|
|
26
26
|
export type Serialize<T> =
|
|
27
27
|
IsAny<T> extends true ? any :
|
|
28
28
|
unknown extends T ? unknown :
|
|
29
|
+
T extends AsyncIterable<infer U> ? AsyncIterable<Serialize<U>> :
|
|
29
30
|
T extends JsonReturnable ? T :
|
|
30
31
|
T extends Map<any, any> | Set<any> ? object :
|
|
31
32
|
T extends NonJsonPrimitive ? never :
|