@trpc/server 11.0.0-rc.528 → 11.0.0-rc.531
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/ws.d.ts +9 -3
- package/dist/adapters/ws.d.ts.map +1 -1
- package/dist/adapters/ws.js +58 -33
- package/dist/adapters/ws.mjs +58 -33
- package/dist/bundle-analysis.json +59 -59
- package/package.json +2 -2
- package/src/adapters/ws.ts +78 -39
package/dist/adapters/ws.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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:
|
|
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;
|
|
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,mBAsXzD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,EAAE,CAAC,SAAS,EACpB,MAAM,SAAS,EACf,UAAU,SAAQ,QAiCnB;AAED,wBAAgB,eAAe,CAAC,OAAO,SAAS,SAAS,EACvD,IAAI,EAAE,iBAAiB,CAAC,OAAO,CAAC;;EAwCjC"}
|
package/dist/adapters/ws.js
CHANGED
|
@@ -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
|
}
|
|
@@ -277,13 +281,23 @@ function getWSConnectionHandler(opts) {
|
|
|
277
281
|
});
|
|
278
282
|
}
|
|
279
283
|
}
|
|
280
|
-
client.on('message', async (
|
|
284
|
+
client.on('message', async (rawData)=>{
|
|
285
|
+
const msgStr = rawData.toString();
|
|
286
|
+
if (msgStr === 'PONG') {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (msgStr === 'PING') {
|
|
290
|
+
if (!opts.dangerouslyDisablePong) {
|
|
291
|
+
client.send('PONG');
|
|
292
|
+
}
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
281
295
|
if (ctxPromise === unsetContextPromiseSymbol) {
|
|
282
296
|
// If the ctxPromise wasn't created immediately, we're expecting the first message to be a TRPCConnectionParamsMessage
|
|
283
297
|
ctxPromise = createCtxPromise(()=>{
|
|
284
298
|
let msg;
|
|
285
299
|
try {
|
|
286
|
-
msg = JSON.parse(
|
|
300
|
+
msg = JSON.parse(msgStr);
|
|
287
301
|
if (!utils.isObject(msg)) {
|
|
288
302
|
throw new Error('Message was not an object');
|
|
289
303
|
}
|
|
@@ -300,7 +314,7 @@ function getWSConnectionHandler(opts) {
|
|
|
300
314
|
return;
|
|
301
315
|
}
|
|
302
316
|
try {
|
|
303
|
-
const msgJSON = JSON.parse(
|
|
317
|
+
const msgJSON = JSON.parse(msgStr);
|
|
304
318
|
const msgs = Array.isArray(msgJSON) ? msgJSON : [
|
|
305
319
|
msgJSON
|
|
306
320
|
];
|
|
@@ -346,48 +360,59 @@ function getWSConnectionHandler(opts) {
|
|
|
346
360
|
abortController.abort();
|
|
347
361
|
});
|
|
348
362
|
if (ctxPromise !== unsetContextPromiseSymbol) {
|
|
349
|
-
|
|
350
|
-
await ctxPromise.catch(()=>null);
|
|
363
|
+
await ctxPromise;
|
|
351
364
|
}
|
|
352
365
|
};
|
|
353
366
|
}
|
|
354
367
|
/**
|
|
355
368
|
* Handle WebSocket keep-alive messages
|
|
356
369
|
*/ function handleKeepAlive(client, pingMs = 30000, pongWaitMs = 5000) {
|
|
357
|
-
let
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
client.
|
|
367
|
-
|
|
368
|
-
},
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
370
|
+
let timeout = undefined;
|
|
371
|
+
let ping = undefined;
|
|
372
|
+
const schedulePing = ()=>{
|
|
373
|
+
const scheduleTimeout = ()=>{
|
|
374
|
+
timeout = setTimeout(()=>{
|
|
375
|
+
client.terminate();
|
|
376
|
+
}, pongWaitMs);
|
|
377
|
+
};
|
|
378
|
+
ping = setTimeout(()=>{
|
|
379
|
+
client.send('PING');
|
|
380
|
+
scheduleTimeout();
|
|
381
|
+
}, pingMs);
|
|
382
|
+
};
|
|
383
|
+
const onMessage = ()=>{
|
|
384
|
+
clearTimeout(ping);
|
|
385
|
+
clearTimeout(timeout);
|
|
386
|
+
schedulePing();
|
|
387
|
+
};
|
|
388
|
+
client.on('message', onMessage);
|
|
375
389
|
client.on('close', ()=>{
|
|
376
|
-
|
|
390
|
+
clearTimeout(ping);
|
|
391
|
+
clearTimeout(timeout);
|
|
377
392
|
});
|
|
393
|
+
schedulePing();
|
|
378
394
|
}
|
|
379
395
|
function applyWSSHandler(opts) {
|
|
380
|
-
const { wss , prefix , keepAlive } = opts;
|
|
381
396
|
const onConnection = getWSConnectionHandler(opts);
|
|
382
|
-
wss.on('connection',
|
|
383
|
-
if (prefix && !req.url?.startsWith(prefix)) {
|
|
397
|
+
opts.wss.on('connection', (client, req)=>{
|
|
398
|
+
if (opts.prefix && !req.url?.startsWith(opts.prefix)) {
|
|
384
399
|
return;
|
|
385
400
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
401
|
+
onConnection(client, req).catch((cause)=>{
|
|
402
|
+
opts.onError?.({
|
|
403
|
+
error: new TRPCError.TRPCError({
|
|
404
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
405
|
+
cause,
|
|
406
|
+
message: 'Failed to handle WebSocket connection'
|
|
407
|
+
}),
|
|
408
|
+
req: req,
|
|
409
|
+
path: undefined,
|
|
410
|
+
type: 'unknown',
|
|
411
|
+
ctx: undefined,
|
|
412
|
+
input: undefined
|
|
413
|
+
});
|
|
414
|
+
client.close();
|
|
415
|
+
});
|
|
391
416
|
});
|
|
392
417
|
return {
|
|
393
418
|
broadcastReconnectNotification: ()=>{
|
|
@@ -396,7 +421,7 @@ function applyWSSHandler(opts) {
|
|
|
396
421
|
method: 'reconnect'
|
|
397
422
|
};
|
|
398
423
|
const data = JSON.stringify(response);
|
|
399
|
-
for (const client of wss.clients){
|
|
424
|
+
for (const client of opts.wss.clients){
|
|
400
425
|
if (client.readyState === WEBSOCKET_OPEN) {
|
|
401
426
|
client.send(data);
|
|
402
427
|
}
|
package/dist/adapters/ws.mjs
CHANGED
|
@@ -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
|
}
|
|
@@ -275,13 +279,23 @@ function getWSConnectionHandler(opts) {
|
|
|
275
279
|
});
|
|
276
280
|
}
|
|
277
281
|
}
|
|
278
|
-
client.on('message', async (
|
|
282
|
+
client.on('message', async (rawData)=>{
|
|
283
|
+
const msgStr = rawData.toString();
|
|
284
|
+
if (msgStr === 'PONG') {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (msgStr === 'PING') {
|
|
288
|
+
if (!opts.dangerouslyDisablePong) {
|
|
289
|
+
client.send('PONG');
|
|
290
|
+
}
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
279
293
|
if (ctxPromise === unsetContextPromiseSymbol) {
|
|
280
294
|
// If the ctxPromise wasn't created immediately, we're expecting the first message to be a TRPCConnectionParamsMessage
|
|
281
295
|
ctxPromise = createCtxPromise(()=>{
|
|
282
296
|
let msg;
|
|
283
297
|
try {
|
|
284
|
-
msg = JSON.parse(
|
|
298
|
+
msg = JSON.parse(msgStr);
|
|
285
299
|
if (!isObject(msg)) {
|
|
286
300
|
throw new Error('Message was not an object');
|
|
287
301
|
}
|
|
@@ -298,7 +312,7 @@ function getWSConnectionHandler(opts) {
|
|
|
298
312
|
return;
|
|
299
313
|
}
|
|
300
314
|
try {
|
|
301
|
-
const msgJSON = JSON.parse(
|
|
315
|
+
const msgJSON = JSON.parse(msgStr);
|
|
302
316
|
const msgs = Array.isArray(msgJSON) ? msgJSON : [
|
|
303
317
|
msgJSON
|
|
304
318
|
];
|
|
@@ -344,48 +358,59 @@ function getWSConnectionHandler(opts) {
|
|
|
344
358
|
abortController.abort();
|
|
345
359
|
});
|
|
346
360
|
if (ctxPromise !== unsetContextPromiseSymbol) {
|
|
347
|
-
|
|
348
|
-
await ctxPromise.catch(()=>null);
|
|
361
|
+
await ctxPromise;
|
|
349
362
|
}
|
|
350
363
|
};
|
|
351
364
|
}
|
|
352
365
|
/**
|
|
353
366
|
* Handle WebSocket keep-alive messages
|
|
354
367
|
*/ function handleKeepAlive(client, pingMs = 30000, pongWaitMs = 5000) {
|
|
355
|
-
let
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
client.
|
|
365
|
-
|
|
366
|
-
},
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
368
|
+
let timeout = undefined;
|
|
369
|
+
let ping = undefined;
|
|
370
|
+
const schedulePing = ()=>{
|
|
371
|
+
const scheduleTimeout = ()=>{
|
|
372
|
+
timeout = setTimeout(()=>{
|
|
373
|
+
client.terminate();
|
|
374
|
+
}, pongWaitMs);
|
|
375
|
+
};
|
|
376
|
+
ping = setTimeout(()=>{
|
|
377
|
+
client.send('PING');
|
|
378
|
+
scheduleTimeout();
|
|
379
|
+
}, pingMs);
|
|
380
|
+
};
|
|
381
|
+
const onMessage = ()=>{
|
|
382
|
+
clearTimeout(ping);
|
|
383
|
+
clearTimeout(timeout);
|
|
384
|
+
schedulePing();
|
|
385
|
+
};
|
|
386
|
+
client.on('message', onMessage);
|
|
373
387
|
client.on('close', ()=>{
|
|
374
|
-
|
|
388
|
+
clearTimeout(ping);
|
|
389
|
+
clearTimeout(timeout);
|
|
375
390
|
});
|
|
391
|
+
schedulePing();
|
|
376
392
|
}
|
|
377
393
|
function applyWSSHandler(opts) {
|
|
378
|
-
const { wss , prefix , keepAlive } = opts;
|
|
379
394
|
const onConnection = getWSConnectionHandler(opts);
|
|
380
|
-
wss.on('connection',
|
|
381
|
-
if (prefix && !req.url?.startsWith(prefix)) {
|
|
395
|
+
opts.wss.on('connection', (client, req)=>{
|
|
396
|
+
if (opts.prefix && !req.url?.startsWith(opts.prefix)) {
|
|
382
397
|
return;
|
|
383
398
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
399
|
+
onConnection(client, req).catch((cause)=>{
|
|
400
|
+
opts.onError?.({
|
|
401
|
+
error: new TRPCError({
|
|
402
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
403
|
+
cause,
|
|
404
|
+
message: 'Failed to handle WebSocket connection'
|
|
405
|
+
}),
|
|
406
|
+
req: req,
|
|
407
|
+
path: undefined,
|
|
408
|
+
type: 'unknown',
|
|
409
|
+
ctx: undefined,
|
|
410
|
+
input: undefined
|
|
411
|
+
});
|
|
412
|
+
client.close();
|
|
413
|
+
});
|
|
389
414
|
});
|
|
390
415
|
return {
|
|
391
416
|
broadcastReconnectNotification: ()=>{
|
|
@@ -394,7 +419,7 @@ function applyWSSHandler(opts) {
|
|
|
394
419
|
method: 'reconnect'
|
|
395
420
|
};
|
|
396
421
|
const data = JSON.stringify(response);
|
|
397
|
-
for (const client of wss.clients){
|
|
422
|
+
for (const client of opts.wss.clients){
|
|
398
423
|
if (client.readyState === WEBSOCKET_OPEN) {
|
|
399
424
|
client.send(data);
|
|
400
425
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"bundleSize":
|
|
3
|
-
"bundleOrigSize":
|
|
4
|
-
"bundleReduction": 26.
|
|
2
|
+
"bundleSize": 136151,
|
|
3
|
+
"bundleOrigSize": 185917,
|
|
4
|
+
"bundleReduction": 26.77,
|
|
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.
|
|
17
|
+
"percent": 13.16,
|
|
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.
|
|
34
|
+
"percent": 12.9,
|
|
35
35
|
"reduction": 4.31
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
"id": "/src/adapters/ws.ts",
|
|
39
|
-
"size":
|
|
40
|
-
"origSize":
|
|
39
|
+
"size": 16286,
|
|
40
|
+
"origSize": 15256,
|
|
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.
|
|
50
|
+
"percent": 11.96,
|
|
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.
|
|
65
|
+
"percent": 5.65,
|
|
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.
|
|
83
|
+
"percent": 4.72,
|
|
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.
|
|
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.
|
|
115
|
+
"percent": 4.26,
|
|
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.
|
|
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.
|
|
149
|
+
"percent": 3.02,
|
|
150
150
|
"reduction": 0
|
|
151
151
|
},
|
|
152
152
|
{
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
"dependents": [
|
|
175
175
|
"/src/adapters/node-http/index.ts"
|
|
176
176
|
],
|
|
177
|
-
"percent": 2.
|
|
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.
|
|
193
|
+
"percent": 2.02,
|
|
194
194
|
"reduction": 0
|
|
195
195
|
},
|
|
196
196
|
{
|
|
@@ -206,9 +206,9 @@
|
|
|
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
213
|
"percent": 2.02,
|
|
214
214
|
"reduction": 45.94
|
|
@@ -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.
|
|
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.
|
|
263
|
+
"percent": 1.71,
|
|
264
264
|
"reduction": 0
|
|
265
265
|
},
|
|
266
266
|
{
|
|
@@ -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.
|
|
292
|
+
"percent": 1.61,
|
|
293
293
|
"reduction": 13.79
|
|
294
294
|
},
|
|
295
295
|
{
|
|
@@ -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.
|
|
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.
|
|
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.
|
|
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/
|
|
396
|
-
"/src/unstable-core-do-not-import/
|
|
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.
|
|
413
|
+
"percent": 0.95,
|
|
414
414
|
"reduction": 55.21
|
|
415
415
|
},
|
|
416
416
|
{
|
|
@@ -429,14 +429,14 @@
|
|
|
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
439
|
"/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
440
|
"/src/unstable-core-do-not-import/http/contentType.ts",
|
|
441
441
|
"/src/unstable-core-do-not-import/procedureBuilder.ts",
|
|
442
442
|
"/src/unstable-core-do-not-import/stream/jsonl.ts",
|
|
@@ -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.
|
|
507
|
+
"percent": 0.72,
|
|
508
508
|
"reduction": 13.65
|
|
509
509
|
},
|
|
510
510
|
{
|
|
@@ -726,6 +726,18 @@
|
|
|
726
726
|
"percent": 0.04,
|
|
727
727
|
"reduction": 93.8
|
|
728
728
|
},
|
|
729
|
+
{
|
|
730
|
+
"id": "/src/http.ts",
|
|
731
|
+
"size": 0,
|
|
732
|
+
"origSize": 37,
|
|
733
|
+
"renderedExports": [],
|
|
734
|
+
"removedExports": [],
|
|
735
|
+
"dependents": [
|
|
736
|
+
"/src/adapters/ws.ts"
|
|
737
|
+
],
|
|
738
|
+
"percent": 0,
|
|
739
|
+
"reduction": 100
|
|
740
|
+
},
|
|
729
741
|
{
|
|
730
742
|
"id": "/src/index.ts",
|
|
731
743
|
"size": 0,
|
|
@@ -747,13 +759,14 @@
|
|
|
747
759
|
"reduction": 100
|
|
748
760
|
},
|
|
749
761
|
{
|
|
750
|
-
"id": "/src/
|
|
762
|
+
"id": "/src/unstable-core-do-not-import.ts",
|
|
751
763
|
"size": 0,
|
|
752
|
-
"origSize":
|
|
764
|
+
"origSize": 2306,
|
|
753
765
|
"renderedExports": [],
|
|
754
766
|
"removedExports": [],
|
|
755
767
|
"dependents": [
|
|
756
|
-
"/src/adapters/ws.ts"
|
|
768
|
+
"/src/adapters/ws.ts",
|
|
769
|
+
"/src/adapters/next-app-dir/nextAppDirCaller.ts"
|
|
757
770
|
],
|
|
758
771
|
"percent": 0,
|
|
759
772
|
"reduction": 100
|
|
@@ -768,19 +781,6 @@
|
|
|
768
781
|
"percent": 0,
|
|
769
782
|
"reduction": 100
|
|
770
783
|
},
|
|
771
|
-
{
|
|
772
|
-
"id": "/src/unstable-core-do-not-import.ts",
|
|
773
|
-
"size": 0,
|
|
774
|
-
"origSize": 2306,
|
|
775
|
-
"renderedExports": [],
|
|
776
|
-
"removedExports": [],
|
|
777
|
-
"dependents": [
|
|
778
|
-
"/src/adapters/ws.ts",
|
|
779
|
-
"/src/adapters/next-app-dir/nextAppDirCaller.ts"
|
|
780
|
-
],
|
|
781
|
-
"percent": 0,
|
|
782
|
-
"reduction": 100
|
|
783
|
-
},
|
|
784
784
|
{
|
|
785
785
|
"id": "/src/adapters/next-app-dir.ts",
|
|
786
786
|
"size": 0,
|
|
@@ -813,16 +813,6 @@
|
|
|
813
813
|
"percent": 0,
|
|
814
814
|
"reduction": 100
|
|
815
815
|
},
|
|
816
|
-
{
|
|
817
|
-
"id": "/src/adapters/fetch/index.ts",
|
|
818
|
-
"size": 0,
|
|
819
|
-
"origSize": 64,
|
|
820
|
-
"renderedExports": [],
|
|
821
|
-
"removedExports": [],
|
|
822
|
-
"dependents": [],
|
|
823
|
-
"percent": 0,
|
|
824
|
-
"reduction": 100
|
|
825
|
-
},
|
|
826
816
|
{
|
|
827
817
|
"id": "/src/adapters/node-http/index.ts",
|
|
828
818
|
"size": 0,
|
|
@@ -837,6 +827,16 @@
|
|
|
837
827
|
],
|
|
838
828
|
"percent": 0,
|
|
839
829
|
"reduction": 100
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
"id": "/src/adapters/fetch/index.ts",
|
|
833
|
+
"size": 0,
|
|
834
|
+
"origSize": 64,
|
|
835
|
+
"renderedExports": [],
|
|
836
|
+
"removedExports": [],
|
|
837
|
+
"dependents": [],
|
|
838
|
+
"percent": 0,
|
|
839
|
+
"reduction": 100
|
|
840
840
|
}
|
|
841
841
|
],
|
|
842
842
|
"moduleCount": 56
|
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.531+42d5af1b1",
|
|
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": "42d5af1b189a1b80b1f128deb81550b1ddc6eeb6"
|
|
153
153
|
}
|
package/src/adapters/ws.ts
CHANGED
|
@@ -79,20 +79,26 @@ export type WSSHandlerOptions<TRouter extends AnyRouter> =
|
|
|
79
79
|
enabled: boolean;
|
|
80
80
|
/**
|
|
81
81
|
* Heartbeat interval in milliseconds
|
|
82
|
-
* @default
|
|
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
|
|
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:
|
|
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(
|
|
@@ -377,13 +388,23 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
|
|
|
377
388
|
});
|
|
378
389
|
}
|
|
379
390
|
}
|
|
380
|
-
client.on('message', async (
|
|
391
|
+
client.on('message', async (rawData) => {
|
|
392
|
+
const msgStr = rawData.toString();
|
|
393
|
+
if (msgStr === 'PONG') {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
if (msgStr === 'PING') {
|
|
397
|
+
if (!opts.dangerouslyDisablePong) {
|
|
398
|
+
client.send('PONG');
|
|
399
|
+
}
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
381
402
|
if (ctxPromise === unsetContextPromiseSymbol) {
|
|
382
403
|
// If the ctxPromise wasn't created immediately, we're expecting the first message to be a TRPCConnectionParamsMessage
|
|
383
404
|
ctxPromise = createCtxPromise(() => {
|
|
384
405
|
let msg;
|
|
385
406
|
try {
|
|
386
|
-
msg = JSON.parse(
|
|
407
|
+
msg = JSON.parse(msgStr) as TRPCConnectionParamsMessage;
|
|
387
408
|
|
|
388
409
|
if (!isObject(msg)) {
|
|
389
410
|
throw new Error('Message was not an object');
|
|
@@ -403,7 +424,7 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
|
|
|
403
424
|
return;
|
|
404
425
|
}
|
|
405
426
|
try {
|
|
406
|
-
const msgJSON: unknown = JSON.parse(
|
|
427
|
+
const msgJSON: unknown = JSON.parse(msgStr);
|
|
407
428
|
const msgs: unknown[] = Array.isArray(msgJSON) ? msgJSON : [msgJSON];
|
|
408
429
|
const promises = msgs
|
|
409
430
|
.map((raw) => parseTRPCMessage(raw, transformer))
|
|
@@ -453,8 +474,7 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
|
|
|
453
474
|
});
|
|
454
475
|
|
|
455
476
|
if (ctxPromise !== unsetContextPromiseSymbol) {
|
|
456
|
-
|
|
457
|
-
await ctxPromise.catch(() => null);
|
|
477
|
+
await ctxPromise;
|
|
458
478
|
}
|
|
459
479
|
};
|
|
460
480
|
}
|
|
@@ -464,48 +484,67 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
|
|
|
464
484
|
*/
|
|
465
485
|
export function handleKeepAlive(
|
|
466
486
|
client: ws.WebSocket,
|
|
467
|
-
pingMs =
|
|
468
|
-
pongWaitMs =
|
|
487
|
+
pingMs = 30_000,
|
|
488
|
+
pongWaitMs = 5_000,
|
|
469
489
|
) {
|
|
470
|
-
let
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
490
|
+
let timeout: NodeJS.Timeout | undefined = undefined;
|
|
491
|
+
let ping: NodeJS.Timeout | undefined = undefined;
|
|
492
|
+
|
|
493
|
+
const schedulePing = () => {
|
|
494
|
+
const scheduleTimeout = () => {
|
|
495
|
+
timeout = setTimeout(() => {
|
|
496
|
+
client.terminate();
|
|
497
|
+
}, pongWaitMs);
|
|
498
|
+
};
|
|
499
|
+
ping = setTimeout(() => {
|
|
500
|
+
client.send('PING');
|
|
501
|
+
|
|
502
|
+
scheduleTimeout();
|
|
503
|
+
}, pingMs);
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
const onMessage = () => {
|
|
507
|
+
clearTimeout(ping);
|
|
508
|
+
clearTimeout(timeout);
|
|
509
|
+
|
|
510
|
+
schedulePing();
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
client.on('message', onMessage);
|
|
514
|
+
|
|
488
515
|
client.on('close', () => {
|
|
489
|
-
|
|
516
|
+
clearTimeout(ping);
|
|
517
|
+
clearTimeout(timeout);
|
|
490
518
|
});
|
|
519
|
+
|
|
520
|
+
schedulePing();
|
|
491
521
|
}
|
|
492
522
|
|
|
493
523
|
export function applyWSSHandler<TRouter extends AnyRouter>(
|
|
494
524
|
opts: WSSHandlerOptions<TRouter>,
|
|
495
525
|
) {
|
|
496
|
-
const { wss, prefix, keepAlive } = opts;
|
|
497
|
-
|
|
498
526
|
const onConnection = getWSConnectionHandler(opts);
|
|
499
|
-
wss.on('connection',
|
|
500
|
-
if (prefix && !req.url?.startsWith(prefix)) {
|
|
527
|
+
opts.wss.on('connection', (client, req) => {
|
|
528
|
+
if (opts.prefix && !req.url?.startsWith(opts.prefix)) {
|
|
501
529
|
return;
|
|
502
530
|
}
|
|
503
531
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
532
|
+
onConnection(client, req).catch((cause) => {
|
|
533
|
+
opts.onError?.({
|
|
534
|
+
error: new TRPCError({
|
|
535
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
536
|
+
cause,
|
|
537
|
+
message: 'Failed to handle WebSocket connection',
|
|
538
|
+
}),
|
|
539
|
+
req: req,
|
|
540
|
+
path: undefined,
|
|
541
|
+
type: 'unknown',
|
|
542
|
+
ctx: undefined,
|
|
543
|
+
input: undefined,
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
client.close();
|
|
547
|
+
});
|
|
509
548
|
});
|
|
510
549
|
|
|
511
550
|
return {
|
|
@@ -515,7 +554,7 @@ export function applyWSSHandler<TRouter extends AnyRouter>(
|
|
|
515
554
|
method: 'reconnect',
|
|
516
555
|
};
|
|
517
556
|
const data = JSON.stringify(response);
|
|
518
|
-
for (const client of wss.clients) {
|
|
557
|
+
for (const client of opts.wss.clients) {
|
|
519
558
|
if (client.readyState === WEBSOCKET_OPEN) {
|
|
520
559
|
client.send(data);
|
|
521
560
|
}
|