Skip to content

Commit

Permalink
this is getting more and more complex every day
Browse files Browse the repository at this point in the history
  • Loading branch information
d3rpp committed Aug 15, 2024
1 parent b1820b9 commit 98dc811
Show file tree
Hide file tree
Showing 12 changed files with 166 additions and 10 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ I was aiming for a "_soydev_" stack, I think I've got it.
- [TailwindCSS](https://tailwindcss.com/)
- [TypeScript](https://www.typescriptlang.org/)
- [Bun](https://bun.sh)
- [tRPC](https://trpc.io) (with [svelte-query](https://github.com/vishalbalaji/trpc-svelte-query-adapter))

# Building

Expand Down
Binary file modified bun.lockb
Binary file not shown.
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,20 @@
"svelte-preprocess"
],
"dependencies": {
"@tanstack/svelte-query": "^5.51.21",
"@tanstack/svelte-query-devtools": "^5.51.21",
"@trpc/client": "^10.45.2",
"@trpc/server": "^10.45.2",
"bits-ui": "^0.21.13",
"clsx": "^2.1.1",
"drizzle-orm": "^0.33.0",
"lucide-svelte": "^0.427.0",
"mode-watcher": "^0.4.1",
"svelte-radix": "^1.1.0",
"tailwind-merge": "^2.5.2",
"tailwind-variants": "^0.2.1"
"tailwind-variants": "^0.2.1",
"trpc-svelte-query-adapter": "^2.3.14",
"trpc-sveltekit": "^3.6.2",
"zod": "^3.23.8"
}
}
6 changes: 6 additions & 0 deletions src/hooks.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { createContext } from "$lib/trpc/context";
import { router } from "$lib/trpc/router";
import type { Handle } from "@sveltejs/kit";
import { createTRPCHandle } from "trpc-sveltekit";

export const handle: Handle = createTRPCHandle({ router, createContext });
28 changes: 28 additions & 0 deletions src/lib/components/suspense.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<script lang="ts" generics="T, E">
import type { CreateQueryResult } from '@tanstack/svelte-query';
import type { Snippet } from "svelte";
interface Props {
query: CreateQueryResult<T, E>,
onpending?: Snippet,
onerror?: Snippet<[E]>,
ondone: Snippet<[T | undefined, boolean]>
};
const {
query,
onpending,
onerror,
ondone
}: Props = $props();
</script>

{#if $query.isPending && onpending}
{@render onpending()}
{:else if $query.isError && onerror}
{@render onerror($query.error)}
{:else}
{@render ondone($query.data, $query.isPlaceholderData)}
{/if}
29 changes: 29 additions & 0 deletions src/lib/trpc/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// type imported for TSDoc, ignore this.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import type { page } from "$app/stores";
import type { Router } from "$lib/trpc/router";

import { createTRPCClient, type TRPCClientInit } from "trpc-sveltekit";
import type { QueryClient } from "@tanstack/svelte-query";
import { svelteQueryWrapper } from "trpc-svelte-query-adapter";

let browserClient: ReturnType<typeof svelteQueryWrapper<Router>>;

/**
* allows access to a client-side tRPC client
*
* @param init it's easier to just set this to {@link page | `$page`}
* @returns a client-side client for tRPC with this server
*/
export const trpc = (init?: TRPCClientInit, queryClient?: QueryClient) => {
const isBrowser = typeof window !== "undefined";
if (isBrowser && browserClient) return browserClient;
const client = svelteQueryWrapper({
client: createTRPCClient<Router>({ init }),
queryClient,
});
if (isBrowser) browserClient = client;
return client;
};

export type trpcClient = typeof browserClient;
9 changes: 9 additions & 0 deletions src/lib/trpc/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { RequestEvent } from "@sveltejs/kit";

export const createContext = async (event: RequestEvent) => {
return {
event,
};
};

export type Context = Awaited<ReturnType<typeof createContext>>;
23 changes: 23 additions & 0 deletions src/lib/trpc/router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import z from "zod";

import type { Context } from "$lib/trpc/context";
import { initTRPC } from "@trpc/server";

export const t = initTRPC.context<Context>().create();

export const router = t.router({
greeting: t.procedure
.input(
z.object({
name: z.string().min(10).max(20).describe("The name to greet"),
}),
)
.query(async (opts) => {
await new Promise((res) => setTimeout(res, 1000));
return `Hello ${opts.input.name}`;
}),
});

export const createCaller = t.createCallerFactory(router);

export type Router = typeof router;
28 changes: 25 additions & 3 deletions src/routes/(landing)/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
<script lang="ts">
import { page } from "$app/stores";
import { trpc } from "$lib/trpc/client";
import Main from "@/main.svelte";
import Suspense from "@/suspense.svelte";
const query = trpc($page).greeting.createQuery({name: "123456789"})
</script>

<Main>
<a href="/app" class="hover:text-blue-300">
Go to <code>/app</code>
</a>
<div class="flex flex-col items-center justify-start">
<h1 class="text-hero">Jail Bird</h1>

{#snippet onpending()}
<span>Loading...</span>
{/snippet}

{#snippet onerror(error: (typeof $query)['error'])}
<span>Error</span>
<pre><code>{error?.message}</code></pre>
{/snippet}

{#snippet ondone(data: string | undefined, is_placeholder: boolean)}
<pre>is_placeholder: {is_placeholder}</pre>
<span>{data}</span>
{/snippet}

<Suspense {query} {ondone} {onerror} {onpending} />
</div>
</Main>
19 changes: 13 additions & 6 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@
import type { Snippet } from "svelte";
import { ModeWatcher } from "mode-watcher";
import { QueryClientProvider } from "@tanstack/svelte-query";
import { SvelteQueryDevtools } from "@tanstack/svelte-query-devtools"
interface Props {
children: Snippet;
}
import type { LayoutData } from "./$types";
const { children }: Props = $props();
const { queryClient, children }: LayoutData & { children: Snippet } = $props();
</script>

<ModeWatcher defaultMode="dark" />
<svelte:head>
<title>Jail Bird</title>
</svelte:head>

{@render children()}
<ModeWatcher defaultMode="system" />

<QueryClientProvider client={queryClient}>
{@render children()}
<SvelteQueryDevtools />
</QueryClientProvider>
16 changes: 16 additions & 0 deletions src/routes/+layout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { browser } from "$app/environment";
import { QueryClient } from "@tanstack/svelte-query";

import type { LayoutLoad } from "./$types";

export const load = (async () => {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
enabled: browser
}
}
});

return { queryClient };
}) satisfies LayoutLoad;
8 changes: 8 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ const config = {
fontFamily: {
sans: [...fontFamily.sans],
},
fontSize: {
hero: [
"10em",
{
letterSpacing: "20px",
},
],
},
},
},
};
Expand Down

0 comments on commit 98dc811

Please sign in to comment.