@trpc/server 10.29.0 → 10.29.1

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 (38) hide show
  1. package/dist/adapters/aws-lambda/index.js +1 -1
  2. package/dist/adapters/aws-lambda/index.mjs +1 -1
  3. package/dist/adapters/express.js +2 -2
  4. package/dist/adapters/express.mjs +2 -2
  5. package/dist/adapters/fastify/fastifyRequestHandler.d.ts.map +1 -1
  6. package/dist/adapters/fastify/index.js +17 -16
  7. package/dist/adapters/fastify/index.mjs +17 -16
  8. package/dist/adapters/fetch/fetchRequestHandler.d.ts.map +1 -1
  9. package/dist/adapters/fetch/index.js +24 -23
  10. package/dist/adapters/fetch/index.mjs +24 -23
  11. package/dist/adapters/next.js +2 -2
  12. package/dist/adapters/next.mjs +2 -2
  13. package/dist/adapters/node-http/index.js +2 -2
  14. package/dist/adapters/node-http/index.mjs +2 -2
  15. package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts.map +1 -1
  16. package/dist/adapters/node-http/types.d.ts +11 -1
  17. package/dist/adapters/node-http/types.d.ts.map +1 -1
  18. package/dist/adapters/standalone.js +2 -2
  19. package/dist/adapters/standalone.mjs +2 -2
  20. package/dist/http/index.js +1 -1
  21. package/dist/http/index.mjs +1 -1
  22. package/dist/http/internals/types.d.ts +1 -1
  23. package/dist/http/internals/types.d.ts.map +1 -1
  24. package/dist/http/resolveHTTPResponse.d.ts +10 -9
  25. package/dist/http/resolveHTTPResponse.d.ts.map +1 -1
  26. package/dist/{nodeHTTPRequestHandler-e637755a.js → nodeHTTPRequestHandler-071d36b5.js} +21 -19
  27. package/dist/{nodeHTTPRequestHandler-53b9fc2d.js → nodeHTTPRequestHandler-51d58a23.js} +21 -18
  28. package/dist/{nodeHTTPRequestHandler-bdad2781.mjs → nodeHTTPRequestHandler-bb12529f.mjs} +21 -19
  29. package/dist/{resolveHTTPResponse-2c307e04.js → resolveHTTPResponse-1f03fdfd.js} +11 -11
  30. package/dist/{resolveHTTPResponse-a9be3d96.mjs → resolveHTTPResponse-dd3677b3.mjs} +11 -11
  31. package/dist/{resolveHTTPResponse-2bdf2cd7.js → resolveHTTPResponse-e0047ea2.js} +12 -12
  32. package/package.json +2 -2
  33. package/src/adapters/fastify/fastifyRequestHandler.ts +18 -17
  34. package/src/adapters/fetch/fetchRequestHandler.ts +23 -22
  35. package/src/adapters/node-http/nodeHTTPRequestHandler.ts +23 -21
  36. package/src/adapters/node-http/types.ts +11 -1
  37. package/src/http/internals/types.ts +1 -1
  38. package/src/http/resolveHTTPResponse.ts +26 -22
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  require('./index-4a823936.js');
4
- var resolveHTTPResponse = require('./resolveHTTPResponse-2c307e04.js');
4
+ var resolveHTTPResponse = require('./resolveHTTPResponse-1f03fdfd.js');
5
5
  var batchStreamFormatter = require('./batchStreamFormatter-93cdcdd4.js');
6
6
  var adapters_nodeHttp_contentType_json_index = require('./adapters/node-http/content-type/json/index.js');
7
7
 
@@ -33,7 +33,9 @@ async function nodeHTTPRequestHandler(opts) {
33
33
  query,
34
34
  body: bodyResult.ok ? bodyResult.data : undefined
35
35
  };
36
- const onHead = (head)=>{
36
+ let isStream = false;
37
+ let formatter;
38
+ const unstable_onHead = (head, isStreaming)=>{
37
39
  if ('status' in head && (!opts.res.statusCode || opts.res.statusCode === 200)) {
38
40
  opts.res.statusCode = head.status;
39
41
  }
@@ -43,25 +45,26 @@ async function nodeHTTPRequestHandler(opts) {
43
45
  }
44
46
  opts.res.setHeader(key, value);
45
47
  }
48
+ if (isStreaming) {
49
+ opts.res.setHeader('Transfer-Encoding', 'chunked');
50
+ const vary = opts.res.getHeader('Vary');
51
+ opts.res.setHeader('Vary', vary ? 'trpc-batch-mode, ' + vary : 'trpc-batch-mode');
52
+ isStream = true;
53
+ formatter = batchStreamFormatter.getBatchStreamFormatter();
54
+ opts.res.flushHeaders();
55
+ }
46
56
  };
47
- const formatter = batchStreamFormatter.getBatchStreamFormatter();
48
- let isStream = false;
49
- const onChunk = ([index, string])=>{
57
+ const unstable_onChunk = ([index, string])=>{
50
58
  if (index === -1) {
51
59
  /**
52
60
  * Full response, no streaming. This can happen
53
61
  * - if the response is an error
54
62
  * - if response is empty (HEAD request)
55
63
  */ opts.res.end(string);
56
- return;
57
- }
58
- if (!isStream) {
59
- opts.res.setHeader('Transfer-Encoding', 'chunked');
60
- const vary = opts.res.getHeader('Vary');
61
- opts.res.setHeader('Vary', vary ? 'trpc-batch-mode, ' + vary : 'trpc-batch-mode');
62
- isStream = true;
64
+ } else {
65
+ opts.res.write(formatter(index, string));
66
+ opts.res.flush?.();
63
67
  }
64
- opts.res.write(formatter(index, string));
65
68
  };
66
69
  await resolveHTTPResponse.resolveHTTPResponse({
67
70
  batching: opts.batching,
@@ -79,14 +82,13 @@ async function nodeHTTPRequestHandler(opts) {
79
82
  });
80
83
  },
81
84
  contentTypeHandler,
82
- onHead,
83
- onChunk
85
+ unstable_onHead,
86
+ unstable_onChunk
84
87
  });
85
- if (!isStream) {
86
- return opts.res;
88
+ if (isStream) {
89
+ opts.res.write(formatter.end());
90
+ opts.res.end();
87
91
  }
88
- opts.res.write(formatter.end());
89
- opts.res.end();
90
92
  return opts.res;
91
93
  });
92
94
  }
@@ -1,5 +1,5 @@
1
1
  import './index-ca9a128e.js';
2
- import { r as resolveHTTPResponse } from './resolveHTTPResponse-2bdf2cd7.js';
2
+ import { r as resolveHTTPResponse } from './resolveHTTPResponse-e0047ea2.js';
3
3
  import { g as getBatchStreamFormatter } from './batchStreamFormatter-2c1405a1.js';
4
4
  import { nodeHTTPJSONContentTypeHandler } from './adapters/node-http/content-type/json/index.js';
5
5
 
@@ -35,7 +35,9 @@ async function nodeHTTPRequestHandler(opts) {
35
35
  query,
36
36
  body: bodyResult.ok ? bodyResult.data : undefined,
37
37
  };
38
- const onHead = (head) => {
38
+ let isStream = false;
39
+ let formatter;
40
+ const unstable_onHead = (head, isStreaming) => {
39
41
  if ('status' in head &&
40
42
  (!opts.res.statusCode || opts.res.statusCode === 200)) {
41
43
  opts.res.statusCode = head.status;
@@ -47,10 +49,16 @@ async function nodeHTTPRequestHandler(opts) {
47
49
  }
48
50
  opts.res.setHeader(key, value);
49
51
  }
52
+ if (isStreaming) {
53
+ opts.res.setHeader('Transfer-Encoding', 'chunked');
54
+ const vary = opts.res.getHeader('Vary');
55
+ opts.res.setHeader('Vary', vary ? 'trpc-batch-mode, ' + vary : 'trpc-batch-mode');
56
+ isStream = true;
57
+ formatter = getBatchStreamFormatter();
58
+ opts.res.flushHeaders();
59
+ }
50
60
  };
51
- const formatter = getBatchStreamFormatter();
52
- let isStream = false;
53
- const onChunk = ([index, string]) => {
61
+ const unstable_onChunk = ([index, string]) => {
54
62
  if (index === -1) {
55
63
  /**
56
64
  * Full response, no streaming. This can happen
@@ -58,15 +66,11 @@ async function nodeHTTPRequestHandler(opts) {
58
66
  * - if response is empty (HEAD request)
59
67
  */
60
68
  opts.res.end(string);
61
- return;
62
69
  }
63
- if (!isStream) {
64
- opts.res.setHeader('Transfer-Encoding', 'chunked');
65
- const vary = opts.res.getHeader('Vary');
66
- opts.res.setHeader('Vary', vary ? 'trpc-batch-mode, ' + vary : 'trpc-batch-mode');
67
- isStream = true;
70
+ else {
71
+ opts.res.write(formatter(index, string));
72
+ opts.res.flush?.();
68
73
  }
69
- opts.res.write(formatter(index, string));
70
74
  };
71
75
  await resolveHTTPResponse({
72
76
  batching: opts.batching,
@@ -84,14 +88,13 @@ async function nodeHTTPRequestHandler(opts) {
84
88
  });
85
89
  },
86
90
  contentTypeHandler,
87
- onHead,
88
- onChunk,
91
+ unstable_onHead,
92
+ unstable_onChunk,
89
93
  });
90
- if (!isStream) {
91
- return opts.res;
94
+ if (isStream) {
95
+ opts.res.write(formatter.end());
96
+ opts.res.end();
92
97
  }
93
- opts.res.write(formatter.end());
94
- opts.res.end();
95
98
  return opts.res;
96
99
  });
97
100
  }
@@ -1,5 +1,5 @@
1
1
  import './index-044a193b.mjs';
2
- import { r as resolveHTTPResponse } from './resolveHTTPResponse-a9be3d96.mjs';
2
+ import { r as resolveHTTPResponse } from './resolveHTTPResponse-dd3677b3.mjs';
3
3
  import { g as getBatchStreamFormatter } from './batchStreamFormatter-fc1ffb26.mjs';
4
4
  import { nodeHTTPJSONContentTypeHandler } from './adapters/node-http/content-type/json/index.mjs';
5
5
 
@@ -31,7 +31,9 @@ async function nodeHTTPRequestHandler(opts) {
31
31
  query,
32
32
  body: bodyResult.ok ? bodyResult.data : undefined
33
33
  };
34
- const onHead = (head)=>{
34
+ let isStream = false;
35
+ let formatter;
36
+ const unstable_onHead = (head, isStreaming)=>{
35
37
  if ('status' in head && (!opts.res.statusCode || opts.res.statusCode === 200)) {
36
38
  opts.res.statusCode = head.status;
37
39
  }
@@ -41,25 +43,26 @@ async function nodeHTTPRequestHandler(opts) {
41
43
  }
42
44
  opts.res.setHeader(key, value);
43
45
  }
46
+ if (isStreaming) {
47
+ opts.res.setHeader('Transfer-Encoding', 'chunked');
48
+ const vary = opts.res.getHeader('Vary');
49
+ opts.res.setHeader('Vary', vary ? 'trpc-batch-mode, ' + vary : 'trpc-batch-mode');
50
+ isStream = true;
51
+ formatter = getBatchStreamFormatter();
52
+ opts.res.flushHeaders();
53
+ }
44
54
  };
45
- const formatter = getBatchStreamFormatter();
46
- let isStream = false;
47
- const onChunk = ([index, string])=>{
55
+ const unstable_onChunk = ([index, string])=>{
48
56
  if (index === -1) {
49
57
  /**
50
58
  * Full response, no streaming. This can happen
51
59
  * - if the response is an error
52
60
  * - if response is empty (HEAD request)
53
61
  */ opts.res.end(string);
54
- return;
55
- }
56
- if (!isStream) {
57
- opts.res.setHeader('Transfer-Encoding', 'chunked');
58
- const vary = opts.res.getHeader('Vary');
59
- opts.res.setHeader('Vary', vary ? 'trpc-batch-mode, ' + vary : 'trpc-batch-mode');
60
- isStream = true;
62
+ } else {
63
+ opts.res.write(formatter(index, string));
64
+ opts.res.flush?.();
61
65
  }
62
- opts.res.write(formatter(index, string));
63
66
  };
64
67
  await resolveHTTPResponse({
65
68
  batching: opts.batching,
@@ -77,14 +80,13 @@ async function nodeHTTPRequestHandler(opts) {
77
80
  });
78
81
  },
79
82
  contentTypeHandler,
80
- onHead,
81
- onChunk
83
+ unstable_onHead,
84
+ unstable_onChunk
82
85
  });
83
- if (!isStream) {
84
- return opts.res;
86
+ if (isStream) {
87
+ opts.res.write(formatter.end());
88
+ opts.res.end();
85
89
  }
86
- opts.res.write(formatter.end());
87
- opts.res.end();
88
90
  return opts.res;
89
91
  });
90
92
  }
@@ -110,14 +110,14 @@ function caughtErrorToData(cause, errorOpts) {
110
110
  }
111
111
  // implementation
112
112
  async function resolveHTTPResponse(opts) {
113
- const { router , req , onHead , onChunk } = opts;
113
+ const { router , req , unstable_onHead , unstable_onChunk } = opts;
114
114
  if (req.method === 'HEAD') {
115
115
  // can be used for lambda warmup
116
116
  const headResponse = {
117
117
  status: 204
118
118
  };
119
- onHead?.(headResponse);
120
- onChunk?.([
119
+ unstable_onHead?.(headResponse, false);
120
+ unstable_onChunk?.([
121
121
  -1,
122
122
  ''
123
123
  ]);
@@ -129,7 +129,7 @@ async function resolveHTTPResponse(opts) {
129
129
  let ctx = undefined;
130
130
  let paths;
131
131
  const isBatchCall = !!req.query.get('batch');
132
- const isStreamCall = isBatchCall && onHead && onChunk && req.headers['trpc-batch-mode'] === 'stream';
132
+ const isStreamCall = isBatchCall && unstable_onHead && unstable_onChunk && req.headers['trpc-batch-mode'] === 'stream';
133
133
  try {
134
134
  if (opts.error) {
135
135
  throw opts.error;
@@ -184,12 +184,12 @@ async function resolveHTTPResponse(opts) {
184
184
  untransformedJSON,
185
185
  errors
186
186
  });
187
- onHead?.(headResponse1);
187
+ unstable_onHead?.(headResponse1, false);
188
188
  // return body stuff
189
189
  const result = isBatchCall ? untransformedJSON : untransformedJSON[0]; // eslint-disable-line @typescript-eslint/no-non-null-assertion -- `untransformedJSON` should be the length of `paths` which should be at least 1 otherwise there wouldn't be a request at all
190
190
  const transformedJSON = transformTRPCResponse.transformTRPCResponse(router._def._config, result);
191
191
  const body = JSON.stringify(transformedJSON);
192
- onChunk?.([
192
+ unstable_onChunk?.([
193
193
  -1,
194
194
  body
195
195
  ]);
@@ -210,7 +210,7 @@ async function resolveHTTPResponse(opts) {
210
210
  type,
211
211
  responseMeta: opts.responseMeta
212
212
  });
213
- onHead(headResponse2);
213
+ unstable_onHead(headResponse2, true);
214
214
  const indexedPromises = new Map(promises.map((promise, index)=>[
215
215
  index,
216
216
  promise.then((r)=>[
@@ -224,7 +224,7 @@ async function resolveHTTPResponse(opts) {
224
224
  try {
225
225
  const transformedJSON1 = transformTRPCResponse.transformTRPCResponse(router._def._config, untransformedJSON1);
226
226
  const body1 = JSON.stringify(transformedJSON1);
227
- onChunk([
227
+ unstable_onChunk([
228
228
  index,
229
229
  body1
230
230
  ]);
@@ -238,7 +238,7 @@ async function resolveHTTPResponse(opts) {
238
238
  path,
239
239
  input
240
240
  });
241
- onChunk([
241
+ unstable_onChunk([
242
242
  index,
243
243
  body2
244
244
  ]);
@@ -268,8 +268,8 @@ async function resolveHTTPResponse(opts) {
268
268
  error
269
269
  ]
270
270
  });
271
- onHead?.(headResponse3);
272
- onChunk?.([
271
+ unstable_onHead?.(headResponse3, false);
272
+ unstable_onChunk?.([
273
273
  -1,
274
274
  body3
275
275
  ]);
@@ -108,14 +108,14 @@ function caughtErrorToData(cause, errorOpts) {
108
108
  }
109
109
  // implementation
110
110
  async function resolveHTTPResponse(opts) {
111
- const { router , req , onHead , onChunk } = opts;
111
+ const { router , req , unstable_onHead , unstable_onChunk } = opts;
112
112
  if (req.method === 'HEAD') {
113
113
  // can be used for lambda warmup
114
114
  const headResponse = {
115
115
  status: 204
116
116
  };
117
- onHead?.(headResponse);
118
- onChunk?.([
117
+ unstable_onHead?.(headResponse, false);
118
+ unstable_onChunk?.([
119
119
  -1,
120
120
  ''
121
121
  ]);
@@ -127,7 +127,7 @@ async function resolveHTTPResponse(opts) {
127
127
  let ctx = undefined;
128
128
  let paths;
129
129
  const isBatchCall = !!req.query.get('batch');
130
- const isStreamCall = isBatchCall && onHead && onChunk && req.headers['trpc-batch-mode'] === 'stream';
130
+ const isStreamCall = isBatchCall && unstable_onHead && unstable_onChunk && req.headers['trpc-batch-mode'] === 'stream';
131
131
  try {
132
132
  if (opts.error) {
133
133
  throw opts.error;
@@ -182,12 +182,12 @@ async function resolveHTTPResponse(opts) {
182
182
  untransformedJSON,
183
183
  errors
184
184
  });
185
- onHead?.(headResponse1);
185
+ unstable_onHead?.(headResponse1, false);
186
186
  // return body stuff
187
187
  const result = isBatchCall ? untransformedJSON : untransformedJSON[0]; // eslint-disable-line @typescript-eslint/no-non-null-assertion -- `untransformedJSON` should be the length of `paths` which should be at least 1 otherwise there wouldn't be a request at all
188
188
  const transformedJSON = transformTRPCResponse(router._def._config, result);
189
189
  const body = JSON.stringify(transformedJSON);
190
- onChunk?.([
190
+ unstable_onChunk?.([
191
191
  -1,
192
192
  body
193
193
  ]);
@@ -208,7 +208,7 @@ async function resolveHTTPResponse(opts) {
208
208
  type,
209
209
  responseMeta: opts.responseMeta
210
210
  });
211
- onHead(headResponse2);
211
+ unstable_onHead(headResponse2, true);
212
212
  const indexedPromises = new Map(promises.map((promise, index)=>[
213
213
  index,
214
214
  promise.then((r)=>[
@@ -222,7 +222,7 @@ async function resolveHTTPResponse(opts) {
222
222
  try {
223
223
  const transformedJSON1 = transformTRPCResponse(router._def._config, untransformedJSON1);
224
224
  const body1 = JSON.stringify(transformedJSON1);
225
- onChunk([
225
+ unstable_onChunk([
226
226
  index,
227
227
  body1
228
228
  ]);
@@ -236,7 +236,7 @@ async function resolveHTTPResponse(opts) {
236
236
  path,
237
237
  input
238
238
  });
239
- onChunk([
239
+ unstable_onChunk([
240
240
  index,
241
241
  body2
242
242
  ]);
@@ -266,8 +266,8 @@ async function resolveHTTPResponse(opts) {
266
266
  error
267
267
  ]
268
268
  });
269
- onHead?.(headResponse3);
270
- onChunk?.([
269
+ unstable_onHead?.(headResponse3, false);
270
+ unstable_onChunk?.([
271
271
  -1,
272
272
  body3
273
273
  ]);
@@ -104,14 +104,14 @@ function caughtErrorToData(cause, errorOpts) {
104
104
  }
105
105
  // implementation
106
106
  async function resolveHTTPResponse(opts) {
107
- const { router, req, onHead, onChunk } = opts;
107
+ const { router, req, unstable_onHead, unstable_onChunk } = opts;
108
108
  if (req.method === 'HEAD') {
109
109
  // can be used for lambda warmup
110
110
  const headResponse = {
111
111
  status: 204,
112
112
  };
113
- onHead?.(headResponse);
114
- onChunk?.([-1, '']);
113
+ unstable_onHead?.(headResponse, false);
114
+ unstable_onChunk?.([-1, '']);
115
115
  return headResponse;
116
116
  }
117
117
  const contentTypeHandler = opts.contentTypeHandler ?? fallbackContentTypeHandler;
@@ -121,8 +121,8 @@ async function resolveHTTPResponse(opts) {
121
121
  let paths;
122
122
  const isBatchCall = !!req.query.get('batch');
123
123
  const isStreamCall = isBatchCall &&
124
- onHead &&
125
- onChunk &&
124
+ unstable_onHead &&
125
+ unstable_onChunk &&
126
126
  req.headers['trpc-batch-mode'] === 'stream';
127
127
  try {
128
128
  if (opts.error) {
@@ -170,12 +170,12 @@ async function resolveHTTPResponse(opts) {
170
170
  untransformedJSON,
171
171
  errors,
172
172
  });
173
- onHead?.(headResponse);
173
+ unstable_onHead?.(headResponse, false);
174
174
  // return body stuff
175
175
  const result = isBatchCall ? untransformedJSON : untransformedJSON[0]; // eslint-disable-line @typescript-eslint/no-non-null-assertion -- `untransformedJSON` should be the length of `paths` which should be at least 1 otherwise there wouldn't be a request at all
176
176
  const transformedJSON = transformTRPCResponse(router._def._config, result);
177
177
  const body = JSON.stringify(transformedJSON);
178
- onChunk?.([-1, body]);
178
+ unstable_onChunk?.([-1, body]);
179
179
  return {
180
180
  status: headResponse.status,
181
181
  headers: headResponse.headers,
@@ -194,7 +194,7 @@ async function resolveHTTPResponse(opts) {
194
194
  type,
195
195
  responseMeta: opts.responseMeta,
196
196
  });
197
- onHead(headResponse);
197
+ unstable_onHead(headResponse, true);
198
198
  const indexedPromises = new Map(promises.map((promise, index) => [
199
199
  index,
200
200
  promise.then((r) => [index, r]),
@@ -205,7 +205,7 @@ async function resolveHTTPResponse(opts) {
205
205
  try {
206
206
  const transformedJSON = transformTRPCResponse(router._def._config, untransformedJSON);
207
207
  const body = JSON.stringify(transformedJSON);
208
- onChunk([index, body]);
208
+ unstable_onChunk([index, body]);
209
209
  }
210
210
  catch (cause) {
211
211
  const path = paths[index];
@@ -217,7 +217,7 @@ async function resolveHTTPResponse(opts) {
217
217
  path,
218
218
  input,
219
219
  });
220
- onChunk([index, body]);
220
+ unstable_onChunk([index, body]);
221
221
  }
222
222
  }
223
223
  return;
@@ -243,8 +243,8 @@ async function resolveHTTPResponse(opts) {
243
243
  untransformedJSON,
244
244
  errors: [error],
245
245
  });
246
- onHead?.(headResponse);
247
- onChunk?.([-1, body]);
246
+ unstable_onHead?.(headResponse, false);
247
+ unstable_onChunk?.([-1, body]);
248
248
  return {
249
249
  status: headResponse.status,
250
250
  headers: headResponse.headers,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trpc/server",
3
- "version": "10.29.0",
3
+ "version": "10.29.1",
4
4
  "description": "The tRPC server library",
5
5
  "author": "KATT",
6
6
  "license": "MIT",
@@ -173,5 +173,5 @@
173
173
  "funding": [
174
174
  "https://trpc.io/sponsor"
175
175
  ],
176
- "gitHead": "49b0a55b74b57bbf7451dad5976d315d9fb7785c"
176
+ "gitHead": "3dbc7b7e9fff233f89627c21450ba89754bc3e46"
177
177
  }
@@ -52,7 +52,10 @@ export async function fastifyRequestHandler<
52
52
  let resolve: (value: FastifyReply) => void;
53
53
  const promise = new Promise<FastifyReply>((r) => (resolve = r));
54
54
 
55
- const onHead = (head: HTTPResponse) => {
55
+ let isStream = false;
56
+ let stream: Readable;
57
+ let formatter: ReturnType<typeof getBatchStreamFormatter>;
58
+ const unstable_onHead = (head: HTTPResponse, isStreaming: boolean) => {
56
59
  if (!opts.res.statusCode || opts.res.statusCode === 200) {
57
60
  opts.res.statusCode = head.status;
58
61
  }
@@ -63,18 +66,7 @@ export async function fastifyRequestHandler<
63
66
  }
64
67
  void opts.res.header(key, value);
65
68
  }
66
- };
67
-
68
- let isStream = false;
69
- let stream: Readable;
70
- const formatter = getBatchStreamFormatter();
71
- const onChunk = ([index, string]: ResponseChunk) => {
72
- if (index === -1) {
73
- // full response, no streaming
74
- resolve(opts.res.send(string));
75
- return;
76
- }
77
- if (!isStream) {
69
+ if (isStreaming) {
78
70
  void opts.res.header('Transfer-Encoding', 'chunked');
79
71
  void opts.res.header(
80
72
  'Vary',
@@ -86,8 +78,17 @@ export async function fastifyRequestHandler<
86
78
  stream._read = () => {}; // eslint-disable-line @typescript-eslint/no-empty-function -- https://github.com/fastify/fastify/issues/805#issuecomment-369172154
87
79
  resolve(opts.res.send(stream));
88
80
  isStream = true;
81
+ formatter = getBatchStreamFormatter();
82
+ }
83
+ };
84
+
85
+ const unstable_onChunk = ([index, string]: ResponseChunk) => {
86
+ if (index === -1) {
87
+ // full response, no streaming
88
+ resolve(opts.res.send(string));
89
+ } else {
90
+ stream.push(formatter!(index, string));
89
91
  }
90
- stream.push(formatter(index, string));
91
92
  };
92
93
 
93
94
  resolveHTTPResponse({
@@ -100,12 +101,12 @@ export async function fastifyRequestHandler<
100
101
  onError(o) {
101
102
  opts?.onError?.({ ...o, req: opts.req });
102
103
  },
103
- onHead,
104
- onChunk,
104
+ unstable_onHead,
105
+ unstable_onChunk,
105
106
  })
106
107
  .then(() => {
107
108
  if (isStream) {
108
- stream.push(formatter.end());
109
+ stream.push(formatter!.end());
109
110
  stream.push(null); // https://github.com/fastify/fastify/issues/805#issuecomment-369172154
110
111
  }
111
112
  })
@@ -34,7 +34,11 @@ export async function fetchRequestHandler<TRouter extends AnyRouter>(
34
34
  const promise = new Promise<Response>((r) => (resolve = r));
35
35
  let status = 200;
36
36
 
37
- const onHead = (head: HTTPResponse) => {
37
+ let isStream = false;
38
+ let controller: ReadableStreamController<any>;
39
+ let encoder: TextEncoder;
40
+ let formatter: ReturnType<typeof getBatchStreamFormatter>;
41
+ const unstable_onHead = (head: HTTPResponse, isStreaming: boolean) => {
38
42
  for (const [key, value] of Object.entries(head.headers ?? {})) {
39
43
  /* istanbul ignore if -- @preserve */
40
44
  if (typeof value === 'undefined') {
@@ -49,23 +53,7 @@ export async function fetchRequestHandler<TRouter extends AnyRouter>(
49
53
  }
50
54
  }
51
55
  status = head.status;
52
- };
53
-
54
- let isStream = false;
55
- let controller: ReadableStreamController<any>;
56
- let encoder: TextEncoder;
57
- const formatter = getBatchStreamFormatter();
58
- const onChunk = ([index, string]: ResponseChunk) => {
59
- if (index === -1) {
60
- // full response, no streaming
61
- const response = new Response(string || null, {
62
- status,
63
- headers: resHeaders,
64
- });
65
- resolve(response);
66
- return;
67
- }
68
- if (!isStream) {
56
+ if (isStreaming) {
69
57
  resHeaders.set('Transfer-Encoding', 'chunked');
70
58
  resHeaders.append('Vary', 'trpc-batch-mode');
71
59
  const stream = new ReadableStream({
@@ -79,9 +67,22 @@ export async function fetchRequestHandler<TRouter extends AnyRouter>(
79
67
  });
80
68
  resolve(response);
81
69
  encoder = new TextEncoder();
70
+ formatter = getBatchStreamFormatter();
82
71
  isStream = true;
83
72
  }
84
- controller.enqueue(encoder.encode(formatter(index, string)));
73
+ };
74
+
75
+ const unstable_onChunk = ([index, string]: ResponseChunk) => {
76
+ if (index === -1) {
77
+ // full response, no streaming
78
+ const response = new Response(string || null, {
79
+ status,
80
+ headers: resHeaders,
81
+ });
82
+ resolve(response);
83
+ } else {
84
+ controller.enqueue(encoder.encode(formatter!(index, string)));
85
+ }
85
86
  };
86
87
 
87
88
  resolveHTTPResponse({
@@ -94,12 +95,12 @@ export async function fetchRequestHandler<TRouter extends AnyRouter>(
94
95
  onError(o) {
95
96
  opts?.onError?.({ ...o, req: opts.req });
96
97
  },
97
- onHead,
98
- onChunk,
98
+ unstable_onHead,
99
+ unstable_onChunk,
99
100
  })
100
101
  .then(() => {
101
102
  if (isStream) {
102
- controller.enqueue(encoder.encode(formatter.end()));
103
+ controller.enqueue(encoder.encode(formatter!.end()));
103
104
  controller.close();
104
105
  }
105
106
  })