@trpc/server 11.0.0-rc.599 → 11.0.0-rc.604

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 (78) hide show
  1. package/dist/adapters/aws-lambda/getPlanner.d.ts.map +1 -1
  2. package/dist/adapters/aws-lambda/index.d.ts.map +1 -1
  3. package/dist/adapters/fastify/fastifyTRPCPlugin.d.ts.map +1 -1
  4. package/dist/adapters/next-app-dir/nextAppDirCaller.d.ts.map +1 -1
  5. package/dist/adapters/next-app-dir/nextAppDirCaller.js +1 -0
  6. package/dist/adapters/next-app-dir/nextAppDirCaller.mjs +1 -0
  7. package/dist/adapters/next-app-dir/rethrowNextErrors.d.ts.map +1 -1
  8. package/dist/adapters/next-app-dir/rethrowNextErrors.js +2 -1
  9. package/dist/adapters/next-app-dir/rethrowNextErrors.mjs +2 -1
  10. package/dist/adapters/ws.d.ts.map +1 -1
  11. package/dist/adapters/ws.js +11 -2
  12. package/dist/adapters/ws.mjs +11 -2
  13. package/dist/bundle-analysis.json +131 -118
  14. package/dist/observable/observable.d.ts.map +1 -1
  15. package/dist/unstable-core-do-not-import/clientish/inference.d.ts.map +1 -1
  16. package/dist/unstable-core-do-not-import/clientish/inferrable.d.ts.map +1 -1
  17. package/dist/unstable-core-do-not-import/clientish/serialize.d.ts.map +1 -1
  18. package/dist/unstable-core-do-not-import/initTRPC.d.ts +1 -1
  19. package/dist/unstable-core-do-not-import/initTRPC.d.ts.map +1 -1
  20. package/dist/unstable-core-do-not-import/middleware.d.ts.map +1 -1
  21. package/dist/unstable-core-do-not-import/parser.d.ts.map +1 -1
  22. package/dist/unstable-core-do-not-import/procedureBuilder.d.ts +1 -1
  23. package/dist/unstable-core-do-not-import/procedureBuilder.d.ts.map +1 -1
  24. package/dist/unstable-core-do-not-import/router.d.ts.map +1 -1
  25. package/dist/unstable-core-do-not-import/stream/jsonl.d.ts.map +1 -1
  26. package/dist/unstable-core-do-not-import/stream/jsonl.js +3 -2
  27. package/dist/unstable-core-do-not-import/stream/jsonl.mjs +3 -2
  28. package/dist/unstable-core-do-not-import/stream/sse.d.ts.map +1 -1
  29. package/dist/unstable-core-do-not-import/stream/sse.js +9 -2
  30. package/dist/unstable-core-do-not-import/stream/sse.mjs +9 -2
  31. package/dist/unstable-core-do-not-import/stream/tracked.d.ts.map +1 -1
  32. package/dist/unstable-core-do-not-import/stream/utils/asyncIterable.d.ts.map +1 -1
  33. package/dist/unstable-core-do-not-import/stream/utils/asyncIterable.js +11 -2
  34. package/dist/unstable-core-do-not-import/stream/utils/asyncIterable.mjs +11 -2
  35. package/dist/unstable-core-do-not-import/stream/utils/withPing.d.ts.map +1 -1
  36. package/dist/unstable-core-do-not-import/stream/utils/withPing.js +6 -2
  37. package/dist/unstable-core-do-not-import/stream/utils/withPing.mjs +6 -2
  38. package/dist/unstable-core-do-not-import/transformer.js +1 -1
  39. package/dist/unstable-core-do-not-import/transformer.mjs +1 -1
  40. package/dist/unstable-core-do-not-import/types.d.ts +3 -3
  41. package/dist/unstable-core-do-not-import/types.d.ts.map +1 -1
  42. package/dist/vendor/unpromise/index.d.ts +3 -0
  43. package/dist/vendor/unpromise/index.d.ts.map +1 -0
  44. package/dist/vendor/unpromise/types.d.ts +28 -0
  45. package/dist/vendor/unpromise/types.d.ts.map +1 -0
  46. package/dist/vendor/unpromise/unpromise.d.ts +121 -0
  47. package/dist/vendor/unpromise/unpromise.d.ts.map +1 -0
  48. package/dist/vendor/unpromise/unpromise.js +276 -0
  49. package/dist/vendor/unpromise/unpromise.mjs +273 -0
  50. package/package.json +6 -6
  51. package/src/adapters/aws-lambda/getPlanner.ts +2 -2
  52. package/src/adapters/aws-lambda/index.ts +5 -6
  53. package/src/adapters/fastify/fastifyTRPCPlugin.ts +8 -3
  54. package/src/adapters/next-app-dir/nextAppDirCaller.ts +1 -0
  55. package/src/adapters/next-app-dir/rethrowNextErrors.ts +2 -1
  56. package/src/adapters/ws.ts +18 -2
  57. package/src/observable/observable.ts +2 -6
  58. package/src/unstable-core-do-not-import/clientish/inference.ts +4 -4
  59. package/src/unstable-core-do-not-import/clientish/inferrable.ts +6 -6
  60. package/src/unstable-core-do-not-import/clientish/serialize.ts +3 -3
  61. package/src/unstable-core-do-not-import/http/resolveResponse.ts +2 -2
  62. package/src/unstable-core-do-not-import/initTRPC.ts +3 -9
  63. package/src/unstable-core-do-not-import/middleware.ts +3 -3
  64. package/src/unstable-core-do-not-import/parser.ts +5 -5
  65. package/src/unstable-core-do-not-import/procedureBuilder.ts +51 -53
  66. package/src/unstable-core-do-not-import/router.ts +6 -7
  67. package/src/unstable-core-do-not-import/stream/jsonl.ts +3 -2
  68. package/src/unstable-core-do-not-import/stream/sse.ts +13 -2
  69. package/src/unstable-core-do-not-import/stream/tracked.ts +2 -5
  70. package/src/unstable-core-do-not-import/stream/utils/asyncIterable.ts +11 -2
  71. package/src/unstable-core-do-not-import/stream/utils/withPing.ts +6 -2
  72. package/src/unstable-core-do-not-import/transformer.ts +1 -1
  73. package/src/unstable-core-do-not-import/types.ts +11 -13
  74. package/src/vendor/unpromise/ATTRIBUTION.txt +1 -0
  75. package/src/vendor/unpromise/LICENSE +20 -0
  76. package/src/vendor/unpromise/index.ts +7 -0
  77. package/src/vendor/unpromise/types.ts +55 -0
  78. package/src/vendor/unpromise/unpromise.ts +380 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trpc/server",
3
- "version": "11.0.0-rc.599+e16cd8d7c",
3
+ "version": "11.0.0-rc.604+03cd991db",
4
4
  "description": "The tRPC server library",
5
5
  "author": "KATT",
6
6
  "license": "MIT",
@@ -18,7 +18,7 @@
18
18
  "dev": "pnpm build --watch",
19
19
  "codegen-entrypoints": "tsx entrypoints.script.ts",
20
20
  "benchmark": "tsc --project tsconfig.benchmark.json",
21
- "lint": "eslint --cache --ext \".js,.ts,.tsx\" --ignore-path ../../.gitignore src",
21
+ "lint": "eslint --cache src",
22
22
  "ts-watch": "tsc --watch"
23
23
  },
24
24
  "exports": {
@@ -121,18 +121,18 @@
121
121
  "@types/aws-lambda": "^8.10.137",
122
122
  "@types/express": "^4.17.17",
123
123
  "@types/hash-sum": "^1.0.0",
124
- "@types/node": "^20.10.0",
124
+ "@types/node": "^20.17.3",
125
125
  "@types/react": "^18.3.1",
126
126
  "@types/react-dom": "^18.3.0",
127
127
  "@types/ws": "^8.2.0",
128
128
  "devalue": "^5.0.0",
129
- "eslint": "^8.57.0",
129
+ "eslint": "^9.13.0",
130
130
  "express": "^4.17.1",
131
131
  "fastify": "^4.16.0",
132
132
  "fastify-plugin": "^5.0.0",
133
133
  "hash-sum": "^2.0.0",
134
134
  "myzod": "^1.3.1",
135
- "next": "^14.2.5",
135
+ "next": "^15.0.2",
136
136
  "react": "^18.3.1",
137
137
  "react-dom": "^18.3.1",
138
138
  "rollup": "^4.9.5",
@@ -149,5 +149,5 @@
149
149
  "funding": [
150
150
  "https://trpc.io/sponsor"
151
151
  ],
152
- "gitHead": "e16cd8d7cee12eaf1545273858407f0947ca97fc"
152
+ "gitHead": "03cd991dba00fe219759b308897137ecca1fe111"
153
153
  }
@@ -29,8 +29,8 @@ function determinePayloadFormat(event: LambdaEvent): string {
29
29
  export type inferAPIGWReturn<TEvent> = TEvent extends APIGatewayProxyEvent
30
30
  ? APIGatewayProxyResult
31
31
  : TEvent extends APIGatewayProxyEventV2
32
- ? APIGatewayProxyStructuredResultV2
33
- : never;
32
+ ? APIGatewayProxyStructuredResultV2
33
+ : never;
34
34
 
35
35
  interface Processor<TEvent extends LambdaEvent> {
36
36
  getTRPCPath: (event: TEvent) => string;
@@ -33,12 +33,11 @@ export type CreateAWSLambdaContextOptions<TEvent extends LambdaEvent> = {
33
33
  export type AWSLambdaOptions<
34
34
  TRouter extends AnyRouter,
35
35
  TEvent extends LambdaEvent,
36
- > =
37
- | HTTPBaseHandlerOptions<TRouter, TEvent> &
38
- CreateContextCallback<
39
- inferRouterContext<AnyRouter>,
40
- AWSLambdaCreateContextFn<TRouter, TEvent>
41
- >;
36
+ > = HTTPBaseHandlerOptions<TRouter, TEvent> &
37
+ CreateContextCallback<
38
+ inferRouterContext<AnyRouter>,
39
+ AWSLambdaCreateContextFn<TRouter, TEvent>
40
+ >;
42
41
 
43
42
  export type AWSLambdaCreateContextFn<
44
43
  TRouter extends AnyRouter,
@@ -14,7 +14,11 @@ import type { AnyRouter } from '../../@trpc/server';
14
14
  // @trpc/server/http
15
15
  import type { NodeHTTPCreateContextFnOptions } from '../node-http';
16
16
  // @trpc/server/ws
17
- import { getWSConnectionHandler, handleKeepAlive, type WSSHandlerOptions } from '../ws';
17
+ import {
18
+ getWSConnectionHandler,
19
+ handleKeepAlive,
20
+ type WSSHandlerOptions,
21
+ } from '../ws';
18
22
  import type { FastifyHandlerOptions } from './fastifyRequestHandler';
19
23
  import { fastifyRequestHandler } from './fastifyRequestHandler';
20
24
 
@@ -57,8 +61,9 @@ export function fastifyTRPCPlugin<TRouter extends AnyRouter>(
57
61
  });
58
62
 
59
63
  if (opts.useWSS) {
60
- const trpcOptions = opts.trpcOptions as unknown as WSSHandlerOptions<TRouter>;
61
-
64
+ const trpcOptions =
65
+ opts.trpcOptions as unknown as WSSHandlerOptions<TRouter>;
66
+
62
67
  const onConnection = getWSConnectionHandler<TRouter>({
63
68
  ...trpcOptions,
64
69
  });
@@ -121,6 +121,7 @@ export function nextAppDirCaller<TContext, TMeta>(
121
121
  })
122
122
  .catch(handleError);
123
123
  }
124
+ case 'subscription':
124
125
  default: {
125
126
  throw new TRPCError({
126
127
  code: 'NOT_IMPLEMENTED',
@@ -62,6 +62,7 @@ export const rethrowNextErrors = (error: TRPCError) => {
62
62
 
63
63
  // Before Next.js 15, we have to check and rethrow the error manually.
64
64
  if (isRedirectError(cause) || isNotFoundError(cause)) {
65
- throw error.cause;
65
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
66
+ throw cause!;
66
67
  }
67
68
  };
@@ -33,6 +33,7 @@ import {
33
33
  run,
34
34
  type MaybePromise,
35
35
  } from '../unstable-core-do-not-import';
36
+ import { Unpromise } from '../vendor/unpromise';
36
37
  import type { NodeHTTPCreateContextFnOptions } from './node-http';
37
38
 
38
39
  /**
@@ -282,8 +283,18 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
282
283
  });
283
284
 
284
285
  run(async () => {
286
+ // We need those declarations outside the loop for garbage collection reasons. If they
287
+ // were declared inside, they would not be freed until the next value is present.
288
+ let next:
289
+ | null
290
+ | TRPCError
291
+ | Awaited<
292
+ typeof abortPromise | ReturnType<(typeof iterator)['next']>
293
+ >;
294
+ let result: null | TRPCResultMessage<unknown>['result'];
295
+
285
296
  while (true) {
286
- const next = await Promise.race([
297
+ next = await Unpromise.race([
287
298
  iterator.next().catch(getTRPCErrorFromUnknown),
288
299
  abortPromise,
289
300
  ]);
@@ -313,7 +324,7 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
313
324
  break;
314
325
  }
315
326
 
316
- const result: TRPCResultMessage<unknown>['result'] = {
327
+ result = {
317
328
  type: 'data',
318
329
  data: next.value,
319
330
  };
@@ -332,6 +343,10 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
332
343
  jsonrpc,
333
344
  result,
334
345
  });
346
+
347
+ // free up references for garbage collection
348
+ next = null;
349
+ result = null;
335
350
  }
336
351
 
337
352
  await iterator.return?.();
@@ -388,6 +403,7 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
388
403
  }
389
404
  }
390
405
  client.on('message', async (rawData) => {
406
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
391
407
  const msgStr = rawData.toString();
392
408
  if (msgStr === 'PONG') {
393
409
  return;
@@ -9,12 +9,8 @@ import type {
9
9
  } from './types';
10
10
 
11
11
  /** @public */
12
- export type inferObservableValue<TObservable> = TObservable extends Observable<
13
- infer TValue,
14
- unknown
15
- >
16
- ? TValue
17
- : never;
12
+ export type inferObservableValue<TObservable> =
13
+ TObservable extends Observable<infer TValue, unknown> ? TValue : never;
18
14
 
19
15
  /** @public */
20
16
  export function isObservable(x: unknown): x is Observable<unknown, unknown> {
@@ -40,10 +40,10 @@ export type GetInferenceHelpers<
40
40
  ? $Value extends RouterRecord
41
41
  ? GetInferenceHelpers<TType, TRoot, $Value>
42
42
  : $Value extends AnyProcedure
43
- ? TType extends 'input'
44
- ? inferProcedureInput<$Value>
45
- : inferTransformedProcedureOutput<TRoot, $Value>
46
- : never
43
+ ? TType extends 'input'
44
+ ? inferProcedureInput<$Value>
45
+ : inferTransformedProcedureOutput<TRoot, $Value>
46
+ : never
47
47
  : never;
48
48
  };
49
49
 
@@ -41,9 +41,9 @@ export type inferClientTypes<TInferrable extends InferrableClientTypes> =
41
41
  TInferrable extends AnyClientTypes
42
42
  ? TInferrable
43
43
  : TInferrable extends RootConfigLike
44
- ? TInferrable['$types']
45
- : TInferrable extends InitLike
46
- ? TInferrable['_config']['$types']
47
- : TInferrable extends RouterLike
48
- ? TInferrable['_def']['_config']['$types']
49
- : never;
44
+ ? TInferrable['$types']
45
+ : TInferrable extends InitLike
46
+ ? TInferrable['_config']['$types']
47
+ : TInferrable extends RouterLike
48
+ ? TInferrable['_def']['_config']['$types']
49
+ : never;
@@ -5,7 +5,7 @@ import type { Simplify, WithoutIndexSignature } from '../types';
5
5
  * @see https://github.com/remix-run/remix/blob/2248669ed59fd716e267ea41df5d665d4781f4a9/packages/remix-server-runtime/serialize.ts
6
6
  */
7
7
  type JsonPrimitive = boolean | number | string | null;
8
- // eslint-disable-next-line @typescript-eslint/ban-types
8
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
9
9
  type NonJsonPrimitive = Function | symbol | undefined;
10
10
  /*
11
11
  * `any` is the only type that can let you equate `0` with `1`
@@ -119,5 +119,5 @@ type UndefinedToOptional<T extends object> =
119
119
  (ExactOptionalPropertyTypes extends true
120
120
  ? HandleIndexSignature<T> & HandleUndefined<WithoutIndexSignature<T>>
121
121
  : HasIndexSignature<T> extends true
122
- ? HandleIndexSignature<T>
123
- : HandleUndefined<T>);
122
+ ? HandleIndexSignature<T>
123
+ : HandleUndefined<T>);
@@ -101,8 +101,8 @@ function initResponse<TRouter extends AnyRouter, TRequest>(initOpts: {
101
101
  const data = eagerGeneration
102
102
  ? []
103
103
  : Array.isArray(untransformedJSON)
104
- ? untransformedJSON
105
- : [untransformedJSON];
104
+ ? untransformedJSON
105
+ : [untransformedJSON];
106
106
 
107
107
  const meta =
108
108
  responseMeta?.({
@@ -16,12 +16,8 @@ import type { DataTransformerOptions } from './transformer';
16
16
  import { defaultTransformer, getDataTransformer } from './transformer';
17
17
  import type { Unwrap, ValidateShape } from './types';
18
18
 
19
- type inferErrorFormatterShape<TType> = TType extends ErrorFormatter<
20
- any,
21
- infer TShape
22
- >
23
- ? TShape
24
- : DefaultErrorShape;
19
+ type inferErrorFormatterShape<TType> =
20
+ TType extends ErrorFormatter<any, infer TShape> ? TShape : DefaultErrorShape;
25
21
  interface RuntimeConfigOptions<TContext extends object, TMeta extends object>
26
22
  extends Partial<
27
23
  Omit<
@@ -68,9 +64,7 @@ class TRPCBuilder<TContext extends object, TMeta extends object> {
68
64
  * @see https://trpc.io/docs/v11/server/routers#initialize-trpc
69
65
  */
70
66
  create<TOptions extends RuntimeConfigOptions<TContext, TMeta>>(
71
- opts?:
72
- | ValidateShape<TOptions, RuntimeConfigOptions<TContext, TMeta>>
73
- | undefined,
67
+ opts?: ValidateShape<TOptions, RuntimeConfigOptions<TContext, TMeta>>,
74
68
  ) {
75
69
  type $Root = CreateRootTypes<{
76
70
  ctx: TContext;
@@ -107,9 +107,9 @@ export type MiddlewareFunction<
107
107
  ctx?: $ContextOverride;
108
108
  input?: unknown;
109
109
  }): Promise<MiddlewareResult<$ContextOverride>>;
110
- (opts: { getRawInput: GetRawInputFn }): Promise<
111
- MiddlewareResult<TContextOverridesIn>
112
- >;
110
+ (opts: {
111
+ getRawInput: GetRawInputFn;
112
+ }): Promise<MiddlewareResult<TContextOverridesIn>>;
113
113
  };
114
114
  }): Promise<MiddlewareResult<$ContextOverridesOut>>;
115
115
  _type?: string | undefined;
@@ -59,11 +59,11 @@ export type inferParser<TParser extends Parser> =
59
59
  out: $TOut;
60
60
  }
61
61
  : TParser extends ParserWithoutInput<infer $InOut>
62
- ? {
63
- in: $InOut;
64
- out: $InOut;
65
- }
66
- : never;
62
+ ? {
63
+ in: $InOut;
64
+ out: $InOut;
65
+ }
66
+ : never;
67
67
 
68
68
  export type ParseFn<TType> = (value: unknown) => Promise<TType> | TType;
69
69
 
@@ -37,24 +37,21 @@ import { mergeWithoutOverrides } from './utils';
37
37
  type IntersectIfDefined<TType, TWith> = TType extends UnsetMarker
38
38
  ? TWith
39
39
  : TWith extends UnsetMarker
40
- ? TType
41
- : Simplify<TType & TWith>;
42
- ``;
40
+ ? TType
41
+ : Simplify<TType & TWith>;
42
+
43
43
  type DefaultValue<TValue, TFallback> = TValue extends UnsetMarker
44
44
  ? TFallback
45
45
  : TValue;
46
46
 
47
- type inferAsyncIterator<TOutput> = TOutput extends AsyncIterator<
48
- infer $Yield,
49
- infer $Return,
50
- infer $Next
51
- >
52
- ? {
53
- yield: $Yield;
54
- return: $Return;
55
- next: $Next;
56
- }
57
- : never;
47
+ type inferAsyncIterator<TOutput> =
48
+ TOutput extends AsyncIterator<infer $Yield, infer $Return, infer $Next>
49
+ ? {
50
+ yield: $Yield;
51
+ return: $Return;
52
+ next: $Next;
53
+ }
54
+ : never;
58
55
  type inferSubscriptionOutput<TOutput> = TOutput extends AsyncGenerator
59
56
  ? AsyncGenerator<
60
57
  inferTrackedOutput<inferAsyncIterator<TOutput>['yield']>,
@@ -146,35 +143,36 @@ export type AnyProcedureBuilder = ProcedureBuilder<
146
143
  */
147
144
  export type inferProcedureBuilderResolverOptions<
148
145
  TProcedureBuilder extends AnyProcedureBuilder,
149
- > = TProcedureBuilder extends ProcedureBuilder<
150
- infer TContext,
151
- infer TMeta,
152
- infer TContextOverrides,
153
- infer _TInputIn,
154
- infer TInputOut,
155
- infer _TOutputIn,
156
- infer _TOutputOut,
157
- infer _TCaller
158
- >
159
- ? ProcedureResolverOptions<
160
- TContext,
161
- TMeta,
162
- TContextOverrides,
163
- TInputOut extends UnsetMarker
164
- ? // if input is not set, we don't want to infer it as `undefined` since a procedure further down the chain might have set an input
165
- unknown
166
- : TInputOut extends object
167
- ? Simplify<
168
- TInputOut & {
169
- /**
170
- * Extra input params might have been added by a `.input()` further down the chain
171
- */
172
- [keyAddedByInputCallFurtherDown: string]: unknown;
173
- }
174
- >
175
- : TInputOut
176
- >
177
- : never;
146
+ > =
147
+ TProcedureBuilder extends ProcedureBuilder<
148
+ infer TContext,
149
+ infer TMeta,
150
+ infer TContextOverrides,
151
+ infer _TInputIn,
152
+ infer TInputOut,
153
+ infer _TOutputIn,
154
+ infer _TOutputOut,
155
+ infer _TCaller
156
+ >
157
+ ? ProcedureResolverOptions<
158
+ TContext,
159
+ TMeta,
160
+ TContextOverrides,
161
+ TInputOut extends UnsetMarker
162
+ ? // if input is not set, we don't want to infer it as `undefined` since a procedure further down the chain might have set an input
163
+ unknown
164
+ : TInputOut extends object
165
+ ? Simplify<
166
+ TInputOut & {
167
+ /**
168
+ * Extra input params might have been added by a `.input()` further down the chain
169
+ */
170
+ [keyAddedByInputCallFurtherDown: string]: unknown;
171
+ }
172
+ >
173
+ : TInputOut
174
+ >
175
+ : never;
178
176
 
179
177
  export interface ProcedureBuilder<
180
178
  TContext,
@@ -194,14 +192,14 @@ export interface ProcedureBuilder<
194
192
  schema: TInputOut extends UnsetMarker
195
193
  ? $Parser
196
194
  : inferParser<$Parser>['out'] extends Record<string, unknown> | undefined
197
- ? TInputOut extends Record<string, unknown> | undefined
198
- ? undefined extends inferParser<$Parser>['out'] // if current is optional the previous must be too
199
- ? undefined extends TInputOut
200
- ? $Parser
201
- : TypeError<'Cannot chain an optional parser to a required parser'>
202
- : $Parser
203
- : TypeError<'All input parsers did not resolve to an object'>
204
- : TypeError<'All input parsers did not resolve to an object'>,
195
+ ? TInputOut extends Record<string, unknown> | undefined
196
+ ? undefined extends inferParser<$Parser>['out'] // if current is optional the previous must be too
197
+ ? undefined extends TInputOut
198
+ ? $Parser
199
+ : TypeError<'Cannot chain an optional parser to a required parser'>
200
+ : $Parser
201
+ : TypeError<'All input parsers did not resolve to an object'>
202
+ : TypeError<'All input parsers did not resolve to an object'>,
205
203
  ): ProcedureBuilder<
206
204
  TContext,
207
205
  TMeta,
@@ -358,7 +356,7 @@ export interface ProcedureBuilder<
358
356
  * Subscription procedure
359
357
  * @see https://trpc.io/docs/v11/server/subscriptions
360
358
  */
361
- subscription<$Output extends AsyncGenerator<any, void, any>>(
359
+ subscription<$Output extends AsyncIterable<any, void, any>>(
362
360
  resolver: ProcedureResolver<
363
361
  TContext,
364
362
  TMeta,
@@ -430,7 +428,7 @@ function createNewBuilder(
430
428
  ...mergeWithoutOverrides(def1, rest),
431
429
  inputs: [...def1.inputs, ...(inputs ?? [])],
432
430
  middlewares: [...def1.middlewares, ...middlewares],
433
- meta: def1.meta && meta ? { ...def1.meta, ...meta } : meta ?? def1.meta,
431
+ meta: def1.meta && meta ? { ...def1.meta, ...meta } : (meta ?? def1.meta),
434
432
  });
435
433
  }
436
434
 
@@ -36,8 +36,8 @@ export type DecorateRouterRecord<TRecord extends RouterRecord> = {
36
36
  [TKey in keyof TRecord]: TRecord[TKey] extends AnyProcedure
37
37
  ? DecorateProcedure<TRecord[TKey]>
38
38
  : TRecord[TKey] extends RouterRecord
39
- ? DecorateRouterRecord<TRecord[TKey]>
40
- : never;
39
+ ? DecorateRouterRecord<TRecord[TKey]>
40
+ : never;
41
41
  };
42
42
 
43
43
  /**
@@ -146,10 +146,10 @@ export type DecorateCreateRouterOptions<
146
146
  ? $Value extends AnyProcedure
147
147
  ? $Value
148
148
  : $Value extends Router<any, infer TRecord>
149
- ? TRecord
150
- : $Value extends CreateRouterOptions
151
- ? DecorateCreateRouterOptions<$Value>
152
- : never
149
+ ? TRecord
150
+ : $Value extends CreateRouterOptions
151
+ ? DecorateCreateRouterOptions<$Value>
152
+ : never
153
153
  : never;
154
154
  };
155
155
 
@@ -318,7 +318,6 @@ export function createCallerFactory<TRoot extends AnyRootTypes>() {
318
318
  type MergeRouters<
319
319
  TRouters extends AnyRouter[],
320
320
  TRoot extends AnyRootTypes = TRouters[0]['_def']['_config']['$types'],
321
- // eslint-disable-next-line @typescript-eslint/ban-types
322
321
  TRecord extends RouterRecord = {},
323
322
  > = TRouters extends [
324
323
  infer Head extends AnyRouter,
@@ -1,3 +1,4 @@
1
+ import { Unpromise } from '../../vendor/unpromise';
1
2
  import { getTRPCErrorFromUnknown } from '../error/TRPCError';
2
3
  import { isAsyncIterable, isFunction, isObject, run } from '../utils';
3
4
  import type { Deferred } from './utils/createDeferred';
@@ -148,7 +149,7 @@ function createBatchStreamProducer(opts: ProducerOptions) {
148
149
  const idx = counter++ as ChunkIndex;
149
150
  pending.add(idx);
150
151
 
151
- Promise.race([promise, stream.cancelledPromise])
152
+ Unpromise.race([promise, stream.cancelledPromise])
152
153
  .then((it) => {
153
154
  if (isCancelledStreamResult(it)) {
154
155
  return;
@@ -191,7 +192,7 @@ function createBatchStreamProducer(opts: ProducerOptions) {
191
192
  const iterator = iterable[Symbol.asyncIterator]();
192
193
 
193
194
  while (true) {
194
- const next = await Promise.race([
195
+ const next = await Unpromise.race([
195
196
  iterator.next().catch(getTRPCErrorFromUnknown),
196
197
  stream.cancelledPromise,
197
198
  ]);
@@ -76,6 +76,8 @@ export function sseStreamProducer<TValue = unknown>(
76
76
  };
77
77
 
78
78
  run(async () => {
79
+ type TIteratorValue = Awaited<TValue> | typeof PING_SYM;
80
+
79
81
  let iterable: AsyncIterable<TValue | typeof PING_SYM> = opts.data;
80
82
 
81
83
  iterable = withCancel(iterable, stream.cancelledPromise);
@@ -106,13 +108,18 @@ export function sseStreamProducer<TValue = unknown>(
106
108
  }
107
109
 
108
110
  try {
109
- for await (const value of iterable) {
111
+ // We need those declarations outside the loop for garbage collection reasons. If they were
112
+ // declared inside, they would not be freed until the next value is present.
113
+ let value: null | TIteratorValue;
114
+ let chunk: null | SSEvent;
115
+
116
+ for await (value of iterable) {
110
117
  if (value === PING_SYM) {
111
118
  stream.controller.enqueue({ comment: 'ping' });
112
119
  continue;
113
120
  }
114
121
 
115
- const chunk: SSEvent = isTrackedEnvelope(value)
122
+ chunk = isTrackedEnvelope(value)
116
123
  ? { id: value[0], data: value[1] }
117
124
  : { data: value };
118
125
  if ('data' in chunk) {
@@ -120,6 +127,10 @@ export function sseStreamProducer<TValue = unknown>(
120
127
  }
121
128
 
122
129
  stream.controller.enqueue(chunk);
130
+
131
+ // free up references for garbage collection
132
+ value = null;
133
+ chunk = null;
123
134
  }
124
135
  } catch (err) {
125
136
  // ignore abort errors, send any other errors
@@ -45,8 +45,5 @@ export function tracked<TData>(
45
45
  return [id as TrackedId, data, trackedSymbol];
46
46
  }
47
47
 
48
- export type inferTrackedOutput<TData> = TData extends TrackedEnvelope<
49
- infer $Data
50
- >
51
- ? TrackedData<$Data>
52
- : TData;
48
+ export type inferTrackedOutput<TData> =
49
+ TData extends TrackedEnvelope<infer $Data> ? TrackedData<$Data> : TData;
@@ -1,3 +1,4 @@
1
+ import { Unpromise } from '../../../vendor/unpromise';
1
2
  import { noop } from '../../utils';
2
3
  import { createPromiseTimer } from './promiseTimer';
3
4
 
@@ -11,8 +12,10 @@ export async function* withCancel<T>(
11
12
  ): AsyncGenerator<T> {
12
13
  const cancelPromise = cancel.then(noop);
13
14
  const iterator = iterable[Symbol.asyncIterator]();
15
+ // declaration outside the loop for garbage collection reasons
16
+ let result: null | IteratorResult<T> | void;
14
17
  while (true) {
15
- const result = await Promise.race([iterator.next(), cancelPromise]);
18
+ result = await Unpromise.race([iterator.next(), cancelPromise]);
16
19
  if (result == null) {
17
20
  await iterator.return?.();
18
21
  break;
@@ -21,6 +24,8 @@ export async function* withCancel<T>(
21
24
  break;
22
25
  }
23
26
  yield result.value;
27
+ // free up reference for garbage collection
28
+ result = null;
24
29
  }
25
30
  }
26
31
 
@@ -42,8 +47,10 @@ export async function* takeWithGrace<T>(
42
47
  const iterator = iterable[Symbol.asyncIterator]();
43
48
  const timer = createPromiseTimer(gracePeriodMs);
44
49
  try {
50
+ // declaration outside the loop for garbage collection reasons
51
+ let result: null | IteratorResult<T> | void;
45
52
  while (true) {
46
- const result = await Promise.race([iterator.next(), timer.promise]);
53
+ result = await Unpromise.race([iterator.next(), timer.promise]);
47
54
  if (result == null) {
48
55
  // cancelled
49
56
  await iterator.return?.();
@@ -56,6 +63,8 @@ export async function* takeWithGrace<T>(
56
63
  if (--count === 0) {
57
64
  timer.start().promise.then(onCancel, noop);
58
65
  }
66
+ // free up reference for garbage collection
67
+ result = null;
59
68
  }
60
69
  } finally {
61
70
  timer.clear();
@@ -1,3 +1,4 @@
1
+ import { Unpromise } from '../../../vendor/unpromise';
1
2
  import { createPromiseTimer } from './promiseTimer';
2
3
 
3
4
  export const PING_SYM = Symbol('ping');
@@ -17,12 +18,13 @@ export async function* withPing<TValue>(
17
18
  ): AsyncGenerator<TValue | typeof PING_SYM> {
18
19
  const timer = createPromiseTimer(pingIntervalMs);
19
20
  const iterator = iterable[Symbol.asyncIterator]();
21
+ // declaration outside the loop for garbage collection reasons
22
+ let result: null | IteratorResult<TValue | typeof PING_SYM>;
20
23
  while (true) {
21
24
  const nextPromise = iterator.next();
22
25
  const pingPromise = timer.start().promise.then(() => PING_RESULT);
23
- let result: IteratorResult<TValue | typeof PING_SYM>;
24
26
  try {
25
- result = await Promise.race([nextPromise, pingPromise]);
27
+ result = await Unpromise.race([nextPromise, pingPromise]);
26
28
  } finally {
27
29
  timer.clear();
28
30
  }
@@ -31,5 +33,7 @@ export async function* withPing<TValue>(
31
33
  }
32
34
  yield result.value;
33
35
  timer.reset();
36
+ // free up reference for garbage collection
37
+ result = null;
34
38
  }
35
39
  }
@@ -175,7 +175,7 @@ export function transformResult<TRouter extends AnyRouter, TOutput>(
175
175
  try {
176
176
  // Use the data transformers on the JSON-response
177
177
  result = transformResultInner(response, transformer);
178
- } catch (err) {
178
+ } catch {
179
179
  throw new TransformResultError();
180
180
  }
181
181