```ts
export const db = new Dexie("opchan");
db.version(1).stores({
cells: "id, timestamp",
posts: "id, cellId, timestamp",
comments: "id, postId, timestamp",
votes: "&[targetId+author], timestamp",
moderations: "targetId, timestamp",
outbox: "id, type, timestamp" // unsent msgs
});
```
Local-First Data Layer & Offline Support
Goal
Make the forum usable even when the Waku network is unavailable by caching data in the browser (IndexedDB) and automatically syncing when connectivity is restored.
Motivation
Today, all forum content is fetched live from Waku and kept only in memory (
messageCache).If the user reloads while offline – or loads the site before peers are discovered – the UI is empty.
Making the app local-first will:
High-Level Design
cells,posts,comments,votes,moderations).src/lib/waku/index.ts)– Maintain an outbox collection of locally-created messages with
isPublished = false.messageCachefrom IndexedDB before touching the network.– While offline: queue outgoing messages → outbox.
– When
MessageManager.isReady === true: replay outbox, markisPublished = true, then delete.ForumContext, pages)– Shows a small “Offline” banner when
isNetworkConnectedis false.– Shows a “⟳ syncing n items…” indicator while flushing the outbox.
Implementation Plan
Set up Dexie wrapper (
src/lib/storage/db.ts)Hydrate on bootstrap
In
ForumContext, beforeinitializeNetwork()call:1. Load all tables into
messageManager.messageCache.2.
updateStateFromCache()so the UI renders instantly.Persist incoming messages
Extend
MessageManager.updateCache()toawait db.<table>.put(message).Offline detection
The existing
messageManager.onHealthChange()already emits readiness; surface this in UI (banner).Outbox queue
1.
sendMessage()detects offline →db.outbox.put({...msg, isPublished:false}).2. When health flips to online, iterate
outbox, push viaephemeralProtocolsManager.sendMessage(), thendb.outbox.delete(id).Conflict handling (simple)
If Waku later returns a message with the same
id, just overwrite local copy – messages are immutable.Unit tests for the storage layer (Dexie mock) & sync logic.
E2E smoke test:
1. Load site → disconnect network → create post.
2. Reload (still offline) → post is visible.
3. Reconnect network → post is published and visible on a second device.
Acceptance Criteria
References & Inspiration
Related Code Pointers
src/lib/waku/index.ts– TODO at top about IndexedDB storage.src/contexts/ForumContext.tsx– initial loading flow &updateStateFromCache.src/contexts/forum/network.ts– health monitoring utilities.