tablinum 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -72,6 +72,118 @@ const program = Effect.gen(function* () {
|
|
|
72
72
|
Effect.runPromise(Effect.scoped(program));
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
+
## Svelte 5
|
|
76
|
+
|
|
77
|
+
Import from `tablinum/svelte` for reactive bindings that use Svelte 5 runes. No Effect knowledge needed — the API is plain async/await.
|
|
78
|
+
|
|
79
|
+
### Setup
|
|
80
|
+
|
|
81
|
+
Create a database helper that defines your schema and initializes the database:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// src/lib/db.ts
|
|
85
|
+
import { createTablinum, collection, field } from "tablinum/svelte";
|
|
86
|
+
|
|
87
|
+
const schema = {
|
|
88
|
+
todos: collection(
|
|
89
|
+
"todos",
|
|
90
|
+
{
|
|
91
|
+
title: field.string(),
|
|
92
|
+
done: field.boolean(),
|
|
93
|
+
},
|
|
94
|
+
{ indices: ["done"] },
|
|
95
|
+
),
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export type AppSchema = typeof schema;
|
|
99
|
+
|
|
100
|
+
export async function initDb() {
|
|
101
|
+
return createTablinum({
|
|
102
|
+
schema,
|
|
103
|
+
relays: ["wss://relay.example.com"],
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Component
|
|
109
|
+
|
|
110
|
+
Collections and live queries are reactive — their `.items` property updates automatically when data changes.
|
|
111
|
+
|
|
112
|
+
```svelte
|
|
113
|
+
<script lang="ts">
|
|
114
|
+
import { onDestroy } from "svelte";
|
|
115
|
+
import { initDb, type AppSchema } from "$lib/db";
|
|
116
|
+
import type { Database, Collection, LiveQuery } from "tablinum/svelte";
|
|
117
|
+
|
|
118
|
+
let db: Database<AppSchema> | null = $state(null);
|
|
119
|
+
let todos: Collection<AppSchema["todos"]> | null = $state(null);
|
|
120
|
+
let pending: LiveQuery<{ id: string; title: string; done: boolean }> | null = $state(null);
|
|
121
|
+
|
|
122
|
+
let title = $state("");
|
|
123
|
+
|
|
124
|
+
async function init() {
|
|
125
|
+
db = await initDb();
|
|
126
|
+
todos = db.collection("todos");
|
|
127
|
+
pending = todos.where("done").equals(false).live();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
init();
|
|
131
|
+
|
|
132
|
+
async function addTodo(e: SubmitEvent) {
|
|
133
|
+
e.preventDefault();
|
|
134
|
+
if (!todos || !title.trim()) return;
|
|
135
|
+
await todos.add({ title: title.trim(), done: false });
|
|
136
|
+
title = "";
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function toggle(id: string, currentDone: boolean) {
|
|
140
|
+
await todos?.update(id, { done: !currentDone });
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function remove(id: string) {
|
|
144
|
+
await todos?.delete(id);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
onDestroy(() => {
|
|
148
|
+
pending?.destroy();
|
|
149
|
+
db?.close();
|
|
150
|
+
});
|
|
151
|
+
</script>
|
|
152
|
+
|
|
153
|
+
<!-- All todos (reactive via collection.items) -->
|
|
154
|
+
<p>{todos?.items.length ?? 0} total</p>
|
|
155
|
+
|
|
156
|
+
<!-- Filtered todos (reactive via live query) -->
|
|
157
|
+
<form onsubmit={addTodo}>
|
|
158
|
+
<input bind:value={title} placeholder="Add a todo..." />
|
|
159
|
+
<button type="submit">Add</button>
|
|
160
|
+
</form>
|
|
161
|
+
|
|
162
|
+
<ul>
|
|
163
|
+
{#each pending?.items ?? [] as todo (todo.id)}
|
|
164
|
+
<li>
|
|
165
|
+
<input type="checkbox" checked={todo.done} onchange={() => toggle(todo.id, todo.done)} />
|
|
166
|
+
<span>{todo.title}</span>
|
|
167
|
+
<button onclick={() => remove(todo.id)}>Delete</button>
|
|
168
|
+
</li>
|
|
169
|
+
{/each}
|
|
170
|
+
</ul>
|
|
171
|
+
|
|
172
|
+
<!-- Sync status is reactive -->
|
|
173
|
+
{#if db?.status === "syncing"}
|
|
174
|
+
<p>Syncing...</p>
|
|
175
|
+
{/if}
|
|
176
|
+
|
|
177
|
+
<button onclick={() => db?.sync()}>Sync</button>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Key concepts
|
|
181
|
+
|
|
182
|
+
- **`createTablinum`** returns a `Promise<Database>` (no Effect boilerplate)
|
|
183
|
+
- **`collection.items`** is a reactive `$state` array of all records in the collection
|
|
184
|
+
- **`.where("field").equals(value).live()`** returns a `LiveQuery` whose `.items` update automatically
|
|
185
|
+
- **Cleanup**: call `.destroy()` on live queries and `.close()` on the database in `onDestroy`
|
|
186
|
+
|
|
75
187
|
## License
|
|
76
188
|
|
|
77
189
|
MIT
|