add expo, massively simplify svelte and solid examples
This commit is contained in:
@@ -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:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
import @tailwindcss;
|
||||
@@ -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>
|
||||
@@ -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}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>>()
|
||||
@@ -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()}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()]
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user