@falcondev-oss/trpc-vue-query 0.4.2 → 0.5.0-rc.1
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/README.md +7 -3
- package/dist/index.cjs +90 -30
- package/dist/index.d.cts +35 -23
- package/dist/index.d.ts +35 -23
- package/dist/index.mjs +98 -33
- package/package.json +32 -27
package/README.md
CHANGED
|
@@ -20,9 +20,10 @@ pnpm add @falcondev-oss/trpc-vue-query
|
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
22
|
import { createTRPCVueQueryClient } from '@falcondev-oss/trpc-vue-query'
|
|
23
|
-
import type { AppRouter } from '../your_server/trpc'
|
|
24
23
|
import { VueQueryPlugin, useQueryClient } from '@tanstack/vue-query'
|
|
25
24
|
|
|
25
|
+
import type { AppRouter } from '../your_server/trpc'
|
|
26
|
+
|
|
26
27
|
app.use(VueQueryPlugin)
|
|
27
28
|
app.use({
|
|
28
29
|
install(app) {
|
|
@@ -45,6 +46,7 @@ app.use({
|
|
|
45
46
|
|
|
46
47
|
```ts
|
|
47
48
|
import { createTRPCVueQueryClient } from '@falcondev-oss/trpc-vue-query'
|
|
49
|
+
|
|
48
50
|
import type { AppRouter } from '../your_server/trpc'
|
|
49
51
|
|
|
50
52
|
export function useTRPC() {
|
|
@@ -58,6 +60,7 @@ export function useTRPC() {
|
|
|
58
60
|
<script lang="ts" setup>
|
|
59
61
|
const { data: greeting } = useTRPC().hello.useQuery({ name: 'World' })
|
|
60
62
|
</script>
|
|
63
|
+
|
|
61
64
|
<template>
|
|
62
65
|
<div>
|
|
63
66
|
<h1>{{ greeting }}</h1>
|
|
@@ -102,7 +105,7 @@ const { mutate: updateGreeting } = useTRPC().hello.update.useMutation({
|
|
|
102
105
|
<template>
|
|
103
106
|
<div>
|
|
104
107
|
<input v-model="name" type="text" />
|
|
105
|
-
<button @click="updateGreeting({ name })">Update greeting</button>
|
|
108
|
+
<button @click="() => updateGreeting({ name })">Update greeting</button>
|
|
106
109
|
</div>
|
|
107
110
|
</template>
|
|
108
111
|
```
|
|
@@ -115,6 +118,7 @@ Setup `trpc-nuxt` as described in their [documentation](https://trpc-nuxt.vercel
|
|
|
115
118
|
import { createTRPCVueQueryClient } from '@falcondev-oss/trpc-vue-query'
|
|
116
119
|
import { useQueryClient } from '@tanstack/vue-query'
|
|
117
120
|
import { httpBatchLink } from 'trpc-nuxt/client'
|
|
121
|
+
|
|
118
122
|
import type { AppRouter } from '~/server/trpc/routers'
|
|
119
123
|
|
|
120
124
|
export default defineNuxtPlugin(() => {
|
|
@@ -148,4 +152,4 @@ export function useTRPC() {
|
|
|
148
152
|
|
|
149
153
|
## Acknowledgements
|
|
150
154
|
|
|
151
|
-
Huge thanks to [Robert Soriano](https://github.com/wobsoriano) for creating `nuxt
|
|
155
|
+
Huge thanks to [Robert Soriano](https://github.com/wobsoriano) for creating `trpc-nuxt`! We just adapted his work to work with Vue Query.
|
package/dist/index.cjs
CHANGED
|
@@ -25,63 +25,123 @@ __export(src_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(src_exports);
|
|
26
26
|
var import_vue_query = require("@tanstack/vue-query");
|
|
27
27
|
var import_client = require("@trpc/client");
|
|
28
|
-
var
|
|
28
|
+
var import_server = require("@trpc/server");
|
|
29
|
+
var import_unstable_core_do_not_import = require("@trpc/server/unstable-core-do-not-import");
|
|
29
30
|
var import_core = require("@vueuse/core");
|
|
30
31
|
var import_vue = require("vue");
|
|
31
|
-
function getQueryKey(path, input) {
|
|
32
|
-
|
|
32
|
+
function getQueryKey(path, input, type) {
|
|
33
|
+
const splitPath = path.flatMap((part) => part.split("."));
|
|
34
|
+
if (input === void 0 && !type) {
|
|
35
|
+
return splitPath.length > 0 ? [splitPath] : [];
|
|
36
|
+
}
|
|
37
|
+
return [
|
|
38
|
+
splitPath,
|
|
39
|
+
{
|
|
40
|
+
...input !== void 0 && input !== import_vue_query.skipToken && { input },
|
|
41
|
+
...type && { type }
|
|
42
|
+
}
|
|
43
|
+
];
|
|
33
44
|
}
|
|
34
45
|
function maybeToRefs(obj) {
|
|
35
46
|
return (0, import_vue.isReactive)(obj) ? (0, import_core.toRefs)(obj) : (0, import_core.toRefs)((0, import_core.toRef)(obj));
|
|
36
47
|
}
|
|
37
|
-
function createVueQueryProxyDecoration(name,
|
|
38
|
-
return (0,
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
const lastProperty = path.pop();
|
|
48
|
+
function createVueQueryProxyDecoration(name, trpc, queryClient) {
|
|
49
|
+
return (0, import_unstable_core_do_not_import.createRecursiveProxy)(({ args, path: _path }) => {
|
|
50
|
+
const path = [name, ..._path];
|
|
51
|
+
const prop = path.pop();
|
|
42
52
|
const joinedPath = path.join(".");
|
|
43
|
-
const [
|
|
44
|
-
|
|
53
|
+
const [firstArg, ...rest] = args;
|
|
54
|
+
const opts = rest[0] || {};
|
|
55
|
+
if (prop === "_def") {
|
|
45
56
|
return { path };
|
|
46
57
|
}
|
|
47
|
-
if (
|
|
48
|
-
|
|
58
|
+
if (prop === "query") {
|
|
59
|
+
return trpc.query(joinedPath, firstArg, opts);
|
|
60
|
+
}
|
|
61
|
+
if (prop === "useQuery") {
|
|
62
|
+
const { trpc: trpcOptions, ...queryOptions } = opts;
|
|
49
63
|
return (0, import_vue_query.useQuery)({
|
|
50
|
-
queryKey: (0, import_vue.computed)(() => getQueryKey(path, (0, import_core.toValue)(
|
|
51
|
-
queryFn: ({ queryKey, signal }) =>
|
|
64
|
+
queryKey: (0, import_vue.computed)(() => getQueryKey(path, (0, import_core.toValue)(firstArg), "query")),
|
|
65
|
+
queryFn: async ({ queryKey, signal }) => trpc.query(joinedPath, queryKey[1]?.input, {
|
|
52
66
|
signal,
|
|
53
|
-
...
|
|
67
|
+
...trpcOptions
|
|
54
68
|
}),
|
|
55
69
|
...maybeToRefs(queryOptions)
|
|
56
70
|
});
|
|
57
71
|
}
|
|
58
|
-
if (
|
|
72
|
+
if (prop === "invalidate") {
|
|
59
73
|
return queryClient.invalidateQueries({
|
|
60
|
-
queryKey: getQueryKey(path, (0, import_core.toValue)(
|
|
74
|
+
queryKey: getQueryKey(path, (0, import_core.toValue)(firstArg), "query")
|
|
61
75
|
});
|
|
62
76
|
}
|
|
63
|
-
if (
|
|
64
|
-
return queryClient.setQueryData(getQueryKey(path, (0, import_core.toValue)(
|
|
77
|
+
if (prop === "setQueryData") {
|
|
78
|
+
return queryClient.setQueryData(getQueryKey(path, (0, import_core.toValue)(opts), "query"), firstArg);
|
|
65
79
|
}
|
|
66
|
-
if (
|
|
67
|
-
return getQueryKey(path, (0, import_core.toValue)(
|
|
80
|
+
if (prop === "key") {
|
|
81
|
+
return getQueryKey(path, (0, import_core.toValue)(firstArg), "query");
|
|
68
82
|
}
|
|
69
|
-
if (
|
|
70
|
-
|
|
83
|
+
if (prop === "mutate") {
|
|
84
|
+
return trpc.mutation(joinedPath, firstArg, opts);
|
|
85
|
+
}
|
|
86
|
+
if (prop === "useMutation") {
|
|
87
|
+
const { trpc: trpcOptions, ...mutationOptions } = firstArg || {};
|
|
71
88
|
return (0, import_vue_query.useMutation)({
|
|
72
|
-
|
|
73
|
-
|
|
89
|
+
mutationKey: (0, import_vue.computed)(() => getQueryKey(path, void 0)),
|
|
90
|
+
mutationFn: async (payload) => trpc.mutation(joinedPath, payload, {
|
|
91
|
+
...trpcOptions
|
|
74
92
|
}),
|
|
75
93
|
...maybeToRefs(mutationOptions)
|
|
76
94
|
});
|
|
77
95
|
}
|
|
78
|
-
|
|
96
|
+
if (prop === "subscribe") {
|
|
97
|
+
return trpc.subscription(joinedPath, firstArg, opts);
|
|
98
|
+
}
|
|
99
|
+
if (prop === "useSubscription") {
|
|
100
|
+
const inputData = (0, import_core.toRef)(firstArg);
|
|
101
|
+
const subscription = (0, import_vue.shallowRef)();
|
|
102
|
+
(0, import_vue.watch)(
|
|
103
|
+
inputData,
|
|
104
|
+
() => {
|
|
105
|
+
subscription.value?.unsubscribe();
|
|
106
|
+
subscription.value = trpc.subscription(joinedPath, inputData.value, {
|
|
107
|
+
...opts
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
{ immediate: true }
|
|
111
|
+
);
|
|
112
|
+
(0, import_vue.onScopeDispose)(() => {
|
|
113
|
+
subscription.value?.unsubscribe();
|
|
114
|
+
}, true);
|
|
115
|
+
return subscription.value;
|
|
116
|
+
}
|
|
117
|
+
if (prop === "useInfiniteQuery") {
|
|
118
|
+
const { trpc: trpcOptions, ...queryOptions } = opts;
|
|
119
|
+
return (0, import_vue_query.useInfiniteQuery)({
|
|
120
|
+
queryKey: (0, import_vue.computed)(() => getQueryKey(path, (0, import_core.toValue)(firstArg), "infinite")),
|
|
121
|
+
queryFn: async ({ queryKey, pageParam, signal }) => trpc.query(
|
|
122
|
+
joinedPath,
|
|
123
|
+
{
|
|
124
|
+
...queryKey[1]?.input,
|
|
125
|
+
cursor: pageParam
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
signal,
|
|
129
|
+
...trpcOptions
|
|
130
|
+
}
|
|
131
|
+
),
|
|
132
|
+
...maybeToRefs(queryOptions)
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
throw new Error(`Method '.${prop}()' not supported`);
|
|
79
136
|
});
|
|
80
137
|
}
|
|
81
|
-
function createTRPCVueQueryClient(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
138
|
+
function createTRPCVueQueryClient({
|
|
139
|
+
trpc,
|
|
140
|
+
queryClient
|
|
141
|
+
}) {
|
|
142
|
+
const client = (0, import_client.createTRPCUntypedClient)(trpc);
|
|
143
|
+
const decoratedClient = (0, import_server.createTRPCFlatProxy)((key) => {
|
|
144
|
+
return createVueQueryProxyDecoration(key, client, queryClient);
|
|
85
145
|
});
|
|
86
146
|
return decoratedClient;
|
|
87
147
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,49 +1,61 @@
|
|
|
1
|
-
import { QueryKey, UseQueryOptions, UseQueryReturnType, QueryClient, UseMutationOptions, UseMutationReturnType } from '@tanstack/vue-query';
|
|
2
|
-
import { TRPCClientErrorLike, TRPCRequestOptions, CreateTRPCClientOptions } from '@trpc/client';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { QueryKey, UseQueryOptions, UseQueryReturnType, QueryClient, InfiniteData, UseInfiniteQueryOptions, InitialPageParam, UseInfiniteQueryReturnType, UseMutationOptions, UseMutationReturnType } from '@tanstack/vue-query';
|
|
2
|
+
import { TRPCClientErrorLike, TRPCRequestOptions, OperationContext, CreateTRPCClientOptions } from '@trpc/client';
|
|
3
|
+
import { AnyTRPCRouter, AnyTRPCProcedure, AnyTRPCQueryProcedure, inferTransformedProcedureOutput, inferProcedureInput, AnyTRPCMutationProcedure, AnyTRPCSubscriptionProcedure, inferProcedureOutput } from '@trpc/server';
|
|
4
|
+
import { Unsubscribable } from '@trpc/server/observable';
|
|
5
|
+
import { ProcedureOptions } from '@trpc/server/unstable-core-do-not-import';
|
|
6
6
|
import { MaybeRefOrGetter, UnwrapRef } from 'vue';
|
|
7
7
|
|
|
8
8
|
type TRPCSubscriptionObserver<TValue, TError> = {
|
|
9
|
-
onStarted: (
|
|
9
|
+
onStarted: (opts: {
|
|
10
|
+
context: OperationContext | undefined;
|
|
11
|
+
}) => void;
|
|
10
12
|
onData: (value: TValue) => void;
|
|
11
13
|
onError: (err: TError) => void;
|
|
12
14
|
onStopped: () => void;
|
|
13
15
|
onComplete: () => void;
|
|
14
16
|
};
|
|
15
|
-
type Resolver<TProcedure extends
|
|
16
|
-
type SubscriptionResolver<TProcedure extends
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
]) => Unsubscribable;
|
|
20
|
-
type DecorateProcedure<TProcedure extends AnyProcedure, TRouter extends AnyRouter> = TProcedure extends AnyQueryProcedure ? {
|
|
21
|
-
useQuery: <TQueryFnData = inferTransformedProcedureOutput<TProcedure>, TError = TRPCClientErrorLike<TProcedure>, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(input: MaybeRefOrGetter<inferProcedureInput<TProcedure>>, opts?: MaybeRefOrGetter<Omit<UnwrapRef<UseQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>>, 'queryKey'> & {
|
|
17
|
+
type Resolver<TRouter extends AnyTRPCRouter, TProcedure extends AnyTRPCProcedure> = (input: inferProcedureInput<TProcedure>, opts?: ProcedureOptions) => Promise<inferTransformedProcedureOutput<TRouter, TProcedure>>;
|
|
18
|
+
type SubscriptionResolver<TProcedure extends AnyTRPCProcedure, TRouter extends AnyTRPCRouter> = (input: inferProcedureInput<TProcedure>, opts: ProcedureOptions & Partial<TRPCSubscriptionObserver<inferProcedureOutput<TProcedure>, TRPCClientErrorLike<TRouter>>>) => Unsubscribable;
|
|
19
|
+
type DecorateProcedure<TProcedure extends AnyTRPCProcedure, TRouter extends AnyTRPCRouter> = TProcedure extends AnyTRPCQueryProcedure ? {
|
|
20
|
+
useQuery: <TQueryFnData = inferTransformedProcedureOutput<TRouter, TProcedure>, TError = TRPCClientErrorLike<TRouter>, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(input: MaybeRefOrGetter<inferProcedureInput<TProcedure>>, opts?: MaybeRefOrGetter<Omit<UnwrapRef<UseQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>>, 'queryKey'> & {
|
|
22
21
|
trpc?: TRPCRequestOptions;
|
|
23
22
|
queryKey?: TQueryKey;
|
|
24
23
|
}>) => UseQueryReturnType<TData, TError>;
|
|
25
|
-
query: Resolver<TProcedure>;
|
|
24
|
+
query: Resolver<TRouter, TProcedure>;
|
|
26
25
|
invalidate: (input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => Promise<void>;
|
|
27
|
-
setQueryData: (updater: inferTransformedProcedureOutput<TProcedure>, input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => ReturnType<QueryClient['setQueryData']>;
|
|
26
|
+
setQueryData: (updater: inferTransformedProcedureOutput<TRouter, TProcedure>, input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => ReturnType<QueryClient['setQueryData']>;
|
|
28
27
|
key: (input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => QueryKey;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
} & (TProcedure['_def']['$types']['input'] extends {
|
|
29
|
+
cursor?: infer CursorType;
|
|
30
|
+
} ? {
|
|
31
|
+
useInfiniteQuery: <TQueryFnData = inferTransformedProcedureOutput<TRouter, TProcedure>, TError = TRPCClientErrorLike<TRouter>, TData = InfiniteData<TQueryFnData>, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(input: MaybeRefOrGetter<Omit<inferProcedureInput<TProcedure>, 'cursor'>>, opts?: MaybeRefOrGetter<Omit<UnwrapRef<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>>, 'queryKey' | keyof InitialPageParam> & {
|
|
32
|
+
trpc?: TRPCRequestOptions;
|
|
33
|
+
queryKey?: TQueryKey;
|
|
34
|
+
} & (undefined extends TProcedure['_def']['$types']['input']['cursor'] ? Partial<InitialPageParam<CursorType>> : InitialPageParam<CursorType>)>) => UseInfiniteQueryReturnType<TData, TError>;
|
|
35
|
+
} : object) : TProcedure extends AnyTRPCMutationProcedure ? {
|
|
36
|
+
mutate: Resolver<TRouter, TProcedure>;
|
|
37
|
+
useMutation: <TData = inferTransformedProcedureOutput<TRouter, TProcedure>, TError = TRPCClientErrorLike<TRouter>, TVariables = inferProcedureInput<TProcedure>, TContext = unknown>(opts?: MaybeRefOrGetter<UseMutationOptions<TData, TError, TVariables, TContext> & {
|
|
32
38
|
trpc?: TRPCRequestOptions;
|
|
33
39
|
}>) => UseMutationReturnType<TData, TError, TVariables, TContext>;
|
|
34
|
-
} : TProcedure extends
|
|
40
|
+
} : TProcedure extends AnyTRPCSubscriptionProcedure ? {
|
|
35
41
|
subscribe: SubscriptionResolver<TProcedure, TRouter>;
|
|
42
|
+
useSubscription: (input: MaybeRefOrGetter<inferProcedureInput<TProcedure>>, opts: ProcedureOptions & Partial<TRPCSubscriptionObserver<inferProcedureOutput<TProcedure>, TRPCClientErrorLike<TRouter>>>) => Unsubscribable;
|
|
36
43
|
} : never;
|
|
37
44
|
/**
|
|
38
45
|
* @internal
|
|
39
46
|
*/
|
|
40
|
-
type DecoratedProcedureRecord<TProcedures extends
|
|
41
|
-
[
|
|
47
|
+
type DecoratedProcedureRecord<TProcedures extends Record<string, any>, TRouter extends AnyTRPCRouter> = {
|
|
48
|
+
[K in keyof TProcedures]: TProcedures[K] extends AnyTRPCProcedure ? DecorateProcedure<TProcedures[K], TRouter> : DecoratedProcedureRecord<TProcedures[K], TRouter>;
|
|
42
49
|
};
|
|
43
50
|
|
|
44
|
-
|
|
51
|
+
type QueryType = 'query' | 'infinite';
|
|
52
|
+
type TRPCQueryKey = [readonly string[], {
|
|
53
|
+
input?: unknown;
|
|
54
|
+
type?: QueryType;
|
|
55
|
+
}?];
|
|
56
|
+
declare function createTRPCVueQueryClient<TRouter extends AnyTRPCRouter>({ trpc, queryClient, }: {
|
|
45
57
|
queryClient: QueryClient;
|
|
46
58
|
trpc: CreateTRPCClientOptions<TRouter>;
|
|
47
59
|
}): DecoratedProcedureRecord<TRouter["_def"]["record"], TRouter>;
|
|
48
60
|
|
|
49
|
-
export { createTRPCVueQueryClient };
|
|
61
|
+
export { type TRPCQueryKey, createTRPCVueQueryClient };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,49 +1,61 @@
|
|
|
1
|
-
import { QueryKey, UseQueryOptions, UseQueryReturnType, QueryClient, UseMutationOptions, UseMutationReturnType } from '@tanstack/vue-query';
|
|
2
|
-
import { TRPCClientErrorLike, TRPCRequestOptions, CreateTRPCClientOptions } from '@trpc/client';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { QueryKey, UseQueryOptions, UseQueryReturnType, QueryClient, InfiniteData, UseInfiniteQueryOptions, InitialPageParam, UseInfiniteQueryReturnType, UseMutationOptions, UseMutationReturnType } from '@tanstack/vue-query';
|
|
2
|
+
import { TRPCClientErrorLike, TRPCRequestOptions, OperationContext, CreateTRPCClientOptions } from '@trpc/client';
|
|
3
|
+
import { AnyTRPCRouter, AnyTRPCProcedure, AnyTRPCQueryProcedure, inferTransformedProcedureOutput, inferProcedureInput, AnyTRPCMutationProcedure, AnyTRPCSubscriptionProcedure, inferProcedureOutput } from '@trpc/server';
|
|
4
|
+
import { Unsubscribable } from '@trpc/server/observable';
|
|
5
|
+
import { ProcedureOptions } from '@trpc/server/unstable-core-do-not-import';
|
|
6
6
|
import { MaybeRefOrGetter, UnwrapRef } from 'vue';
|
|
7
7
|
|
|
8
8
|
type TRPCSubscriptionObserver<TValue, TError> = {
|
|
9
|
-
onStarted: (
|
|
9
|
+
onStarted: (opts: {
|
|
10
|
+
context: OperationContext | undefined;
|
|
11
|
+
}) => void;
|
|
10
12
|
onData: (value: TValue) => void;
|
|
11
13
|
onError: (err: TError) => void;
|
|
12
14
|
onStopped: () => void;
|
|
13
15
|
onComplete: () => void;
|
|
14
16
|
};
|
|
15
|
-
type Resolver<TProcedure extends
|
|
16
|
-
type SubscriptionResolver<TProcedure extends
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
]) => Unsubscribable;
|
|
20
|
-
type DecorateProcedure<TProcedure extends AnyProcedure, TRouter extends AnyRouter> = TProcedure extends AnyQueryProcedure ? {
|
|
21
|
-
useQuery: <TQueryFnData = inferTransformedProcedureOutput<TProcedure>, TError = TRPCClientErrorLike<TProcedure>, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(input: MaybeRefOrGetter<inferProcedureInput<TProcedure>>, opts?: MaybeRefOrGetter<Omit<UnwrapRef<UseQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>>, 'queryKey'> & {
|
|
17
|
+
type Resolver<TRouter extends AnyTRPCRouter, TProcedure extends AnyTRPCProcedure> = (input: inferProcedureInput<TProcedure>, opts?: ProcedureOptions) => Promise<inferTransformedProcedureOutput<TRouter, TProcedure>>;
|
|
18
|
+
type SubscriptionResolver<TProcedure extends AnyTRPCProcedure, TRouter extends AnyTRPCRouter> = (input: inferProcedureInput<TProcedure>, opts: ProcedureOptions & Partial<TRPCSubscriptionObserver<inferProcedureOutput<TProcedure>, TRPCClientErrorLike<TRouter>>>) => Unsubscribable;
|
|
19
|
+
type DecorateProcedure<TProcedure extends AnyTRPCProcedure, TRouter extends AnyTRPCRouter> = TProcedure extends AnyTRPCQueryProcedure ? {
|
|
20
|
+
useQuery: <TQueryFnData = inferTransformedProcedureOutput<TRouter, TProcedure>, TError = TRPCClientErrorLike<TRouter>, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(input: MaybeRefOrGetter<inferProcedureInput<TProcedure>>, opts?: MaybeRefOrGetter<Omit<UnwrapRef<UseQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>>, 'queryKey'> & {
|
|
22
21
|
trpc?: TRPCRequestOptions;
|
|
23
22
|
queryKey?: TQueryKey;
|
|
24
23
|
}>) => UseQueryReturnType<TData, TError>;
|
|
25
|
-
query: Resolver<TProcedure>;
|
|
24
|
+
query: Resolver<TRouter, TProcedure>;
|
|
26
25
|
invalidate: (input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => Promise<void>;
|
|
27
|
-
setQueryData: (updater: inferTransformedProcedureOutput<TProcedure>, input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => ReturnType<QueryClient['setQueryData']>;
|
|
26
|
+
setQueryData: (updater: inferTransformedProcedureOutput<TRouter, TProcedure>, input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => ReturnType<QueryClient['setQueryData']>;
|
|
28
27
|
key: (input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => QueryKey;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
} & (TProcedure['_def']['$types']['input'] extends {
|
|
29
|
+
cursor?: infer CursorType;
|
|
30
|
+
} ? {
|
|
31
|
+
useInfiniteQuery: <TQueryFnData = inferTransformedProcedureOutput<TRouter, TProcedure>, TError = TRPCClientErrorLike<TRouter>, TData = InfiniteData<TQueryFnData>, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(input: MaybeRefOrGetter<Omit<inferProcedureInput<TProcedure>, 'cursor'>>, opts?: MaybeRefOrGetter<Omit<UnwrapRef<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>>, 'queryKey' | keyof InitialPageParam> & {
|
|
32
|
+
trpc?: TRPCRequestOptions;
|
|
33
|
+
queryKey?: TQueryKey;
|
|
34
|
+
} & (undefined extends TProcedure['_def']['$types']['input']['cursor'] ? Partial<InitialPageParam<CursorType>> : InitialPageParam<CursorType>)>) => UseInfiniteQueryReturnType<TData, TError>;
|
|
35
|
+
} : object) : TProcedure extends AnyTRPCMutationProcedure ? {
|
|
36
|
+
mutate: Resolver<TRouter, TProcedure>;
|
|
37
|
+
useMutation: <TData = inferTransformedProcedureOutput<TRouter, TProcedure>, TError = TRPCClientErrorLike<TRouter>, TVariables = inferProcedureInput<TProcedure>, TContext = unknown>(opts?: MaybeRefOrGetter<UseMutationOptions<TData, TError, TVariables, TContext> & {
|
|
32
38
|
trpc?: TRPCRequestOptions;
|
|
33
39
|
}>) => UseMutationReturnType<TData, TError, TVariables, TContext>;
|
|
34
|
-
} : TProcedure extends
|
|
40
|
+
} : TProcedure extends AnyTRPCSubscriptionProcedure ? {
|
|
35
41
|
subscribe: SubscriptionResolver<TProcedure, TRouter>;
|
|
42
|
+
useSubscription: (input: MaybeRefOrGetter<inferProcedureInput<TProcedure>>, opts: ProcedureOptions & Partial<TRPCSubscriptionObserver<inferProcedureOutput<TProcedure>, TRPCClientErrorLike<TRouter>>>) => Unsubscribable;
|
|
36
43
|
} : never;
|
|
37
44
|
/**
|
|
38
45
|
* @internal
|
|
39
46
|
*/
|
|
40
|
-
type DecoratedProcedureRecord<TProcedures extends
|
|
41
|
-
[
|
|
47
|
+
type DecoratedProcedureRecord<TProcedures extends Record<string, any>, TRouter extends AnyTRPCRouter> = {
|
|
48
|
+
[K in keyof TProcedures]: TProcedures[K] extends AnyTRPCProcedure ? DecorateProcedure<TProcedures[K], TRouter> : DecoratedProcedureRecord<TProcedures[K], TRouter>;
|
|
42
49
|
};
|
|
43
50
|
|
|
44
|
-
|
|
51
|
+
type QueryType = 'query' | 'infinite';
|
|
52
|
+
type TRPCQueryKey = [readonly string[], {
|
|
53
|
+
input?: unknown;
|
|
54
|
+
type?: QueryType;
|
|
55
|
+
}?];
|
|
56
|
+
declare function createTRPCVueQueryClient<TRouter extends AnyTRPCRouter>({ trpc, queryClient, }: {
|
|
45
57
|
queryClient: QueryClient;
|
|
46
58
|
trpc: CreateTRPCClientOptions<TRouter>;
|
|
47
59
|
}): DecoratedProcedureRecord<TRouter["_def"]["record"], TRouter>;
|
|
48
60
|
|
|
49
|
-
export { createTRPCVueQueryClient };
|
|
61
|
+
export { type TRPCQueryKey, createTRPCVueQueryClient };
|
package/dist/index.mjs
CHANGED
|
@@ -1,65 +1,130 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import { useMutation, useQuery } from "@tanstack/vue-query";
|
|
3
2
|
import {
|
|
4
|
-
|
|
3
|
+
skipToken,
|
|
4
|
+
useInfiniteQuery,
|
|
5
|
+
useMutation,
|
|
6
|
+
useQuery
|
|
7
|
+
} from "@tanstack/vue-query";
|
|
8
|
+
import {
|
|
9
|
+
createTRPCUntypedClient
|
|
5
10
|
} from "@trpc/client";
|
|
6
|
-
import {
|
|
11
|
+
import { createTRPCFlatProxy } from "@trpc/server";
|
|
12
|
+
import { createRecursiveProxy } from "@trpc/server/unstable-core-do-not-import";
|
|
7
13
|
import { toRef, toRefs, toValue } from "@vueuse/core";
|
|
8
|
-
import { computed, isReactive } from "vue";
|
|
9
|
-
function getQueryKey(path, input) {
|
|
10
|
-
|
|
14
|
+
import { computed, isReactive, onScopeDispose, shallowRef, watch } from "vue";
|
|
15
|
+
function getQueryKey(path, input, type) {
|
|
16
|
+
const splitPath = path.flatMap((part) => part.split("."));
|
|
17
|
+
if (input === void 0 && !type) {
|
|
18
|
+
return splitPath.length > 0 ? [splitPath] : [];
|
|
19
|
+
}
|
|
20
|
+
return [
|
|
21
|
+
splitPath,
|
|
22
|
+
{
|
|
23
|
+
...input !== void 0 && input !== skipToken && { input },
|
|
24
|
+
...type && { type }
|
|
25
|
+
}
|
|
26
|
+
];
|
|
11
27
|
}
|
|
12
28
|
function maybeToRefs(obj) {
|
|
13
29
|
return isReactive(obj) ? toRefs(obj) : toRefs(toRef(obj));
|
|
14
30
|
}
|
|
15
|
-
function createVueQueryProxyDecoration(name,
|
|
16
|
-
return createRecursiveProxy((
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const lastProperty = path.pop();
|
|
31
|
+
function createVueQueryProxyDecoration(name, trpc, queryClient) {
|
|
32
|
+
return createRecursiveProxy(({ args, path: _path }) => {
|
|
33
|
+
const path = [name, ..._path];
|
|
34
|
+
const prop = path.pop();
|
|
20
35
|
const joinedPath = path.join(".");
|
|
21
|
-
const [
|
|
22
|
-
|
|
36
|
+
const [firstArg, ...rest] = args;
|
|
37
|
+
const opts = rest[0] || {};
|
|
38
|
+
if (prop === "_def") {
|
|
23
39
|
return { path };
|
|
24
40
|
}
|
|
25
|
-
if (
|
|
26
|
-
|
|
41
|
+
if (prop === "query") {
|
|
42
|
+
return trpc.query(joinedPath, firstArg, opts);
|
|
43
|
+
}
|
|
44
|
+
if (prop === "useQuery") {
|
|
45
|
+
const { trpc: trpcOptions, ...queryOptions } = opts;
|
|
27
46
|
return useQuery({
|
|
28
|
-
queryKey: computed(() => getQueryKey(path, toValue(
|
|
29
|
-
queryFn: ({ queryKey, signal }) =>
|
|
47
|
+
queryKey: computed(() => getQueryKey(path, toValue(firstArg), "query")),
|
|
48
|
+
queryFn: async ({ queryKey, signal }) => trpc.query(joinedPath, queryKey[1]?.input, {
|
|
30
49
|
signal,
|
|
31
|
-
...
|
|
50
|
+
...trpcOptions
|
|
32
51
|
}),
|
|
33
52
|
...maybeToRefs(queryOptions)
|
|
34
53
|
});
|
|
35
54
|
}
|
|
36
|
-
if (
|
|
55
|
+
if (prop === "invalidate") {
|
|
37
56
|
return queryClient.invalidateQueries({
|
|
38
|
-
queryKey: getQueryKey(path, toValue(
|
|
57
|
+
queryKey: getQueryKey(path, toValue(firstArg), "query")
|
|
39
58
|
});
|
|
40
59
|
}
|
|
41
|
-
if (
|
|
42
|
-
return queryClient.setQueryData(getQueryKey(path, toValue(
|
|
60
|
+
if (prop === "setQueryData") {
|
|
61
|
+
return queryClient.setQueryData(getQueryKey(path, toValue(opts), "query"), firstArg);
|
|
43
62
|
}
|
|
44
|
-
if (
|
|
45
|
-
return getQueryKey(path, toValue(
|
|
63
|
+
if (prop === "key") {
|
|
64
|
+
return getQueryKey(path, toValue(firstArg), "query");
|
|
46
65
|
}
|
|
47
|
-
if (
|
|
48
|
-
|
|
66
|
+
if (prop === "mutate") {
|
|
67
|
+
return trpc.mutation(joinedPath, firstArg, opts);
|
|
68
|
+
}
|
|
69
|
+
if (prop === "useMutation") {
|
|
70
|
+
const { trpc: trpcOptions, ...mutationOptions } = firstArg || {};
|
|
49
71
|
return useMutation({
|
|
50
|
-
|
|
51
|
-
|
|
72
|
+
mutationKey: computed(() => getQueryKey(path, void 0)),
|
|
73
|
+
mutationFn: async (payload) => trpc.mutation(joinedPath, payload, {
|
|
74
|
+
...trpcOptions
|
|
52
75
|
}),
|
|
53
76
|
...maybeToRefs(mutationOptions)
|
|
54
77
|
});
|
|
55
78
|
}
|
|
56
|
-
|
|
79
|
+
if (prop === "subscribe") {
|
|
80
|
+
return trpc.subscription(joinedPath, firstArg, opts);
|
|
81
|
+
}
|
|
82
|
+
if (prop === "useSubscription") {
|
|
83
|
+
const inputData = toRef(firstArg);
|
|
84
|
+
const subscription = shallowRef();
|
|
85
|
+
watch(
|
|
86
|
+
inputData,
|
|
87
|
+
() => {
|
|
88
|
+
subscription.value?.unsubscribe();
|
|
89
|
+
subscription.value = trpc.subscription(joinedPath, inputData.value, {
|
|
90
|
+
...opts
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
{ immediate: true }
|
|
94
|
+
);
|
|
95
|
+
onScopeDispose(() => {
|
|
96
|
+
subscription.value?.unsubscribe();
|
|
97
|
+
}, true);
|
|
98
|
+
return subscription.value;
|
|
99
|
+
}
|
|
100
|
+
if (prop === "useInfiniteQuery") {
|
|
101
|
+
const { trpc: trpcOptions, ...queryOptions } = opts;
|
|
102
|
+
return useInfiniteQuery({
|
|
103
|
+
queryKey: computed(() => getQueryKey(path, toValue(firstArg), "infinite")),
|
|
104
|
+
queryFn: async ({ queryKey, pageParam, signal }) => trpc.query(
|
|
105
|
+
joinedPath,
|
|
106
|
+
{
|
|
107
|
+
...queryKey[1]?.input,
|
|
108
|
+
cursor: pageParam
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
signal,
|
|
112
|
+
...trpcOptions
|
|
113
|
+
}
|
|
114
|
+
),
|
|
115
|
+
...maybeToRefs(queryOptions)
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
throw new Error(`Method '.${prop}()' not supported`);
|
|
57
119
|
});
|
|
58
120
|
}
|
|
59
|
-
function createTRPCVueQueryClient(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
121
|
+
function createTRPCVueQueryClient({
|
|
122
|
+
trpc,
|
|
123
|
+
queryClient
|
|
124
|
+
}) {
|
|
125
|
+
const client = createTRPCUntypedClient(trpc);
|
|
126
|
+
const decoratedClient = createTRPCFlatProxy((key) => {
|
|
127
|
+
return createVueQueryProxyDecoration(key, client, queryClient);
|
|
63
128
|
});
|
|
64
129
|
return decoratedClient;
|
|
65
130
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@falcondev-oss/trpc-vue-query",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
5
|
-
"packageManager": "pnpm@8.15.3",
|
|
4
|
+
"version": "0.5.0-rc.1",
|
|
6
5
|
"description": "A tRPC wrapper around '@tanstack/vue-query'",
|
|
7
6
|
"license": "MIT",
|
|
8
7
|
"repository": "github:falcondev-oss/trpc-vue-query",
|
|
@@ -22,6 +21,10 @@
|
|
|
22
21
|
"files": [
|
|
23
22
|
"dist"
|
|
24
23
|
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": "20",
|
|
26
|
+
"pnpm": "9"
|
|
27
|
+
},
|
|
25
28
|
"peerDependencies": {
|
|
26
29
|
"@tanstack/vue-query": "^5.22.2",
|
|
27
30
|
"@trpc/client": "^10.45.1",
|
|
@@ -29,33 +32,35 @@
|
|
|
29
32
|
"vue": "^3.4.19"
|
|
30
33
|
},
|
|
31
34
|
"dependencies": {
|
|
32
|
-
"@vueuse/core": "^
|
|
35
|
+
"@vueuse/core": "^11.1.0"
|
|
33
36
|
},
|
|
34
37
|
"devDependencies": {
|
|
35
|
-
"@commitlint/cli": "^19.
|
|
36
|
-
"@eslint/eslintrc": "^3.0
|
|
37
|
-
"@louishaftmann/commitlint-config": "^
|
|
38
|
-
"@louishaftmann/eslint-config": "^
|
|
39
|
-
"@louishaftmann/lintstaged-config": "^
|
|
40
|
-
"@louishaftmann/prettier-config": "^
|
|
41
|
-
"@tanstack/vue-query": "^5.
|
|
42
|
-
"@trpc/client": "
|
|
43
|
-
"@trpc/server": "
|
|
44
|
-
"@types/eslint": "^
|
|
45
|
-
"@types/eslint__eslintrc": "^2.1.
|
|
46
|
-
"@
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"husky": "^9.
|
|
50
|
-
"lint-staged": "^15.2.
|
|
51
|
-
"prettier": "^3.
|
|
52
|
-
"start-server-and-test": "^2.0.
|
|
53
|
-
"tsup": "^8.0
|
|
54
|
-
"tsx": "^4.
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"vue
|
|
38
|
+
"@commitlint/cli": "^19.5.0",
|
|
39
|
+
"@eslint/eslintrc": "^3.1.0",
|
|
40
|
+
"@louishaftmann/commitlint-config": "^4.0.3",
|
|
41
|
+
"@louishaftmann/eslint-config": "^4.0.3",
|
|
42
|
+
"@louishaftmann/lintstaged-config": "^4.0.3",
|
|
43
|
+
"@louishaftmann/prettier-config": "^4.0.3",
|
|
44
|
+
"@tanstack/vue-query": "^5.56.2",
|
|
45
|
+
"@trpc/client": "11.0.0-rc.490",
|
|
46
|
+
"@trpc/server": "11.0.0-rc.490",
|
|
47
|
+
"@types/eslint": "^9.6.1",
|
|
48
|
+
"@types/eslint__eslintrc": "^2.1.2",
|
|
49
|
+
"@types/ws": "^8.5.12",
|
|
50
|
+
"@vitest/ui": "^2.1.1",
|
|
51
|
+
"eslint": "^9.11.0",
|
|
52
|
+
"husky": "^9.1.6",
|
|
53
|
+
"lint-staged": "^15.2.10",
|
|
54
|
+
"prettier": "^3.3.3",
|
|
55
|
+
"start-server-and-test": "^2.0.8",
|
|
56
|
+
"tsup": "^8.3.0",
|
|
57
|
+
"tsx": "^4.19.1",
|
|
58
|
+
"type-fest": "^4.26.1",
|
|
59
|
+
"typescript": "^5.6.2",
|
|
60
|
+
"vitest": "^2.1.1",
|
|
61
|
+
"vue": "^3.5.7",
|
|
62
|
+
"ws": "^8.18.0",
|
|
63
|
+
"zod": "^3.23.8"
|
|
59
64
|
},
|
|
60
65
|
"changelogithub": {
|
|
61
66
|
"extends": "gh:falcondev-it/configs/changelogithub"
|