@trpc/server 11.1.0 → 11.1.1-canary.8
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/fastify/fastifyTRPCPlugin.js +2 -2
- package/dist/adapters/fastify/fastifyTRPCPlugin.mjs +2 -2
- package/dist/adapters/ws.d.ts +1 -1
- package/dist/adapters/ws.d.ts.map +1 -1
- package/dist/adapters/ws.js +102 -84
- package/dist/adapters/ws.mjs +102 -84
- package/dist/bundle-analysis.json +997 -0
- package/package.json +2 -2
- package/src/adapters/fastify/fastifyTRPCPlugin.ts +2 -2
- package/src/adapters/ws.ts +115 -91
- package/adapters/node-http/content-type/form-data/index.d.ts +0 -1
- package/adapters/node-http/content-type/form-data/index.js +0 -1
- package/adapters/node-http/content-type/json/index.d.ts +0 -1
- package/adapters/node-http/content-type/json/index.js +0 -1
- package/src/adapters/node-http/__generated__/cert.csr +0 -16
- package/src/adapters/node-http/__generated__/certificate/cert.csr +0 -16
- package/src/adapters/node-http/__generated__/certificate/certificate.crt +0 -21
- package/src/adapters/node-http/__generated__/certificate/private.key +0 -28
- package/src/adapters/node-http/__generated__/certificate.crt +0 -21
- package/src/adapters/node-http/__generated__/private.key +0 -28
|
@@ -42,8 +42,8 @@ function fastifyTRPCPlugin(fastify, opts, done) {
|
|
|
42
42
|
});
|
|
43
43
|
fastify.get(prefix ?? '/', {
|
|
44
44
|
websocket: true
|
|
45
|
-
},
|
|
46
|
-
|
|
45
|
+
}, (socket, req)=>{
|
|
46
|
+
onConnection(socket, req.raw);
|
|
47
47
|
if (trpcOptions?.keepAlive?.enabled) {
|
|
48
48
|
const { pingMs, pongWaitMs } = trpcOptions.keepAlive;
|
|
49
49
|
ws.handleKeepAlive(socket, pingMs, pongWaitMs);
|
|
@@ -40,8 +40,8 @@ function fastifyTRPCPlugin(fastify, opts, done) {
|
|
|
40
40
|
});
|
|
41
41
|
fastify.get(prefix ?? '/', {
|
|
42
42
|
websocket: true
|
|
43
|
-
},
|
|
44
|
-
|
|
43
|
+
}, (socket, req)=>{
|
|
44
|
+
onConnection(socket, req.raw);
|
|
45
45
|
if (trpcOptions?.keepAlive?.enabled) {
|
|
46
46
|
const { pingMs, pongWaitMs } = trpcOptions.keepAlive;
|
|
47
47
|
handleKeepAlive(socket, pingMs, pongWaitMs);
|
package/dist/adapters/ws.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export type WSSHandlerOptions<TRouter extends AnyRouter> = WSConnectionHandlerOp
|
|
|
43
43
|
*/
|
|
44
44
|
dangerouslyDisablePong?: boolean;
|
|
45
45
|
};
|
|
46
|
-
export declare function getWSConnectionHandler<TRouter extends AnyRouter>(opts: WSSHandlerOptions<TRouter>): (client: ws.WebSocket, req: IncomingMessage) =>
|
|
46
|
+
export declare function getWSConnectionHandler<TRouter extends AnyRouter>(opts: WSSHandlerOptions<TRouter>): (client: ws.WebSocket, req: IncomingMessage) => void;
|
|
47
47
|
/**
|
|
48
48
|
* Handle WebSocket keep-alive messages
|
|
49
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,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAa/D,OAAO,EAKL,KAAK,YAAY,EAClB,MAAM,gCAAgC,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,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAa/D,OAAO,EAKL,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AAMxC,OAAO,EAAa,KAAK,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAQ7E;;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;AAEJ,wBAAgB,sBAAsB,CAAC,OAAO,SAAS,SAAS,EAC9D,IAAI,EAAE,iBAAiB,CAAC,OAAO,CAAC,IAKxB,QAAQ,EAAE,CAAC,SAAS,EAAE,KAAK,eAAe,UAyanD;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;;EAyBjC"}
|
package/dist/adapters/ws.js
CHANGED
|
@@ -84,11 +84,10 @@ function _ts_dispose_resources(env) {
|
|
|
84
84
|
* Importing ws causes a build error
|
|
85
85
|
* @see https://github.com/trpc/trpc/pull/5279
|
|
86
86
|
*/ const WEBSOCKET_OPEN = 1; /* ws.WebSocket.OPEN */
|
|
87
|
-
const unsetContextPromiseSymbol = Symbol('unsetContextPromise');
|
|
88
87
|
function getWSConnectionHandler(opts) {
|
|
89
88
|
const { createContext, router: router$1 } = opts;
|
|
90
89
|
const { transformer: transformer$1 } = router$1._def._config;
|
|
91
|
-
return
|
|
90
|
+
return (client, req)=>{
|
|
92
91
|
const clientSubscriptions = new Map();
|
|
93
92
|
const abortController = new AbortController();
|
|
94
93
|
if (opts.keepAlive?.enabled) {
|
|
@@ -98,23 +97,28 @@ function getWSConnectionHandler(opts) {
|
|
|
98
97
|
function respond(untransformedJSON) {
|
|
99
98
|
client.send(JSON.stringify(transformer.transformTRPCResponse(router$1._def._config, untransformedJSON)));
|
|
100
99
|
}
|
|
101
|
-
function createCtxPromise(getConnectionParams) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
100
|
+
async function createCtxPromise(getConnectionParams) {
|
|
101
|
+
try {
|
|
102
|
+
return await utils.run(async ()=>{
|
|
103
|
+
ctx = await createContext?.({
|
|
104
|
+
req,
|
|
105
|
+
res: client,
|
|
106
|
+
info: {
|
|
107
|
+
connectionParams: getConnectionParams(),
|
|
108
|
+
calls: [],
|
|
109
|
+
isBatchCall: false,
|
|
110
|
+
accept: null,
|
|
111
|
+
type: 'unknown',
|
|
112
|
+
signal: abortController.signal,
|
|
113
|
+
url: null
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
return {
|
|
117
|
+
ok: true,
|
|
118
|
+
value: ctx
|
|
119
|
+
};
|
|
115
120
|
});
|
|
116
|
-
|
|
117
|
-
}).catch((cause)=>{
|
|
121
|
+
} catch (cause) {
|
|
118
122
|
const error = TRPCError.getTRPCErrorFromUnknown(cause);
|
|
119
123
|
opts.onError?.({
|
|
120
124
|
error,
|
|
@@ -139,8 +143,11 @@ function getWSConnectionHandler(opts) {
|
|
|
139
143
|
(globalThis.setImmediate ?? globalThis.setTimeout)(()=>{
|
|
140
144
|
client.close();
|
|
141
145
|
});
|
|
142
|
-
|
|
143
|
-
|
|
146
|
+
return {
|
|
147
|
+
ok: false,
|
|
148
|
+
error
|
|
149
|
+
};
|
|
150
|
+
}
|
|
144
151
|
}
|
|
145
152
|
let ctx = undefined;
|
|
146
153
|
/**
|
|
@@ -148,14 +155,35 @@ function getWSConnectionHandler(opts) {
|
|
|
148
155
|
*
|
|
149
156
|
* - the context promise will be created immediately on connection if no connectionParams are expected
|
|
150
157
|
* - if connection params are expected, they will be created once received
|
|
151
|
-
*/ let ctxPromise = incomingMessageToRequest.createURL(req).searchParams.get('connectionParams') === '1' ?
|
|
152
|
-
|
|
158
|
+
*/ let ctxPromise = incomingMessageToRequest.createURL(req).searchParams.get('connectionParams') === '1' ? null : createCtxPromise(()=>null);
|
|
159
|
+
function handleRequest(msg) {
|
|
153
160
|
const { id, jsonrpc } = msg;
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
code: '
|
|
161
|
+
if (id === null) {
|
|
162
|
+
const error = TRPCError.getTRPCErrorFromUnknown(new TRPCError.TRPCError({
|
|
163
|
+
code: 'PARSE_ERROR',
|
|
157
164
|
message: '`id` is required'
|
|
165
|
+
}));
|
|
166
|
+
opts.onError?.({
|
|
167
|
+
error,
|
|
168
|
+
path: undefined,
|
|
169
|
+
type: 'unknown',
|
|
170
|
+
ctx,
|
|
171
|
+
req,
|
|
172
|
+
input: undefined
|
|
158
173
|
});
|
|
174
|
+
respond({
|
|
175
|
+
id,
|
|
176
|
+
jsonrpc,
|
|
177
|
+
error: getErrorShape.getErrorShape({
|
|
178
|
+
config: router$1._def._config,
|
|
179
|
+
error,
|
|
180
|
+
type: 'unknown',
|
|
181
|
+
path: undefined,
|
|
182
|
+
input: undefined,
|
|
183
|
+
ctx
|
|
184
|
+
})
|
|
185
|
+
});
|
|
186
|
+
return;
|
|
159
187
|
}
|
|
160
188
|
if (msg.method === 'subscription.stop') {
|
|
161
189
|
clientSubscriptions.get(id)?.abort();
|
|
@@ -164,20 +192,24 @@ function getWSConnectionHandler(opts) {
|
|
|
164
192
|
const { path, lastEventId } = msg.params;
|
|
165
193
|
let { input } = msg.params;
|
|
166
194
|
const type = msg.method;
|
|
167
|
-
|
|
168
|
-
if (
|
|
169
|
-
|
|
170
|
-
input
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
195
|
+
if (lastEventId !== undefined) {
|
|
196
|
+
if (utils.isObject(input)) {
|
|
197
|
+
input = {
|
|
198
|
+
...input,
|
|
199
|
+
lastEventId: lastEventId
|
|
200
|
+
};
|
|
201
|
+
} else {
|
|
202
|
+
input ?? (input = {
|
|
203
|
+
lastEventId: lastEventId
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
utils.run(async ()=>{
|
|
208
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
209
|
+
const res = await ctxPromise; // asserts context has been set
|
|
210
|
+
if (!res.ok) {
|
|
211
|
+
throw res.error;
|
|
179
212
|
}
|
|
180
|
-
await ctxPromise; // asserts context has been set
|
|
181
213
|
const abortController = new AbortController();
|
|
182
214
|
const result = await router.callProcedure({
|
|
183
215
|
router: router$1,
|
|
@@ -345,7 +377,7 @@ function getWSConnectionHandler(opts) {
|
|
|
345
377
|
type: 'started'
|
|
346
378
|
}
|
|
347
379
|
});
|
|
348
|
-
}
|
|
380
|
+
}).catch((cause)=>{
|
|
349
381
|
// procedure threw an error
|
|
350
382
|
const error = TRPCError.getTRPCErrorFromUnknown(cause);
|
|
351
383
|
opts.onError?.({
|
|
@@ -368,9 +400,9 @@ function getWSConnectionHandler(opts) {
|
|
|
368
400
|
ctx
|
|
369
401
|
})
|
|
370
402
|
});
|
|
371
|
-
}
|
|
403
|
+
});
|
|
372
404
|
}
|
|
373
|
-
client.on('message',
|
|
405
|
+
client.on('message', (rawData)=>{
|
|
374
406
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
375
407
|
const msgStr = rawData.toString();
|
|
376
408
|
if (msgStr === 'PONG') {
|
|
@@ -382,7 +414,7 @@ function getWSConnectionHandler(opts) {
|
|
|
382
414
|
}
|
|
383
415
|
return;
|
|
384
416
|
}
|
|
385
|
-
if (ctxPromise
|
|
417
|
+
if (!ctxPromise) {
|
|
386
418
|
// If the ctxPromise wasn't created immediately, we're expecting the first message to be a TRPCConnectionParamsMessage
|
|
387
419
|
ctxPromise = createCtxPromise(()=>{
|
|
388
420
|
let msg;
|
|
@@ -403,30 +435,33 @@ function getWSConnectionHandler(opts) {
|
|
|
403
435
|
});
|
|
404
436
|
return;
|
|
405
437
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
msgJSON
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
438
|
+
const parsedMsgs = utils.run(()=>{
|
|
439
|
+
try {
|
|
440
|
+
const msgJSON = JSON.parse(msgStr);
|
|
441
|
+
const msgs = Array.isArray(msgJSON) ? msgJSON : [
|
|
442
|
+
msgJSON
|
|
443
|
+
];
|
|
444
|
+
return msgs.map((raw)=>parseTRPCMessage.parseTRPCMessage(raw, transformer$1));
|
|
445
|
+
} catch (cause) {
|
|
446
|
+
const error = new TRPCError.TRPCError({
|
|
447
|
+
code: 'PARSE_ERROR',
|
|
448
|
+
cause
|
|
449
|
+
});
|
|
450
|
+
respond({
|
|
451
|
+
id: null,
|
|
452
|
+
error: getErrorShape.getErrorShape({
|
|
453
|
+
config: router$1._def._config,
|
|
454
|
+
error,
|
|
455
|
+
type: 'unknown',
|
|
456
|
+
path: undefined,
|
|
457
|
+
input: undefined,
|
|
458
|
+
ctx
|
|
459
|
+
})
|
|
460
|
+
});
|
|
461
|
+
return [];
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
parsedMsgs.map(handleRequest);
|
|
430
465
|
});
|
|
431
466
|
// WebSocket errors should be handled, as otherwise unhandled exceptions will crash Node.js.
|
|
432
467
|
// This line was introduced after the following error brought down production systems:
|
|
@@ -449,9 +484,6 @@ function getWSConnectionHandler(opts) {
|
|
|
449
484
|
clientSubscriptions.clear();
|
|
450
485
|
abortController.abort();
|
|
451
486
|
});
|
|
452
|
-
if (ctxPromise !== unsetContextPromiseSymbol) {
|
|
453
|
-
await ctxPromise;
|
|
454
|
-
}
|
|
455
487
|
};
|
|
456
488
|
}
|
|
457
489
|
/**
|
|
@@ -488,21 +520,7 @@ function applyWSSHandler(opts) {
|
|
|
488
520
|
if (opts.prefix && !req.url?.startsWith(opts.prefix)) {
|
|
489
521
|
return;
|
|
490
522
|
}
|
|
491
|
-
onConnection(client, req)
|
|
492
|
-
opts.onError?.({
|
|
493
|
-
error: new TRPCError.TRPCError({
|
|
494
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
495
|
-
cause,
|
|
496
|
-
message: 'Failed to handle WebSocket connection'
|
|
497
|
-
}),
|
|
498
|
-
req: req,
|
|
499
|
-
path: undefined,
|
|
500
|
-
type: 'unknown',
|
|
501
|
-
ctx: undefined,
|
|
502
|
-
input: undefined
|
|
503
|
-
});
|
|
504
|
-
client.close();
|
|
505
|
-
});
|
|
523
|
+
onConnection(client, req);
|
|
506
524
|
});
|
|
507
525
|
return {
|
|
508
526
|
broadcastReconnectNotification: ()=>{
|
package/dist/adapters/ws.mjs
CHANGED
|
@@ -82,11 +82,10 @@ function _ts_dispose_resources(env) {
|
|
|
82
82
|
* Importing ws causes a build error
|
|
83
83
|
* @see https://github.com/trpc/trpc/pull/5279
|
|
84
84
|
*/ const WEBSOCKET_OPEN = 1; /* ws.WebSocket.OPEN */
|
|
85
|
-
const unsetContextPromiseSymbol = Symbol('unsetContextPromise');
|
|
86
85
|
function getWSConnectionHandler(opts) {
|
|
87
86
|
const { createContext, router } = opts;
|
|
88
87
|
const { transformer } = router._def._config;
|
|
89
|
-
return
|
|
88
|
+
return (client, req)=>{
|
|
90
89
|
const clientSubscriptions = new Map();
|
|
91
90
|
const abortController = new AbortController();
|
|
92
91
|
if (opts.keepAlive?.enabled) {
|
|
@@ -96,23 +95,28 @@ function getWSConnectionHandler(opts) {
|
|
|
96
95
|
function respond(untransformedJSON) {
|
|
97
96
|
client.send(JSON.stringify(transformTRPCResponse(router._def._config, untransformedJSON)));
|
|
98
97
|
}
|
|
99
|
-
function createCtxPromise(getConnectionParams) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
98
|
+
async function createCtxPromise(getConnectionParams) {
|
|
99
|
+
try {
|
|
100
|
+
return await run(async ()=>{
|
|
101
|
+
ctx = await createContext?.({
|
|
102
|
+
req,
|
|
103
|
+
res: client,
|
|
104
|
+
info: {
|
|
105
|
+
connectionParams: getConnectionParams(),
|
|
106
|
+
calls: [],
|
|
107
|
+
isBatchCall: false,
|
|
108
|
+
accept: null,
|
|
109
|
+
type: 'unknown',
|
|
110
|
+
signal: abortController.signal,
|
|
111
|
+
url: null
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
return {
|
|
115
|
+
ok: true,
|
|
116
|
+
value: ctx
|
|
117
|
+
};
|
|
113
118
|
});
|
|
114
|
-
|
|
115
|
-
}).catch((cause)=>{
|
|
119
|
+
} catch (cause) {
|
|
116
120
|
const error = getTRPCErrorFromUnknown(cause);
|
|
117
121
|
opts.onError?.({
|
|
118
122
|
error,
|
|
@@ -137,8 +141,11 @@ function getWSConnectionHandler(opts) {
|
|
|
137
141
|
(globalThis.setImmediate ?? globalThis.setTimeout)(()=>{
|
|
138
142
|
client.close();
|
|
139
143
|
});
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
return {
|
|
145
|
+
ok: false,
|
|
146
|
+
error
|
|
147
|
+
};
|
|
148
|
+
}
|
|
142
149
|
}
|
|
143
150
|
let ctx = undefined;
|
|
144
151
|
/**
|
|
@@ -146,14 +153,35 @@ function getWSConnectionHandler(opts) {
|
|
|
146
153
|
*
|
|
147
154
|
* - the context promise will be created immediately on connection if no connectionParams are expected
|
|
148
155
|
* - if connection params are expected, they will be created once received
|
|
149
|
-
*/ let ctxPromise = createURL(req).searchParams.get('connectionParams') === '1' ?
|
|
150
|
-
|
|
156
|
+
*/ let ctxPromise = createURL(req).searchParams.get('connectionParams') === '1' ? null : createCtxPromise(()=>null);
|
|
157
|
+
function handleRequest(msg) {
|
|
151
158
|
const { id, jsonrpc } = msg;
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
code: '
|
|
159
|
+
if (id === null) {
|
|
160
|
+
const error = getTRPCErrorFromUnknown(new TRPCError({
|
|
161
|
+
code: 'PARSE_ERROR',
|
|
155
162
|
message: '`id` is required'
|
|
163
|
+
}));
|
|
164
|
+
opts.onError?.({
|
|
165
|
+
error,
|
|
166
|
+
path: undefined,
|
|
167
|
+
type: 'unknown',
|
|
168
|
+
ctx,
|
|
169
|
+
req,
|
|
170
|
+
input: undefined
|
|
156
171
|
});
|
|
172
|
+
respond({
|
|
173
|
+
id,
|
|
174
|
+
jsonrpc,
|
|
175
|
+
error: getErrorShape({
|
|
176
|
+
config: router._def._config,
|
|
177
|
+
error,
|
|
178
|
+
type: 'unknown',
|
|
179
|
+
path: undefined,
|
|
180
|
+
input: undefined,
|
|
181
|
+
ctx
|
|
182
|
+
})
|
|
183
|
+
});
|
|
184
|
+
return;
|
|
157
185
|
}
|
|
158
186
|
if (msg.method === 'subscription.stop') {
|
|
159
187
|
clientSubscriptions.get(id)?.abort();
|
|
@@ -162,20 +190,24 @@ function getWSConnectionHandler(opts) {
|
|
|
162
190
|
const { path, lastEventId } = msg.params;
|
|
163
191
|
let { input } = msg.params;
|
|
164
192
|
const type = msg.method;
|
|
165
|
-
|
|
166
|
-
if (
|
|
167
|
-
|
|
168
|
-
input
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
193
|
+
if (lastEventId !== undefined) {
|
|
194
|
+
if (isObject(input)) {
|
|
195
|
+
input = {
|
|
196
|
+
...input,
|
|
197
|
+
lastEventId: lastEventId
|
|
198
|
+
};
|
|
199
|
+
} else {
|
|
200
|
+
input ?? (input = {
|
|
201
|
+
lastEventId: lastEventId
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
run(async ()=>{
|
|
206
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
207
|
+
const res = await ctxPromise; // asserts context has been set
|
|
208
|
+
if (!res.ok) {
|
|
209
|
+
throw res.error;
|
|
177
210
|
}
|
|
178
|
-
await ctxPromise; // asserts context has been set
|
|
179
211
|
const abortController = new AbortController();
|
|
180
212
|
const result = await callProcedure({
|
|
181
213
|
router,
|
|
@@ -343,7 +375,7 @@ function getWSConnectionHandler(opts) {
|
|
|
343
375
|
type: 'started'
|
|
344
376
|
}
|
|
345
377
|
});
|
|
346
|
-
}
|
|
378
|
+
}).catch((cause)=>{
|
|
347
379
|
// procedure threw an error
|
|
348
380
|
const error = getTRPCErrorFromUnknown(cause);
|
|
349
381
|
opts.onError?.({
|
|
@@ -366,9 +398,9 @@ function getWSConnectionHandler(opts) {
|
|
|
366
398
|
ctx
|
|
367
399
|
})
|
|
368
400
|
});
|
|
369
|
-
}
|
|
401
|
+
});
|
|
370
402
|
}
|
|
371
|
-
client.on('message',
|
|
403
|
+
client.on('message', (rawData)=>{
|
|
372
404
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
373
405
|
const msgStr = rawData.toString();
|
|
374
406
|
if (msgStr === 'PONG') {
|
|
@@ -380,7 +412,7 @@ function getWSConnectionHandler(opts) {
|
|
|
380
412
|
}
|
|
381
413
|
return;
|
|
382
414
|
}
|
|
383
|
-
if (ctxPromise
|
|
415
|
+
if (!ctxPromise) {
|
|
384
416
|
// If the ctxPromise wasn't created immediately, we're expecting the first message to be a TRPCConnectionParamsMessage
|
|
385
417
|
ctxPromise = createCtxPromise(()=>{
|
|
386
418
|
let msg;
|
|
@@ -401,30 +433,33 @@ function getWSConnectionHandler(opts) {
|
|
|
401
433
|
});
|
|
402
434
|
return;
|
|
403
435
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
msgJSON
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
436
|
+
const parsedMsgs = run(()=>{
|
|
437
|
+
try {
|
|
438
|
+
const msgJSON = JSON.parse(msgStr);
|
|
439
|
+
const msgs = Array.isArray(msgJSON) ? msgJSON : [
|
|
440
|
+
msgJSON
|
|
441
|
+
];
|
|
442
|
+
return msgs.map((raw)=>parseTRPCMessage(raw, transformer));
|
|
443
|
+
} catch (cause) {
|
|
444
|
+
const error = new TRPCError({
|
|
445
|
+
code: 'PARSE_ERROR',
|
|
446
|
+
cause
|
|
447
|
+
});
|
|
448
|
+
respond({
|
|
449
|
+
id: null,
|
|
450
|
+
error: getErrorShape({
|
|
451
|
+
config: router._def._config,
|
|
452
|
+
error,
|
|
453
|
+
type: 'unknown',
|
|
454
|
+
path: undefined,
|
|
455
|
+
input: undefined,
|
|
456
|
+
ctx
|
|
457
|
+
})
|
|
458
|
+
});
|
|
459
|
+
return [];
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
parsedMsgs.map(handleRequest);
|
|
428
463
|
});
|
|
429
464
|
// WebSocket errors should be handled, as otherwise unhandled exceptions will crash Node.js.
|
|
430
465
|
// This line was introduced after the following error brought down production systems:
|
|
@@ -447,9 +482,6 @@ function getWSConnectionHandler(opts) {
|
|
|
447
482
|
clientSubscriptions.clear();
|
|
448
483
|
abortController.abort();
|
|
449
484
|
});
|
|
450
|
-
if (ctxPromise !== unsetContextPromiseSymbol) {
|
|
451
|
-
await ctxPromise;
|
|
452
|
-
}
|
|
453
485
|
};
|
|
454
486
|
}
|
|
455
487
|
/**
|
|
@@ -486,21 +518,7 @@ function applyWSSHandler(opts) {
|
|
|
486
518
|
if (opts.prefix && !req.url?.startsWith(opts.prefix)) {
|
|
487
519
|
return;
|
|
488
520
|
}
|
|
489
|
-
onConnection(client, req)
|
|
490
|
-
opts.onError?.({
|
|
491
|
-
error: new TRPCError({
|
|
492
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
493
|
-
cause,
|
|
494
|
-
message: 'Failed to handle WebSocket connection'
|
|
495
|
-
}),
|
|
496
|
-
req: req,
|
|
497
|
-
path: undefined,
|
|
498
|
-
type: 'unknown',
|
|
499
|
-
ctx: undefined,
|
|
500
|
-
input: undefined
|
|
501
|
-
});
|
|
502
|
-
client.close();
|
|
503
|
-
});
|
|
521
|
+
onConnection(client, req);
|
|
504
522
|
});
|
|
505
523
|
return {
|
|
506
524
|
broadcastReconnectNotification: ()=>{
|