From efe56dc44d42b1d29d2258cfd0edc0e92e5c4086 Mon Sep 17 00:00:00 2001 From: OrJDev Date: Sat, 5 Nov 2022 02:29:59 +0200 Subject: [PATCH] treat pathandinput as solid accessor --- README.MD | 9 +++ package.json | 2 +- src/createTRPCSolid.ts | 14 ++-- src/shared/hooks/createHooksInternal.tsx | 83 ++++++++++++------------ src/shared/proxy/decorationProxy.ts | 7 +- src/shared/queryClient.ts | 4 +- 6 files changed, 64 insertions(+), 55 deletions(-) diff --git a/README.MD b/README.MD index c9f622f..445896b 100644 --- a/README.MD +++ b/README.MD @@ -50,3 +50,12 @@ const App: Component = ({}) => { export default App; ``` + +### Example + +```ts +import { trpc } from "./utils/trpc"; +import { createSignal } from "solid-js"; +const [name, setName] = createSignal(""); +const res = trpc.queryName.useQuery(() => ({ name: name() })); // this will be called when name changes +``` diff --git a/package.json b/package.json index a47b360..4eba4ad 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "SolidJS tRPC", "author": "OrJDev", "license": "MIT", - "version": "0.0.3-rc.1", + "version": "0.0.4-rc.1", "publishConfig": { "access": "public", "tag": "next" diff --git a/src/createTRPCSolid.ts b/src/createTRPCSolid.ts index 81c11a5..3288d6a 100644 --- a/src/createTRPCSolid.ts +++ b/src/createTRPCSolid.ts @@ -44,8 +44,8 @@ export type DecorateProcedure< TQueryFnData = inferProcedureOutput, TData = inferProcedureOutput >( - input: inferProcedureInput, - opts?: UseTRPCQueryOptions< + input: () => inferProcedureInput, + opts?: () => UseTRPCQueryOptions< TPath, inferProcedureInput, TQueryFnData, @@ -59,8 +59,8 @@ export type DecorateProcedure< _TQueryFnData = inferProcedureOutput, TData = inferProcedureOutput >( - input: Omit, "cursor">, - opts?: UseTRPCInfiniteQueryOptions< + input: () => Omit, "cursor">, + opts?: () => UseTRPCInfiniteQueryOptions< TPath, inferProcedureInput, TData, @@ -75,7 +75,7 @@ export type DecorateProcedure< : TProcedure extends AnyMutationProcedure ? { useMutation: ( - opts?: UseTRPCMutationOptions< + opts?: () => UseTRPCMutationOptions< inferProcedureInput, TRPCClientErrorLike, inferProcedureOutput, @@ -91,8 +91,8 @@ export type DecorateProcedure< : TProcedure extends AnySubscriptionProcedure ? { useSubscription: ( - input: inferProcedureInput, - opts?: UseTRPCSubscriptionOptions< + input: () => inferProcedureInput, + opts?: () => UseTRPCSubscriptionOptions< inferObservableValue>, TRPCClientErrorLike > diff --git a/src/shared/hooks/createHooksInternal.tsx b/src/shared/hooks/createHooksInternal.tsx index 27f06fc..1099028 100644 --- a/src/shared/hooks/createHooksInternal.tsx +++ b/src/shared/hooks/createHooksInternal.tsx @@ -372,8 +372,11 @@ export function createHooksInternal< TQueryFnData = TQueryValues[TPath]["output"], TData = TQueryValues[TPath]["output"] >( - pathAndInput: [path: TPath, ...args: inferHandlerInput], - opts?: UseTRPCQueryOptions< + pathAndInput: () => [ + path: TPath, + ...args: inferHandlerInput + ], + opts?: () => UseTRPCQueryOptions< TPath, TQueryValues[TPath]["input"], TQueryFnData, @@ -382,25 +385,23 @@ export function createHooksInternal< > ): UseTRPCQueryResult { const ctx = useContext(); - if ( typeof window === "undefined" && ctx.ssrState() === "prepass" && - opts?.trpc?.ssr !== false && - opts?.enabled !== false && - !ctx.queryClient.getQueryCache().find(getArrayQueryKey(pathAndInput)) + opts?.().trpc?.ssr !== false && + opts?.().enabled !== false && + !ctx.queryClient.getQueryCache().find(getArrayQueryKey(pathAndInput())) ) { - void ctx.prefetchQuery(pathAndInput as any, opts as any); + void ctx.prefetchQuery(pathAndInput(), opts as any); } - const ssrOpts = useSSRQueryOptionsIfNeeded(pathAndInput, opts); + const ssrOpts = useSSRQueryOptionsIfNeeded(pathAndInput(), opts?.()); // request option should take priority over global const shouldAbortOnUnmount = - opts?.trpc?.abortOnUnmount ?? ctx?.abortOnUnmount ?? false; - + opts?.().trpc?.abortOnUnmount ?? ctx?.abortOnUnmount ?? false; const hook = __useQuery( - () => getArrayQueryKey(pathAndInput), + () => getArrayQueryKey(pathAndInput()), (queryFunctionContext) => { - const actualOpts = { + const actualOpts = () => ({ ...ssrOpts, trpc: { ...ssrOpts?.trpc, @@ -408,16 +409,16 @@ export function createHooksInternal< ? { signal: queryFunctionContext.signal } : {}), }, - }; + }); return (ctx.client as any).query( - ...getClientArgs(pathAndInput, actualOpts) + ...getClientArgs(pathAndInput(), actualOpts()) ); }, { context: SolidQueryContext, ...ssrOpts } as any ) as UseTRPCQueryResult; hook.trpc = useHookResult({ - path: pathAndInput[0], + path: pathAndInput()[0], }); return hook; @@ -428,7 +429,7 @@ export function createHooksInternal< TContext = unknown >( path: TPath | [TPath], - opts?: UseTRPCMutationOptions< + opts?: () => UseTRPCMutationOptions< TMutationValues[TPath]["input"], TError, TMutationValues[TPath]["output"], @@ -448,14 +449,14 @@ export function createHooksInternal< const actualPath = Array.isArray(path) ? path[0] : path; return (ctx.client.mutation as any)( - ...getClientArgs([actualPath, input], opts) + ...getClientArgs([actualPath, input], opts?.()) ); }, { context: SolidQueryContext, - ...opts, + ...opts?.(), onSuccess(...args) { - const originalFn = () => opts?.onSuccess?.(...args); + const originalFn = () => opts?.().onSuccess?.(...args); return mutationSuccessOverride({ originalFn, queryClient }); }, } @@ -483,16 +484,16 @@ export function createHooksInternal< TPath extends keyof TSubscriptions & string, TOutput extends inferSubscriptionOutput >( - pathAndInput: [ + pathAndInput: () => [ path: TPath, ...args: inferHandlerInput ], - opts: UseTRPCSubscriptionOptions< + opts: () => UseTRPCSubscriptionOptions< inferObservableValue>, inferProcedureClientError > ) { - const enabled = opts?.enabled ?? true; + const enabled = opts?.().enabled ?? true; const ctx = useContext(); return createEffect(() => { @@ -501,29 +502,28 @@ export function createHooksInternal< } // noop (() => { - return hashQueryKey(pathAndInput); + return hashQueryKey(pathAndInput()); })(); - const [path, input] = pathAndInput; let isStopped = false; const subscription = ctx.client.subscription< TRouter["_def"]["subscriptions"], TPath, TOutput, inferProcedureInput - >(path, (input ?? undefined) as any, { + >(pathAndInput()[0], (pathAndInput()[1] ?? undefined) as any, { onStarted: () => { if (!isStopped) { - opts.onStarted?.(); + opts?.().onStarted?.(); } }, onData: (data) => { if (!isStopped) { - opts.onData(data); + opts().onData(data); } }, onError: (err) => { if (!isStopped) { - opts.onError?.(err); + opts().onError?.(err); } }, }); @@ -535,40 +535,39 @@ export function createHooksInternal< } function useInfiniteQuery( - pathAndInput: [ + pathAndInput: () => [ path: TPath, input: Omit ], - opts?: UseTRPCInfiniteQueryOptions< + opts?: () => UseTRPCInfiniteQueryOptions< TPath, Omit, TQueryValues[TPath]["output"], TError > ): UseTRPCInfiniteQueryResult { - const [path, input] = pathAndInput; const ctx = useContext(); if ( typeof window === "undefined" && ctx.ssrState() === "prepass" && - opts?.trpc?.ssr !== false && - opts?.enabled !== false && - !ctx.queryClient.getQueryCache().find(getArrayQueryKey(pathAndInput)) + opts?.()?.trpc?.ssr !== false && + opts?.()?.enabled !== false && + !ctx.queryClient.getQueryCache().find(getArrayQueryKey(pathAndInput())) ) { void ctx.prefetchInfiniteQuery(pathAndInput as any, opts as any); } - const ssrOpts = useSSRQueryOptionsIfNeeded(pathAndInput, opts); + const ssrOpts = useSSRQueryOptionsIfNeeded(pathAndInput(), opts?.()); // request option should take priority over global const shouldAbortOnUnmount = - opts?.trpc?.abortOnUnmount ?? ctx?.abortOnUnmount ?? false; + opts?.()?.trpc?.abortOnUnmount ?? ctx?.abortOnUnmount ?? false; const hook = __useInfiniteQuery( - () => getArrayQueryKey(pathAndInput), + () => getArrayQueryKey(pathAndInput()), (queryFunctionContext) => { - const actualOpts = { + const actualOpts = () => ({ ...ssrOpts, trpc: { ...ssrOpts?.trpc, @@ -576,22 +575,22 @@ export function createHooksInternal< ? { signal: queryFunctionContext.signal } : {}), }, - }; + }); const actualInput = { - ...((input as any) ?? {}), + ...((pathAndInput()[1] as any) ?? {}), cursor: queryFunctionContext.pageParam, }; return (ctx.client as any).query( - ...getClientArgs([path, actualInput], actualOpts) + ...getClientArgs([pathAndInput()[0], actualInput], actualOpts()) ); }, { context: SolidQueryContext, ...ssrOpts } as any ) as UseTRPCInfiniteQueryResult; hook.trpc = useHookResult({ - path, + path: pathAndInput()[0], }); return hook; } diff --git a/src/shared/proxy/decorationProxy.ts b/src/shared/proxy/decorationProxy.ts index 057374d..b3c456a 100644 --- a/src/shared/proxy/decorationProxy.ts +++ b/src/shared/proxy/decorationProxy.ts @@ -26,8 +26,9 @@ export function createSolidProxyDecoration< return (hooks as any)[lastArg](path, ...args); } const [input, ...rest] = args; - - const queryKey = getQueryKey(path, input); - return (hooks as any)[lastArg](queryKey, ...rest); + return (hooks as any)[lastArg]( + () => getQueryKey(path, typeof input === "function" ? input() : input), + () => rest.map((arg) => (typeof arg === "function" ? arg() : arg)) + ); }); } diff --git a/src/shared/queryClient.ts b/src/shared/queryClient.ts index 74101cd..1b7673a 100644 --- a/src/shared/queryClient.ts +++ b/src/shared/queryClient.ts @@ -3,7 +3,7 @@ import { QueryClient, QueryClientConfig } from "@tanstack/solid-query"; /** * @internal */ -export type CreateTRPCReactQueryClientConfig = +export type CreateTRPCSolidQueryClientConfig = | { queryClient?: QueryClient; queryClientConfig?: never; @@ -16,5 +16,5 @@ export type CreateTRPCReactQueryClientConfig = /** * @internal */ -export const getQueryClient = (config: CreateTRPCReactQueryClientConfig) => +export const getQueryClient = (config: CreateTRPCSolidQueryClientConfig) => config.queryClient ?? new QueryClient(config.queryClientConfig);