@gomani/data
v0.5.0
Published
Offline-first, local-first data: an IndexedDB store, optimistic mutations, and a sync engine.
Maintainers
Readme
@gomani/data
Offline-first, local-first data with a built-in sync engine for Gomani.
Offline is the baseline (P5): the local device is authoritative, the network is opportunistic. Writes
are optimistic and instant, the app is fully usable disconnected, and a sync reconciles when
connectivity returns. The main entry is server-safe (the sync server half + shared types); the
client store lives at @gomani/data/client.
The client store
import { createStore, createFetchTransport, online, watchOnline } from '@gomani/data/client';
const store = createStore({
collections: ['todos'],
transport: createFetchTransport('/_gomani/sync'),
});
const todos = store.collection<Todo>('todos');
await todos.put({ id: '1', text: 'Sound the drum', done: false }); // optimistic + queued + persisted
todos.get('1'); // synchronous read from the local cache
todos.items.value; // a reactive snapshot — bind it in an island
await store.sync(); // push queued mutations, pull server changes, reconcile
store.pending.value; // mutations still awaiting sync
watchOnline((isOnline) => isOnline && store.sync()); // sync on reconnectThe sync server
import { createSyncHandler, createMemoryStore } from '@gomani/data';
const sync = createSyncHandler({ store: createMemoryStore() });
// mount it in app/server.ts:
export default (req) => (new URL(req.url).pathname === '/_gomani/sync' ? sync(req) : null);Push/pull with a monotonic cursor; conflicts resolve by last-write-wins (pluggable — a Yjs CRDT is
a later drop-in). The in-memory store is the local default; a Postgres-backed ServerStore is a
drop-in for production.
Service worker
import { generateServiceWorker } from '@gomani/data'; // used by `gomani build` to emit sw.js
import { registerServiceWorker } from '@gomani/data/client'; // call it in an islandgomani build emits sw.js precaching the shell (routes + eager runtime + CSS): cache-first for hashed
assets, network-first with an offline fallback for navigations — so the app loads offline after the
first visit.
License
MIT © Venancio Gomani / Kwacha Kulture.
