- Notifications
You must be signed in to change notification settings - Fork8
vishalbalaji/trpc-svelte-query-adapter
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
See#67 for the latest updates on this project
Note
The README onnpmjs might not be fully up to date. Please refer totheREADME on the Github Repo for the latest setup instructions.
An adapter to calltRPC
procedures wrapped with@tanstack/svelte-query
, similar to@trpc/react-query
. This is made possible usingproxy-deep
.
# npmnpm install trpc-svelte-query-adapter @trpc/client @trpc/server @tanstack/svelte-query# yarnyarn add trpc-svelte-query-adapter @trpc/client @trpc/server @tanstack/svelte-query# pnpmpnpm add trpc-svelte-query-adapter @trpc/client @trpc/server @tanstack/svelte-query
If you are using client-side Svelte, you would need to install@trpc/server
as adevDependency
using--save-dev
.
The following functions from@trpc/react-query
are ported over:
useQuery
->createQuery
useInfiniteQuery
->createInfiniteQuery
useMutation
->createMutation
useSubscription
->createSubscription
useQueries
->createQueries
useUtils
->createUtils
getQueryKey
You can refer totanstack-query docs
and@trpc/react-query docs
for documentation on how to use them.
There are also some new procedures that are only relevant for SvelteKit:
createServerQuery
createServerInfiniteQuery
createServerQueries
As for these procedures, you can refer to theServer-Side Query Pre-Fetching section.
The following instructions assume thetRPC
router to have the following procedures:
exportconstrouter=t.router({greeting:t.procedure.input((name:unknown)=>{if(typeofname==='string')returnname;thrownewError(`Invalid input:${typeofname}`);}).query(async({ input})=>{return`Hello,${input} from tRPC v10 @${newDate().toLocaleTimeString()}`;}),});exporttypeRouter=typeofrouter;
- Setup
@tanstack/svelte-query
as persvelte-query docs. - Setup
@trpc/client
and export thetRPC
client. - Wrap the exported
tRPC
client withsvelteQueryWrapper
fromtrpc-svelte-query-adapter
, as demonstrated in the example below:
// src/lib/trpc.tsimporttype{Router}from'/path/to/trpc/router';import{createTRPCProxyClient,httpBatchLink}from'@trpc/client';import{svelteQueryWrapper}from'trpc-svelte-query-adapter';constclient=createTRPCProxyClient<Router>({links:[httpBatchLink({// Replace this URL with that of your tRPC serverurl:'http://localhost:5000/api/v1/trpc/',}),],});exportconsttrpc=svelteQueryWrapper<Router>({ client});
- The exported
tRPC
client can then be used insvelte
components as follows:
<scriptlang="ts">import {trpc }from"/path/to/lib/trpc";const foo=trpc.greeting.createQuery('foo', { retry:false });</script>{#if$foo.isPending} Loading...{:elseif$foo.isError} Error: {$foo.error.message}{:elseif$foo.data} {$foo.data.message}{/if}
For SvelteKit, the process is pretty much the same as for client-only svelte. However, if you intend to call queries from the server in aload
function, you would need to setup@tanstack/svelte-query
according to thethe ssr example in the svelte-query docs.
Upon doing that, you would also need to pass in thequeryClient
tosvelteQueryWrapper
when initializing on the server, which you can get by calling theevent.parent
method in theload
function. You can see an example of this in theServer-Side Query Pre-Fetching section. For this purpose, you might also want to export your client wrapped in a function that optionally takes inqueryClient
and passes it ontosvelteQueryWrapper
.
Here is an example of what that might look like:
importtype{QueryClient}from'@tanstack/svelte-query';constclient=createTRPCProxyClient<Router>({links:[httpBatchLink({// Replace this URL with that of your tRPC serverurl:'http://localhost:5000/api/v1/trpc/',}),],});exportfunctiontrpc(queryClient?:QueryClient){returnsvelteQueryWrapper<Router>({ client, queryClient,});}
Which can then be used in a component as such:
<!-- routes/+page.svelte --><scriptlang="ts">import {trpc }from"$lib/trpc/client";const client=trpc();const foo=client.greeting.createQuery("foo", { retry:false });</script><p> {#if$foo.isPending} Loading... {:elseif$foo.isError} Error: {$foo.error.message} {:else} {$foo.data} {/if}</p>
The main thing that needs to passed in tosvelteQueryWrapper
is thetRPC
client itself. So, this adapter should support different implementations oftRPC
for Svelte and SvelteKit. For example, if you are usingtrpc-sveltekit by icflorescu
, all you would need to do after setting it up would be to change the client initialization function from something like this:
letbrowserClient:ReturnType<typeofcreateTRPCClient<Router>>;exportfunctiontrpc(init?:TRPCClientInit){constisBrowser=typeofwindow!=='undefined';if(isBrowser&&browserClient)returnbrowserClient;constclient=createTRPCClient<Router>({ init});if(isBrowser)browserClient=client;returnclient;}
to this:
import{svelteQueryWrapper}from'trpc-svelte-query-adapter';importtype{QueryClient}from'@tanstack/svelte-query';letbrowserClient:ReturnType<typeofsvelteQueryWrapper<Router>>;exportfunctiontrpc(init?:TRPCClientInit,queryClient?:QueryClient){constisBrowser=typeofwindow!=='undefined';if(isBrowser&&browserClient)returnbrowserClient;constclient=svelteQueryWrapper<Router>({client:createTRPCClient<Router>({ init}), queryClient,});if(isBrowser)browserClient=client;returnclient;}
Which can then be initialized and used in the way that it is describedin its docs.
This adapter provides 3 additional procedures:createServerQuery
,createServerInfiniteQuery
andcreateServerQueries
, which can be used to call their counterpart procedures in theload
function in either a+page.ts
or+layout.ts
. These procedures return apromise
and therefore can only really be called on the server.
By default, these 3 procedures will pre-fetch the data required to pre-render the page on the server. However, if you wish to disable this behaviour on certain queries, you can do so by setting thessr
option tofalse
.
These procedures can be used as such:
// +page.ts// tRPC is setup using `trpc-sveltekit` for this example.import{trpc}from'$lib/trpc/client';importtype{PageLoad}from'./$types';exportconstload=(async(event)=>{const{ queryClient}=awaitevent.parent();constclient=trpc(event,queryClient);return{foo:awaitclient.greeting.createServerQuery('foo'),queries:awaitclient.createServerQueries((t)=>['bar','baz'].map((name)=>t.greeting(name,{ssr:name!=='baz'}))// pre-fetching disabled for the `baz` query.),};})satisfiesPageLoad;
Then, in the component:
<!-- +page.svelte --><scriptlang="ts">import {page }from"$app/stores";importtype {PageData }from"./$types";exportlet data:PageData;const foo=data.foo();const queries=data.queries();</script>{#if$foo.isPending} Loading...{:elseif$foo.isError} {$foo.error}{:elseif$foo.data} {$foo.data}{/if}<br /><br />{#each$queriesasquery} {#ifquery.isPending} Loading... {:elseifquery.isError} {query.error.message} {:elseifquery.data} {query.data} {/if} <br />{/each}
You can also optionally pass new inputs to the queries and infinite queries from the client side(see#34,#47) like so:
<scriptlang="ts">import {page }from"$app/stores";importtype {PageData }from"./$types";import {derived,writable }from'@svelte/store';exportlet data:PageData;const name=writable('foo');const newNames=writable<string[]>([]);const foo=data.foo($name);// You can also access the default input if you pass in a callback as the new input:// const foo = data.foo((old) => derived(name, ($name) => old + name));const queries=data.queries((t,old)=>derived(newNames, ($newNames)=> [...old,...$newNames.map((name)=>t.greeting(name))]));</script><div> {#if$foo.isPending} Loading... {:elseif$foo.isError} {$foo.error} {:elseif$foo.data} {$foo.data} {/if} <inputbind:value={$name} /></div><br /><div> {#each$queriesasquery} {#ifquery.isPending} Loading... {:elseifquery.isError} {query.error.message} {:elseifquery.data} {query.data} {/if} <br /> {/each} <formon:submit|preventDefault={(e)=> {const data=newFormData(e.currentTarget).get('name');if (typeofdata==='string')$newNames.push(data);$newNames=$newNames; }}> <inputname="name" /> <buttontype="submit">Submit</button> </form></div>
For more usage examples, you can refer to theexample app provided in the repo.
About
A simple adapter to use `@tanstack/svelte-query` with trpc, similar to `@trpc/react-query`.
Topics
Resources
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors4
Uh oh!
There was an error while loading.Please reload this page.