add expo, massively simplify svelte and solid examples

This commit is contained in:
2026-06-03 17:05:06 +02:00
parent d33b9c5467
commit d1c46cdee1
28 changed files with 232 additions and 465 deletions

View File

@@ -21,14 +21,6 @@
"vite": "^8.0.7"
},
"dependencies": {
"@bufbuild/protobuf": "^2.11.0",
"@connectrpc/connect": "^2.1.1",
"@connectrpc/connect-web": "^2.1.1",
"@<@var(context.project.name)>/rpc": "workspace:*",
"@tailwindcss/vite": "^4.3.0",
"@tanstack/query-db-collection": "^1.0.33",
"@tanstack/svelte-db": "^0.1.79",
"@tanstack/svelte-query": "^6.1.13",
"tailwindcss": "^4.3.0"
"@<@var(context.project.name)>/rpc": "workspace:*"
}
}

View File

@@ -1,25 +0,0 @@
<script lang="ts">
import type { ExtractPayload, Todo } from '@<@var(context.project.name)>/rpc';
import { getTodoCollection } from '$lib/todocollectionscontext';
const todoCollection = getTodoCollection();
let todo = $state<ExtractPayload<Todo>>({
id: crypto.randomUUID(),
task: '',
done: false
});
const insertTodo = () => {
todoCollection.insert({ ...todo });
todo = {
id: crypto.randomUUID(),
task: '',
done: false
};
};
</script>
<input class="rounded-md border px-3 py-1" type="text" bind:value={todo.task} />
<button class="cursor-pointer rounded-md bg-teal-800 p-1 text-teal-100" onclick={insertTodo}>
create
</button>

View File

@@ -1,29 +0,0 @@
<script lang="ts">
import { getTodoCollection } from '$lib/todocollectionscontext';
import { useLiveQuery } from '@tanstack/svelte-db';
import Todo from './Todo.svelte';
const todoCollection = getTodoCollection();
const data = useLiveQuery((q) => q.from({ todos: todoCollection }));
const todos = $derived.by(() => {
return data.data.toSorted((a, b) => {
if (a.done != b.done) {
return a.done ? -1 : 1;
}
if (!a.done && !b.done) {
const adate = a.createdAt ? new Date(a.createdAt) : new Date();
const bdate = b.createdAt ? new Date(b.createdAt) : new Date();
return bdate.getTime() - adate.getTime();
}
return 0;
});
});
</script>
{#if data.isLoading}
<div>Loading...</div>
{:else}
{#each todos as todo (todo.id)}
<Todo {todo} />
{/each}
{/if}

View File

@@ -1,48 +0,0 @@
<script lang="ts">
import type { ExtractPayload, Todo as RpcTodo } from '@<@var(context.project.name)>/rpc';
import { getTodoCollection } from '$lib/todocollectionscontext';
let { todo }: { todo: ExtractPayload<RpcTodo> } = $props();
const getInitialTodo = () => todo;
let todoState = $state<ExtractPayload<RpcTodo>>({ ...getInitialTodo() });
let commitUpdateTimeoutId: ReturnType<typeof setTimeout> | null = null;
const todoCollection = getTodoCollection();
const updateTask = () => {
if (commitUpdateTimeoutId != null) {
clearTimeout(commitUpdateTimeoutId);
}
commitUpdateTimeoutId = setTimeout(() => {
todoCollection.update(todoState.id, (draft) => {
draft.task = todoState.task;
});
}, 3000);
};
const updateDone = () => {
todoCollection.update(todoState.id, (draft) => {
draft.done = todoState.done;
});
};
const del = () => {
todoCollection.delete(todoState.id || '');
};
</script>
<div class="flex flex-col items-center gap-2 rounded-md border p-5">
<input
class="rounded-md border px-3 py-1 text-center"
type="text"
bind:value={todoState.task}
oninput={updateTask}
/>
<span>{new Date(todoState.createdAt || '').toLocaleString()}</span>
<span>{new Date(todoState.updatesAt || '').toLocaleString()}</span>
<input type="checkbox" bind:checked={todoState.done} onchange={updateDone} />
<button class="cursor-pointer rounded-md bg-amber-800 p-1 text-amber-100" onclick={del}>
delete
</button>
</div>

View File

@@ -1,8 +0,0 @@
import {createRouter} from '@<@var(context.project.name)>/rpc'
const router = createRouter("http://127.0.0.1:8080")
export const getRouter = () => {
return router;
}

View File

@@ -1,4 +0,0 @@
import { createContext } from "svelte";
import { type CollectionImpl } from '@tanstack/svelte-db'
import type { Todo, ExtractPayload } from "@<@var(context.project.name)>/rpc";
export const [getTodoCollection,setTodoCollection] = createContext<CollectionImpl<ExtractPayload<Todo>,string>>()

View File

@@ -1,53 +1,11 @@
<script lang="ts">
import { createCollection } from '@tanstack/svelte-db';
import { queryCollectionOptions } from '@tanstack/query-db-collection';
import { getRouter } from "$lib/getconnectrouter"
import favicon from '$lib/assets/favicon.svg';
import "../app.css"
import { QueryClient, QueryClientProvider } from '@tanstack/svelte-query';
import type { ExtractPayload, Todo } from '@<@var(context.project.name)>/rpc';
import { browser } from '$app/environment';
import { setTodoCollection } from '$lib/todocollectionscontext';
let { children } = $props();
const router = getRouter()
const queryClient = new QueryClient({
defaultOptions: {
queries: {
enabled: browser
}
},
})
const todosCollection = createCollection(
queryCollectionOptions({
queryKey: ["todos"],
queryFn: async () => {
const todos = await router.todos.listTodos({})
return todos.todos as ExtractPayload<Todo>[];
},
queryClient,
getKey: (item) => item.id ? item.id : crypto.randomUUID(),
onInsert: async ({transaction}) => {
Promise.all(transaction.mutations.map((m) => {
router.todos.createTodo({ todo: m.modified })
}))
},
onDelete: async ({transaction}) => {
Promise.all(transaction.mutations.map((m) => {
router.todos.deleteTodo({todo: m.modified})
}))
},
onUpdate: async ({transaction}) => {
Promise.all(transaction.mutations.map((m) => {
router.todos.updateTodo({todo: m.modified})
}))
}
})
)
setTodoCollection(todosCollection)
</script>
<svelte:head>
<link rel="icon" href={favicon} />
</svelte:head>
<QueryClientProvider client={queryClient}>
{@render children()}
</QueryClientProvider>
{@render children()}

View File

@@ -1,11 +1,51 @@
<script>
import CreateTodo from "$lib/components/CreateTodo.svelte";
import ListTodos from "$lib/components/ListTodos.svelte";
<script lang="ts">
import { createRouter, type Todo } from "@glstack-test/rpc"
import type { ChangeEventHandler } from "svelte/elements";
const router = createRouter("http://127.0.0.1:8080");
let todos = $state<Todo[]>([])
let todoToCreateTask = $state<string>("")
const fetchTodos = () => {
router.todos.listTodos({}).then((r) => {
todos = r.todos;
})
}
$effect(() => {
fetchTodos()
})
const setTodoDone = (id: string, task: string) => {
return async (event : Event & { currentTarget: HTMLInputElement }) => {
await router.todos.updateTodo({ todo: { id, task, done: event.currentTarget.checked } })
fetchTodos()
}
}
const deleteTodo = (id: string) => {
return async () => {
await router.todos.deleteTodo({ todo: { id } })
fetchTodos()
}
}
const createTodo = () => {
router.todos.createTodo({ todo: { id: crypto.randomUUID(), task: todoToCreateTask } }).then((r) => {
console.log(r)
fetchTodos()
}).catch((e) => {
console.log(e)
})
}
</script>
<main class="flex flex-col items-center gap-2 py-5">
<title>Todos</title>
<h1 class="text-5xl"> Todos </h1>
<CreateTodo/>
<ListTodos/>
</main>
<div>
<h1>Create Todo</h1>
<input bind:value={todoToCreateTask} type="text"/>
<button onclick={createTodo}> create </button>
{#each todos as todo (todo.id)}
<div>
{todo.task}
<input type='checkbox' onchange={setTodoDone(todo.id || "",todo.task)}/>
<button onclick={deleteTodo(todo.id || "")}>delete</button>
</div>
{/each}
</div>

View File

@@ -1,9 +1,6 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [
tailwindcss(),
sveltekit(),
]
plugins: [sveltekit()]
});