@trpc/server 11.0.0-rc.528 → 11.0.0-rc.530

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.
@@ -27,17 +27,23 @@ export type WSSHandlerOptions<TRouter extends AnyRouter> = WSConnectionHandlerOp
27
27
  enabled: boolean;
28
28
  /**
29
29
  * Heartbeat interval in milliseconds
30
- * @default 30000
30
+ * @default 30_000
31
31
  */
32
32
  pingMs?: number;
33
33
  /**
34
34
  * Terminate the WebSocket if no pong is received after this many milliseconds
35
- * @default 5000
35
+ * @default 5_000
36
36
  */
37
37
  pongWaitMs?: number;
38
38
  };
39
+ /**
40
+ * Disable responding to ping messages from the client
41
+ * **Not recommended** - this is mainly used for testing
42
+ * @default false
43
+ */
44
+ dangerouslyDisablePong?: boolean;
39
45
  };
40
- export declare function getWSConnectionHandler<TRouter extends AnyRouter>(opts: WSConnectionHandlerOptions<TRouter>): (client: ws.WebSocket, req: IncomingMessage) => Promise<void>;
46
+ export declare function getWSConnectionHandler<TRouter extends AnyRouter>(opts: WSSHandlerOptions<TRouter>): (client: ws.WebSocket, req: IncomingMessage) => Promise<void>;
41
47
  /**
42
48
  * Handle WebSocket keep-alive messages
43
49
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../../src/adapters/ws.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EACV,SAAS,EACT,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AASzB,OAAO,EAAS,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AActE,OAAO,EAKL,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAQlE;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,8BAA8B,CACpE,eAAe,EACf,EAAE,CAAC,SAAS,CACb,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,CAAC,OAAO,SAAS,SAAS,IAAI,CAC1D,IAAI,EAAE,yBAAyB,KAC5B,YAAY,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC;AAE/C,MAAM,MAAM,0BAA0B,CAAC,OAAO,SAAS,SAAS,IAC9D,kBAAkB,CAAC,OAAO,EAAE,eAAe,CAAC,GAC1C,qBAAqB,CACnB,kBAAkB,CAAC,OAAO,CAAC,EAC3B,kBAAkB,CAAC,OAAO,CAAC,CAC5B,CAAC;AAEN;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,OAAO,SAAS,SAAS,IACrD,0BAA0B,CAAC,OAAO,CAAC,GAAG;IACpC,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE;QACV;;;WAGG;QACH,OAAO,EAAE,OAAO,CAAC;QACjB;;;WAGG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB;;;WAGG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,CAAC;AAGJ,wBAAgB,sBAAsB,CAAC,OAAO,SAAS,SAAS,EAC9D,IAAI,EAAE,0BAA0B,CAAC,OAAO,CAAC,YAKnB,EAAE,CAAC,SAAS,OAAO,eAAe,mBAwWzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,EAAE,CAAC,SAAS,EACpB,MAAM,SAAQ,EACd,UAAU,SAAO,QAuBlB;AAED,wBAAgB,eAAe,CAAC,OAAO,SAAS,SAAS,EACvD,IAAI,EAAE,iBAAiB,CAAC,OAAO,CAAC;;EA+BjC"}
1
+ {"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../../src/adapters/ws.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EACV,SAAS,EACT,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AASzB,OAAO,EAAS,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AActE,OAAO,EAKL,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAQlE;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,8BAA8B,CACpE,eAAe,EACf,EAAE,CAAC,SAAS,CACb,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,CAAC,OAAO,SAAS,SAAS,IAAI,CAC1D,IAAI,EAAE,yBAAyB,KAC5B,YAAY,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC;AAE/C,MAAM,MAAM,0BAA0B,CAAC,OAAO,SAAS,SAAS,IAC9D,kBAAkB,CAAC,OAAO,EAAE,eAAe,CAAC,GAC1C,qBAAqB,CACnB,kBAAkB,CAAC,OAAO,CAAC,EAC3B,kBAAkB,CAAC,OAAO,CAAC,CAC5B,CAAC;AAEN;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,OAAO,SAAS,SAAS,IACrD,0BAA0B,CAAC,OAAO,CAAC,GAAG;IACpC,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE;QACV;;;WAGG;QACH,OAAO,EAAE,OAAO,CAAC;QACjB;;;WAGG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB;;;WAGG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,CAAC;AAGJ,wBAAgB,sBAAsB,CAAC,OAAO,SAAS,SAAS,EAC9D,IAAI,EAAE,iBAAiB,CAAC,OAAO,CAAC,YAKV,EAAE,CAAC,SAAS,OAAO,eAAe,mBAoXzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,EAAE,CAAC,SAAS,EACpB,MAAM,SAAS,EACf,UAAU,SAAQ,QAuBnB;AAED,wBAAgB,eAAe,CAAC,OAAO,SAAS,SAAS,EACvD,IAAI,EAAE,iBAAiB,CAAC,OAAO,CAAC;;EAwCjC"}
@@ -23,6 +23,10 @@ function getWSConnectionHandler(opts) {
23
23
  return async (client, req)=>{
24
24
  const clientSubscriptions = new Map();
25
25
  const abortController = new AbortController();
26
+ if (opts.keepAlive?.enabled) {
27
+ const { pingMs , pongWaitMs } = opts.keepAlive;
28
+ handleKeepAlive(client, pingMs, pongWaitMs);
29
+ }
26
30
  function respond(untransformedJSON) {
27
31
  client.send(JSON.stringify(transformer.transformTRPCResponse(router$1._def._config, untransformedJSON)));
28
32
  }
@@ -300,7 +304,14 @@ function getWSConnectionHandler(opts) {
300
304
  return;
301
305
  }
302
306
  try {
303
- const msgJSON = JSON.parse(message.toString());
307
+ const str = message.toString();
308
+ if (str === 'PING') {
309
+ if (!opts.dangerouslyDisablePong) {
310
+ client.send('PONG');
311
+ }
312
+ return;
313
+ }
314
+ const msgJSON = JSON.parse(str);
304
315
  const msgs = Array.isArray(msgJSON) ? msgJSON : [
305
316
  msgJSON
306
317
  ];
@@ -346,8 +357,7 @@ function getWSConnectionHandler(opts) {
346
357
  abortController.abort();
347
358
  });
348
359
  if (ctxPromise !== unsetContextPromiseSymbol) {
349
- // prevent unhandled promise rejection errors
350
- await ctxPromise.catch(()=>null);
360
+ await ctxPromise;
351
361
  }
352
362
  };
353
363
  }
@@ -377,17 +387,26 @@ function getWSConnectionHandler(opts) {
377
387
  });
378
388
  }
379
389
  function applyWSSHandler(opts) {
380
- const { wss , prefix , keepAlive } = opts;
381
390
  const onConnection = getWSConnectionHandler(opts);
382
- wss.on('connection', async (client, req)=>{
383
- if (prefix && !req.url?.startsWith(prefix)) {
391
+ opts.wss.on('connection', (client, req)=>{
392
+ if (opts.prefix && !req.url?.startsWith(opts.prefix)) {
384
393
  return;
385
394
  }
386
- await onConnection(client, req);
387
- if (keepAlive?.enabled) {
388
- const { pingMs , pongWaitMs } = keepAlive;
389
- handleKeepAlive(client, pingMs, pongWaitMs);
390
- }
395
+ onConnection(client, req).catch((cause)=>{
396
+ opts.onError?.({
397
+ error: new TRPCError.TRPCError({
398
+ code: 'INTERNAL_SERVER_ERROR',
399
+ cause,
400
+ message: 'Failed to handle WebSocket connection'
401
+ }),
402
+ req: req,
403
+ path: undefined,
404
+ type: 'unknown',
405
+ ctx: undefined,
406
+ input: undefined
407
+ });
408
+ client.close();
409
+ });
391
410
  });
392
411
  return {
393
412
  broadcastReconnectNotification: ()=>{
@@ -396,7 +415,7 @@ function applyWSSHandler(opts) {
396
415
  method: 'reconnect'
397
416
  };
398
417
  const data = JSON.stringify(response);
399
- for (const client of wss.clients){
418
+ for (const client of opts.wss.clients){
400
419
  if (client.readyState === WEBSOCKET_OPEN) {
401
420
  client.send(data);
402
421
  }
@@ -21,6 +21,10 @@ function getWSConnectionHandler(opts) {
21
21
  return async (client, req)=>{
22
22
  const clientSubscriptions = new Map();
23
23
  const abortController = new AbortController();
24
+ if (opts.keepAlive?.enabled) {
25
+ const { pingMs , pongWaitMs } = opts.keepAlive;
26
+ handleKeepAlive(client, pingMs, pongWaitMs);
27
+ }
24
28
  function respond(untransformedJSON) {
25
29
  client.send(JSON.stringify(transformTRPCResponse(router._def._config, untransformedJSON)));
26
30
  }
@@ -298,7 +302,14 @@ function getWSConnectionHandler(opts) {
298
302
  return;
299
303
  }
300
304
  try {
301
- const msgJSON = JSON.parse(message.toString());
305
+ const str = message.toString();
306
+ if (str === 'PING') {
307
+ if (!opts.dangerouslyDisablePong) {
308
+ client.send('PONG');
309
+ }
310
+ return;
311
+ }
312
+ const msgJSON = JSON.parse(str);
302
313
  const msgs = Array.isArray(msgJSON) ? msgJSON : [
303
314
  msgJSON
304
315
  ];
@@ -344,8 +355,7 @@ function getWSConnectionHandler(opts) {
344
355
  abortController.abort();
345
356
  });
346
357
  if (ctxPromise !== unsetContextPromiseSymbol) {
347
- // prevent unhandled promise rejection errors
348
- await ctxPromise.catch(()=>null);
358
+ await ctxPromise;
349
359
  }
350
360
  };
351
361
  }
@@ -375,17 +385,26 @@ function getWSConnectionHandler(opts) {
375
385
  });
376
386
  }
377
387
  function applyWSSHandler(opts) {
378
- const { wss , prefix , keepAlive } = opts;
379
388
  const onConnection = getWSConnectionHandler(opts);
380
- wss.on('connection', async (client, req)=>{
381
- if (prefix && !req.url?.startsWith(prefix)) {
389
+ opts.wss.on('connection', (client, req)=>{
390
+ if (opts.prefix && !req.url?.startsWith(opts.prefix)) {
382
391
  return;
383
392
  }
384
- await onConnection(client, req);
385
- if (keepAlive?.enabled) {
386
- const { pingMs , pongWaitMs } = keepAlive;
387
- handleKeepAlive(client, pingMs, pongWaitMs);
388
- }
393
+ onConnection(client, req).catch((cause)=>{
394
+ opts.onError?.({
395
+ error: new TRPCError({
396
+ code: 'INTERNAL_SERVER_ERROR',
397
+ cause,
398
+ message: 'Failed to handle WebSocket connection'
399
+ }),
400
+ req: req,
401
+ path: undefined,
402
+ type: 'unknown',
403
+ ctx: undefined,
404
+ input: undefined
405
+ });
406
+ client.close();
407
+ });
389
408
  });
390
409
  return {
391
410
  broadcastReconnectNotification: ()=>{
@@ -394,7 +413,7 @@ function applyWSSHandler(opts) {
394
413
  method: 'reconnect'
395
414
  };
396
415
  const data = JSON.stringify(response);
397
- for (const client of wss.clients){
416
+ for (const client of opts.wss.clients){
398
417
  if (client.readyState === WEBSOCKET_OPEN) {
399
418
  client.send(data);
400
419
  }
@@ -1,7 +1,7 @@
1
1
  {
2
- "bundleSize": 135647,
3
- "bundleOrigSize": 185375,
4
- "bundleReduction": 26.83,
2
+ "bundleSize": 136257,
3
+ "bundleOrigSize": 186007,
4
+ "bundleReduction": 26.75,
5
5
  "modules": [
6
6
  {
7
7
  "id": "/src/unstable-core-do-not-import/http/resolveResponse.ts",
@@ -14,7 +14,7 @@
14
14
  "dependents": [
15
15
  "/src/unstable-core-do-not-import.ts"
16
16
  ],
17
- "percent": 13.2,
17
+ "percent": 13.15,
18
18
  "reduction": 0
19
19
  },
20
20
  {
@@ -31,13 +31,13 @@
31
31
  "/src/unstable-core-do-not-import.ts",
32
32
  "/src/unstable-core-do-not-import/http/resolveResponse.ts"
33
33
  ],
34
- "percent": 12.95,
34
+ "percent": 12.89,
35
35
  "reduction": 4.31
36
36
  },
37
37
  {
38
38
  "id": "/src/adapters/ws.ts",
39
- "size": 15782,
40
- "origSize": 14714,
39
+ "size": 16392,
40
+ "origSize": 15346,
41
41
  "renderedExports": [
42
42
  "getWSConnectionHandler",
43
43
  "handleKeepAlive",
@@ -47,7 +47,7 @@
47
47
  "dependents": [
48
48
  "/src/adapters/fastify/fastifyTRPCPlugin.ts"
49
49
  ],
50
- "percent": 11.63,
50
+ "percent": 12.03,
51
51
  "reduction": 0
52
52
  },
53
53
  {
@@ -62,7 +62,7 @@
62
62
  "/src/unstable-core-do-not-import.ts",
63
63
  "/src/unstable-core-do-not-import/http/resolveResponse.ts"
64
64
  ],
65
- "percent": 5.67,
65
+ "percent": 5.64,
66
66
  "reduction": 0
67
67
  },
68
68
  {
@@ -80,7 +80,7 @@
80
80
  "/src/unstable-core-do-not-import.ts",
81
81
  "/src/unstable-core-do-not-import/initTRPC.ts"
82
82
  ],
83
- "percent": 4.73,
83
+ "percent": 4.71,
84
84
  "reduction": 40.18
85
85
  },
86
86
  {
@@ -97,7 +97,7 @@
97
97
  "/src/unstable-core-do-not-import.ts",
98
98
  "/src/unstable-core-do-not-import/http/resolveResponse.ts"
99
99
  ],
100
- "percent": 4.36,
100
+ "percent": 4.34,
101
101
  "reduction": 15.22
102
102
  },
103
103
  {
@@ -112,7 +112,7 @@
112
112
  "/src/unstable-core-do-not-import.ts",
113
113
  "/src/unstable-core-do-not-import/initTRPC.ts"
114
114
  ],
115
- "percent": 4.27,
115
+ "percent": 4.25,
116
116
  "reduction": 63.05
117
117
  },
118
118
  {
@@ -126,7 +126,7 @@
126
126
  "dependents": [
127
127
  "/src/adapters/aws-lambda/index.ts"
128
128
  ],
129
- "percent": 3.99,
129
+ "percent": 3.98,
130
130
  "reduction": 11.38
131
131
  },
132
132
  {
@@ -146,7 +146,7 @@
146
146
  "/src/unstable-core-do-not-import/http/resolveResponse.ts",
147
147
  "/src/observable/operators.ts"
148
148
  ],
149
- "percent": 3.03,
149
+ "percent": 3.02,
150
150
  "reduction": 0
151
151
  },
152
152
  {
@@ -160,7 +160,7 @@
160
160
  "dependents": [
161
161
  "/src/adapters/next-app-dir.ts"
162
162
  ],
163
- "percent": 2.37,
163
+ "percent": 2.36,
164
164
  "reduction": 22.57
165
165
  },
166
166
  {
@@ -174,7 +174,7 @@
174
174
  "dependents": [
175
175
  "/src/adapters/node-http/index.ts"
176
176
  ],
177
- "percent": 2.11,
177
+ "percent": 2.1,
178
178
  "reduction": 6.07
179
179
  },
180
180
  {
@@ -190,7 +190,7 @@
190
190
  "dependents": [
191
191
  "/src/observable/index.ts"
192
192
  ],
193
- "percent": 2.03,
193
+ "percent": 2.02,
194
194
  "reduction": 0
195
195
  },
196
196
  {
@@ -206,11 +206,11 @@
206
206
  "removedExports": [],
207
207
  "dependents": [
208
208
  "/src/unstable-core-do-not-import.ts",
209
+ "/src/unstable-core-do-not-import/http/resolveResponse.ts",
209
210
  "/src/unstable-core-do-not-import/initTRPC.ts",
210
- "/src/unstable-core-do-not-import/router.ts",
211
- "/src/unstable-core-do-not-import/http/resolveResponse.ts"
211
+ "/src/unstable-core-do-not-import/router.ts"
212
212
  ],
213
- "percent": 2.02,
213
+ "percent": 2.01,
214
214
  "reduction": 45.94
215
215
  },
216
216
  {
@@ -224,7 +224,7 @@
224
224
  "dependents": [
225
225
  "/src/unstable-core-do-not-import.ts"
226
226
  ],
227
- "percent": 1.99,
227
+ "percent": 1.98,
228
228
  "reduction": 40.91
229
229
  },
230
230
  {
@@ -244,7 +244,7 @@
244
244
  "/src/unstable-core-do-not-import/initTRPC.ts",
245
245
  "/src/unstable-core-do-not-import/procedureBuilder.ts"
246
246
  ],
247
- "percent": 1.94,
247
+ "percent": 1.93,
248
248
  "reduction": 55.77
249
249
  },
250
250
  {
@@ -260,7 +260,7 @@
260
260
  "/src/unstable-core-do-not-import.ts",
261
261
  "/src/unstable-core-do-not-import/router.ts"
262
262
  ],
263
- "percent": 1.72,
263
+ "percent": 1.71,
264
264
  "reduction": 0
265
265
  },
266
266
  {
@@ -274,7 +274,7 @@
274
274
  "dependents": [
275
275
  "/src/adapters/fetch/index.ts"
276
276
  ],
277
- "percent": 1.66,
277
+ "percent": 1.65,
278
278
  "reduction": 2.17
279
279
  },
280
280
  {
@@ -289,7 +289,7 @@
289
289
  "/src/adapters/node-http/index.ts",
290
290
  "/src/adapters/node-http/nodeHTTPRequestHandler.ts"
291
291
  ],
292
- "percent": 1.62,
292
+ "percent": 1.61,
293
293
  "reduction": 13.79
294
294
  },
295
295
  {
@@ -303,7 +303,7 @@
303
303
  "dependents": [
304
304
  "/src/adapters/next-app-dir/nextAppDirCaller.ts"
305
305
  ],
306
- "percent": 1.51,
306
+ "percent": 1.5,
307
307
  "reduction": 5.79
308
308
  },
309
309
  {
@@ -332,16 +332,16 @@
332
332
  "removedExports": [],
333
333
  "dependents": [
334
334
  "/src/unstable-core-do-not-import.ts",
335
- "/src/unstable-core-do-not-import/middleware.ts",
336
- "/src/unstable-core-do-not-import/router.ts",
337
335
  "/src/unstable-core-do-not-import/http/parseConnectionParams.ts",
338
336
  "/src/unstable-core-do-not-import/http/resolveResponse.ts",
337
+ "/src/unstable-core-do-not-import/middleware.ts",
338
+ "/src/unstable-core-do-not-import/router.ts",
339
339
  "/src/unstable-core-do-not-import/http/contentType.ts",
340
340
  "/src/unstable-core-do-not-import/procedureBuilder.ts",
341
341
  "/src/unstable-core-do-not-import/stream/jsonl.ts",
342
342
  "/src/unstable-core-do-not-import/stream/sse.ts"
343
343
  ],
344
- "percent": 1.28,
344
+ "percent": 1.27,
345
345
  "reduction": 19.47
346
346
  },
347
347
  {
@@ -366,7 +366,7 @@
366
366
  ],
367
367
  "removedExports": [],
368
368
  "dependents": [],
369
- "percent": 1.19,
369
+ "percent": 1.18,
370
370
  "reduction": 27.47
371
371
  },
372
372
  {
@@ -378,7 +378,7 @@
378
378
  ],
379
379
  "removedExports": [],
380
380
  "dependents": [],
381
- "percent": 1.14,
381
+ "percent": 1.13,
382
382
  "reduction": 26.94
383
383
  },
384
384
  {
@@ -392,8 +392,8 @@
392
392
  "removedExports": [],
393
393
  "dependents": [
394
394
  "/src/unstable-core-do-not-import.ts",
395
- "/src/unstable-core-do-not-import/error/getErrorShape.ts",
396
- "/src/unstable-core-do-not-import/http/resolveResponse.ts"
395
+ "/src/unstable-core-do-not-import/http/resolveResponse.ts",
396
+ "/src/unstable-core-do-not-import/error/getErrorShape.ts"
397
397
  ],
398
398
  "percent": 1.06,
399
399
  "reduction": 16.73
@@ -410,7 +410,7 @@
410
410
  "/src/unstable-core-do-not-import.ts",
411
411
  "/src/unstable-core-do-not-import/procedureBuilder.ts"
412
412
  ],
413
- "percent": 0.96,
413
+ "percent": 0.95,
414
414
  "reduction": 55.21
415
415
  },
416
416
  {
@@ -429,16 +429,16 @@
429
429
  "removedExports": [],
430
430
  "dependents": [
431
431
  "/src/unstable-core-do-not-import.ts",
432
+ "/src/unstable-core-do-not-import/http/getHTTPStatusCode.ts",
433
+ "/src/unstable-core-do-not-import/http/parseConnectionParams.ts",
434
+ "/src/unstable-core-do-not-import/http/resolveResponse.ts",
432
435
  "/src/unstable-core-do-not-import/error/TRPCError.ts",
433
436
  "/src/unstable-core-do-not-import/transformer.ts",
434
437
  "/src/unstable-core-do-not-import/middleware.ts",
435
438
  "/src/unstable-core-do-not-import/router.ts",
436
- "/src/unstable-core-do-not-import/rpc/parseTRPCMessage.ts",
437
- "/src/unstable-core-do-not-import/http/getHTTPStatusCode.ts",
438
- "/src/unstable-core-do-not-import/http/parseConnectionParams.ts",
439
- "/src/unstable-core-do-not-import/http/resolveResponse.ts",
440
439
  "/src/unstable-core-do-not-import/http/contentType.ts",
441
440
  "/src/unstable-core-do-not-import/procedureBuilder.ts",
441
+ "/src/unstable-core-do-not-import/rpc/parseTRPCMessage.ts",
442
442
  "/src/unstable-core-do-not-import/stream/jsonl.ts",
443
443
  "/src/unstable-core-do-not-import/stream/sse.ts"
444
444
  ],
@@ -504,7 +504,7 @@
504
504
  "/src/adapters/next-app-dir/nextAppDirCaller.ts",
505
505
  "/src/adapters/next-app-dir/rethrowNextErrors.ts"
506
506
  ],
507
- "percent": 0.73,
507
+ "percent": 0.72,
508
508
  "reduction": 13.65
509
509
  },
510
510
  {
@@ -539,7 +539,7 @@
539
539
  "/src/unstable-core-do-not-import.ts",
540
540
  "/src/unstable-core-do-not-import/stream/sse.ts"
541
541
  ],
542
- "percent": 0.59,
542
+ "percent": 0.58,
543
543
  "reduction": 44.65
544
544
  },
545
545
  {
@@ -727,19 +727,21 @@
727
727
  "reduction": 93.8
728
728
  },
729
729
  {
730
- "id": "/src/index.ts",
730
+ "id": "/src/http.ts",
731
731
  "size": 0,
732
- "origSize": 32,
732
+ "origSize": 37,
733
733
  "renderedExports": [],
734
734
  "removedExports": [],
735
- "dependents": [],
735
+ "dependents": [
736
+ "/src/adapters/ws.ts"
737
+ ],
736
738
  "percent": 0,
737
739
  "reduction": 100
738
740
  },
739
741
  {
740
- "id": "/src/rpc.ts",
742
+ "id": "/src/index.ts",
741
743
  "size": 0,
742
- "origSize": 36,
744
+ "origSize": 32,
743
745
  "renderedExports": [],
744
746
  "removedExports": [],
745
747
  "dependents": [],
@@ -747,21 +749,22 @@
747
749
  "reduction": 100
748
750
  },
749
751
  {
750
- "id": "/src/http.ts",
752
+ "id": "/src/unstable-core-do-not-import.ts",
751
753
  "size": 0,
752
- "origSize": 37,
754
+ "origSize": 2306,
753
755
  "renderedExports": [],
754
756
  "removedExports": [],
755
757
  "dependents": [
756
- "/src/adapters/ws.ts"
758
+ "/src/adapters/ws.ts",
759
+ "/src/adapters/next-app-dir/nextAppDirCaller.ts"
757
760
  ],
758
761
  "percent": 0,
759
762
  "reduction": 100
760
763
  },
761
764
  {
762
- "id": "/src/shared.ts",
765
+ "id": "/src/rpc.ts",
763
766
  "size": 0,
764
- "origSize": 653,
767
+ "origSize": 36,
765
768
  "renderedExports": [],
766
769
  "removedExports": [],
767
770
  "dependents": [],
@@ -769,15 +772,12 @@
769
772
  "reduction": 100
770
773
  },
771
774
  {
772
- "id": "/src/unstable-core-do-not-import.ts",
775
+ "id": "/src/shared.ts",
773
776
  "size": 0,
774
- "origSize": 2306,
777
+ "origSize": 653,
775
778
  "renderedExports": [],
776
779
  "removedExports": [],
777
- "dependents": [
778
- "/src/adapters/ws.ts",
779
- "/src/adapters/next-app-dir/nextAppDirCaller.ts"
780
- ],
780
+ "dependents": [],
781
781
  "percent": 0,
782
782
  "reduction": 100
783
783
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trpc/server",
3
- "version": "11.0.0-rc.528+32e6b1285",
3
+ "version": "11.0.0-rc.530+d1e8f33f6",
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": "32e6b1285dd844776d323ae23fbea638312d676e"
152
+ "gitHead": "d1e8f33f6bc6104003f4a0d4030c6cf306e6dec2"
153
153
  }
@@ -79,20 +79,26 @@ export type WSSHandlerOptions<TRouter extends AnyRouter> =
79
79
  enabled: boolean;
80
80
  /**
81
81
  * Heartbeat interval in milliseconds
82
- * @default 30000
82
+ * @default 30_000
83
83
  */
84
84
  pingMs?: number;
85
85
  /**
86
86
  * Terminate the WebSocket if no pong is received after this many milliseconds
87
- * @default 5000
87
+ * @default 5_000
88
88
  */
89
89
  pongWaitMs?: number;
90
90
  };
91
+ /**
92
+ * Disable responding to ping messages from the client
93
+ * **Not recommended** - this is mainly used for testing
94
+ * @default false
95
+ */
96
+ dangerouslyDisablePong?: boolean;
91
97
  };
92
98
 
93
99
  const unsetContextPromiseSymbol = Symbol('unsetContextPromise');
94
100
  export function getWSConnectionHandler<TRouter extends AnyRouter>(
95
- opts: WSConnectionHandlerOptions<TRouter>,
101
+ opts: WSSHandlerOptions<TRouter>,
96
102
  ) {
97
103
  const { createContext, router } = opts;
98
104
  const { transformer } = router._def._config;
@@ -101,6 +107,11 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
101
107
  const clientSubscriptions = new Map<number | string, AbortController>();
102
108
  const abortController = new AbortController();
103
109
 
110
+ if (opts.keepAlive?.enabled) {
111
+ const { pingMs, pongWaitMs } = opts.keepAlive;
112
+ handleKeepAlive(client, pingMs, pongWaitMs);
113
+ }
114
+
104
115
  function respond(untransformedJSON: TRPCResponseMessage) {
105
116
  client.send(
106
117
  JSON.stringify(
@@ -403,7 +414,15 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
403
414
  return;
404
415
  }
405
416
  try {
406
- const msgJSON: unknown = JSON.parse(message.toString());
417
+ const str = message.toString();
418
+ if (str === 'PING') {
419
+ if (!opts.dangerouslyDisablePong) {
420
+ client.send('PONG');
421
+ }
422
+
423
+ return;
424
+ }
425
+ const msgJSON: unknown = JSON.parse(str);
407
426
  const msgs: unknown[] = Array.isArray(msgJSON) ? msgJSON : [msgJSON];
408
427
  const promises = msgs
409
428
  .map((raw) => parseTRPCMessage(raw, transformer))
@@ -453,8 +472,7 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
453
472
  });
454
473
 
455
474
  if (ctxPromise !== unsetContextPromiseSymbol) {
456
- // prevent unhandled promise rejection errors
457
- await ctxPromise.catch(() => null);
475
+ await ctxPromise;
458
476
  }
459
477
  };
460
478
  }
@@ -464,8 +482,8 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
464
482
  */
465
483
  export function handleKeepAlive(
466
484
  client: ws.WebSocket,
467
- pingMs = 30000,
468
- pongWaitMs = 5000,
485
+ pingMs = 30_000,
486
+ pongWaitMs = 5_000,
469
487
  ) {
470
488
  let heartbeatTimeout: NodeJS.Timeout | undefined;
471
489
  const heartbeatInterval = setInterval(() => {
@@ -493,19 +511,28 @@ export function handleKeepAlive(
493
511
  export function applyWSSHandler<TRouter extends AnyRouter>(
494
512
  opts: WSSHandlerOptions<TRouter>,
495
513
  ) {
496
- const { wss, prefix, keepAlive } = opts;
497
-
498
514
  const onConnection = getWSConnectionHandler(opts);
499
- wss.on('connection', async (client, req) => {
500
- if (prefix && !req.url?.startsWith(prefix)) {
515
+ opts.wss.on('connection', (client, req) => {
516
+ if (opts.prefix && !req.url?.startsWith(opts.prefix)) {
501
517
  return;
502
518
  }
503
519
 
504
- await onConnection(client, req);
505
- if (keepAlive?.enabled) {
506
- const { pingMs, pongWaitMs } = keepAlive;
507
- handleKeepAlive(client, pingMs, pongWaitMs);
508
- }
520
+ onConnection(client, req).catch((cause) => {
521
+ opts.onError?.({
522
+ error: new TRPCError({
523
+ code: 'INTERNAL_SERVER_ERROR',
524
+ cause,
525
+ message: 'Failed to handle WebSocket connection',
526
+ }),
527
+ req: req,
528
+ path: undefined,
529
+ type: 'unknown',
530
+ ctx: undefined,
531
+ input: undefined,
532
+ });
533
+
534
+ client.close();
535
+ });
509
536
  });
510
537
 
511
538
  return {
@@ -515,7 +542,7 @@ export function applyWSSHandler<TRouter extends AnyRouter>(
515
542
  method: 'reconnect',
516
543
  };
517
544
  const data = JSON.stringify(response);
518
- for (const client of wss.clients) {
545
+ for (const client of opts.wss.clients) {
519
546
  if (client.readyState === WEBSOCKET_OPEN) {
520
547
  client.send(data);
521
548
  }