@falcondev-oss/trpc-vue-query 0.5.0-rc.0 → 0.5.0-rc.2

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 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() {
@@ -116,6 +118,7 @@ Setup `trpc-nuxt` as described in their [documentation](https://trpc-nuxt.vercel
116
118
  import { createTRPCVueQueryClient } from '@falcondev-oss/trpc-vue-query'
117
119
  import { useQueryClient } from '@tanstack/vue-query'
118
120
  import { httpBatchLink } from 'trpc-nuxt/client'
121
+
119
122
  import type { AppRouter } from '~/server/trpc/routers'
120
123
 
121
124
  export default defineNuxtPlugin(() => {
@@ -149,4 +152,4 @@ export function useTRPC() {
149
152
 
150
153
  ## Acknowledgements
151
154
 
152
- Huge thanks to [Robert Soriano](https://github.com/wobsoriano) for creating `nuxt-trpc`! We just adapted his work to work with Vue Query.
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
@@ -29,60 +29,119 @@ var import_server = require("@trpc/server");
29
29
  var import_unstable_core_do_not_import = require("@trpc/server/unstable-core-do-not-import");
30
30
  var import_core = require("@vueuse/core");
31
31
  var import_vue = require("vue");
32
- function getQueryKey(path, input) {
33
- return input === void 0 ? path : [...path, input];
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
+ ];
34
44
  }
35
45
  function maybeToRefs(obj) {
36
46
  return (0, import_vue.isReactive)(obj) ? (0, import_core.toRefs)(obj) : (0, import_core.toRefs)((0, import_core.toRef)(obj));
37
47
  }
38
- function createVueQueryProxyDecoration(name, client, queryClient) {
39
- return (0, import_unstable_core_do_not_import.createRecursiveProxy)((opts) => {
40
- const args = opts.args;
41
- const path = [name, ...opts.path];
42
- 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();
43
52
  const joinedPath = path.join(".");
44
- const [firstParam, secondParam] = args;
45
- if (lastProperty === "_def") {
53
+ const [firstArg, ...rest] = args;
54
+ const opts = rest[0] || {};
55
+ if (prop === "_def") {
46
56
  return { path };
47
57
  }
48
- if (lastProperty === "useQuery") {
49
- const { trpc, ...queryOptions } = secondParam || {};
58
+ if (prop === "query") {
59
+ return trpc.query(joinedPath, firstArg, opts);
60
+ }
61
+ if (prop === "useQuery") {
62
+ const { trpc: trpcOptions, ...queryOptions } = opts;
50
63
  return (0, import_vue_query.useQuery)({
51
- queryKey: (0, import_vue.computed)(() => getQueryKey(path, (0, import_core.toValue)(firstParam))),
52
- queryFn: ({ queryKey, signal }) => client[joinedPath].query(queryKey.at(-1), {
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, {
53
66
  signal,
54
- ...trpc
67
+ ...trpcOptions
55
68
  }),
56
69
  ...maybeToRefs(queryOptions)
57
70
  });
58
71
  }
59
- if (lastProperty === "invalidate") {
72
+ if (prop === "invalidate") {
60
73
  return queryClient.invalidateQueries({
61
- queryKey: getQueryKey(path, (0, import_core.toValue)(firstParam))
74
+ queryKey: getQueryKey(path, (0, import_core.toValue)(firstArg), "query")
62
75
  });
63
76
  }
64
- if (lastProperty === "setQueryData") {
65
- return queryClient.setQueryData(getQueryKey(path, (0, import_core.toValue)(secondParam)), firstParam);
77
+ if (prop === "setQueryData") {
78
+ return queryClient.setQueryData(getQueryKey(path, (0, import_core.toValue)(opts), "query"), firstArg);
66
79
  }
67
- if (lastProperty === "key") {
68
- return getQueryKey(path, (0, import_core.toValue)(firstParam));
80
+ if (prop === "key") {
81
+ return getQueryKey(path, (0, import_core.toValue)(firstArg), "query");
69
82
  }
70
- if (lastProperty === "useMutation") {
71
- const { trpc, ...mutationOptions } = firstParam || {};
83
+ if (prop === "mutate") {
84
+ return trpc.mutation(joinedPath, firstArg, opts);
85
+ }
86
+ if (prop === "useMutation") {
87
+ const { trpc: trpcOptions, ...mutationOptions } = firstArg || {};
72
88
  return (0, import_vue_query.useMutation)({
73
- mutationFn: (payload) => client[joinedPath].mutate(payload, {
74
- ...trpc
89
+ mutationKey: (0, import_vue.computed)(() => getQueryKey(path, void 0)),
90
+ mutationFn: async (payload) => trpc.mutation(joinedPath, payload, {
91
+ ...trpcOptions
75
92
  }),
76
93
  ...maybeToRefs(mutationOptions)
77
94
  });
78
95
  }
79
- return client[joinedPath][lastProperty](...args);
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`);
80
136
  });
81
137
  }
82
- function createTRPCVueQueryClient(opts) {
83
- const client = (0, import_client.createTRPCClient)(opts.trpc);
138
+ function createTRPCVueQueryClient({
139
+ trpc,
140
+ queryClient
141
+ }) {
142
+ const client = (0, import_client.createTRPCUntypedClient)(trpc);
84
143
  const decoratedClient = (0, import_server.createTRPCFlatProxy)((key) => {
85
- return createVueQueryProxyDecoration(key, client, opts.queryClient);
144
+ return createVueQueryProxyDecoration(key, client, queryClient);
86
145
  });
87
146
  return decoratedClient;
88
147
  }
package/dist/index.d.cts CHANGED
@@ -1,36 +1,47 @@
1
- import { QueryKey, UseQueryOptions, UseQueryReturnType, QueryClient, UseMutationOptions, UseMutationReturnType } from '@tanstack/vue-query';
2
- import { TRPCClientErrorLike, TRPCRequestOptions, CreateTRPCClientOptions } from '@trpc/client';
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
3
  import { AnyTRPCRouter, AnyTRPCProcedure, AnyTRPCQueryProcedure, inferTransformedProcedureOutput, inferProcedureInput, AnyTRPCMutationProcedure, AnyTRPCSubscriptionProcedure, inferProcedureOutput } from '@trpc/server';
4
- import { inferObservableValue, Unsubscribable } from '@trpc/server/observable';
4
+ import { Unsubscribable } from '@trpc/server/observable';
5
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: () => void;
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<TRouter extends AnyTRPCRouter, TProcedure extends AnyTRPCProcedure> = (input: inferProcedureInput<TProcedure>, opts?: ProcedureOptions) => Promise<inferTransformedProcedureOutput<TRouter, TProcedure>>;
16
- type SubscriptionResolver<TProcedure extends AnyTRPCProcedure, TRouter extends AnyTRPCRouter> = (input: inferProcedureInput<TProcedure>, opts: ProcedureOptions & Partial<TRPCSubscriptionObserver<inferObservableValue<inferProcedureOutput<TProcedure>>, TRPCClientErrorLike<TRouter>>>) => Unsubscribable;
17
+ type Exact<Shape, T extends Shape> = {
18
+ [Key in keyof T]: Key extends keyof Shape ? T[Key] extends Date ? T[Key] : T[Key] extends object ? Exact<Shape[Key], T[Key]> : T[Key] : never;
19
+ };
17
20
  type DecorateProcedure<TProcedure extends AnyTRPCProcedure, TRouter extends AnyTRPCRouter> = TProcedure extends AnyTRPCQueryProcedure ? {
18
- 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'> & {
21
+ useQuery: <TQueryFnData extends inferTransformedProcedureOutput<TRouter, TProcedure>, TError extends TRPCClientErrorLike<TRouter>, TData extends TQueryFnData, TQueryData extends TQueryFnData, TQueryKey extends QueryKey, TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input: MaybeRefOrGetter<Exact<TInput, TTInput>>, opts?: MaybeRefOrGetter<Omit<UnwrapRef<UseQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>>, 'queryKey'> & {
19
22
  trpc?: TRPCRequestOptions;
20
23
  queryKey?: TQueryKey;
21
24
  }>) => UseQueryReturnType<TData, TError>;
22
- query: Resolver<TRouter, TProcedure>;
23
- invalidate: (input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => Promise<void>;
24
- setQueryData: (updater: inferTransformedProcedureOutput<TRouter, TProcedure>, input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => ReturnType<QueryClient['setQueryData']>;
25
- key: (input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => QueryKey;
26
- } : TProcedure extends AnyTRPCMutationProcedure ? {
27
- mutate: Resolver<TRouter, TProcedure>;
25
+ query: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input: Exact<TInput, TTInput>, opts?: ProcedureOptions) => Promise<inferTransformedProcedureOutput<TRouter, TProcedure>>;
26
+ invalidate: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input?: MaybeRefOrGetter<Exact<TInput, TTInput>>) => Promise<void>;
27
+ setQueryData: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(updater: inferTransformedProcedureOutput<TRouter, TProcedure>, input?: MaybeRefOrGetter<Exact<TInput, TTInput>>) => ReturnType<QueryClient['setQueryData']>;
28
+ key: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input?: MaybeRefOrGetter<Exact<TInput, TTInput>>) => QueryKey;
29
+ } & (TProcedure['_def']['$types']['input'] extends {
30
+ cursor?: infer CursorType;
31
+ } ? {
32
+ useInfiniteQuery: <TQueryFnData extends inferTransformedProcedureOutput<TRouter, TProcedure>, TError extends TRPCClientErrorLike<TRouter>, TData extends InfiniteData<TQueryFnData>, TQueryData extends TQueryFnData, TQueryKey extends QueryKey, TInput extends Omit<inferProcedureInput<TProcedure>, 'cursor'>, TTInput extends TInput>(input: MaybeRefOrGetter<Exact<TInput, TTInput>>, opts?: MaybeRefOrGetter<Omit<UnwrapRef<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>>, 'queryKey' | keyof InitialPageParam> & {
33
+ trpc?: TRPCRequestOptions;
34
+ queryKey?: TQueryKey;
35
+ } & (undefined extends TProcedure['_def']['$types']['input']['cursor'] ? Partial<InitialPageParam<CursorType>> : InitialPageParam<CursorType>)>) => UseInfiniteQueryReturnType<TData, TError>;
36
+ } : object) : TProcedure extends AnyTRPCMutationProcedure ? {
37
+ mutate: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input: Exact<TInput, TTInput>, opts?: ProcedureOptions) => Promise<inferTransformedProcedureOutput<TRouter, TProcedure>>;
28
38
  useMutation: <TData = inferTransformedProcedureOutput<TRouter, TProcedure>, TError = TRPCClientErrorLike<TRouter>, TVariables = inferProcedureInput<TProcedure>, TContext = unknown>(opts?: MaybeRefOrGetter<UseMutationOptions<TData, TError, TVariables, TContext> & {
29
39
  trpc?: TRPCRequestOptions;
30
40
  }>) => UseMutationReturnType<TData, TError, TVariables, TContext>;
31
41
  } : TProcedure extends AnyTRPCSubscriptionProcedure ? {
32
- subscribe: SubscriptionResolver<TProcedure, TRouter>;
33
- } : 'test';
42
+ subscribe: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input: Exact<TInput, TTInput>, opts: ProcedureOptions & Partial<TRPCSubscriptionObserver<inferProcedureOutput<TProcedure>, TRPCClientErrorLike<TRouter>>>) => Unsubscribable;
43
+ useSubscription: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input: MaybeRefOrGetter<Exact<TInput, TTInput>>, opts: ProcedureOptions & Partial<TRPCSubscriptionObserver<inferProcedureOutput<TProcedure>, TRPCClientErrorLike<TRouter>>>) => Unsubscribable;
44
+ } : never;
34
45
  /**
35
46
  * @internal
36
47
  */
@@ -38,9 +49,14 @@ type DecoratedProcedureRecord<TProcedures extends Record<string, any>, TRouter e
38
49
  [K in keyof TProcedures]: TProcedures[K] extends AnyTRPCProcedure ? DecorateProcedure<TProcedures[K], TRouter> : DecoratedProcedureRecord<TProcedures[K], TRouter>;
39
50
  };
40
51
 
41
- declare function createTRPCVueQueryClient<TRouter extends AnyTRPCRouter>(opts: {
52
+ type QueryType = 'query' | 'infinite';
53
+ type TRPCQueryKey = [readonly string[], {
54
+ input?: unknown;
55
+ type?: QueryType;
56
+ }?];
57
+ declare function createTRPCVueQueryClient<TRouter extends AnyTRPCRouter>({ trpc, queryClient, }: {
42
58
  queryClient: QueryClient;
43
59
  trpc: CreateTRPCClientOptions<TRouter>;
44
60
  }): DecoratedProcedureRecord<TRouter["_def"]["record"], TRouter>;
45
61
 
46
- export { createTRPCVueQueryClient };
62
+ export { type TRPCQueryKey, createTRPCVueQueryClient };
package/dist/index.d.ts CHANGED
@@ -1,36 +1,47 @@
1
- import { QueryKey, UseQueryOptions, UseQueryReturnType, QueryClient, UseMutationOptions, UseMutationReturnType } from '@tanstack/vue-query';
2
- import { TRPCClientErrorLike, TRPCRequestOptions, CreateTRPCClientOptions } from '@trpc/client';
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
3
  import { AnyTRPCRouter, AnyTRPCProcedure, AnyTRPCQueryProcedure, inferTransformedProcedureOutput, inferProcedureInput, AnyTRPCMutationProcedure, AnyTRPCSubscriptionProcedure, inferProcedureOutput } from '@trpc/server';
4
- import { inferObservableValue, Unsubscribable } from '@trpc/server/observable';
4
+ import { Unsubscribable } from '@trpc/server/observable';
5
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: () => void;
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<TRouter extends AnyTRPCRouter, TProcedure extends AnyTRPCProcedure> = (input: inferProcedureInput<TProcedure>, opts?: ProcedureOptions) => Promise<inferTransformedProcedureOutput<TRouter, TProcedure>>;
16
- type SubscriptionResolver<TProcedure extends AnyTRPCProcedure, TRouter extends AnyTRPCRouter> = (input: inferProcedureInput<TProcedure>, opts: ProcedureOptions & Partial<TRPCSubscriptionObserver<inferObservableValue<inferProcedureOutput<TProcedure>>, TRPCClientErrorLike<TRouter>>>) => Unsubscribable;
17
+ type Exact<Shape, T extends Shape> = {
18
+ [Key in keyof T]: Key extends keyof Shape ? T[Key] extends Date ? T[Key] : T[Key] extends object ? Exact<Shape[Key], T[Key]> : T[Key] : never;
19
+ };
17
20
  type DecorateProcedure<TProcedure extends AnyTRPCProcedure, TRouter extends AnyTRPCRouter> = TProcedure extends AnyTRPCQueryProcedure ? {
18
- 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'> & {
21
+ useQuery: <TQueryFnData extends inferTransformedProcedureOutput<TRouter, TProcedure>, TError extends TRPCClientErrorLike<TRouter>, TData extends TQueryFnData, TQueryData extends TQueryFnData, TQueryKey extends QueryKey, TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input: MaybeRefOrGetter<Exact<TInput, TTInput>>, opts?: MaybeRefOrGetter<Omit<UnwrapRef<UseQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>>, 'queryKey'> & {
19
22
  trpc?: TRPCRequestOptions;
20
23
  queryKey?: TQueryKey;
21
24
  }>) => UseQueryReturnType<TData, TError>;
22
- query: Resolver<TRouter, TProcedure>;
23
- invalidate: (input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => Promise<void>;
24
- setQueryData: (updater: inferTransformedProcedureOutput<TRouter, TProcedure>, input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => ReturnType<QueryClient['setQueryData']>;
25
- key: (input?: MaybeRefOrGetter<inferProcedureInput<TProcedure>>) => QueryKey;
26
- } : TProcedure extends AnyTRPCMutationProcedure ? {
27
- mutate: Resolver<TRouter, TProcedure>;
25
+ query: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input: Exact<TInput, TTInput>, opts?: ProcedureOptions) => Promise<inferTransformedProcedureOutput<TRouter, TProcedure>>;
26
+ invalidate: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input?: MaybeRefOrGetter<Exact<TInput, TTInput>>) => Promise<void>;
27
+ setQueryData: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(updater: inferTransformedProcedureOutput<TRouter, TProcedure>, input?: MaybeRefOrGetter<Exact<TInput, TTInput>>) => ReturnType<QueryClient['setQueryData']>;
28
+ key: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input?: MaybeRefOrGetter<Exact<TInput, TTInput>>) => QueryKey;
29
+ } & (TProcedure['_def']['$types']['input'] extends {
30
+ cursor?: infer CursorType;
31
+ } ? {
32
+ useInfiniteQuery: <TQueryFnData extends inferTransformedProcedureOutput<TRouter, TProcedure>, TError extends TRPCClientErrorLike<TRouter>, TData extends InfiniteData<TQueryFnData>, TQueryData extends TQueryFnData, TQueryKey extends QueryKey, TInput extends Omit<inferProcedureInput<TProcedure>, 'cursor'>, TTInput extends TInput>(input: MaybeRefOrGetter<Exact<TInput, TTInput>>, opts?: MaybeRefOrGetter<Omit<UnwrapRef<UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>>, 'queryKey' | keyof InitialPageParam> & {
33
+ trpc?: TRPCRequestOptions;
34
+ queryKey?: TQueryKey;
35
+ } & (undefined extends TProcedure['_def']['$types']['input']['cursor'] ? Partial<InitialPageParam<CursorType>> : InitialPageParam<CursorType>)>) => UseInfiniteQueryReturnType<TData, TError>;
36
+ } : object) : TProcedure extends AnyTRPCMutationProcedure ? {
37
+ mutate: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input: Exact<TInput, TTInput>, opts?: ProcedureOptions) => Promise<inferTransformedProcedureOutput<TRouter, TProcedure>>;
28
38
  useMutation: <TData = inferTransformedProcedureOutput<TRouter, TProcedure>, TError = TRPCClientErrorLike<TRouter>, TVariables = inferProcedureInput<TProcedure>, TContext = unknown>(opts?: MaybeRefOrGetter<UseMutationOptions<TData, TError, TVariables, TContext> & {
29
39
  trpc?: TRPCRequestOptions;
30
40
  }>) => UseMutationReturnType<TData, TError, TVariables, TContext>;
31
41
  } : TProcedure extends AnyTRPCSubscriptionProcedure ? {
32
- subscribe: SubscriptionResolver<TProcedure, TRouter>;
33
- } : 'test';
42
+ subscribe: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input: Exact<TInput, TTInput>, opts: ProcedureOptions & Partial<TRPCSubscriptionObserver<inferProcedureOutput<TProcedure>, TRPCClientErrorLike<TRouter>>>) => Unsubscribable;
43
+ useSubscription: <TInput extends inferProcedureInput<TProcedure>, TTInput extends TInput>(input: MaybeRefOrGetter<Exact<TInput, TTInput>>, opts: ProcedureOptions & Partial<TRPCSubscriptionObserver<inferProcedureOutput<TProcedure>, TRPCClientErrorLike<TRouter>>>) => Unsubscribable;
44
+ } : never;
34
45
  /**
35
46
  * @internal
36
47
  */
@@ -38,9 +49,14 @@ type DecoratedProcedureRecord<TProcedures extends Record<string, any>, TRouter e
38
49
  [K in keyof TProcedures]: TProcedures[K] extends AnyTRPCProcedure ? DecorateProcedure<TProcedures[K], TRouter> : DecoratedProcedureRecord<TProcedures[K], TRouter>;
39
50
  };
40
51
 
41
- declare function createTRPCVueQueryClient<TRouter extends AnyTRPCRouter>(opts: {
52
+ type QueryType = 'query' | 'infinite';
53
+ type TRPCQueryKey = [readonly string[], {
54
+ input?: unknown;
55
+ type?: QueryType;
56
+ }?];
57
+ declare function createTRPCVueQueryClient<TRouter extends AnyTRPCRouter>({ trpc, queryClient, }: {
42
58
  queryClient: QueryClient;
43
59
  trpc: CreateTRPCClientOptions<TRouter>;
44
60
  }): DecoratedProcedureRecord<TRouter["_def"]["record"], TRouter>;
45
61
 
46
- export { createTRPCVueQueryClient };
62
+ export { type TRPCQueryKey, createTRPCVueQueryClient };
package/dist/index.mjs CHANGED
@@ -1,66 +1,130 @@
1
1
  // src/index.ts
2
- import { useMutation, useQuery } from "@tanstack/vue-query";
3
2
  import {
4
- createTRPCClient
3
+ skipToken,
4
+ useInfiniteQuery,
5
+ useMutation,
6
+ useQuery
7
+ } from "@tanstack/vue-query";
8
+ import {
9
+ createTRPCUntypedClient
5
10
  } from "@trpc/client";
6
11
  import { createTRPCFlatProxy } from "@trpc/server";
7
12
  import { createRecursiveProxy } from "@trpc/server/unstable-core-do-not-import";
8
13
  import { toRef, toRefs, toValue } from "@vueuse/core";
9
- import { computed, isReactive } from "vue";
10
- function getQueryKey(path, input) {
11
- return input === void 0 ? path : [...path, input];
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
+ ];
12
27
  }
13
28
  function maybeToRefs(obj) {
14
29
  return isReactive(obj) ? toRefs(obj) : toRefs(toRef(obj));
15
30
  }
16
- function createVueQueryProxyDecoration(name, client, queryClient) {
17
- return createRecursiveProxy((opts) => {
18
- const args = opts.args;
19
- const path = [name, ...opts.path];
20
- 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();
21
35
  const joinedPath = path.join(".");
22
- const [firstParam, secondParam] = args;
23
- if (lastProperty === "_def") {
36
+ const [firstArg, ...rest] = args;
37
+ const opts = rest[0] || {};
38
+ if (prop === "_def") {
24
39
  return { path };
25
40
  }
26
- if (lastProperty === "useQuery") {
27
- const { trpc, ...queryOptions } = secondParam || {};
41
+ if (prop === "query") {
42
+ return trpc.query(joinedPath, firstArg, opts);
43
+ }
44
+ if (prop === "useQuery") {
45
+ const { trpc: trpcOptions, ...queryOptions } = opts;
28
46
  return useQuery({
29
- queryKey: computed(() => getQueryKey(path, toValue(firstParam))),
30
- queryFn: ({ queryKey, signal }) => client[joinedPath].query(queryKey.at(-1), {
47
+ queryKey: computed(() => getQueryKey(path, toValue(firstArg), "query")),
48
+ queryFn: async ({ queryKey, signal }) => trpc.query(joinedPath, queryKey[1]?.input, {
31
49
  signal,
32
- ...trpc
50
+ ...trpcOptions
33
51
  }),
34
52
  ...maybeToRefs(queryOptions)
35
53
  });
36
54
  }
37
- if (lastProperty === "invalidate") {
55
+ if (prop === "invalidate") {
38
56
  return queryClient.invalidateQueries({
39
- queryKey: getQueryKey(path, toValue(firstParam))
57
+ queryKey: getQueryKey(path, toValue(firstArg), "query")
40
58
  });
41
59
  }
42
- if (lastProperty === "setQueryData") {
43
- return queryClient.setQueryData(getQueryKey(path, toValue(secondParam)), firstParam);
60
+ if (prop === "setQueryData") {
61
+ return queryClient.setQueryData(getQueryKey(path, toValue(opts), "query"), firstArg);
44
62
  }
45
- if (lastProperty === "key") {
46
- return getQueryKey(path, toValue(firstParam));
63
+ if (prop === "key") {
64
+ return getQueryKey(path, toValue(firstArg), "query");
47
65
  }
48
- if (lastProperty === "useMutation") {
49
- const { trpc, ...mutationOptions } = firstParam || {};
66
+ if (prop === "mutate") {
67
+ return trpc.mutation(joinedPath, firstArg, opts);
68
+ }
69
+ if (prop === "useMutation") {
70
+ const { trpc: trpcOptions, ...mutationOptions } = firstArg || {};
50
71
  return useMutation({
51
- mutationFn: (payload) => client[joinedPath].mutate(payload, {
52
- ...trpc
72
+ mutationKey: computed(() => getQueryKey(path, void 0)),
73
+ mutationFn: async (payload) => trpc.mutation(joinedPath, payload, {
74
+ ...trpcOptions
53
75
  }),
54
76
  ...maybeToRefs(mutationOptions)
55
77
  });
56
78
  }
57
- return client[joinedPath][lastProperty](...args);
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`);
58
119
  });
59
120
  }
60
- function createTRPCVueQueryClient(opts) {
61
- const client = createTRPCClient(opts.trpc);
121
+ function createTRPCVueQueryClient({
122
+ trpc,
123
+ queryClient
124
+ }) {
125
+ const client = createTRPCUntypedClient(trpc);
62
126
  const decoratedClient = createTRPCFlatProxy((key) => {
63
- return createVueQueryProxyDecoration(key, client, opts.queryClient);
127
+ return createVueQueryProxyDecoration(key, client, queryClient);
64
128
  });
65
129
  return decoratedClient;
66
130
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@falcondev-oss/trpc-vue-query",
3
3
  "type": "module",
4
- "version": "0.5.0-rc.0",
4
+ "version": "0.5.0-rc.2",
5
5
  "description": "A tRPC wrapper around '@tanstack/vue-query'",
6
6
  "license": "MIT",
7
7
  "repository": "github:falcondev-oss/trpc-vue-query",
@@ -21,40 +21,46 @@
21
21
  "files": [
22
22
  "dist"
23
23
  ],
24
+ "engines": {
25
+ "node": "20",
26
+ "pnpm": "9"
27
+ },
24
28
  "peerDependencies": {
25
29
  "@tanstack/vue-query": "^5.22.2",
26
- "@trpc/client": "^10.45.1",
27
- "@trpc/server": "^10.45.1",
30
+ "@trpc/client": "11",
31
+ "@trpc/server": "11",
28
32
  "vue": "^3.4.19"
29
33
  },
30
34
  "dependencies": {
31
- "@vueuse/core": "^11.0.3"
35
+ "@vueuse/core": "^11.1.0"
32
36
  },
33
37
  "devDependencies": {
34
- "@commitlint/cli": "^19.4.1",
38
+ "@commitlint/cli": "^19.5.0",
35
39
  "@eslint/eslintrc": "^3.1.0",
36
40
  "@louishaftmann/commitlint-config": "^4.0.3",
37
41
  "@louishaftmann/eslint-config": "^4.0.3",
38
42
  "@louishaftmann/lintstaged-config": "^4.0.3",
39
43
  "@louishaftmann/prettier-config": "^4.0.3",
40
- "@tanstack/vue-query": "^5.53.1",
44
+ "@tanstack/vue-query": "^5.56.2",
41
45
  "@trpc/client": "11.0.0-rc.490",
42
46
  "@trpc/server": "11.0.0-rc.490",
43
47
  "@types/eslint": "^9.6.1",
44
48
  "@types/eslint__eslintrc": "^2.1.2",
45
- "@vitest/ui": "^2.0.5",
46
- "eslint": "^9.9.1",
47
- "happy-dom": "^15.7.2",
48
- "husky": "^9.1.5",
49
- "lint-staged": "^15.2.9",
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",
50
54
  "prettier": "^3.3.3",
51
- "start-server-and-test": "^2.0.5",
52
- "tsup": "^8.2.4",
53
- "tsx": "^4.19.0",
54
- "typescript": "^5.5.4",
55
- "vitest": "^2.0.5",
56
- "vue": "^3.4.38",
57
- "vue-demi": "^0.14.10"
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"
58
64
  },
59
65
  "changelogithub": {
60
66
  "extends": "gh:falcondev-it/configs/changelogithub"