@trpc/server 11.0.0-rc.433 → 11.0.0-rc.435

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 (44) hide show
  1. package/dist/@trpc/server/http.d.ts +1 -2
  2. package/dist/@trpc/server/http.d.ts.map +1 -1
  3. package/dist/@trpc/server/rpc.d.ts +1 -1
  4. package/dist/@trpc/server/rpc.d.ts.map +1 -1
  5. package/dist/adapters/next.js +1 -1
  6. package/dist/adapters/next.mjs +1 -1
  7. package/dist/adapters/ws.d.ts +2 -2
  8. package/dist/adapters/ws.d.ts.map +1 -1
  9. package/dist/adapters/ws.js +76 -35
  10. package/dist/adapters/ws.mjs +77 -36
  11. package/dist/bundle-analysis.json +75 -55
  12. package/dist/http.js +3 -0
  13. package/dist/http.mjs +1 -0
  14. package/dist/index.js +2 -2
  15. package/dist/index.mjs +1 -1
  16. package/dist/unstable-core-do-not-import/http/contentType.d.ts.map +1 -1
  17. package/dist/unstable-core-do-not-import/http/contentType.js +8 -3
  18. package/dist/unstable-core-do-not-import/http/contentType.mjs +8 -3
  19. package/dist/unstable-core-do-not-import/http/parseConnectionParams.d.ts +4 -0
  20. package/dist/unstable-core-do-not-import/http/parseConnectionParams.d.ts.map +1 -0
  21. package/dist/unstable-core-do-not-import/http/parseConnectionParams.js +42 -0
  22. package/dist/unstable-core-do-not-import/http/parseConnectionParams.mjs +39 -0
  23. package/dist/unstable-core-do-not-import/http/resolveResponse.d.ts.map +1 -1
  24. package/dist/unstable-core-do-not-import/http/types.d.ts +9 -14
  25. package/dist/unstable-core-do-not-import/http/types.d.ts.map +1 -1
  26. package/dist/unstable-core-do-not-import/rpc/envelopes.d.ts +7 -0
  27. package/dist/unstable-core-do-not-import/rpc/envelopes.d.ts.map +1 -1
  28. package/dist/unstable-core-do-not-import/rpc/index.d.ts +1 -1
  29. package/dist/unstable-core-do-not-import/rpc/index.d.ts.map +1 -1
  30. package/dist/unstable-core-do-not-import.d.ts +4 -3
  31. package/dist/unstable-core-do-not-import.d.ts.map +1 -1
  32. package/dist/unstable-core-do-not-import.js +16 -13
  33. package/dist/unstable-core-do-not-import.mjs +4 -3
  34. package/package.json +2 -2
  35. package/src/@trpc/server/http.ts +7 -2
  36. package/src/@trpc/server/rpc.ts +1 -0
  37. package/src/adapters/ws.ts +95 -35
  38. package/src/unstable-core-do-not-import/http/contentType.ts +12 -7
  39. package/src/unstable-core-do-not-import/http/parseConnectionParams.ts +49 -0
  40. package/src/unstable-core-do-not-import/http/resolveResponse.ts +8 -6
  41. package/src/unstable-core-do-not-import/http/types.ts +9 -17
  42. package/src/unstable-core-do-not-import/rpc/envelopes.ts +9 -0
  43. package/src/unstable-core-do-not-import/rpc/index.ts +1 -0
  44. package/src/unstable-core-do-not-import.ts +4 -3
@@ -4,6 +4,5 @@ export type { BaseHandlerOptions, HTTPBaseHandlerOptions, HTTPErrorHandler,
4
4
  * @deprecated Use `HTTPErrorHandler` instead
5
5
  */
6
6
  HTTPErrorHandler as OnErrorFunction, ResolveHTTPRequestOptionsContextFn, ResponseMeta, ResponseMetaFn, TRPCRequestInfo, } from '../../unstable-core-do-not-import';
7
- export { getBatchStreamFormatter } from '../../unstable-core-do-not-import';
8
- export { octetInputParser, toURL } from '../../unstable-core-do-not-import';
7
+ export { getBatchStreamFormatter, octetInputParser, parseConnectionParamsFromUnknown, parseConnectionParamsFromString, toURL, } from '../../unstable-core-do-not-import';
9
8
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/@trpc/server/http.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,eAAe,GAChB,MAAM,mCAAmC,CAAC;AAC3C,YAAY,EACV,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB;AAChB;;GAEG;AACH,gBAAgB,IAAI,eAAe,EACnC,kCAAkC,EAClC,YAAY,EACZ,cAAc,EACd,eAAe,GAChB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/@trpc/server/http.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,eAAe,GAChB,MAAM,mCAAmC,CAAC;AAC3C,YAAY,EACV,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB;AAChB;;GAEG;AACH,gBAAgB,IAAI,eAAe,EACnC,kCAAkC,EAClC,YAAY,EACZ,cAAc,EACd,eAAe,GAChB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,gCAAgC,EAChC,+BAA+B,EAC/B,KAAK,GACN,MAAM,mCAAmC,CAAC"}
@@ -1,3 +1,3 @@
1
- export type { JSONRPC2, TRPCClientIncomingMessage, TRPCClientIncomingRequest, TRPCClientOutgoingMessage, TRPCClientOutgoingRequest, TRPCErrorResponse, TRPCErrorShape, TRPCReconnectNotification, TRPCRequest, TRPCRequestMessage, TRPCResponse, TRPCResponseMessage, TRPCResult, TRPCResultMessage, TRPCSubscriptionStopNotification, TRPCSuccessResponse, TRPC_ERROR_CODE_KEY, TRPC_ERROR_CODE_NUMBER, } from '../../unstable-core-do-not-import';
1
+ export type { JSONRPC2, TRPCClientIncomingMessage, TRPCClientIncomingRequest, TRPCClientOutgoingMessage, TRPCClientOutgoingRequest, TRPCErrorResponse, TRPCErrorShape, TRPCReconnectNotification, TRPCRequest, TRPCRequestMessage, TRPCResponse, TRPCResponseMessage, TRPCResult, TRPCResultMessage, TRPCSubscriptionStopNotification, TRPCSuccessResponse, TRPC_ERROR_CODE_KEY, TRPC_ERROR_CODE_NUMBER, TRPCConnectionParamsMessage, } from '../../unstable-core-do-not-import';
2
2
  export { TRPC_ERROR_CODES_BY_KEY, TRPC_ERROR_CODES_BY_NUMBER, parseTRPCMessage, } from '../../unstable-core-do-not-import';
3
3
  //# sourceMappingURL=rpc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../../src/@trpc/server/rpc.ts"],"names":[],"mappings":"AACA,YAAY,EACV,QAAQ,EACR,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,iBAAiB,EACjB,cAAc,EACd,yBAAyB,EACzB,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,UAAU,EACV,iBAAiB,EACjB,gCAAgC,EAChC,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,mCAAmC,CAAC"}
1
+ {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../../src/@trpc/server/rpc.ts"],"names":[],"mappings":"AACA,YAAY,EACV,QAAQ,EACR,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,iBAAiB,EACjB,cAAc,EACd,yBAAyB,EACzB,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,UAAU,EACV,iBAAiB,EACjB,gCAAgC,EAChC,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,mCAAmC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var TRPCError = require('../unstable-core-do-not-import/error/TRPCError.js');
4
3
  var getErrorShape = require('../unstable-core-do-not-import/error/getErrorShape.js');
4
+ var TRPCError = require('../unstable-core-do-not-import/error/TRPCError.js');
5
5
  require('../unstable-core-do-not-import/rootConfig.js');
6
6
  var nodeHTTPRequestHandler = require('./node-http/nodeHTTPRequestHandler.js');
7
7
 
@@ -1,5 +1,5 @@
1
- import { TRPCError } from '../unstable-core-do-not-import/error/TRPCError.mjs';
2
1
  import { getErrorShape } from '../unstable-core-do-not-import/error/getErrorShape.mjs';
2
+ import { TRPCError } from '../unstable-core-do-not-import/error/TRPCError.mjs';
3
3
  import '../unstable-core-do-not-import/rootConfig.mjs';
4
4
  import { nodeHTTPRequestHandler } from './node-http/nodeHTTPRequestHandler.mjs';
5
5
 
@@ -1,13 +1,13 @@
1
1
  import type { IncomingMessage } from 'http';
2
2
  import type ws from 'ws';
3
3
  import type { AnyRouter, CreateContextCallback, inferRouterContext } from '../@trpc/server';
4
- import type { BaseHandlerOptions } from '../@trpc/server/http';
4
+ import { type BaseHandlerOptions } from '../@trpc/server/http';
5
5
  import { type MaybePromise } from '../unstable-core-do-not-import';
6
6
  import type { NodeHTTPCreateContextFnOptions } from './node-http';
7
7
  /**
8
8
  * @public
9
9
  */
10
- export type CreateWSSContextFnOptions = Omit<NodeHTTPCreateContextFnOptions<IncomingMessage, ws.WebSocket>, 'info'>;
10
+ export type CreateWSSContextFnOptions = NodeHTTPCreateContextFnOptions<IncomingMessage, ws.WebSocket>;
11
11
  /**
12
12
  * @public
13
13
  */
@@ -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;AAQzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAW/D,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAQlE;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC1C,8BAA8B,CAAC,eAAe,EAAE,EAAE,CAAC,SAAS,CAAC,EAC7D,MAAM,CACP,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;AAEJ,wBAAgB,sBAAsB,CAAC,OAAO,SAAS,SAAS,EAC9D,IAAI,EAAE,0BAA0B,CAAC,OAAO,CAAC,YAKnB,EAAE,CAAC,SAAS,OAAO,eAAe,mBA2QzD;AAiCD,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;AAatE,OAAO,EAIL,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,mBAkUzD;AAiCD,wBAAgB,eAAe,CAAC,OAAO,SAAS,SAAS,EACvD,IAAI,EAAE,iBAAiB,CAAC,OAAO,CAAC;;EA+BjC"}
@@ -1,11 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var TRPCError = require('../unstable-core-do-not-import/error/TRPCError.js');
4
3
  var getErrorShape = require('../unstable-core-do-not-import/error/getErrorShape.js');
4
+ var TRPCError = require('../unstable-core-do-not-import/error/TRPCError.js');
5
+ var parseConnectionParams = require('../unstable-core-do-not-import/http/parseConnectionParams.js');
5
6
  var utils = require('../unstable-core-do-not-import/utils.js');
6
7
  var parseTRPCMessage = require('../unstable-core-do-not-import/rpc/parseTRPCMessage.js');
7
8
  var observable = require('../observable/observable.js');
8
9
  var transformer = require('../unstable-core-do-not-import/transformer.js');
10
+ var toURL = require('../unstable-core-do-not-import/http/toURL.js');
9
11
  require('../unstable-core-do-not-import/rootConfig.js');
10
12
  var router = require('../unstable-core-do-not-import/router.js');
11
13
 
@@ -13,6 +15,7 @@ var router = require('../unstable-core-do-not-import/router.js');
13
15
  * Importing ws causes a build error
14
16
  * @link https://github.com/trpc/trpc/pull/5279
15
17
  */ const WEBSOCKET_OPEN = 1; /* ws.WebSocket.OPEN */
18
+ const unsetContextSymbol = Symbol('unsetContext');
16
19
  function getWSConnectionHandler(opts) {
17
20
  const { createContext , router: router$1 } = opts;
18
21
  const { transformer: transformer$1 } = router$1._def._config;
@@ -21,10 +24,54 @@ function getWSConnectionHandler(opts) {
21
24
  function respond(untransformedJSON) {
22
25
  client.send(JSON.stringify(transformer.transformTRPCResponse(router$1._def._config, untransformedJSON)));
23
26
  }
24
- const ctxPromise = createContext?.({
25
- req,
26
- res: client
27
- });
27
+ function createCtxPromise(getConnectionParams) {
28
+ return utils.run(async ()=>{
29
+ ctx = await createContext?.({
30
+ req,
31
+ res: client,
32
+ info: {
33
+ connectionParams: getConnectionParams(),
34
+ calls: [],
35
+ isBatchCall: false,
36
+ accept: null,
37
+ type: 'unknown'
38
+ }
39
+ });
40
+ return ctx;
41
+ }).catch((cause)=>{
42
+ const error = TRPCError.getTRPCErrorFromUnknown(cause);
43
+ opts.onError?.({
44
+ error,
45
+ path: undefined,
46
+ type: 'unknown',
47
+ ctx,
48
+ req,
49
+ input: undefined
50
+ });
51
+ respond({
52
+ id: null,
53
+ error: getErrorShape.getErrorShape({
54
+ config: router$1._def._config,
55
+ error,
56
+ type: 'unknown',
57
+ path: undefined,
58
+ input: undefined,
59
+ ctx
60
+ })
61
+ });
62
+ // close in next tick
63
+ (global.setImmediate ?? global.setTimeout)(()=>{
64
+ client.close();
65
+ });
66
+ throw error;
67
+ });
68
+ }
69
+ /**
70
+ * promise for initializing the context
71
+ *
72
+ * - the context promise will be created immediately on connection if no connectionParams are expected
73
+ * - if connection params are expected, they will be created once received
74
+ */ let ctxPromise = toURL.toURL(req.url ?? '').searchParams.get('connectionParams') === '1' ? unsetContextSymbol : createCtxPromise(()=>null);
28
75
  let ctx = undefined;
29
76
  async function handleRequest(msg) {
30
77
  const { id , jsonrpc } = msg;
@@ -198,6 +245,27 @@ function getWSConnectionHandler(opts) {
198
245
  }
199
246
  }
200
247
  client.on('message', async (message)=>{
248
+ if (ctxPromise === unsetContextSymbol) {
249
+ // If the ctxPromise wasn't created immediately, we're expecting the first message to be a TRPCConnectionParamsMessage
250
+ ctxPromise = createCtxPromise(()=>{
251
+ let msg;
252
+ try {
253
+ msg = JSON.parse(message.toString());
254
+ if (!utils.isObject(msg)) {
255
+ throw new Error('Message was not an object');
256
+ }
257
+ } catch (cause) {
258
+ throw new TRPCError.TRPCError({
259
+ code: 'PARSE_ERROR',
260
+ message: `Malformed TRPCConnectionParamsMessage`,
261
+ cause
262
+ });
263
+ }
264
+ const connectionParams = parseConnectionParams.parseConnectionParamsFromUnknown(msg.data);
265
+ return connectionParams;
266
+ });
267
+ return;
268
+ }
201
269
  try {
202
270
  const msgJSON = JSON.parse(message.toString());
203
271
  const msgs = Array.isArray(msgJSON) ? msgJSON : [
@@ -243,37 +311,10 @@ function getWSConnectionHandler(opts) {
243
311
  }
244
312
  clientSubscriptions.clear();
245
313
  });
246
- async function createContextAsync() {
247
- try {
248
- ctx = await ctxPromise;
249
- } catch (cause) {
250
- const error = TRPCError.getTRPCErrorFromUnknown(cause);
251
- opts.onError?.({
252
- error,
253
- path: undefined,
254
- type: 'unknown',
255
- ctx,
256
- req,
257
- input: undefined
258
- });
259
- respond({
260
- id: null,
261
- error: getErrorShape.getErrorShape({
262
- config: router$1._def._config,
263
- error,
264
- type: 'unknown',
265
- path: undefined,
266
- input: undefined,
267
- ctx
268
- })
269
- });
270
- // close in next tick
271
- (global.setImmediate ?? global.setTimeout)(()=>{
272
- client.close();
273
- });
274
- }
314
+ if (ctxPromise !== unsetContextSymbol) {
315
+ // prevent unhandled promise rejection errors
316
+ await ctxPromise.catch(()=>null);
275
317
  }
276
- await createContextAsync();
277
318
  };
278
319
  }
279
320
  /**
@@ -1,9 +1,11 @@
1
- import { TRPCError, getTRPCErrorFromUnknown } from '../unstable-core-do-not-import/error/TRPCError.mjs';
2
1
  import { getErrorShape } from '../unstable-core-do-not-import/error/getErrorShape.mjs';
3
- import { isAsyncIterable, run } from '../unstable-core-do-not-import/utils.mjs';
2
+ import { TRPCError, getTRPCErrorFromUnknown } from '../unstable-core-do-not-import/error/TRPCError.mjs';
3
+ import { parseConnectionParamsFromUnknown } from '../unstable-core-do-not-import/http/parseConnectionParams.mjs';
4
+ import { run, isAsyncIterable, isObject } from '../unstable-core-do-not-import/utils.mjs';
4
5
  import { parseTRPCMessage } from '../unstable-core-do-not-import/rpc/parseTRPCMessage.mjs';
5
6
  import { isObservable, observableToAsyncIterable } from '../observable/observable.mjs';
6
7
  import { transformTRPCResponse } from '../unstable-core-do-not-import/transformer.mjs';
8
+ import { toURL } from '../unstable-core-do-not-import/http/toURL.mjs';
7
9
  import '../unstable-core-do-not-import/rootConfig.mjs';
8
10
  import { callProcedure } from '../unstable-core-do-not-import/router.mjs';
9
11
 
@@ -11,6 +13,7 @@ import { callProcedure } from '../unstable-core-do-not-import/router.mjs';
11
13
  * Importing ws causes a build error
12
14
  * @link https://github.com/trpc/trpc/pull/5279
13
15
  */ const WEBSOCKET_OPEN = 1; /* ws.WebSocket.OPEN */
16
+ const unsetContextSymbol = Symbol('unsetContext');
14
17
  function getWSConnectionHandler(opts) {
15
18
  const { createContext , router } = opts;
16
19
  const { transformer } = router._def._config;
@@ -19,10 +22,54 @@ function getWSConnectionHandler(opts) {
19
22
  function respond(untransformedJSON) {
20
23
  client.send(JSON.stringify(transformTRPCResponse(router._def._config, untransformedJSON)));
21
24
  }
22
- const ctxPromise = createContext?.({
23
- req,
24
- res: client
25
- });
25
+ function createCtxPromise(getConnectionParams) {
26
+ return run(async ()=>{
27
+ ctx = await createContext?.({
28
+ req,
29
+ res: client,
30
+ info: {
31
+ connectionParams: getConnectionParams(),
32
+ calls: [],
33
+ isBatchCall: false,
34
+ accept: null,
35
+ type: 'unknown'
36
+ }
37
+ });
38
+ return ctx;
39
+ }).catch((cause)=>{
40
+ const error = getTRPCErrorFromUnknown(cause);
41
+ opts.onError?.({
42
+ error,
43
+ path: undefined,
44
+ type: 'unknown',
45
+ ctx,
46
+ req,
47
+ input: undefined
48
+ });
49
+ respond({
50
+ id: null,
51
+ error: getErrorShape({
52
+ config: router._def._config,
53
+ error,
54
+ type: 'unknown',
55
+ path: undefined,
56
+ input: undefined,
57
+ ctx
58
+ })
59
+ });
60
+ // close in next tick
61
+ (global.setImmediate ?? global.setTimeout)(()=>{
62
+ client.close();
63
+ });
64
+ throw error;
65
+ });
66
+ }
67
+ /**
68
+ * promise for initializing the context
69
+ *
70
+ * - the context promise will be created immediately on connection if no connectionParams are expected
71
+ * - if connection params are expected, they will be created once received
72
+ */ let ctxPromise = toURL(req.url ?? '').searchParams.get('connectionParams') === '1' ? unsetContextSymbol : createCtxPromise(()=>null);
26
73
  let ctx = undefined;
27
74
  async function handleRequest(msg) {
28
75
  const { id , jsonrpc } = msg;
@@ -196,6 +243,27 @@ function getWSConnectionHandler(opts) {
196
243
  }
197
244
  }
198
245
  client.on('message', async (message)=>{
246
+ if (ctxPromise === unsetContextSymbol) {
247
+ // If the ctxPromise wasn't created immediately, we're expecting the first message to be a TRPCConnectionParamsMessage
248
+ ctxPromise = createCtxPromise(()=>{
249
+ let msg;
250
+ try {
251
+ msg = JSON.parse(message.toString());
252
+ if (!isObject(msg)) {
253
+ throw new Error('Message was not an object');
254
+ }
255
+ } catch (cause) {
256
+ throw new TRPCError({
257
+ code: 'PARSE_ERROR',
258
+ message: `Malformed TRPCConnectionParamsMessage`,
259
+ cause
260
+ });
261
+ }
262
+ const connectionParams = parseConnectionParamsFromUnknown(msg.data);
263
+ return connectionParams;
264
+ });
265
+ return;
266
+ }
199
267
  try {
200
268
  const msgJSON = JSON.parse(message.toString());
201
269
  const msgs = Array.isArray(msgJSON) ? msgJSON : [
@@ -241,37 +309,10 @@ function getWSConnectionHandler(opts) {
241
309
  }
242
310
  clientSubscriptions.clear();
243
311
  });
244
- async function createContextAsync() {
245
- try {
246
- ctx = await ctxPromise;
247
- } catch (cause) {
248
- const error = getTRPCErrorFromUnknown(cause);
249
- opts.onError?.({
250
- error,
251
- path: undefined,
252
- type: 'unknown',
253
- ctx,
254
- req,
255
- input: undefined
256
- });
257
- respond({
258
- id: null,
259
- error: getErrorShape({
260
- config: router._def._config,
261
- error,
262
- type: 'unknown',
263
- path: undefined,
264
- input: undefined,
265
- ctx
266
- })
267
- });
268
- // close in next tick
269
- (global.setImmediate ?? global.setTimeout)(()=>{
270
- client.close();
271
- });
272
- }
312
+ if (ctxPromise !== unsetContextSymbol) {
313
+ // prevent unhandled promise rejection errors
314
+ await ctxPromise.catch(()=>null);
273
315
  }
274
- await createContextAsync();
275
316
  };
276
317
  }
277
318
  /**