inital
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
# SolidJS tRPC
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
I recommend using [Create JD App](https://github.com/OrJDev/create-jd-app) but if you want to create a project from scratch, you can follow the steps below:
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install solid-trpc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Creating A Client
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// utils/trpc.ts
|
||||||
|
import { IAppRouter } from "api/src/routers/_route"; // your trpc appRouter type
|
||||||
|
import { createSolidQueryHooks } from "solid-trpc";
|
||||||
|
|
||||||
|
export const trpc = createSolidQueryHooks<IAppRouter>();
|
||||||
|
export const client = trpc.createClient({
|
||||||
|
url: "/api/trpc", // your trpc server url
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### TRPC Provider
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// App.tsx
|
||||||
|
import { QueryClient } from "@tanstack/solid-query";
|
||||||
|
import { Component } from "solid-js";
|
||||||
|
import { TRPCProvider } from "solid-trpc";
|
||||||
|
import { client } from "./utils/trpc"; // the client we created above
|
||||||
|
import Home from "./pages/Home"; // any page that uses trpc
|
||||||
|
|
||||||
|
interface IAppProps {}
|
||||||
|
|
||||||
|
const queryClient = new QueryClient();
|
||||||
|
const App: Component<IAppProps> = ({}) => {
|
||||||
|
return (
|
||||||
|
<TRPCProvider client={client} queryClient={queryClient}>
|
||||||
|
<Home />
|
||||||
|
</TRPCProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default App;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Queries
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// pages/Home.tsx
|
||||||
|
import { Component } from "solid-js";
|
||||||
|
import { trpc } from "../../utils/trpc";
|
||||||
|
|
||||||
|
interface IHomeProps {}
|
||||||
|
|
||||||
|
const Home: Component<IHomeProps> = ({}) => {
|
||||||
|
const test = trpc.createQuery(() => ["example.test", { name: "example" }]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>{test.data ?? "no data || yet"}</h1>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Home;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mutations
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// pages/Home.tsx
|
||||||
|
import { Component, onMount } from "solid-js";
|
||||||
|
import { trpc } from "../../utils/trpc";
|
||||||
|
|
||||||
|
interface IHomeProps {}
|
||||||
|
|
||||||
|
const Home: Component<IHomeProps> = ({}) => {
|
||||||
|
const test = trpc.createMutation(() => "example.mTest");
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
test.mutateAsync({ number: 3 });
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>{test.data ?? "no data || yet"}</h1>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Home;
|
||||||
|
```
|
||||||
|
|
||||||
|
## What is different
|
||||||
|
|
||||||
|
- No SSR
|
||||||
|
- Replace "use" with "create" (e.g. useQuery -> createQuery)
|
||||||
|
- Query paths (key and input) are being treated as Solid Accessor (callback) instead of a string (eg: useQuery(["MyKey", {...}]) -> createQuery(()=> ["MyKey", {...}]))
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
module.exports = {
|
||||||
|
env: {
|
||||||
|
test: {
|
||||||
|
presets: [
|
||||||
|
['@babel/preset-env', { targets: { node: 'current' } }],
|
||||||
|
'@babel/preset-typescript'
|
||||||
|
],
|
||||||
|
plugins: ['babel-plugin-jsx-dom-expressions']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
Generated
+1985
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"name": "solid-trpc",
|
||||||
|
"description": "SolidJS tRPC",
|
||||||
|
"author": "OrJDev",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "0.0.2",
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
},
|
||||||
|
"type": "module",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"solid": "./dist/index.jsx",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"sideEffects": false,
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc && rollup -c && node scripts/cp",
|
||||||
|
"patch": "npm version patch --no-git-tag-version"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.18.13",
|
||||||
|
"@babel/preset-typescript": "^7.18.6",
|
||||||
|
"@rollup/plugin-babel": "5.3.1",
|
||||||
|
"@rollup/plugin-node-resolve": "13.3.0",
|
||||||
|
"@tanstack/query-core": "^4.6.1",
|
||||||
|
"@tanstack/solid-query": "^4.6.1",
|
||||||
|
"@trpc/client": "^9.27.2",
|
||||||
|
"@trpc/server": "^9.27.2",
|
||||||
|
"@types/node": "^18.7.14",
|
||||||
|
"babel-preset-solid": "^1.5.3",
|
||||||
|
"rollup": "^2.79.0",
|
||||||
|
"solid-js": "^1.5.3",
|
||||||
|
"typescript": "^4.8.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@tanstack/query-core": "^4.6.1",
|
||||||
|
"@tanstack/solid-query": "^4.6.1",
|
||||||
|
"@trpc/client": "^9.12.0",
|
||||||
|
"@trpc/server": "^9.12.0",
|
||||||
|
"solid-js": "^1.5.3"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"solidjs",
|
||||||
|
"trpc"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import babel from "@rollup/plugin-babel";
|
||||||
|
import nodeResolve from "@rollup/plugin-node-resolve";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
input: "src/index.tsx",
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
file: "dist/index.js",
|
||||||
|
format: "es",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
external: ["solid-js", "solid-js/web"],
|
||||||
|
plugins: [
|
||||||
|
nodeResolve({
|
||||||
|
extensions: [".js", ".ts", ".tsx"],
|
||||||
|
}),
|
||||||
|
babel({
|
||||||
|
extensions: [".js", ".ts", ".tsx"],
|
||||||
|
babelHelpers: "bundled",
|
||||||
|
presets: ["solid", "@babel/preset-typescript"],
|
||||||
|
exclude: "node_modules/**",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { existsSync } from "fs";
|
||||||
|
import fs from "fs/promises";
|
||||||
|
import path from "path";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
if (!existsSync(path.join(__dirname, "../dist"))) {
|
||||||
|
await fs.mkdir(path.join(__dirname, "../dist"));
|
||||||
|
}
|
||||||
|
await fs.copyFile(
|
||||||
|
path.join(__dirname, "../README.MD"),
|
||||||
|
path.join(__dirname, "../dist/README.MD")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
main().catch((e) => {
|
||||||
|
console.log(e);
|
||||||
|
});
|
||||||
+253
@@ -0,0 +1,253 @@
|
|||||||
|
import {
|
||||||
|
CreateTRPCClientOptions,
|
||||||
|
TRPCClient,
|
||||||
|
TRPCClientErrorLike,
|
||||||
|
TRPCRequestOptions,
|
||||||
|
createTRPCClient,
|
||||||
|
} from "@trpc/client";
|
||||||
|
import type {
|
||||||
|
AnyRouter,
|
||||||
|
ProcedureRecord,
|
||||||
|
inferHandlerInput,
|
||||||
|
inferProcedureInput,
|
||||||
|
inferProcedureOutput,
|
||||||
|
inferSubscriptionOutput,
|
||||||
|
} from "@trpc/server";
|
||||||
|
import {
|
||||||
|
CreateInfiniteQueryOptions,
|
||||||
|
CreateInfiniteQueryResult,
|
||||||
|
CreateMutationOptions,
|
||||||
|
CreateMutationResult,
|
||||||
|
CreateQueryOptions,
|
||||||
|
CreateQueryResult,
|
||||||
|
createInfiniteQuery as __createInfiniteQuery,
|
||||||
|
createMutation as __createMutation,
|
||||||
|
createQuery as __createQuery,
|
||||||
|
} from "@tanstack/solid-query";
|
||||||
|
import {
|
||||||
|
Context,
|
||||||
|
createEffect,
|
||||||
|
onCleanup,
|
||||||
|
useContext as __useContext,
|
||||||
|
} from "solid-js";
|
||||||
|
import { TRPCContext, TRPCContextState } from "./types";
|
||||||
|
import { getClientArgs } from "./utils";
|
||||||
|
|
||||||
|
export type OutputWithCursor<TData, TCursor extends any = any> = {
|
||||||
|
cursor: TCursor | null;
|
||||||
|
data: TData;
|
||||||
|
};
|
||||||
|
|
||||||
|
type OmitContext<T> = Omit<T, "context"> & {
|
||||||
|
context?: TRPCRequestOptions["context"];
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface CreateTRPCQueryOptions<TPath, TInput, TOutput, TData, TError>
|
||||||
|
extends OmitContext<
|
||||||
|
CreateQueryOptions<TOutput, TError, TData, () => [TPath, TInput]>
|
||||||
|
>,
|
||||||
|
TRPCRequestOptions {}
|
||||||
|
|
||||||
|
export interface CreateTRPCInfiniteQueryOptions<TPath, TInput, TOutput, TError>
|
||||||
|
extends OmitContext<
|
||||||
|
CreateInfiniteQueryOptions<
|
||||||
|
TOutput,
|
||||||
|
TError,
|
||||||
|
TOutput,
|
||||||
|
TOutput,
|
||||||
|
() => [TPath, TInput]
|
||||||
|
>
|
||||||
|
>,
|
||||||
|
TRPCRequestOptions {}
|
||||||
|
|
||||||
|
export interface CreateTRPCMutationOptions<
|
||||||
|
TInput,
|
||||||
|
TError,
|
||||||
|
TOutput,
|
||||||
|
TContext = unknown
|
||||||
|
> extends OmitContext<CreateMutationOptions<TOutput, TError, TInput, TContext>>,
|
||||||
|
TRPCRequestOptions {}
|
||||||
|
|
||||||
|
type inferInfiniteQueryNames<
|
||||||
|
TObj extends ProcedureRecord<any, any, any, any, any, any>
|
||||||
|
> = {
|
||||||
|
[TPath in keyof TObj]: inferProcedureInput<TObj[TPath]> extends {
|
||||||
|
cursor?: any;
|
||||||
|
}
|
||||||
|
? TPath
|
||||||
|
: never;
|
||||||
|
}[keyof TObj];
|
||||||
|
|
||||||
|
type inferProcedures<
|
||||||
|
TObj extends ProcedureRecord<any, any, any, any, any, any>
|
||||||
|
> = {
|
||||||
|
[TPath in keyof TObj]: {
|
||||||
|
input: inferProcedureInput<TObj[TPath]>;
|
||||||
|
output: inferProcedureOutput<TObj[TPath]>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createSolidQueryHooks<TRouter extends AnyRouter>() {
|
||||||
|
type TQueries = TRouter["_def"]["queries"];
|
||||||
|
type TSubscriptions = TRouter["_def"]["subscriptions"];
|
||||||
|
type TError = TRPCClientErrorLike<TRouter>;
|
||||||
|
type TInfiniteQueryNames = inferInfiniteQueryNames<TQueries>;
|
||||||
|
|
||||||
|
type TQueryValues = inferProcedures<TRouter["_def"]["queries"]>;
|
||||||
|
type TMutationValues = inferProcedures<TRouter["_def"]["mutations"]>;
|
||||||
|
|
||||||
|
type ProviderContext = TRPCContextState<TRouter>;
|
||||||
|
const Context = TRPCContext as Context<ProviderContext>;
|
||||||
|
|
||||||
|
function createClient(
|
||||||
|
opts: CreateTRPCClientOptions<TRouter>
|
||||||
|
): TRPCClient<TRouter> {
|
||||||
|
return createTRPCClient(opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
function useContext() {
|
||||||
|
return __useContext(Context);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createQuery<
|
||||||
|
TPath extends keyof TQueryValues & string,
|
||||||
|
TQueryFnData = TQueryValues[TPath]["output"],
|
||||||
|
TData = TQueryValues[TPath]["output"]
|
||||||
|
>(
|
||||||
|
pathAndInput: () => [
|
||||||
|
path: TPath,
|
||||||
|
...args: inferHandlerInput<TQueries[TPath]>
|
||||||
|
],
|
||||||
|
opts?: CreateTRPCQueryOptions<
|
||||||
|
TPath,
|
||||||
|
TQueryValues[TPath]["input"],
|
||||||
|
TQueryFnData,
|
||||||
|
TData,
|
||||||
|
TError
|
||||||
|
>
|
||||||
|
): CreateQueryResult<TData, TError> {
|
||||||
|
const ctx = useContext();
|
||||||
|
if (
|
||||||
|
typeof window === "undefined" &&
|
||||||
|
opts?.enabled !== false &&
|
||||||
|
!ctx.queryClient.getQueryCache().find(pathAndInput())
|
||||||
|
) {
|
||||||
|
ctx.prefetchQuery(pathAndInput as any, opts as any);
|
||||||
|
}
|
||||||
|
|
||||||
|
return __createQuery(pathAndInput, () =>
|
||||||
|
(ctx.client as any).query(...getClientArgs(pathAndInput(), opts))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMutation<
|
||||||
|
TPath extends keyof TMutationValues & string,
|
||||||
|
TContext = unknown
|
||||||
|
>(
|
||||||
|
path: () => TPath | [TPath],
|
||||||
|
opts?: CreateTRPCMutationOptions<
|
||||||
|
TMutationValues[TPath]["input"],
|
||||||
|
TError,
|
||||||
|
TMutationValues[TPath]["output"],
|
||||||
|
TContext
|
||||||
|
>
|
||||||
|
): CreateMutationResult<
|
||||||
|
TMutationValues[TPath]["output"],
|
||||||
|
TError,
|
||||||
|
TMutationValues[TPath]["input"],
|
||||||
|
TContext
|
||||||
|
> {
|
||||||
|
const ctx = useContext();
|
||||||
|
return __createMutation((input) => {
|
||||||
|
const curr = path();
|
||||||
|
const actualPath = Array.isArray(curr) ? curr[0] : curr;
|
||||||
|
return (ctx.client.mutation as any)(actualPath, input, opts);
|
||||||
|
}, opts as any);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createInfiniteQuery<TPath extends TInfiniteQueryNames & string>(
|
||||||
|
pathAndInput: () => [
|
||||||
|
path: TPath,
|
||||||
|
input: Omit<TQueryValues[TPath]["input"], "cursor">
|
||||||
|
],
|
||||||
|
opts?: CreateTRPCInfiniteQueryOptions<
|
||||||
|
TPath,
|
||||||
|
Omit<TQueryValues[TPath]["input"], "cursor">,
|
||||||
|
TQueryValues[TPath]["output"],
|
||||||
|
TError
|
||||||
|
>
|
||||||
|
): CreateInfiniteQueryResult<TQueryValues[TPath]["output"], TError> {
|
||||||
|
const [path, input] = pathAndInput();
|
||||||
|
const { client, prefetchInfiniteQuery, queryClient } = useContext();
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof window === "undefined" &&
|
||||||
|
opts?.enabled !== false &&
|
||||||
|
!queryClient.getQueryCache().find(pathAndInput())
|
||||||
|
) {
|
||||||
|
prefetchInfiniteQuery(pathAndInput as any, opts as any);
|
||||||
|
}
|
||||||
|
|
||||||
|
return __createInfiniteQuery(
|
||||||
|
pathAndInput as any,
|
||||||
|
({ pageParam }) => {
|
||||||
|
const actualInput = { ...((input as any) ?? {}), cursor: pageParam };
|
||||||
|
return (client as any).query(
|
||||||
|
...getClientArgs([path, actualInput], opts)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
opts as any
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function createSubscription<
|
||||||
|
TPath extends keyof TSubscriptions & string,
|
||||||
|
TOutput extends inferSubscriptionOutput<TRouter, TPath>
|
||||||
|
>(
|
||||||
|
pathAndInput: () => [
|
||||||
|
path: TPath,
|
||||||
|
...args: inferHandlerInput<TSubscriptions[TPath]>
|
||||||
|
],
|
||||||
|
opts: {
|
||||||
|
enabled?: boolean;
|
||||||
|
onError?: (err: TError) => void;
|
||||||
|
onNext: (data: TOutput) => void;
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
const enabled = opts?.enabled ?? true;
|
||||||
|
const { client } = useContext();
|
||||||
|
|
||||||
|
return createEffect(() => {
|
||||||
|
if (!enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const [path, input] = pathAndInput();
|
||||||
|
let isStopped = false;
|
||||||
|
const unsub = client.subscription(path, (input ?? undefined) as any, {
|
||||||
|
onError: (err) => {
|
||||||
|
if (!isStopped) {
|
||||||
|
opts.onError?.(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onNext: (res) => {
|
||||||
|
if (res.type === "data" && !isStopped) {
|
||||||
|
opts.onNext(res.data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
onCleanup(() => {
|
||||||
|
isStopped = true;
|
||||||
|
unsub();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
createClient,
|
||||||
|
useContext,
|
||||||
|
createQuery,
|
||||||
|
createMutation,
|
||||||
|
createInfiniteQuery,
|
||||||
|
createSubscription,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export { default as TRPCProvider } from "./provider";
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
import {
|
||||||
|
QueryClient,
|
||||||
|
QueryClientProvider,
|
||||||
|
QueryClientProviderProps,
|
||||||
|
} from "@tanstack/solid-query";
|
||||||
|
import { TRPCClient } from "@trpc/client";
|
||||||
|
import { AnyRouter } from "@trpc/server";
|
||||||
|
import { Context, JSX } from "solid-js";
|
||||||
|
import { TRPCContext, TRPCContextState } from "./types";
|
||||||
|
import { getClientArgs } from "./utils";
|
||||||
|
|
||||||
|
export default function TRPCProvider<TRouter extends AnyRouter>(props: {
|
||||||
|
queryClient: QueryClient;
|
||||||
|
client: TRPCClient<TRouter>;
|
||||||
|
children: JSX.Element;
|
||||||
|
queryClientOpts?: Omit<QueryClientProviderProps, "client">;
|
||||||
|
}) {
|
||||||
|
const Context = TRPCContext as Context<TRPCContextState<TRouter>>;
|
||||||
|
return (
|
||||||
|
<Context.Provider
|
||||||
|
value={{
|
||||||
|
queryClient: props.queryClient,
|
||||||
|
client: props.client,
|
||||||
|
fetchQuery: (pathAndInput, opts) =>
|
||||||
|
props.queryClient.fetchQuery(
|
||||||
|
pathAndInput,
|
||||||
|
() =>
|
||||||
|
(props.client as any).query(...getClientArgs(pathAndInput, opts)),
|
||||||
|
opts
|
||||||
|
),
|
||||||
|
fetchInfiniteQuery: (pathAndInput, opts) =>
|
||||||
|
props.queryClient.fetchInfiniteQuery(
|
||||||
|
pathAndInput,
|
||||||
|
({ pageParam }) => {
|
||||||
|
const [path, input] = pathAndInput;
|
||||||
|
const actualInput = { ...(input as any), cursor: pageParam };
|
||||||
|
return (props.client as any).query(
|
||||||
|
...getClientArgs([path, actualInput], opts)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
opts
|
||||||
|
),
|
||||||
|
prefetchQuery: (pathAndInput, opts) =>
|
||||||
|
props.queryClient.prefetchQuery(
|
||||||
|
pathAndInput,
|
||||||
|
() =>
|
||||||
|
(props.client as any).query(...getClientArgs(pathAndInput, opts)),
|
||||||
|
opts
|
||||||
|
),
|
||||||
|
prefetchInfiniteQuery: (pathAndInput, opts) =>
|
||||||
|
props.queryClient.prefetchInfiniteQuery(
|
||||||
|
pathAndInput,
|
||||||
|
({ pageParam }) => {
|
||||||
|
const [path, input] = pathAndInput;
|
||||||
|
const actualInput = { ...(input as any), cursor: pageParam };
|
||||||
|
return (props.client as any).query(
|
||||||
|
...getClientArgs([path, actualInput], opts)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
opts
|
||||||
|
),
|
||||||
|
/**
|
||||||
|
* @deprecated use `invalidateQueries`
|
||||||
|
*/
|
||||||
|
invalidateQuery: (...args: any[]) =>
|
||||||
|
props.queryClient.invalidateQueries(...args),
|
||||||
|
invalidateQueries: (...args: any[]) =>
|
||||||
|
props.queryClient.invalidateQueries(...args),
|
||||||
|
refetchQueries: (...args: any[]) =>
|
||||||
|
props.queryClient.refetchQueries(...args),
|
||||||
|
cancelQuery: (pathAndInput) =>
|
||||||
|
props.queryClient.cancelQueries(pathAndInput),
|
||||||
|
setQueryData: (...args) => props.queryClient.setQueryData(...args),
|
||||||
|
getQueryData: (...args) => props.queryClient.getQueryData(...args),
|
||||||
|
setInfiniteQueryData: (...args) =>
|
||||||
|
props.queryClient.setQueryData(...args),
|
||||||
|
getInfiniteQueryData: (...args) =>
|
||||||
|
props.queryClient.getQueryData(...args),
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<QueryClientProvider
|
||||||
|
client={props.queryClient}
|
||||||
|
{...((props.queryClientOpts ?? {}) as any)}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</QueryClientProvider>
|
||||||
|
</Context.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
+197
@@ -0,0 +1,197 @@
|
|||||||
|
import { TRPCClient, TRPCClientError, TRPCRequestOptions } from "@trpc/client";
|
||||||
|
import type {
|
||||||
|
AnyRouter,
|
||||||
|
inferHandlerInput,
|
||||||
|
inferProcedureInput,
|
||||||
|
inferProcedureOutput,
|
||||||
|
} from "@trpc/server";
|
||||||
|
import { createContext } from "solid-js";
|
||||||
|
import {
|
||||||
|
CancelOptions,
|
||||||
|
FetchInfiniteQueryOptions,
|
||||||
|
FetchQueryOptions,
|
||||||
|
InfiniteData,
|
||||||
|
InvalidateOptions,
|
||||||
|
InvalidateQueryFilters,
|
||||||
|
QueryClient,
|
||||||
|
RefetchOptions,
|
||||||
|
RefetchQueryFilters,
|
||||||
|
SetDataOptions,
|
||||||
|
} from "@tanstack/solid-query";
|
||||||
|
import { Updater } from "@tanstack/query-core";
|
||||||
|
|
||||||
|
interface TRPCFetchQueryOptions<TInput, TError, TOutput>
|
||||||
|
extends FetchQueryOptions<TInput, TError, TOutput>,
|
||||||
|
TRPCRequestOptions {}
|
||||||
|
|
||||||
|
interface TRPCFetchInfiniteQueryOptions<TInput, TError, TOutput>
|
||||||
|
extends FetchInfiniteQueryOptions<TInput, TError, TOutput>,
|
||||||
|
TRPCRequestOptions {}
|
||||||
|
|
||||||
|
export interface TRPCContextState<TRouter extends AnyRouter> {
|
||||||
|
queryClient: QueryClient;
|
||||||
|
client: TRPCClient<TRouter>;
|
||||||
|
/**
|
||||||
|
* @link https://react-query.tanstack.com/guides/prefetching
|
||||||
|
*/
|
||||||
|
fetchQuery<
|
||||||
|
TPath extends keyof TRouter["_def"]["queries"] & string,
|
||||||
|
TProcedure extends TRouter["_def"]["queries"][TPath],
|
||||||
|
TOutput extends inferProcedureOutput<TProcedure>,
|
||||||
|
TInput extends inferProcedureInput<TProcedure>
|
||||||
|
>(
|
||||||
|
pathAndInput: [path: TPath, ...args: inferHandlerInput<TProcedure>],
|
||||||
|
opts?: TRPCFetchQueryOptions<TInput, TRPCClientError<TRouter>, TOutput>
|
||||||
|
): Promise<TOutput>;
|
||||||
|
/**
|
||||||
|
* @link https://react-query.tanstack.com/guides/prefetching
|
||||||
|
*/
|
||||||
|
fetchInfiniteQuery<
|
||||||
|
TPath extends keyof TRouter["_def"]["queries"] & string,
|
||||||
|
TProcedure extends TRouter["_def"]["queries"][TPath],
|
||||||
|
TOutput extends inferProcedureOutput<TProcedure>,
|
||||||
|
TInput extends inferProcedureInput<TProcedure>
|
||||||
|
>(
|
||||||
|
pathAndInput: [path: TPath, ...args: inferHandlerInput<TProcedure>],
|
||||||
|
opts?: TRPCFetchInfiniteQueryOptions<
|
||||||
|
TInput,
|
||||||
|
TRPCClientError<TRouter>,
|
||||||
|
TOutput
|
||||||
|
>
|
||||||
|
): Promise<InfiniteData<TOutput>>;
|
||||||
|
/**
|
||||||
|
* @link https://react-query.tanstack.com/guides/prefetching
|
||||||
|
*/
|
||||||
|
prefetchQuery<
|
||||||
|
TPath extends keyof TRouter["_def"]["queries"] & string,
|
||||||
|
TProcedure extends TRouter["_def"]["queries"][TPath],
|
||||||
|
TOutput extends inferProcedureOutput<TProcedure>,
|
||||||
|
TInput extends inferProcedureInput<TProcedure>
|
||||||
|
>(
|
||||||
|
pathAndInput: [path: TPath, ...args: inferHandlerInput<TProcedure>],
|
||||||
|
opts?: TRPCFetchQueryOptions<TInput, TRPCClientError<TRouter>, TOutput>
|
||||||
|
): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://react-query.tanstack.com/guides/prefetching
|
||||||
|
*/
|
||||||
|
prefetchInfiniteQuery<
|
||||||
|
TPath extends keyof TRouter["_def"]["queries"] & string,
|
||||||
|
TProcedure extends TRouter["_def"]["queries"][TPath],
|
||||||
|
TOutput extends inferProcedureOutput<TProcedure>,
|
||||||
|
TInput extends inferProcedureInput<TProcedure>
|
||||||
|
>(
|
||||||
|
pathAndInput: [path: TPath, ...args: inferHandlerInput<TProcedure>],
|
||||||
|
opts?: TRPCFetchInfiniteQueryOptions<
|
||||||
|
TInput,
|
||||||
|
TRPCClientError<TRouter>,
|
||||||
|
TOutput
|
||||||
|
>
|
||||||
|
): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use `invalidateQueries`
|
||||||
|
*/
|
||||||
|
invalidateQuery<
|
||||||
|
TPath extends keyof TRouter["_def"]["queries"] & string,
|
||||||
|
TInput extends inferProcedureInput<TRouter["_def"]["queries"][TPath]>
|
||||||
|
>(
|
||||||
|
pathAndInput: [TPath, TInput?],
|
||||||
|
options?: InvalidateOptions
|
||||||
|
): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://react-query.tanstack.com/guides/query-invalidation
|
||||||
|
*/
|
||||||
|
invalidateQueries<
|
||||||
|
TPath extends keyof TRouter["_def"]["queries"] & string,
|
||||||
|
TInput extends inferProcedureInput<TRouter["_def"]["queries"][TPath]>
|
||||||
|
>(
|
||||||
|
pathAndInput?: [TPath, TInput?] | TPath,
|
||||||
|
filters?: InvalidateQueryFilters,
|
||||||
|
options?: InvalidateOptions
|
||||||
|
): Promise<void>;
|
||||||
|
/**
|
||||||
|
* @link https://react-query.tanstack.com/guides/query-invalidation
|
||||||
|
*/
|
||||||
|
invalidateQueries(
|
||||||
|
filters?: InvalidateQueryFilters,
|
||||||
|
options?: InvalidateOptions
|
||||||
|
): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://react-query.tanstack.com/reference/QueryClient#queryclientrefetchqueries
|
||||||
|
*/
|
||||||
|
refetchQueries<
|
||||||
|
TPath extends keyof TRouter["_def"]["queries"] & string,
|
||||||
|
TInput extends inferProcedureInput<TRouter["_def"]["queries"][TPath]>
|
||||||
|
>(
|
||||||
|
pathAndInput: [TPath, TInput?],
|
||||||
|
filters?: RefetchQueryFilters,
|
||||||
|
options?: RefetchOptions
|
||||||
|
): Promise<void>;
|
||||||
|
/**
|
||||||
|
* @link https://react-query.tanstack.com/reference/QueryClient#queryclientrefetchqueries
|
||||||
|
*/
|
||||||
|
refetchQueries(
|
||||||
|
filters?: RefetchQueryFilters,
|
||||||
|
options?: RefetchOptions
|
||||||
|
): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://react-query.tanstack.com/guides/query-cancellation
|
||||||
|
*/
|
||||||
|
cancelQuery<
|
||||||
|
TPath extends keyof TRouter["_def"]["queries"] & string,
|
||||||
|
TInput extends inferProcedureInput<TRouter["_def"]["queries"][TPath]>
|
||||||
|
>(
|
||||||
|
pathAndInput: [TPath, TInput?],
|
||||||
|
options?: CancelOptions
|
||||||
|
): Promise<void>;
|
||||||
|
/**
|
||||||
|
* @link https://react-query.tanstack.com/reference/QueryClient#queryclientsetquerydata
|
||||||
|
*/
|
||||||
|
setQueryData<
|
||||||
|
TPath extends keyof TRouter["_def"]["queries"] & string,
|
||||||
|
TInput extends inferProcedureInput<TRouter["_def"]["queries"][TPath]>,
|
||||||
|
TOutput extends inferProcedureOutput<TRouter["_def"]["queries"][TPath]>
|
||||||
|
>(
|
||||||
|
pathAndInput: [TPath, TInput?],
|
||||||
|
updater: Updater<TOutput | undefined, TOutput>,
|
||||||
|
options?: SetDataOptions
|
||||||
|
): void;
|
||||||
|
/**
|
||||||
|
* @link https://react-query.tanstack.com/reference/QueryClient#queryclientgetquerydata
|
||||||
|
*/
|
||||||
|
getQueryData<
|
||||||
|
TPath extends keyof TRouter["_def"]["queries"] & string,
|
||||||
|
TInput extends inferProcedureInput<TRouter["_def"]["queries"][TPath]>,
|
||||||
|
TOutput extends inferProcedureOutput<TRouter["_def"]["queries"][TPath]>
|
||||||
|
>(
|
||||||
|
pathAndInput: [TPath, TInput?]
|
||||||
|
): TOutput | undefined;
|
||||||
|
/**
|
||||||
|
* @link https://react-query.tanstack.com/reference/QueryClient#queryclientgetquerydata
|
||||||
|
*/
|
||||||
|
setInfiniteQueryData<
|
||||||
|
TPath extends keyof TRouter["_def"]["queries"] & string,
|
||||||
|
TInput extends inferProcedureInput<TRouter["_def"]["queries"][TPath]>,
|
||||||
|
TOutput extends inferProcedureOutput<TRouter["_def"]["queries"][TPath]>
|
||||||
|
>(
|
||||||
|
pathAndInput: [TPath, TInput?],
|
||||||
|
updater: Updater<InfiniteData<TOutput> | undefined, InfiniteData<TOutput>>,
|
||||||
|
options?: SetDataOptions
|
||||||
|
): void;
|
||||||
|
/**
|
||||||
|
* @link https://react-query.tanstack.com/reference/QueryClient#queryclientgetquerydata
|
||||||
|
*/
|
||||||
|
getInfiniteQueryData<
|
||||||
|
TPath extends keyof TRouter["_def"]["queries"] & string,
|
||||||
|
TInput extends inferProcedureInput<TRouter["_def"]["queries"][TPath]>,
|
||||||
|
TOutput extends inferProcedureOutput<TRouter["_def"]["queries"][TPath]>
|
||||||
|
>(
|
||||||
|
pathAndInput: [TPath, TInput?]
|
||||||
|
): InfiniteData<TOutput> | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TRPCContext = createContext(null as any);
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export function getClientArgs<TPathAndInput extends unknown[], TOptions>(
|
||||||
|
pathAndInput: TPathAndInput,
|
||||||
|
opts: TOptions
|
||||||
|
) {
|
||||||
|
const [path, input] = pathAndInput;
|
||||||
|
return [path, input, opts] as const;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"declaration": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"target": "esnext",
|
||||||
|
"newLine": "LF",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"strict": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"jsxImportSource": "solid-js",
|
||||||
|
"outDir": "./dist",
|
||||||
|
"module": "esnext"
|
||||||
|
},
|
||||||
|
"include": ["./src"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user