Local-First Store
The data/store.js module provides a local-first collection store backed by IndexedDB. Data is
available offline instantly, with optional background sync to a server.
Creating a Collection
js
import { collection } from 'weblisk/data/store.js'; const todos = collection('todos');
With server sync:
js
const todos = collection('todos', { syncUrl: 'https://api.example.com/todos' });
CRUD Operations
Create / Update
js
// Auto-generates an ID await todos.put({ text: 'Buy milk', done: false }); // Provide your own ID await todos.put({ id: 'abc123', text: 'Buy milk', done: false }); // Update existing await todos.put({ id: 'abc123', done: true });
Records automatically get an _updated timestamp.
Read
js
// Single record const todo = await todos.get('abc123'); // All records const all = await todos.getAll(); // Filtered const done = await todos.getAll(r => r.done === true); // Count const total = await todos.count();
Delete
js
// Soft-delete (marks _deleted, keeps for sync) await todos.delete('abc123'); // Hard-delete all soft-deleted records await todos.purgeDeleted();
Reactive Queries
Create a signal that live-updates when the collection changes:
js
import { effect } from 'weblisk'; import { collection } from 'weblisk/data/store.js'; const todos = collection('todos'); const allTodos = todos.live(); effect(() => { const items = allTodos(); document.querySelector('.count').textContent = `${items.length} items`; });
With a filter:
js
const activeTodos = todos.live(r => !r.done);
Change Events
js
const unsub = todos.onChange((records) => { console.log('Collection changed:', records.length, 'items'); });
Server Sync
When syncUrl is configured, mutations are queued for Background Sync:
js
const todos = collection('todos', { syncUrl: 'https://api.example.com/todos' }); await todos.put({ text: 'Buy milk' }); // → Saved to IDB immediately // → Queued for background sync to server
Merging Server Data
Pull changes from the server and merge (newer timestamps win):
js
const serverData = await fetch('/api/todos').then(r => r.json()); await todos.merge(serverData);
Incremental Sync
Get only records changed since a timestamp:
js
const changes = await todos.changesSince(lastSyncTimestamp);
Listening for Sync Results
js
import { onSyncResult } from 'weblisk/data/store.js'; onSyncResult((msg) => { if (msg.ok) console.log(`Synced ${msg.collection}`); else console.error(`Sync failed:`, msg.error); });