@trpc/client 11.0.0-rc.474 → 11.0.0-rc.477

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.
@@ -1,20 +1,20 @@
1
1
  {
2
- "bundleSize": 51847,
3
- "bundleOrigSize": 69119,
4
- "bundleReduction": 24.99,
2
+ "bundleSize": 52634,
3
+ "bundleOrigSize": 69964,
4
+ "bundleReduction": 24.77,
5
5
  "modules": [
6
6
  {
7
7
  "id": "/src/links/wsLink.ts",
8
- "size": 13069,
9
- "origSize": 14556,
8
+ "size": 13683,
9
+ "origSize": 15132,
10
10
  "renderedExports": [
11
11
  "createWSClient",
12
12
  "wsLink"
13
13
  ],
14
14
  "removedExports": [],
15
15
  "dependents": [],
16
- "percent": 25.21,
17
- "reduction": 10.22
16
+ "percent": 26,
17
+ "reduction": 9.58
18
18
  },
19
19
  {
20
20
  "id": "/src/links/httpBatchStreamLink.ts",
@@ -25,7 +25,7 @@
25
25
  ],
26
26
  "removedExports": [],
27
27
  "dependents": [],
28
- "percent": 11.3,
28
+ "percent": 11.14,
29
29
  "reduction": 3.51
30
30
  },
31
31
  {
@@ -37,7 +37,7 @@
37
37
  ],
38
38
  "removedExports": [],
39
39
  "dependents": [],
40
- "percent": 10.53,
40
+ "percent": 10.37,
41
41
  "reduction": 18.48
42
42
  },
43
43
  {
@@ -61,7 +61,7 @@
61
61
  "/src/links/httpBatchStreamLink.ts",
62
62
  "/src/links/httpSubscriptionLink.ts"
63
63
  ],
64
- "percent": 8.61,
64
+ "percent": 8.48,
65
65
  "reduction": 32.82
66
66
  },
67
67
  {
@@ -76,7 +76,7 @@
76
76
  "/src/links/httpBatchLink.ts",
77
77
  "/src/links/httpBatchStreamLink.ts"
78
78
  ],
79
- "percent": 7.88,
79
+ "percent": 7.76,
80
80
  "reduction": 5.64
81
81
  },
82
82
  {
@@ -88,20 +88,20 @@
88
88
  ],
89
89
  "removedExports": [],
90
90
  "dependents": [],
91
- "percent": 7.57,
91
+ "percent": 7.46,
92
92
  "reduction": 4.69
93
93
  },
94
94
  {
95
95
  "id": "/src/links/httpSubscriptionLink.ts",
96
- "size": 3632,
97
- "origSize": 3952,
96
+ "size": 3805,
97
+ "origSize": 4221,
98
98
  "renderedExports": [
99
99
  "unstable_httpSubscriptionLink"
100
100
  ],
101
101
  "removedExports": [],
102
102
  "dependents": [],
103
- "percent": 7.01,
104
- "reduction": 8.1
103
+ "percent": 7.23,
104
+ "reduction": 9.86
105
105
  },
106
106
  {
107
107
  "id": "/src/links/httpLink.ts",
@@ -112,7 +112,7 @@
112
112
  ],
113
113
  "removedExports": [],
114
114
  "dependents": [],
115
- "percent": 6.14,
115
+ "percent": 6.05,
116
116
  "reduction": 14.15
117
117
  },
118
118
  {
@@ -127,7 +127,7 @@
127
127
  "/src/createTRPCUntypedClient.ts",
128
128
  "/src/createTRPCClient.ts"
129
129
  ],
130
- "percent": 4.17,
130
+ "percent": 4.11,
131
131
  "reduction": 47.6
132
132
  },
133
133
  {
@@ -147,7 +147,7 @@
147
147
  "/src/links/httpSubscriptionLink.ts",
148
148
  "/src/internals/TRPCUntypedClient.ts"
149
149
  ],
150
- "percent": 3.74,
150
+ "percent": 3.69,
151
151
  "reduction": 45.43
152
152
  },
153
153
  {
@@ -164,7 +164,7 @@
164
164
  "dependents": [
165
165
  "/src/index.ts"
166
166
  ],
167
- "percent": 2.29,
167
+ "percent": 2.26,
168
168
  "reduction": 73.19
169
169
  },
170
170
  {
@@ -179,7 +179,7 @@
179
179
  "/src/links/splitLink.ts",
180
180
  "/src/internals/TRPCUntypedClient.ts"
181
181
  ],
182
- "percent": 1.33,
182
+ "percent": 1.31,
183
183
  "reduction": 32.75
184
184
  },
185
185
  {
@@ -191,7 +191,7 @@
191
191
  ],
192
192
  "removedExports": [],
193
193
  "dependents": [],
194
- "percent": 1.18,
194
+ "percent": 1.16,
195
195
  "reduction": 44.95
196
196
  },
197
197
  {
@@ -205,7 +205,7 @@
205
205
  "dependents": [
206
206
  "/src/unstable-internals.ts"
207
207
  ],
208
- "percent": 1.09,
208
+ "percent": 1.07,
209
209
  "reduction": 66.75
210
210
  },
211
211
  {
@@ -220,7 +220,7 @@
220
220
  "/src/index.ts",
221
221
  "/src/links/internals/httpUtils.ts"
222
222
  ],
223
- "percent": 0.83,
223
+ "percent": 0.81,
224
224
  "reduction": 33.54
225
225
  },
226
226
  {
@@ -234,7 +234,7 @@
234
234
  ],
235
235
  "removedExports": [],
236
236
  "dependents": [],
237
- "percent": 0.64,
237
+ "percent": 0.63,
238
238
  "reduction": 15.17
239
239
  },
240
240
  {
@@ -1 +1 @@
1
- {"version":3,"file":"httpSubscriptionLink.d.ts","sourceRoot":"","sources":["../../src/links/httpSubscriptionLink.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EAEtB,MAAM,0CAA0C,CAAC;AAMlD,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAEL,KAAK,8BAA8B,EACpC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAiBxC,KAAK,2BAA2B,CAAC,KAAK,SAAS,cAAc,IAAI;IAC/D;;OAEG;IACH,kBAAkB,CAAC,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;CACvD,GAAG,kBAAkB,CAAC,KAAK,CAAC,GAC3B,8BAA8B,CAAC;AAEjC;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,WAAW,SAAS,qBAAqB,EAEzC,IAAI,EAAE,2BAA2B,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,GAC/D,QAAQ,CAAC,WAAW,CAAC,CAgFvB"}
1
+ {"version":3,"file":"httpSubscriptionLink.d.ts","sourceRoot":"","sources":["../../src/links/httpSubscriptionLink.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACtB,MAAM,0CAA0C,CAAC;AAMlD,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAEL,KAAK,8BAA8B,EACpC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAiBxC,KAAK,2BAA2B,CAAC,KAAK,SAAS,cAAc,IAAI;IAC/D;;OAEG;IACH,kBAAkB,CAAC,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;CACvD,GAAG,kBAAkB,CAAC,KAAK,CAAC,GAC3B,8BAA8B,CAAC;AAEjC;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,WAAW,SAAS,qBAAqB,EAEzC,IAAI,EAAE,2BAA2B,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,GAC/D,QAAQ,CAAC,WAAW,CAAC,CA2FvB"}
@@ -63,8 +63,12 @@ async function urlWithConnectionParams(opts) {
63
63
  deserialize: transformer$1.output.deserialize
64
64
  });
65
65
  for await (const chunk of iterable){
66
- // if the `sse({})`-helper is used, we always have an `id` field
67
- const data = 'id' in chunk ? chunk : chunk.data;
66
+ if (!chunk.ok) {
67
+ continue;
68
+ }
69
+ const chunkData = chunk.data;
70
+ // if the `tracked()`-helper is used, we always have an `id` field
71
+ const data = 'id' in chunkData ? chunkData : chunkData.data;
68
72
  observer.next({
69
73
  result: {
70
74
  data
@@ -61,8 +61,12 @@ async function urlWithConnectionParams(opts) {
61
61
  deserialize: transformer.output.deserialize
62
62
  });
63
63
  for await (const chunk of iterable){
64
- // if the `sse({})`-helper is used, we always have an `id` field
65
- const data = 'id' in chunk ? chunk : chunk.data;
64
+ if (!chunk.ok) {
65
+ continue;
66
+ }
67
+ const chunkData = chunk.data;
68
+ // if the `tracked()`-helper is used, we always have an `id` field
69
+ const data = 'id' in chunkData ? chunkData : chunkData.data;
66
70
  observer.next({
67
71
  result: {
68
72
  data
@@ -45,7 +45,11 @@ export interface WebSocketClientOptions extends UrlOptionsWithConnectionParams {
45
45
  }
46
46
  export declare function createWSClient(opts: WebSocketClientOptions): {
47
47
  close: () => void;
48
- request: (op: Operation, callbacks: WSCallbackObserver<AnyRouter, unknown>) => UnsubscribeFn;
48
+ request: (opts: {
49
+ op: Operation;
50
+ callbacks: WSCallbackObserver<AnyRouter, unknown>;
51
+ lastEventId: string | undefined;
52
+ }) => UnsubscribeFn;
49
53
  readonly connection: ({
50
54
  id: number;
51
55
  } & ({
@@ -1 +1 @@
1
- {"version":3,"file":"wsLink.d.ts","sourceRoot":"","sources":["../../src/links/wsLink.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGvE,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAMhB,mBAAmB,EACpB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,EAEL,KAAK,8BAA8B,EACpC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAInD,KAAK,gBAAgB,CAAC,OAAO,SAAS,SAAS,EAAE,OAAO,IAAI,mBAAmB,CAC7E,OAAO,EACP,gBAAgB,CAAC,OAAO,CAAC,CAC1B,CAAC;AAEF,KAAK,kBAAkB,CAAC,OAAO,SAAS,SAAS,EAAE,OAAO,IAAI,QAAQ,CACpE,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,EAClC,eAAe,CAAC,OAAO,CAAC,CACzB,CAAC;AAEF,QAAA,MAAM,kBAAkB,iBAAkB,MAAM,WACoB,CAAC;AAErE,MAAM,WAAW,sBAAuB,SAAQ,8BAA8B;IAC5E;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC;IAC7B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,kBAAkB,CAAC;IACzC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9C;;OAEG;IACH,IAAI,CAAC,EAAE;QACL;;;WAGG;QACH,OAAO,EAAE,OAAO,CAAC;QACjB;;;WAGG;QACH,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAOD,wBAAgB,cAAc,CAAC,IAAI,EAAE,sBAAsB;;kBAuTpC,SAAS,wDAA0B,aAAa;;YAxQ/D,MAAM;;eAGC,MAAM;YACT,SAAS;;eAGN,QAAQ;YACX,SAAS;;eAGN,YAAY;aACd,SAAS;;IA2TlB;;OAEG;;EAGN;AACD,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAEpE,MAAM,MAAM,oBAAoB,CAAC,OAAO,SAAS,SAAS,IAAI;IAC5D,MAAM,EAAE,mBAAmB,CAAC;CAC7B,GAAG,kBAAkB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;AASlD;;GAEG;AACH,wBAAgB,MAAM,CAAC,OAAO,SAAS,SAAS,EAC9C,IAAI,EAAE,oBAAoB,CAAC,OAAO,CAAC,GAClC,QAAQ,CAAC,OAAO,CAAC,CA8CnB"}
1
+ {"version":3,"file":"wsLink.d.ts","sourceRoot":"","sources":["../../src/links/wsLink.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGvE,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAMhB,mBAAmB,EACpB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,EAEL,KAAK,8BAA8B,EACpC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAInD,KAAK,gBAAgB,CAAC,OAAO,SAAS,SAAS,EAAE,OAAO,IAAI,mBAAmB,CAC7E,OAAO,EACP,gBAAgB,CAAC,OAAO,CAAC,CAC1B,CAAC;AAEF,KAAK,kBAAkB,CAAC,OAAO,SAAS,SAAS,EAAE,OAAO,IAAI,QAAQ,CACpE,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,EAClC,eAAe,CAAC,OAAO,CAAC,CACzB,CAAC;AAEF,QAAA,MAAM,kBAAkB,iBAAkB,MAAM,WACoB,CAAC;AAErE,MAAM,WAAW,sBAAuB,SAAQ,8BAA8B;IAC5E;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC;IAC7B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,kBAAkB,CAAC;IACzC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9C;;OAEG;IACH,IAAI,CAAC,EAAE;QACL;;;WAGG;QACH,OAAO,EAAE,OAAO,CAAC;QACjB;;;WAGG;QACH,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAOD,wBAAgB,cAAc,CAAC,IAAI,EAAE,sBAAsB;;oBAsUlC;QACrB,EAAE,EAAE,SAAS,CAAC;QACd,SAAS,yCAAa;QACtB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;KACjC,KAAG,aAAa;;YAvRX,MAAM;;eAGC,MAAM;YACT,SAAS;;eAGN,QAAQ;YACX,SAAS;;eAGN,YAAY;aACd,SAAS;;IA8UlB;;OAEG;;EAGN;AACD,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAEpE,MAAM,MAAM,oBAAoB,CAAC,OAAO,SAAS,SAAS,IAAI;IAC5D,MAAM,EAAE,mBAAmB,CAAC;CAC7B,GAAG,kBAAkB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;AASlD;;GAEG;AACH,wBAAgB,MAAM,CAAC,OAAO,SAAS,SAAS,EAC9C,IAAI,EAAE,oBAAoB,CAAC,OAAO,CAAC,GAClC,QAAQ,CAAC,OAAO,CAAC,CA+CnB"}
@@ -99,7 +99,11 @@ function createWSClient(opts) {
99
99
  if (outgoing.some((r)=>r.id === req.op.id)) {
100
100
  return;
101
101
  }
102
- request(req.op, req.callbacks);
102
+ request({
103
+ op: req.op,
104
+ callbacks: req.callbacks,
105
+ lastEventId: req.lastEventId
106
+ });
103
107
  }
104
108
  const startLazyDisconnectTimer = ()=>{
105
109
  if (!lazyOpts.enabled) {
@@ -189,6 +193,9 @@ function createWSClient(opts) {
189
193
  req.connection = self;
190
194
  oldConn && closeIfNoPending(oldConn);
191
195
  }
196
+ if ('result' in data && data.result.type === 'data' && typeof data.result.id === 'string') {
197
+ req.lastEventId = data.result.id;
198
+ }
192
199
  if ('result' in data && data.result.type === 'stopped' && activeConnection === self) {
193
200
  req.callbacks.complete();
194
201
  }
@@ -241,21 +248,24 @@ function createWSClient(opts) {
241
248
  }).catch(onError);
242
249
  return self;
243
250
  }
244
- function request(op, callbacks) {
251
+ function request(opts) {
252
+ const { op , callbacks , lastEventId } = opts;
245
253
  const { type , input , path , id } = op;
246
254
  const envelope = {
247
255
  id,
248
256
  method: type,
249
257
  params: {
250
258
  input,
251
- path
259
+ path,
260
+ lastEventId
252
261
  }
253
262
  };
254
263
  pendingRequests[id] = {
255
264
  connection: null,
256
265
  type,
257
266
  callbacks,
258
- op
267
+ op,
268
+ lastEventId
259
269
  };
260
270
  // enqueue message
261
271
  outgoing.push(envelope);
@@ -318,35 +328,39 @@ class TRPCWebSocketClosedError extends Error {
318
328
  const { type , path , id , context } = op;
319
329
  const input = transformer$1.input.serialize(op.input);
320
330
  const unsub = client.request({
321
- type,
322
- path,
323
- input,
324
- id,
325
- context,
326
- signal: null
327
- }, {
328
- error (err) {
329
- observer.error(err);
330
- unsub();
331
- },
332
- complete () {
333
- observer.complete();
331
+ op: {
332
+ type,
333
+ path,
334
+ input,
335
+ id,
336
+ context,
337
+ signal: null
334
338
  },
335
- next (message) {
336
- const transformed = unstableCoreDoNotImport.transformResult(message, transformer$1.output);
337
- if (!transformed.ok) {
338
- observer.error(TRPCClientError.TRPCClientError.from(transformed.error));
339
- return;
340
- }
341
- observer.next({
342
- result: transformed.result
343
- });
344
- if (op.type !== 'subscription') {
345
- // if it isn't a subscription we don't care about next response
339
+ callbacks: {
340
+ error (err) {
341
+ observer.error(err);
346
342
  unsub();
343
+ },
344
+ complete () {
347
345
  observer.complete();
346
+ },
347
+ next (message) {
348
+ const transformed = unstableCoreDoNotImport.transformResult(message, transformer$1.output);
349
+ if (!transformed.ok) {
350
+ observer.error(TRPCClientError.TRPCClientError.from(transformed.error));
351
+ return;
352
+ }
353
+ observer.next({
354
+ result: transformed.result
355
+ });
356
+ if (op.type !== 'subscription') {
357
+ // if it isn't a subscription we don't care about next response
358
+ unsub();
359
+ observer.complete();
360
+ }
348
361
  }
349
- }
362
+ },
363
+ lastEventId: undefined
350
364
  });
351
365
  return ()=>{
352
366
  unsub();
@@ -97,7 +97,11 @@ function createWSClient(opts) {
97
97
  if (outgoing.some((r)=>r.id === req.op.id)) {
98
98
  return;
99
99
  }
100
- request(req.op, req.callbacks);
100
+ request({
101
+ op: req.op,
102
+ callbacks: req.callbacks,
103
+ lastEventId: req.lastEventId
104
+ });
101
105
  }
102
106
  const startLazyDisconnectTimer = ()=>{
103
107
  if (!lazyOpts.enabled) {
@@ -187,6 +191,9 @@ function createWSClient(opts) {
187
191
  req.connection = self;
188
192
  oldConn && closeIfNoPending(oldConn);
189
193
  }
194
+ if ('result' in data && data.result.type === 'data' && typeof data.result.id === 'string') {
195
+ req.lastEventId = data.result.id;
196
+ }
190
197
  if ('result' in data && data.result.type === 'stopped' && activeConnection === self) {
191
198
  req.callbacks.complete();
192
199
  }
@@ -239,21 +246,24 @@ function createWSClient(opts) {
239
246
  }).catch(onError);
240
247
  return self;
241
248
  }
242
- function request(op, callbacks) {
249
+ function request(opts) {
250
+ const { op , callbacks , lastEventId } = opts;
243
251
  const { type , input , path , id } = op;
244
252
  const envelope = {
245
253
  id,
246
254
  method: type,
247
255
  params: {
248
256
  input,
249
- path
257
+ path,
258
+ lastEventId
250
259
  }
251
260
  };
252
261
  pendingRequests[id] = {
253
262
  connection: null,
254
263
  type,
255
264
  callbacks,
256
- op
265
+ op,
266
+ lastEventId
257
267
  };
258
268
  // enqueue message
259
269
  outgoing.push(envelope);
@@ -316,35 +326,39 @@ class TRPCWebSocketClosedError extends Error {
316
326
  const { type , path , id , context } = op;
317
327
  const input = transformer.input.serialize(op.input);
318
328
  const unsub = client.request({
319
- type,
320
- path,
321
- input,
322
- id,
323
- context,
324
- signal: null
325
- }, {
326
- error (err) {
327
- observer.error(err);
328
- unsub();
329
- },
330
- complete () {
331
- observer.complete();
329
+ op: {
330
+ type,
331
+ path,
332
+ input,
333
+ id,
334
+ context,
335
+ signal: null
332
336
  },
333
- next (message) {
334
- const transformed = transformResult(message, transformer.output);
335
- if (!transformed.ok) {
336
- observer.error(TRPCClientError.from(transformed.error));
337
- return;
338
- }
339
- observer.next({
340
- result: transformed.result
341
- });
342
- if (op.type !== 'subscription') {
343
- // if it isn't a subscription we don't care about next response
337
+ callbacks: {
338
+ error (err) {
339
+ observer.error(err);
344
340
  unsub();
341
+ },
342
+ complete () {
345
343
  observer.complete();
344
+ },
345
+ next (message) {
346
+ const transformed = transformResult(message, transformer.output);
347
+ if (!transformed.ok) {
348
+ observer.error(TRPCClientError.from(transformed.error));
349
+ return;
350
+ }
351
+ observer.next({
352
+ result: transformed.result
353
+ });
354
+ if (op.type !== 'subscription') {
355
+ // if it isn't a subscription we don't care about next response
356
+ unsub();
357
+ observer.complete();
358
+ }
346
359
  }
347
- }
360
+ },
361
+ lastEventId: undefined
348
362
  });
349
363
  return ()=>{
350
364
  unsub();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trpc/client",
3
- "version": "11.0.0-rc.474+42b880437",
3
+ "version": "11.0.0-rc.477+a467f8314",
4
4
  "description": "The tRPC client library",
5
5
  "author": "KATT",
6
6
  "license": "MIT",
@@ -76,10 +76,10 @@
76
76
  "!**/*.test.*"
77
77
  ],
78
78
  "peerDependencies": {
79
- "@trpc/server": "11.0.0-rc.474+42b880437"
79
+ "@trpc/server": "11.0.0-rc.477+a467f8314"
80
80
  },
81
81
  "devDependencies": {
82
- "@trpc/server": "11.0.0-rc.474+42b880437",
82
+ "@trpc/server": "11.0.0-rc.477+a467f8314",
83
83
  "@types/isomorphic-fetch": "^0.0.39",
84
84
  "@types/node": "^20.10.0",
85
85
  "eslint": "^8.57.0",
@@ -96,5 +96,5 @@
96
96
  "funding": [
97
97
  "https://trpc.io/sponsor"
98
98
  ],
99
- "gitHead": "42b880437961af45a4e59ff33267acbaedc46cec"
99
+ "gitHead": "a467f831416d19c0bf96139fd4ca576fcf80de2a"
100
100
  }
@@ -3,7 +3,6 @@ import type {
3
3
  AnyClientTypes,
4
4
  inferClientTypes,
5
5
  InferrableClientTypes,
6
- SSEMessage,
7
6
  } from '@trpc/server/unstable-core-do-not-import';
8
7
  import {
9
8
  run,
@@ -96,14 +95,25 @@ export function unstable_httpSubscriptionLink<
96
95
  };
97
96
  // console.log('starting', new Date());
98
97
  eventSource.addEventListener('open', onStarted);
99
- const iterable = sseStreamConsumer<Partial<SSEMessage>>({
98
+ const iterable = sseStreamConsumer<
99
+ Partial<{
100
+ id?: string;
101
+ data: unknown;
102
+ }>
103
+ >({
100
104
  from: eventSource,
101
105
  deserialize: transformer.output.deserialize,
102
106
  });
103
107
 
104
108
  for await (const chunk of iterable) {
105
- // if the `sse({})`-helper is used, we always have an `id` field
106
- const data = 'id' in chunk ? chunk : chunk.data;
109
+ if (!chunk.ok) {
110
+ // TODO: handle in https://github.com/trpc/trpc/issues/5871
111
+ continue;
112
+ }
113
+ const chunkData = chunk.data;
114
+
115
+ // if the `tracked()`-helper is used, we always have an `id` field
116
+ const data = 'id' in chunkData ? chunkData : chunkData.data;
107
117
  observer.next({
108
118
  result: {
109
119
  data,
@@ -103,7 +103,7 @@ export function createWSClient(opts: WebSocketClientOptions) {
103
103
  * pending outgoing requests that are awaiting callback
104
104
  */
105
105
  type TCallbacks = WSCallbackObserver<AnyRouter, unknown>;
106
- type TRequest = {
106
+ type WsRequest = {
107
107
  /**
108
108
  * Reference to the WebSocket instance this request was made to
109
109
  */
@@ -111,8 +111,12 @@ export function createWSClient(opts: WebSocketClientOptions) {
111
111
  type: ProcedureType;
112
112
  callbacks: TCallbacks;
113
113
  op: Operation;
114
+ /**
115
+ * The last event id that the client has received
116
+ */
117
+ lastEventId: string | undefined;
114
118
  };
115
- const pendingRequests: Record<number | string, TRequest> =
119
+ const pendingRequests: Record<number | string, WsRequest> =
116
120
  Object.create(null);
117
121
  let connectAttempt = 0;
118
122
  let connectTimer: ReturnType<typeof setTimeout> | undefined = undefined;
@@ -210,11 +214,15 @@ export function createWSClient(opts: WebSocketClientOptions) {
210
214
  conn.ws?.close();
211
215
  }
212
216
  }
213
- function resumeSubscriptionOnReconnect(req: TRequest) {
217
+ function resumeSubscriptionOnReconnect(req: WsRequest) {
214
218
  if (outgoing.some((r) => r.id === req.op.id)) {
215
219
  return;
216
220
  }
217
- request(req.op, req.callbacks);
221
+ request({
222
+ op: req.op,
223
+ callbacks: req.callbacks,
224
+ lastEventId: req.lastEventId,
225
+ });
218
226
  }
219
227
 
220
228
  const startLazyDisconnectTimer = () => {
@@ -323,6 +331,13 @@ export function createWSClient(opts: WebSocketClientOptions) {
323
331
  oldConn && closeIfNoPending(oldConn);
324
332
  }
325
333
 
334
+ if (
335
+ 'result' in data &&
336
+ data.result.type === 'data' &&
337
+ typeof data.result.id === 'string'
338
+ ) {
339
+ req.lastEventId = data.result.id;
340
+ }
326
341
  if (
327
342
  'result' in data &&
328
343
  data.result.type === 'stopped' &&
@@ -388,7 +403,12 @@ export function createWSClient(opts: WebSocketClientOptions) {
388
403
  return self;
389
404
  }
390
405
 
391
- function request(op: Operation, callbacks: TCallbacks): UnsubscribeFn {
406
+ function request(opts: {
407
+ op: Operation;
408
+ callbacks: TCallbacks;
409
+ lastEventId: string | undefined;
410
+ }): UnsubscribeFn {
411
+ const { op, callbacks, lastEventId } = opts;
392
412
  const { type, input, path, id } = op;
393
413
  const envelope: TRPCRequestMessage = {
394
414
  id,
@@ -396,13 +416,16 @@ export function createWSClient(opts: WebSocketClientOptions) {
396
416
  params: {
397
417
  input,
398
418
  path,
419
+ lastEventId,
399
420
  },
400
421
  };
422
+
401
423
  pendingRequests[id] = {
402
424
  connection: null,
403
425
  type,
404
426
  callbacks,
405
427
  op,
428
+ lastEventId,
406
429
  };
407
430
 
408
431
  // enqueue message
@@ -485,9 +508,9 @@ export function wsLink<TRouter extends AnyRouter>(
485
508
 
486
509
  const input = transformer.input.serialize(op.input);
487
510
 
488
- const unsub = client.request(
489
- { type, path, input, id, context, signal: null },
490
- {
511
+ const unsub = client.request({
512
+ op: { type, path, input, id, context, signal: null },
513
+ callbacks: {
491
514
  error(err) {
492
515
  observer.error(err as TRPCClientError<any>);
493
516
  unsub();
@@ -514,7 +537,8 @@ export function wsLink<TRouter extends AnyRouter>(
514
537
  }
515
538
  },
516
539
  },
517
- );
540
+ lastEventId: undefined,
541
+ });
518
542
  return () => {
519
543
  unsub();
520
544
  };