@orpc/tanstack-query 1.14.11 → 1.14.12

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/index.mjs CHANGED
@@ -1,55 +1,35 @@
1
- import { resolveBasePathMeta, getRouterContract, ProcedureContract } from '@orpc/contract';
2
- import { sortPlugins, stringifyJSON, resolveMaybeOptionalOptions, intercept, toArray, isAsyncIteratorObject, isTypescriptObject, bindMethods, getOrBind, get } from '@orpc/shared';
3
- import { RECURSIVE_CLIENT_UNWRAP_KEYS } from '@orpc/client';
1
+ import { stringifyJSON, isAsyncIteratorObject, toArray, get } from '@orpc/shared';
4
2
  import { skipToken } from '@tanstack/query-core';
5
3
 
6
- class CompositeRouterUtilsPlugin {
7
- constructor(plugins = []) {
8
- this.plugins = plugins;
9
- this.plugins = sortPlugins(plugins);
10
- }
11
- name = "~composite";
12
- init(options) {
13
- for (const plugin of this.plugins) {
14
- if (plugin.init) {
15
- options = plugin.init(options);
16
- }
17
- }
18
- return options;
19
- }
20
- initProcedureOptions(path, options) {
21
- for (const plugin of this.plugins) {
22
- if (plugin.initProcedureOptions) {
23
- options = plugin.initProcedureOptions(path, options);
24
- }
25
- }
26
- return options;
27
- }
4
+ function generateOperationKey(path, state = {}) {
5
+ return [path, {
6
+ ...state.input !== void 0 ? { input: state.input } : {},
7
+ ...state.type !== void 0 ? { type: state.type } : {},
8
+ ...state.fnOptions !== void 0 ? { fnOptions: state.fnOptions } : {}
9
+ }];
28
10
  }
29
11
 
30
- function generateOperationKey(path, options = {}) {
31
- return [
32
- ...options.prefix !== void 0 ? [options.prefix] : [],
33
- path,
34
- {
35
- ...options.input !== void 0 ? { input: options.input } : {},
36
- ...options.type !== void 0 ? { type: options.type } : {},
37
- ...options.fnOptions !== void 0 ? { fnOptions: options.fnOptions } : {}
12
+ function createGeneralUtils(path) {
13
+ return {
14
+ key(options) {
15
+ return generateOperationKey(path, options);
38
16
  }
39
- ];
17
+ };
40
18
  }
41
19
 
42
- function liveQuery(queryFn) {
20
+ function experimental_liveQuery(queryFn) {
43
21
  return async (context) => {
44
22
  const stream = await queryFn(context);
45
23
  let last;
46
24
  for await (const chunk of stream) {
47
- context.signal?.throwIfAborted();
25
+ if (context.signal.aborted) {
26
+ throw context.signal.reason;
27
+ }
48
28
  last = { chunk };
49
29
  context.client.setQueryData(context.queryKey, chunk);
50
30
  }
51
31
  if (!last) {
52
- throw new TypeError(
32
+ throw new Error(
53
33
  `Live query for ${stringifyJSON(context.queryKey)} did not yield any data. Ensure the query function returns an AsyncIterable with at least one chunk.`
54
34
  );
55
35
  }
@@ -57,20 +37,7 @@ function liveQuery(queryFn) {
57
37
  };
58
38
  }
59
39
 
60
- class SharedUtils {
61
- constructor(path, options) {
62
- this.path = path;
63
- this.options = options;
64
- }
65
- /**
66
- * Generate a **partial matching** key for actions like revalidating queries, checking mutation status, etc.
67
- */
68
- key(options = {}) {
69
- return generateOperationKey(this.path, { ...options, prefix: this.options.prefix });
70
- }
71
- }
72
-
73
- function serializableStreamedQuery(queryFn, { refetchMode = "reset", maxChunks = Number.POSITIVE_INFINITY } = {}) {
40
+ function experimental_serializableStreamedQuery(queryFn, { refetchMode = "reset", maxChunks = Number.POSITIVE_INFINITY } = {}) {
74
41
  return async (context) => {
75
42
  const query = context.client.getQueryCache().find({ queryKey: context.queryKey, exact: true });
76
43
  const hasPreviousData = !!query && query.state.data !== void 0;
@@ -126,430 +93,194 @@ function limitArraySize(items, maxSize) {
126
93
  return items.slice(items.length - maxSize);
127
94
  }
128
95
 
129
- const OPERATION_CONTEXT_SYMBOL = Symbol.for("ORPC_TANSTACK_QUERY_OPERATION_CONTEXT");
96
+ const OPERATION_CONTEXT_SYMBOL = Symbol("ORPC_OPERATION_CONTEXT");
130
97
 
131
- const PROCEDURE_UTILS_INTERCEPTOR_KEYS = [
132
- "queryInterceptors",
133
- "streamedInterceptors",
134
- "liveInterceptors",
135
- "infiniteInterceptors",
136
- "mutationInterceptors"
137
- ];
138
- const PROCEDURE_UTILS_MODIFIER_KEYS = [
139
- "queryKey",
140
- "queryOptions",
141
- "streamedKey",
142
- "streamedOptions",
143
- "liveKey",
144
- "liveOptions",
145
- "infiniteKey",
146
- "infiniteOptions",
147
- "mutationKey",
148
- "mutationOptions"
149
- ];
150
- function isProcedureUtilsOptions(value) {
151
- if (!isTypescriptObject(value)) {
152
- return false;
153
- }
154
- for (const key in value) {
155
- if (value[key] === void 0) {
156
- continue;
157
- }
158
- if (key === "prefix") {
159
- if (typeof value[key] !== "string") {
160
- return false;
161
- }
162
- } else if (PROCEDURE_UTILS_INTERCEPTOR_KEYS.includes(key)) {
163
- if (!Array.isArray(value[key]) || value[key].some((i) => typeof i !== "function")) {
164
- return false;
165
- }
166
- } else if (PROCEDURE_UTILS_MODIFIER_KEYS.includes(key)) {
167
- if (!isTypescriptObject(value[key])) {
168
- return false;
169
- }
170
- }
171
- }
172
- return true;
173
- }
174
- function mergeProcedureUtilsModifier(base, override) {
175
- if (typeof base !== "function" && typeof override !== "function") {
176
- return { ...base, ...override };
177
- }
178
- const applyBase = typeof base === "function" ? base : (options) => ({ ...base, ...options });
179
- const applyOverride = typeof override === "function" ? override : (options) => ({ ...override, ...options });
180
- return (options) => applyOverride(applyBase(options));
181
- }
182
- function mergeProcedureUtilsOptions(base, override) {
183
- const merged = { ...base, ...override };
184
- for (const key of PROCEDURE_UTILS_INTERCEPTOR_KEYS) {
185
- const baseValue = base[key];
186
- const overrideValue = override[key];
187
- if (baseValue && overrideValue) {
188
- merged[key] = [...baseValue, ...overrideValue];
189
- }
190
- }
191
- for (const key of PROCEDURE_UTILS_MODIFIER_KEYS) {
192
- const baseValue = base[key];
193
- const overrideValue = override[key];
194
- if (baseValue && overrideValue) {
195
- merged[key] = mergeProcedureUtilsModifier(baseValue, overrideValue);
196
- }
197
- }
198
- return merged;
199
- }
200
- class ProcedureUtils extends SharedUtils {
201
- /**
202
- * Calling corresponding procedure client
203
- */
204
- call;
205
- constructor(path, client, options = {}) {
206
- super(path, options);
207
- this.call = client;
208
- }
209
- /**
210
- * Generate a **full matching** key for [Query Options](https://orpc.dev/docs/integrations/tanstack-query#query-options).
211
- */
212
- queryKey(...rest) {
213
- let optionsIn = resolveMaybeOptionalOptions(rest);
214
- if (typeof this.options.queryKey === "function") {
215
- optionsIn = this.options.queryKey(optionsIn);
216
- } else if (this.options.queryKey) {
217
- optionsIn = { ...this.options.queryKey, ...optionsIn };
218
- }
219
- const queryKey = optionsIn.queryKey ?? generateOperationKey(this.path, { prefix: this.options.prefix, type: "query", input: optionsIn.input });
220
- return queryKey;
221
- }
222
- /**
223
- * Generate options used for useQuery/useSuspenseQuery/prefetchQuery/...
224
- */
225
- queryOptions(...rest) {
226
- let optionsIn = resolveMaybeOptionalOptions(rest);
227
- if (typeof this.options.queryOptions === "function") {
228
- optionsIn = this.options.queryOptions(optionsIn);
229
- } else if (this.options.queryOptions) {
230
- optionsIn = { ...this.options.queryOptions, ...optionsIn };
231
- }
232
- const queryKey = this.queryKey(optionsIn);
233
- return {
234
- ...optionsIn,
235
- queryKey,
236
- queryFn: (fnContext) => {
237
- return intercept(
238
- this.options.queryInterceptors,
239
- {
240
- path: this.path,
98
+ function createProcedureUtils(client, options) {
99
+ const utils = {
100
+ call: client,
101
+ queryKey(...[optionsIn = {}]) {
102
+ optionsIn = { ...options.experimental_defaults?.queryKey, ...optionsIn };
103
+ const queryKey = optionsIn.queryKey ?? generateOperationKey(options.path, { type: "query", input: optionsIn.input });
104
+ return queryKey;
105
+ },
106
+ queryOptions(...[optionsIn = {}]) {
107
+ optionsIn = { ...options.experimental_defaults?.queryOptions, ...optionsIn };
108
+ const queryKey = utils.queryKey(optionsIn);
109
+ return {
110
+ queryFn: ({ signal }) => {
111
+ if (optionsIn.input === skipToken) {
112
+ throw new Error("queryFn should not be called with skipToken used as input");
113
+ }
114
+ return client(optionsIn.input, {
115
+ signal,
241
116
  context: {
242
117
  [OPERATION_CONTEXT_SYMBOL]: {
243
118
  key: queryKey,
244
119
  type: "query"
245
120
  },
246
121
  ...optionsIn.context
247
- },
248
- input: optionsIn.input,
249
- fnContext
250
- },
251
- ({ context, input, fnContext: fnContext2 }) => {
252
- if (input === skipToken || optionsIn.queryFn === skipToken) {
253
- throw new Error("queryFn should not be called when skipToken used for skipping");
254
122
  }
255
- if (optionsIn.queryFn) {
256
- return optionsIn.queryFn(fnContext2);
257
- }
258
- return this.call(input, { signal: fnContext2.signal, context });
259
- }
260
- );
261
- },
262
- ...optionsIn.input === skipToken || optionsIn.queryFn === skipToken ? { enabled: false } : {}
263
- };
264
- }
265
- /**
266
- * Generate a **full matching** key for [Streamed Query Options](https://orpc.dev/docs/integrations/tanstack-query#streamed-query-options).
267
- */
268
- streamedKey(...rest) {
269
- let optionsIn = resolveMaybeOptionalOptions(rest);
270
- if (typeof this.options.streamedKey === "function") {
271
- optionsIn = this.options.streamedKey(optionsIn);
272
- } else if (this.options.streamedKey) {
273
- optionsIn = { ...this.options.streamedKey, ...optionsIn };
274
- }
275
- const queryKey = optionsIn.queryKey ?? generateOperationKey(this.path, { prefix: this.options.prefix, type: "streamed", input: optionsIn.input, fnOptions: optionsIn.queryFnOptions });
276
- return queryKey;
277
- }
278
- /**
279
- * Configure queries for [AsyncIteratorObject](https://orpc.dev/docs/async-iterator-object).
280
- * This is built on [TanStack Query streamedQuery](https://tanstack.com/query/latest/docs/reference/streamedQuery)
281
- * and works with hooks like `useQuery`, `useSuspenseQuery`, or `prefetchQuery`.
282
- */
283
- streamedOptions(...rest) {
284
- let optionsIn = resolveMaybeOptionalOptions(rest);
285
- if (typeof this.options.streamedOptions === "function") {
286
- optionsIn = this.options.streamedOptions(optionsIn);
287
- } else if (this.options.streamedOptions) {
288
- optionsIn = { ...this.options.streamedOptions, ...optionsIn };
289
- }
290
- const queryKey = this.streamedKey(optionsIn);
291
- return {
292
- ...optionsIn,
293
- queryKey,
294
- queryFn: (fnContext) => {
295
- return intercept(
296
- toArray(this.options.streamedInterceptors),
297
- {
298
- path: this.path,
299
- context: {
300
- [OPERATION_CONTEXT_SYMBOL]: {
301
- key: queryKey,
302
- type: "streamed"
303
- },
304
- ...optionsIn.context
305
- },
306
- input: optionsIn.input,
307
- fnContext
308
- },
309
- ({ context, fnContext: fnContext2, input }) => {
310
- if (input === skipToken || optionsIn.queryFn === skipToken) {
311
- throw new Error("queryFn should not be called when skipToken used for skipping");
123
+ });
124
+ },
125
+ ...optionsIn.input === skipToken ? { enabled: false } : {},
126
+ ...optionsIn,
127
+ queryKey
128
+ };
129
+ },
130
+ experimental_streamedKey(...[optionsIn = {}]) {
131
+ optionsIn = { ...options.experimental_defaults?.experimental_streamedKey, ...optionsIn };
132
+ const queryKey = optionsIn.queryKey ?? generateOperationKey(options.path, { type: "streamed", input: optionsIn.input, fnOptions: optionsIn.queryFnOptions });
133
+ return queryKey;
134
+ },
135
+ experimental_streamedOptions(...[optionsIn = {}]) {
136
+ optionsIn = { ...options.experimental_defaults?.experimental_streamedOptions, ...optionsIn };
137
+ const queryKey = utils.experimental_streamedKey(optionsIn);
138
+ return {
139
+ queryFn: experimental_serializableStreamedQuery(
140
+ async ({ signal }) => {
141
+ if (optionsIn.input === skipToken) {
142
+ throw new Error("queryFn should not be called with skipToken used as input");
312
143
  }
313
- if (optionsIn.queryFn) {
314
- return optionsIn.queryFn(fnContext2);
144
+ const output = await client(optionsIn.input, {
145
+ signal,
146
+ context: {
147
+ [OPERATION_CONTEXT_SYMBOL]: {
148
+ key: queryKey,
149
+ type: "streamed"
150
+ },
151
+ ...optionsIn.context
152
+ }
153
+ });
154
+ if (!isAsyncIteratorObject(output)) {
155
+ throw new Error("streamedQuery requires an event iterator output");
315
156
  }
316
- return serializableStreamedQuery(
317
- async (queryContext) => {
318
- const output = await this.call(input, { signal: queryContext.signal, context });
319
- if (!isAsyncIteratorObject(output)) {
320
- throw new Error("streamedQuery requires an AsyncIteratorObject output");
321
- }
322
- return output;
323
- },
324
- optionsIn.queryFnOptions
325
- )(fnContext2);
157
+ return output;
158
+ },
159
+ optionsIn.queryFnOptions
160
+ ),
161
+ ...optionsIn.input === skipToken ? { enabled: false } : {},
162
+ ...optionsIn,
163
+ queryKey
164
+ };
165
+ },
166
+ experimental_liveKey(...[optionsIn = {}]) {
167
+ optionsIn = { ...options.experimental_defaults?.experimental_liveKey, ...optionsIn };
168
+ const queryKey = optionsIn.queryKey ?? generateOperationKey(options.path, { type: "live", input: optionsIn.input });
169
+ return queryKey;
170
+ },
171
+ experimental_liveOptions(...[optionsIn = {}]) {
172
+ optionsIn = { ...options.experimental_defaults?.experimental_liveOptions, ...optionsIn };
173
+ const queryKey = utils.experimental_liveKey(optionsIn);
174
+ return {
175
+ queryFn: experimental_liveQuery(async ({ signal }) => {
176
+ if (optionsIn.input === skipToken) {
177
+ throw new Error("queryFn should not be called with skipToken used as input");
326
178
  }
327
- );
328
- },
329
- ...optionsIn.input === skipToken || optionsIn.queryFn === skipToken ? { enabled: false } : {}
330
- };
331
- }
332
- /**
333
- * Generate a **full matching** key for [Live Query Options](https://orpc.dev/docs/integrations/tanstack-query#live-query-options).
334
- */
335
- liveKey(...rest) {
336
- let optionsIn = resolveMaybeOptionalOptions(rest);
337
- if (typeof this.options.liveKey === "function") {
338
- optionsIn = this.options.liveKey(optionsIn);
339
- } else if (this.options.liveKey) {
340
- optionsIn = { ...this.options.liveKey, ...optionsIn };
341
- }
342
- const queryKey = optionsIn.queryKey ?? generateOperationKey(this.path, { prefix: this.options.prefix, type: "live", input: optionsIn.input });
343
- return queryKey;
344
- }
345
- /**
346
- * Configure live queries for [AsyncIteratorObject](https://orpc.dev/docs/async-iterator-object).
347
- * Unlike `.streamedOptions` which accumulates chunks, live queries replace the entire result with each new chunk received.
348
- * Works with hooks like `useQuery`, `useSuspenseQuery`, or `prefetchQuery`.
349
- */
350
- liveOptions(...rest) {
351
- let optionsIn = resolveMaybeOptionalOptions(rest);
352
- if (typeof this.options.liveOptions === "function") {
353
- optionsIn = this.options.liveOptions(optionsIn);
354
- } else if (this.options.liveOptions) {
355
- optionsIn = { ...this.options.liveOptions, ...optionsIn };
356
- }
357
- const queryKey = this.liveKey(optionsIn);
358
- return {
359
- ...optionsIn,
360
- queryKey,
361
- queryFn: (fnContext) => {
362
- return intercept(
363
- toArray(this.options.liveInterceptors),
364
- {
365
- path: this.path,
179
+ const output = await client(optionsIn.input, {
180
+ signal,
366
181
  context: {
367
182
  [OPERATION_CONTEXT_SYMBOL]: {
368
183
  key: queryKey,
369
184
  type: "live"
370
185
  },
371
186
  ...optionsIn.context
372
- },
373
- input: optionsIn.input,
374
- fnContext
375
- },
376
- ({ fnContext: fnContext2, input, context }) => {
377
- if (input === skipToken || optionsIn.queryFn === skipToken) {
378
- throw new Error("queryFn should not be called when skipToken used for skipping");
379
- }
380
- if (optionsIn.queryFn) {
381
- return optionsIn.queryFn(fnContext2);
382
187
  }
383
- return liveQuery(async (queryContext) => {
384
- const output = await this.call(input, {
385
- signal: queryContext.signal,
386
- context
387
- });
388
- if (!isAsyncIteratorObject(output)) {
389
- throw new Error("liveQuery requires an AsyncIteratorObject output");
390
- }
391
- return output;
392
- })(fnContext2);
188
+ });
189
+ if (!isAsyncIteratorObject(output)) {
190
+ throw new Error("liveQuery requires an event iterator output");
393
191
  }
394
- );
395
- },
396
- ...optionsIn.input === skipToken || optionsIn.queryFn === skipToken ? { enabled: false } : {}
397
- };
398
- }
399
- /**
400
- * Generate a **full matching** key for [Infinite Query Options](https://orpc.dev/docs/integrations/tanstack-query#infinite-query-options).
401
- */
402
- infiniteKey(optionsIn) {
403
- if (typeof this.options.infiniteKey === "function") {
404
- optionsIn = this.options.infiniteKey(optionsIn);
405
- } else if (this.options.infiniteKey) {
406
- optionsIn = { ...this.options.infiniteKey, ...optionsIn };
407
- }
408
- const queryKey = optionsIn.queryKey ?? generateOperationKey(this.path, {
409
- prefix: this.options.prefix,
410
- type: "infinite",
411
- input: optionsIn.input === skipToken ? skipToken : optionsIn.input(optionsIn.initialPageParam)
412
- });
413
- return queryKey;
414
- }
415
- /**
416
- * Generate options used for useInfiniteQuery/useSuspenseInfiniteQuery/prefetchInfiniteQuery/...
417
- */
418
- infiniteOptions(optionsIn) {
419
- if (typeof this.options.infiniteOptions === "function") {
420
- optionsIn = this.options.infiniteOptions(optionsIn);
421
- } else if (this.options.infiniteOptions) {
422
- optionsIn = { ...this.options.infiniteOptions, ...optionsIn };
423
- }
424
- const queryKey = this.infiniteKey(optionsIn);
425
- return {
426
- ...optionsIn,
427
- queryKey,
428
- queryFn: (fnContext) => {
429
- return intercept(
430
- toArray(this.options.infiniteInterceptors),
431
- {
432
- path: this.path,
192
+ return output;
193
+ }),
194
+ ...optionsIn.input === skipToken ? { enabled: false } : {},
195
+ ...optionsIn,
196
+ queryKey
197
+ };
198
+ },
199
+ infiniteKey(optionsIn) {
200
+ optionsIn = { ...options.experimental_defaults?.infiniteKey, ...optionsIn };
201
+ const queryKey = optionsIn.queryKey ?? generateOperationKey(options.path, {
202
+ type: "infinite",
203
+ input: optionsIn.input === skipToken ? skipToken : optionsIn.input(optionsIn.initialPageParam)
204
+ });
205
+ return queryKey;
206
+ },
207
+ infiniteOptions(optionsIn) {
208
+ optionsIn = { ...options.experimental_defaults?.infiniteOptions, ...optionsIn };
209
+ const queryKey = utils.infiniteKey(optionsIn);
210
+ return {
211
+ queryFn: ({ pageParam, signal }) => {
212
+ if (optionsIn.input === skipToken) {
213
+ throw new Error("queryFn should not be called with skipToken used as input");
214
+ }
215
+ return client(optionsIn.input(pageParam), {
216
+ signal,
433
217
  context: {
434
218
  [OPERATION_CONTEXT_SYMBOL]: {
435
219
  key: queryKey,
436
220
  type: "infinite"
437
221
  },
438
222
  ...optionsIn.context
439
- },
440
- input: optionsIn.input === skipToken ? skipToken : optionsIn.input(fnContext.pageParam),
441
- fnContext
442
- },
443
- ({ context, input, fnContext: fnContext2 }) => {
444
- if (input === skipToken || optionsIn.queryFn === skipToken) {
445
- throw new Error("queryFn should not be called when skipToken used for skipping");
446
223
  }
447
- if (optionsIn.queryFn) {
448
- return optionsIn.queryFn(fnContext2);
449
- }
450
- return this.call(input, { signal: fnContext2.signal, context });
451
- }
452
- );
453
- },
454
- ...optionsIn.input === skipToken || optionsIn.queryFn === skipToken ? { enabled: false } : {}
455
- };
456
- }
457
- /**
458
- * Generate a **full matching** key for [Mutation Options](https://orpc.dev/docs/integrations/tanstack-query#mutation-options).
459
- */
460
- mutationKey(optionsIn = {}) {
461
- if (typeof this.options.mutationKey === "function") {
462
- optionsIn = this.options.mutationKey(optionsIn);
463
- } else if (this.options.mutationKey) {
464
- optionsIn = { ...this.options.mutationKey, ...optionsIn };
465
- }
466
- const mutationKey = optionsIn.mutationKey ?? generateOperationKey(this.path, { prefix: this.options.prefix, type: "mutation" });
467
- return mutationKey;
468
- }
469
- /**
470
- * Generate options used for useMutation/...
471
- */
472
- mutationOptions(...rest) {
473
- let optionsIn = resolveMaybeOptionalOptions(rest);
474
- if (typeof this.options.mutationOptions === "function") {
475
- optionsIn = this.options.mutationOptions(optionsIn);
476
- } else if (this.options.mutationOptions) {
477
- optionsIn = { ...this.options.mutationOptions, ...optionsIn };
478
- }
479
- const mutationKey = this.mutationKey(optionsIn);
480
- return {
481
- ...optionsIn,
482
- mutationKey,
483
- mutationFn: (input, fnContext) => {
484
- return intercept(
485
- toArray(this.options.mutationInterceptors),
486
- {
487
- path: this.path,
488
- context: {
489
- [OPERATION_CONTEXT_SYMBOL]: {
490
- key: mutationKey,
491
- type: "mutation"
492
- },
493
- ...optionsIn.context
224
+ });
225
+ },
226
+ ...optionsIn.input === skipToken ? { enabled: false } : {},
227
+ ...optionsIn,
228
+ queryKey
229
+ };
230
+ },
231
+ mutationKey(...[optionsIn = {}]) {
232
+ optionsIn = { ...options.experimental_defaults?.mutationKey, ...optionsIn };
233
+ const mutationKey = optionsIn.mutationKey ?? generateOperationKey(options.path, { type: "mutation" });
234
+ return mutationKey;
235
+ },
236
+ mutationOptions(...[optionsIn = {}]) {
237
+ optionsIn = { ...options.experimental_defaults?.mutationOptions, ...optionsIn };
238
+ const mutationKey = utils.mutationKey(optionsIn);
239
+ return {
240
+ mutationFn: (input) => client(input, {
241
+ context: {
242
+ [OPERATION_CONTEXT_SYMBOL]: {
243
+ key: mutationKey,
244
+ type: "mutation"
494
245
  },
495
- fnContext,
496
- input
497
- },
498
- ({ input: input2, fnContext: fnContext2, context }) => {
499
- if (optionsIn.mutationFn) {
500
- return optionsIn.mutationFn(input2, fnContext2);
501
- }
502
- return this.call(input2, { context });
246
+ ...optionsIn.context
503
247
  }
504
- );
505
- }
506
- };
507
- }
248
+ }),
249
+ ...optionsIn,
250
+ mutationKey
251
+ };
252
+ }
253
+ };
254
+ return utils;
508
255
  }
509
256
 
510
257
  function createRouterUtils(client, options = {}) {
511
- const plugin = new CompositeRouterUtilsPlugin(options.plugins);
512
- options = plugin.init(options);
513
- return createRouterUtilsInternal(client, options, plugin);
514
- }
515
- function createRouterUtilsInternal(client, options, plugin) {
516
258
  const path = toArray(options.path);
517
- const utils = typeof client === "function" && (options.scoped === void 0 || isProcedureUtilsOptions(options.scoped)) ? bindMethods(new ProcedureUtils(
259
+ const generalUtils = createGeneralUtils(path);
260
+ const procedureUtils = createProcedureUtils(client, {
518
261
  path,
519
- client,
520
- plugin.initProcedureOptions(path, mergeProcedureUtilsOptions(
521
- {
522
- prefix: options.prefix,
523
- queryInterceptors: options.queryInterceptors,
524
- streamedInterceptors: options.streamedInterceptors,
525
- liveInterceptors: options.liveInterceptors,
526
- infiniteInterceptors: options.infiniteInterceptors,
527
- mutationInterceptors: options.mutationInterceptors
528
- },
529
- options.scoped ?? {}
530
- ))
531
- )) : bindMethods(new SharedUtils(path, options));
532
- const recursive = new Proxy(utils, {
262
+ experimental_defaults: options.experimental_defaults
263
+ });
264
+ const recursive = new Proxy({
265
+ ...generalUtils,
266
+ ...procedureUtils
267
+ }, {
533
268
  get(target, prop) {
534
- const value = getOrBind(target, prop);
535
- const nextClient = client[prop];
536
- if (typeof prop !== "string" || RECURSIVE_CLIENT_UNWRAP_KEYS.has(prop) || !isTypescriptObject(nextClient)) {
269
+ const value = Reflect.get(target, prop);
270
+ if (typeof prop !== "string") {
537
271
  return value;
538
272
  }
539
- const nextUtils = createRouterUtilsInternal(nextClient, {
273
+ const nextUtils = createRouterUtils(client[prop], {
540
274
  ...options,
541
275
  path: [...path, prop],
542
- scoped: get(options.scoped, [prop])
543
- }, plugin);
276
+ experimental_defaults: get(options.experimental_defaults, [prop])
277
+ });
544
278
  if (typeof value !== "function") {
545
279
  return nextUtils;
546
280
  }
547
281
  return new Proxy(value, {
548
- get(target2, prop2) {
549
- if (typeof prop2 !== "string" || RECURSIVE_CLIENT_UNWRAP_KEYS.has(prop2)) {
550
- return getOrBind(target2, prop2);
551
- }
552
- return getOrBind(nextUtils, prop2);
282
+ get(_, prop2) {
283
+ return Reflect.get(nextUtils, prop2);
553
284
  }
554
285
  });
555
286
  }
@@ -557,54 +288,4 @@ function createRouterUtilsInternal(client, options, plugin) {
557
288
  return recursive;
558
289
  }
559
290
 
560
- function createContractUtilsFactory(clientFactory, options) {
561
- const factory = (contract) => {
562
- const client = clientFactory(contract);
563
- const path = resolveBasePathMeta(contract);
564
- if (path === void 0) {
565
- throw new TypeError(
566
- "ContractUtilsFactory: procedure contract must define `meta.path` that matches its path in the root router contract."
567
- );
568
- }
569
- return createRouterUtils(client, { ...options, path, scoped: get(options.scoped, path) });
570
- };
571
- return factory;
572
- }
573
- function createContractJsonifiedUtilsFactory(clientFactory, options) {
574
- return createContractUtilsFactory(clientFactory, options);
575
- }
576
-
577
- function tanstackQuery(options) {
578
- return {
579
- name: "~tanstack-query",
580
- init(meta) {
581
- const current = meta["~tanstack-query"];
582
- return {
583
- ...meta,
584
- "~tanstack-query": current ? mergeProcedureUtilsOptions(current, options) : options
585
- };
586
- }
587
- };
588
- }
589
- function getTanstackQueryMeta(procedureOrLazy) {
590
- return procedureOrLazy["~orpc"].meta["~tanstack-query"];
591
- }
592
- class ContractOptionsUtilsPlugin {
593
- constructor(contract) {
594
- this.contract = contract;
595
- }
596
- name = "~contract-options";
597
- initProcedureOptions(path, options) {
598
- const procedure = getRouterContract(this.contract, path);
599
- if (!(procedure instanceof ProcedureContract)) {
600
- return options;
601
- }
602
- const base = getTanstackQueryMeta(procedure);
603
- if (!base) {
604
- return options;
605
- }
606
- return mergeProcedureUtilsOptions(base, options);
607
- }
608
- }
609
-
610
- export { CompositeRouterUtilsPlugin, ContractOptionsUtilsPlugin, OPERATION_CONTEXT_SYMBOL, ProcedureUtils, SharedUtils, OPERATION_CONTEXT_SYMBOL as TANSTACK_QUERY_OPERATION_CONTEXT_SYMBOL, createContractJsonifiedUtilsFactory, createContractUtilsFactory, createRouterUtils, createRouterUtils as createTanstackQueryUtils, generateOperationKey, getTanstackQueryMeta, isProcedureUtilsOptions, mergeProcedureUtilsOptions, serializableStreamedQuery, tanstackQuery };
291
+ export { OPERATION_CONTEXT_SYMBOL, OPERATION_CONTEXT_SYMBOL as TANSTACK_QUERY_OPERATION_CONTEXT_SYMBOL, createGeneralUtils, createProcedureUtils, createRouterUtils, createRouterUtils as createTanstackQueryUtils, experimental_serializableStreamedQuery, generateOperationKey };