@orpc/pinia-colada 0.0.0
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/LICENSE +21 -0
- package/README.md +198 -0
- package/dist/index.d.mts +422 -0
- package/dist/index.d.ts +422 -0
- package/dist/index.mjs +516 -0
- package/package.json +51 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
import { resolveBasePathMeta } from '@orpc/contract';
|
|
2
|
+
import { sortPlugins, stringifyJSON, resolveMaybeOptionalOptions, intercept, isAsyncIteratorObject, toArray, bindMethods, getOrBind, get, isTypescriptObject } from '@orpc/shared';
|
|
3
|
+
import { RPCJsonSerializer, RECURSIVE_CLIENT_UNWRAP_KEYS } from '@orpc/client';
|
|
4
|
+
|
|
5
|
+
class CompositeRouterUtilsPlugin {
|
|
6
|
+
constructor(plugins = []) {
|
|
7
|
+
this.plugins = plugins;
|
|
8
|
+
this.plugins = sortPlugins(plugins);
|
|
9
|
+
}
|
|
10
|
+
name = "~composite";
|
|
11
|
+
init(options) {
|
|
12
|
+
for (const plugin of this.plugins) {
|
|
13
|
+
if (plugin.init) {
|
|
14
|
+
options = plugin.init(options);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return options;
|
|
18
|
+
}
|
|
19
|
+
initProcedureOptions(path, options) {
|
|
20
|
+
for (const plugin of this.plugins) {
|
|
21
|
+
if (plugin.initProcedureOptions) {
|
|
22
|
+
options = plugin.initProcedureOptions(path, options);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return options;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const serializer = new RPCJsonSerializer();
|
|
30
|
+
function generateOperationKey(path, options = {}) {
|
|
31
|
+
return [
|
|
32
|
+
...options.prefix !== void 0 ? [options.prefix] : [],
|
|
33
|
+
path,
|
|
34
|
+
{
|
|
35
|
+
...options.input !== void 0 ? { input: serializer.serialize(options.input).json } : {},
|
|
36
|
+
...options.type !== void 0 ? { type: options.type } : {},
|
|
37
|
+
...options.fnOptions !== void 0 ? { fnOptions: options.fnOptions } : {}
|
|
38
|
+
}
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function liveQuery(queryFn) {
|
|
43
|
+
return async (context) => {
|
|
44
|
+
const { entry, signal } = context;
|
|
45
|
+
const stream = await queryFn(context);
|
|
46
|
+
let last;
|
|
47
|
+
for await (const chunk of stream) {
|
|
48
|
+
if (signal.aborted) {
|
|
49
|
+
throw signal.reason;
|
|
50
|
+
}
|
|
51
|
+
last = { chunk };
|
|
52
|
+
entry.state.value = { status: "success", data: chunk, error: null };
|
|
53
|
+
}
|
|
54
|
+
if (!last) {
|
|
55
|
+
throw new TypeError(
|
|
56
|
+
`Live query for ${stringifyJSON(entry.key)} did not yield any data. Ensure the query function returns an AsyncIterable with at least one chunk.`
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return last.chunk;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
class SharedUtils {
|
|
64
|
+
constructor(path, options) {
|
|
65
|
+
this.path = path;
|
|
66
|
+
this.options = options;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Generate a **partial matching** key for actions like revalidating queries, checking mutation status, etc.
|
|
70
|
+
*
|
|
71
|
+
* @see {@link https://orpc.dev/docs/integrations/pinia-colada#query-mutation-key Pinia Colada Query/Mutation Key Docs}
|
|
72
|
+
*/
|
|
73
|
+
key(options = {}) {
|
|
74
|
+
return generateOperationKey(this.path, { ...options, prefix: this.options.prefix });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function serializableStreamedQuery(queryFn, { refetchMode = "reset", maxChunks = Number.POSITIVE_INFINITY } = {}) {
|
|
79
|
+
return async (context) => {
|
|
80
|
+
const { entry, signal } = context;
|
|
81
|
+
const previousData = entry.state.value.data;
|
|
82
|
+
const hasPreviousData = previousData !== void 0;
|
|
83
|
+
if (hasPreviousData && refetchMode === "reset") {
|
|
84
|
+
entry.state.value = { status: "pending", data: void 0, error: null };
|
|
85
|
+
}
|
|
86
|
+
const stream = await queryFn(context);
|
|
87
|
+
const shouldUpdateCacheDuringStream = !hasPreviousData || refetchMode !== "replace";
|
|
88
|
+
let result = hasPreviousData && refetchMode === "append" ? limitArraySize(previousData, maxChunks) : [];
|
|
89
|
+
if (shouldUpdateCacheDuringStream) {
|
|
90
|
+
entry.state.value = { status: "success", data: result, error: null };
|
|
91
|
+
}
|
|
92
|
+
for await (const chunk of stream) {
|
|
93
|
+
if (signal.aborted) {
|
|
94
|
+
throw signal.reason;
|
|
95
|
+
}
|
|
96
|
+
result = limitArraySize([...result, chunk], maxChunks);
|
|
97
|
+
if (shouldUpdateCacheDuringStream) {
|
|
98
|
+
entry.state.value = { status: "success", data: result, error: null };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function limitArraySize(items, maxSize) {
|
|
105
|
+
if (items.length <= maxSize) {
|
|
106
|
+
return items;
|
|
107
|
+
}
|
|
108
|
+
return items.slice(items.length - maxSize);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const OPERATION_CONTEXT_SYMBOL = Symbol.for("ORPC_PINIA_COLADA_OPERATION_CONTEXT");
|
|
112
|
+
|
|
113
|
+
class ProcedureUtils extends SharedUtils {
|
|
114
|
+
/**
|
|
115
|
+
* Calling corresponding procedure client
|
|
116
|
+
*
|
|
117
|
+
* @see {@link https://orpc.dev/docs/integrations/pinia-colada#calling-procedure-clients Pinia Colada Calling Procedure Client Docs}
|
|
118
|
+
*/
|
|
119
|
+
call;
|
|
120
|
+
constructor(path, client, options = {}) {
|
|
121
|
+
super(path, options);
|
|
122
|
+
this.call = client;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Generate a **full matching** key for useQuery/...
|
|
126
|
+
*
|
|
127
|
+
* @see {@link https://orpc.dev/docs/integrations/pinia-colada#query-mutation-key Pinia Colada Query/Mutation Key Docs}
|
|
128
|
+
*/
|
|
129
|
+
queryKey(...rest) {
|
|
130
|
+
let optionsIn = resolveMaybeOptionalOptions(rest);
|
|
131
|
+
if (typeof this.options.queryKey === "function") {
|
|
132
|
+
optionsIn = this.options.queryKey(optionsIn);
|
|
133
|
+
} else if (this.options.queryKey) {
|
|
134
|
+
optionsIn = { ...this.options.queryKey, ...optionsIn };
|
|
135
|
+
}
|
|
136
|
+
const key = optionsIn.key ?? generateOperationKey(this.path, { prefix: this.options.prefix, type: "query", input: optionsIn.input });
|
|
137
|
+
return key;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Generate options used for useQuery/...
|
|
141
|
+
*
|
|
142
|
+
* @see {@link https://orpc.dev/docs/integrations/pinia-colada#query-options-utility Pinia Colada Query Options Utility Docs}
|
|
143
|
+
*/
|
|
144
|
+
queryOptions(...rest) {
|
|
145
|
+
let optionsIn = resolveMaybeOptionalOptions(rest);
|
|
146
|
+
if (typeof this.options.queryOptions === "function") {
|
|
147
|
+
optionsIn = this.options.queryOptions(optionsIn);
|
|
148
|
+
} else if (this.options.queryOptions) {
|
|
149
|
+
optionsIn = { ...this.options.queryOptions, ...optionsIn };
|
|
150
|
+
}
|
|
151
|
+
const { input, context, key: _keyIn, query: queryIn, ...restOptions } = optionsIn;
|
|
152
|
+
const key = this.queryKey(optionsIn);
|
|
153
|
+
return {
|
|
154
|
+
...restOptions,
|
|
155
|
+
key,
|
|
156
|
+
query: (fnContext) => {
|
|
157
|
+
return intercept(
|
|
158
|
+
this.options.queryInterceptors,
|
|
159
|
+
{
|
|
160
|
+
path: this.path,
|
|
161
|
+
context: {
|
|
162
|
+
[OPERATION_CONTEXT_SYMBOL]: {
|
|
163
|
+
key,
|
|
164
|
+
type: "query"
|
|
165
|
+
},
|
|
166
|
+
...context
|
|
167
|
+
},
|
|
168
|
+
input,
|
|
169
|
+
fnContext
|
|
170
|
+
},
|
|
171
|
+
({ context: context2, input: input2, fnContext: fnContext2 }) => {
|
|
172
|
+
if (queryIn) {
|
|
173
|
+
return queryIn(fnContext2);
|
|
174
|
+
}
|
|
175
|
+
return this.call(input2, { signal: fnContext2.signal, context: context2 });
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Generate a **full matching** key for [Streamed Query Options](https://orpc.dev/docs/integrations/pinia-colada#streamed-query-options-utility).
|
|
183
|
+
*
|
|
184
|
+
* @see {@link https://orpc.dev/docs/integrations/pinia-colada#query-mutation-key Pinia Colada Query/Mutation Key Docs}
|
|
185
|
+
*/
|
|
186
|
+
streamedKey(...rest) {
|
|
187
|
+
let optionsIn = resolveMaybeOptionalOptions(rest);
|
|
188
|
+
if (typeof this.options.streamedKey === "function") {
|
|
189
|
+
optionsIn = this.options.streamedKey(optionsIn);
|
|
190
|
+
} else if (this.options.streamedKey) {
|
|
191
|
+
optionsIn = { ...this.options.streamedKey, ...optionsIn };
|
|
192
|
+
}
|
|
193
|
+
const key = optionsIn.key ?? generateOperationKey(this.path, { prefix: this.options.prefix, type: "streamed", input: optionsIn.input, fnOptions: optionsIn.fnOptions });
|
|
194
|
+
return key;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Configure queries for [AsyncIteratorObject](https://orpc.dev/docs/async-iterator-object).
|
|
198
|
+
* The resulting data is an array of chunks, and each new chunk is appended as it arrives.
|
|
199
|
+
* Works with `useQuery` and any other API that accepts query options.
|
|
200
|
+
*/
|
|
201
|
+
streamedOptions(...rest) {
|
|
202
|
+
let optionsIn = resolveMaybeOptionalOptions(rest);
|
|
203
|
+
if (typeof this.options.streamedOptions === "function") {
|
|
204
|
+
optionsIn = this.options.streamedOptions(optionsIn);
|
|
205
|
+
} else if (this.options.streamedOptions) {
|
|
206
|
+
optionsIn = { ...this.options.streamedOptions, ...optionsIn };
|
|
207
|
+
}
|
|
208
|
+
const { input, context, key: _keyIn, query: queryIn, fnOptions, ...restOptions } = optionsIn;
|
|
209
|
+
const key = this.streamedKey(optionsIn);
|
|
210
|
+
return {
|
|
211
|
+
...restOptions,
|
|
212
|
+
key,
|
|
213
|
+
query: (fnContext) => {
|
|
214
|
+
return intercept(
|
|
215
|
+
this.options.streamedInterceptors,
|
|
216
|
+
{
|
|
217
|
+
path: this.path,
|
|
218
|
+
context: {
|
|
219
|
+
[OPERATION_CONTEXT_SYMBOL]: {
|
|
220
|
+
key,
|
|
221
|
+
type: "streamed"
|
|
222
|
+
},
|
|
223
|
+
...context
|
|
224
|
+
},
|
|
225
|
+
input,
|
|
226
|
+
fnContext
|
|
227
|
+
},
|
|
228
|
+
({ context: context2, input: input2, fnContext: fnContext2 }) => {
|
|
229
|
+
if (queryIn) {
|
|
230
|
+
return queryIn(fnContext2);
|
|
231
|
+
}
|
|
232
|
+
return serializableStreamedQuery(
|
|
233
|
+
async (queryContext) => {
|
|
234
|
+
const output = await this.call(input2, { signal: queryContext.signal, context: context2 });
|
|
235
|
+
if (!isAsyncIteratorObject(output)) {
|
|
236
|
+
throw new Error("streamedQuery requires an AsyncIteratorObject output");
|
|
237
|
+
}
|
|
238
|
+
return output;
|
|
239
|
+
},
|
|
240
|
+
fnOptions
|
|
241
|
+
)(fnContext2);
|
|
242
|
+
}
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Generate a **full matching** key for [Live Query Options](https://orpc.dev/docs/integrations/pinia-colada#live-query-options-utility).
|
|
249
|
+
*
|
|
250
|
+
* @see {@link https://orpc.dev/docs/integrations/pinia-colada#query-mutation-key Pinia Colada Query/Mutation Key Docs}
|
|
251
|
+
*/
|
|
252
|
+
liveKey(...rest) {
|
|
253
|
+
let optionsIn = resolveMaybeOptionalOptions(rest);
|
|
254
|
+
if (typeof this.options.liveKey === "function") {
|
|
255
|
+
optionsIn = this.options.liveKey(optionsIn);
|
|
256
|
+
} else if (this.options.liveKey) {
|
|
257
|
+
optionsIn = { ...this.options.liveKey, ...optionsIn };
|
|
258
|
+
}
|
|
259
|
+
const key = optionsIn.key ?? generateOperationKey(this.path, { prefix: this.options.prefix, type: "live", input: optionsIn.input });
|
|
260
|
+
return key;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Configure live queries for [AsyncIteratorObject](https://orpc.dev/docs/async-iterator-object).
|
|
264
|
+
* Unlike `.streamedOptions` which accumulates chunks, live queries replace the entire result with each new chunk received.
|
|
265
|
+
* Works with `useQuery` and any other API that accepts query options.
|
|
266
|
+
*/
|
|
267
|
+
liveOptions(...rest) {
|
|
268
|
+
let optionsIn = resolveMaybeOptionalOptions(rest);
|
|
269
|
+
if (typeof this.options.liveOptions === "function") {
|
|
270
|
+
optionsIn = this.options.liveOptions(optionsIn);
|
|
271
|
+
} else if (this.options.liveOptions) {
|
|
272
|
+
optionsIn = { ...this.options.liveOptions, ...optionsIn };
|
|
273
|
+
}
|
|
274
|
+
const { input, context, key: _keyIn, query: queryIn, ...restOptions } = optionsIn;
|
|
275
|
+
const key = this.liveKey(optionsIn);
|
|
276
|
+
return {
|
|
277
|
+
...restOptions,
|
|
278
|
+
key,
|
|
279
|
+
query: (fnContext) => {
|
|
280
|
+
return intercept(
|
|
281
|
+
this.options.liveInterceptors,
|
|
282
|
+
{
|
|
283
|
+
path: this.path,
|
|
284
|
+
context: {
|
|
285
|
+
[OPERATION_CONTEXT_SYMBOL]: {
|
|
286
|
+
key,
|
|
287
|
+
type: "live"
|
|
288
|
+
},
|
|
289
|
+
...context
|
|
290
|
+
},
|
|
291
|
+
input,
|
|
292
|
+
fnContext
|
|
293
|
+
},
|
|
294
|
+
({ context: context2, input: input2, fnContext: fnContext2 }) => {
|
|
295
|
+
if (queryIn) {
|
|
296
|
+
return queryIn(fnContext2);
|
|
297
|
+
}
|
|
298
|
+
return liveQuery(async (queryContext) => {
|
|
299
|
+
const output = await this.call(input2, { signal: queryContext.signal, context: context2 });
|
|
300
|
+
if (!isAsyncIteratorObject(output)) {
|
|
301
|
+
throw new Error("liveQuery requires an AsyncIteratorObject output");
|
|
302
|
+
}
|
|
303
|
+
return output;
|
|
304
|
+
})(fnContext2);
|
|
305
|
+
}
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Generate a **full matching** key for useInfiniteQuery/...
|
|
312
|
+
*
|
|
313
|
+
* @see {@link https://orpc.dev/docs/integrations/pinia-colada#query-mutation-key Pinia Colada Query/Mutation Key Docs}
|
|
314
|
+
*/
|
|
315
|
+
infiniteKey(optionsIn) {
|
|
316
|
+
if (typeof this.options.infiniteKey === "function") {
|
|
317
|
+
optionsIn = this.options.infiniteKey(optionsIn);
|
|
318
|
+
} else if (this.options.infiniteKey) {
|
|
319
|
+
optionsIn = { ...this.options.infiniteKey, ...optionsIn };
|
|
320
|
+
}
|
|
321
|
+
const key = optionsIn.key ?? generateOperationKey(this.path, {
|
|
322
|
+
prefix: this.options.prefix,
|
|
323
|
+
type: "infinite",
|
|
324
|
+
input: optionsIn.input(
|
|
325
|
+
typeof optionsIn.initialPageParam === "function" ? optionsIn.initialPageParam() : optionsIn.initialPageParam
|
|
326
|
+
)
|
|
327
|
+
});
|
|
328
|
+
return key;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Generate options used for useInfiniteQuery/...
|
|
332
|
+
*
|
|
333
|
+
* @see {@link https://orpc.dev/docs/integrations/pinia-colada#infinite-query-options-utility Pinia Colada Infinite Query Options Utility Docs}
|
|
334
|
+
*/
|
|
335
|
+
infiniteOptions(optionsIn) {
|
|
336
|
+
if (typeof this.options.infiniteOptions === "function") {
|
|
337
|
+
optionsIn = this.options.infiniteOptions(optionsIn);
|
|
338
|
+
} else if (this.options.infiniteOptions) {
|
|
339
|
+
optionsIn = { ...this.options.infiniteOptions, ...optionsIn };
|
|
340
|
+
}
|
|
341
|
+
const { input, context, key: _keyIn, query: queryIn, ...restOptions } = optionsIn;
|
|
342
|
+
const key = this.infiniteKey(optionsIn);
|
|
343
|
+
return {
|
|
344
|
+
...restOptions,
|
|
345
|
+
key,
|
|
346
|
+
query: (fnContext) => {
|
|
347
|
+
return intercept(
|
|
348
|
+
this.options.infiniteInterceptors,
|
|
349
|
+
{
|
|
350
|
+
path: this.path,
|
|
351
|
+
context: {
|
|
352
|
+
[OPERATION_CONTEXT_SYMBOL]: {
|
|
353
|
+
key,
|
|
354
|
+
type: "infinite"
|
|
355
|
+
},
|
|
356
|
+
...context
|
|
357
|
+
},
|
|
358
|
+
input: input(fnContext.pageParam),
|
|
359
|
+
fnContext
|
|
360
|
+
},
|
|
361
|
+
({ context: context2, input: input2, fnContext: fnContext2 }) => {
|
|
362
|
+
if (queryIn) {
|
|
363
|
+
return queryIn(fnContext2);
|
|
364
|
+
}
|
|
365
|
+
return this.call(input2, { signal: fnContext2.signal, context: context2 });
|
|
366
|
+
}
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Generate a **full matching** key for useMutation/...
|
|
373
|
+
*
|
|
374
|
+
* @see {@link https://orpc.dev/docs/integrations/pinia-colada#query-mutation-key Pinia Colada Query/Mutation Key Docs}
|
|
375
|
+
*/
|
|
376
|
+
mutationKey(...rest) {
|
|
377
|
+
let optionsIn = resolveMaybeOptionalOptions(rest);
|
|
378
|
+
if (typeof this.options.mutationKey === "function") {
|
|
379
|
+
optionsIn = this.options.mutationKey(optionsIn);
|
|
380
|
+
} else if (this.options.mutationKey) {
|
|
381
|
+
optionsIn = { ...this.options.mutationKey, ...optionsIn };
|
|
382
|
+
}
|
|
383
|
+
const key = optionsIn.key ?? ((input) => generateOperationKey(this.path, { prefix: this.options.prefix, type: "mutation", input }));
|
|
384
|
+
return key;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Generate options used for useMutation/...
|
|
388
|
+
*
|
|
389
|
+
* @see {@link https://orpc.dev/docs/integrations/pinia-colada#mutation-options Pinia Colada Mutation Options Docs}
|
|
390
|
+
*/
|
|
391
|
+
mutationOptions(...rest) {
|
|
392
|
+
let optionsIn = resolveMaybeOptionalOptions(rest);
|
|
393
|
+
if (typeof this.options.mutationOptions === "function") {
|
|
394
|
+
optionsIn = this.options.mutationOptions(optionsIn);
|
|
395
|
+
} else if (this.options.mutationOptions) {
|
|
396
|
+
optionsIn = { ...this.options.mutationOptions, ...optionsIn };
|
|
397
|
+
}
|
|
398
|
+
const { context, key: _keyIn, mutation: mutationIn, ...restOptions } = optionsIn;
|
|
399
|
+
const key = this.mutationKey(optionsIn);
|
|
400
|
+
return {
|
|
401
|
+
...restOptions,
|
|
402
|
+
key,
|
|
403
|
+
mutation: (input, fnContext) => {
|
|
404
|
+
return intercept(
|
|
405
|
+
this.options.mutationInterceptors,
|
|
406
|
+
{
|
|
407
|
+
path: this.path,
|
|
408
|
+
context: {
|
|
409
|
+
[OPERATION_CONTEXT_SYMBOL]: {
|
|
410
|
+
key: typeof key === "function" ? key(input) : key,
|
|
411
|
+
type: "mutation"
|
|
412
|
+
},
|
|
413
|
+
...context
|
|
414
|
+
},
|
|
415
|
+
input,
|
|
416
|
+
fnContext
|
|
417
|
+
},
|
|
418
|
+
({ context: context2, input: input2, fnContext: fnContext2 }) => {
|
|
419
|
+
if (mutationIn) {
|
|
420
|
+
return mutationIn(input2, fnContext2);
|
|
421
|
+
}
|
|
422
|
+
return this.call(input2, { context: context2 });
|
|
423
|
+
}
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function createRouterUtils(client, options = {}) {
|
|
431
|
+
const plugin = new CompositeRouterUtilsPlugin(options.plugins);
|
|
432
|
+
options = plugin.init(options);
|
|
433
|
+
return createRouterUtilsInternal(client, options, plugin);
|
|
434
|
+
}
|
|
435
|
+
function createRouterUtilsInternal(client, options, plugin) {
|
|
436
|
+
const path = toArray(options.path);
|
|
437
|
+
const utils = typeof client === "function" && (options.scoped === void 0 || isProcedureUtilsOptions(options.scoped)) ? bindMethods(new ProcedureUtils(
|
|
438
|
+
path,
|
|
439
|
+
client,
|
|
440
|
+
plugin.initProcedureOptions(path, {
|
|
441
|
+
prefix: options.prefix,
|
|
442
|
+
...options.scoped,
|
|
443
|
+
queryInterceptors: [...toArray(options.queryInterceptors), ...toArray(options.scoped?.queryInterceptors)],
|
|
444
|
+
streamedInterceptors: [...toArray(options.streamedInterceptors), ...toArray(options.scoped?.streamedInterceptors)],
|
|
445
|
+
liveInterceptors: [...toArray(options.liveInterceptors), ...toArray(options.scoped?.liveInterceptors)],
|
|
446
|
+
infiniteInterceptors: [...toArray(options.infiniteInterceptors), ...toArray(options.scoped?.infiniteInterceptors)],
|
|
447
|
+
mutationInterceptors: [...toArray(options.mutationInterceptors), ...toArray(options.scoped?.mutationInterceptors)]
|
|
448
|
+
})
|
|
449
|
+
)) : bindMethods(new SharedUtils(path, options));
|
|
450
|
+
const recursive = new Proxy(utils, {
|
|
451
|
+
get(target, prop) {
|
|
452
|
+
const value = getOrBind(target, prop);
|
|
453
|
+
const nextClient = get(client, [prop]);
|
|
454
|
+
if (typeof prop !== "string" || RECURSIVE_CLIENT_UNWRAP_KEYS.has(prop) || !isTypescriptObject(nextClient)) {
|
|
455
|
+
return value;
|
|
456
|
+
}
|
|
457
|
+
const nextUtils = createRouterUtilsInternal(nextClient, {
|
|
458
|
+
...options,
|
|
459
|
+
path: [...path, prop],
|
|
460
|
+
scoped: get(options.scoped, [prop])
|
|
461
|
+
}, plugin);
|
|
462
|
+
if (typeof value !== "function") {
|
|
463
|
+
return nextUtils;
|
|
464
|
+
}
|
|
465
|
+
return new Proxy(value, {
|
|
466
|
+
get(target2, prop2) {
|
|
467
|
+
if (typeof prop2 !== "string" || RECURSIVE_CLIENT_UNWRAP_KEYS.has(prop2)) {
|
|
468
|
+
return getOrBind(target2, prop2);
|
|
469
|
+
}
|
|
470
|
+
return getOrBind(nextUtils, prop2);
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
return recursive;
|
|
476
|
+
}
|
|
477
|
+
function isProcedureUtilsOptions(value) {
|
|
478
|
+
if (!isTypescriptObject(value)) {
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
if (value.queryInterceptors !== void 0 && !Array.isArray(value.queryInterceptors)) {
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
if (value.streamedInterceptors !== void 0 && !Array.isArray(value.streamedInterceptors)) {
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
if (value.liveInterceptors !== void 0 && !Array.isArray(value.liveInterceptors)) {
|
|
488
|
+
return false;
|
|
489
|
+
}
|
|
490
|
+
if (value.infiniteInterceptors !== void 0 && !Array.isArray(value.infiniteInterceptors)) {
|
|
491
|
+
return false;
|
|
492
|
+
}
|
|
493
|
+
if (value.mutationInterceptors !== void 0 && !Array.isArray(value.mutationInterceptors)) {
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
return true;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function createContractUtilsFactory(clientFactory, options) {
|
|
500
|
+
const factory = (contract) => {
|
|
501
|
+
const client = clientFactory(contract);
|
|
502
|
+
const path = resolveBasePathMeta(contract);
|
|
503
|
+
if (path === void 0) {
|
|
504
|
+
throw new TypeError(
|
|
505
|
+
"ContractUtilsFactory: procedure contract must define `meta.path` that matches its path in the root router contract."
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
return createRouterUtils(client, { ...options, path, scoped: get(options.scoped, path) });
|
|
509
|
+
};
|
|
510
|
+
return factory;
|
|
511
|
+
}
|
|
512
|
+
function createContractJsonifiedUtilsFactory(clientFactory, options) {
|
|
513
|
+
return createContractUtilsFactory(clientFactory, options);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
export { CompositeRouterUtilsPlugin, OPERATION_CONTEXT_SYMBOL, OPERATION_CONTEXT_SYMBOL as PINIA_COLADA_OPERATION_CONTEXT_SYMBOL, ProcedureUtils, SharedUtils, createContractJsonifiedUtilsFactory, createContractUtilsFactory, createRouterUtils as createPiniaColadaUtils, createRouterUtils, generateOperationKey, liveQuery, serializableStreamedQuery };
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@orpc/pinia-colada",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://orpc.dev",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/middleapi/orpc.git",
|
|
10
|
+
"directory": "packages/pinia-colada"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"orpc",
|
|
14
|
+
"vue",
|
|
15
|
+
"pinia",
|
|
16
|
+
"pinia-colada"
|
|
17
|
+
],
|
|
18
|
+
"sideEffects": false,
|
|
19
|
+
"exports": {
|
|
20
|
+
"./package.json": "./package.json",
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.mts",
|
|
23
|
+
"import": "./dist/index.mjs",
|
|
24
|
+
"default": "./dist/index.mjs"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"@pinia/colada": ">=1.0.0",
|
|
32
|
+
"vue": ">=3.5.17"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@orpc/client": "*",
|
|
36
|
+
"@orpc/contract": "*",
|
|
37
|
+
"@orpc/openapi": "*",
|
|
38
|
+
"@orpc/shared": "*"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@pinia/colada": "^1.4.2",
|
|
42
|
+
"@vue/test-utils": "^2.4.11",
|
|
43
|
+
"pinia": "^4.0.2",
|
|
44
|
+
"vue": "^3.5.38",
|
|
45
|
+
"zod": "^4.4.3"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "unbuild",
|
|
49
|
+
"type:check": "tsc -b"
|
|
50
|
+
}
|
|
51
|
+
}
|