Offline and local storage
Keep cursors, unsent messages and a cache across reloads with IndexedDB, AsyncStorage or files.
By default the SDK keeps everything in memory: positions in each topic, queued publishes and recent messages last as long as the client. Give it a persistent store and that state survives page reloads and app restarts:
- Positions (cursors): after a reload, subscriptions resume exactly where they left off.
- Outbox: messages sent while offline, or not yet confirmed, are sent after the reload, without duplicates, for up to 10 minutes.
- Cache: recent messages and values render at once on reload, marked
fromCache: trueuntil the node confirms them.
Choose a store
import { indexedDbStore } from '@folkways/realtime/stores/indexeddb';
const client = new Folkways.Realtime({ url, authUrl, store: indexedDbStore() });Several tabs can share the database safely.
| Store | Import | Arguments |
|---|---|---|
memoryStore() (default) | @folkways/realtime | None. Not persistent |
indexedDbStore(name?) | @folkways/realtime/stores/indexeddb | Database name, default folkways |
asyncStorageStore(storage, prefix?) | @folkways/realtime/stores/async-storage | The AsyncStorage object; key prefix, default @folkways/ |
fileStore(dir) | @folkways/realtime/stores/file | A directory, created if missing |
Per-user data and sign-out
Data is kept separately per segment and per identity, so two users on one device never see each other's state. On sign-out, wipe the current user's data:
await client.close({ clear: true });Switching to another user with client.updateToken() wipes the previous user's data automatically.
Encrypt it
Pass a cipher to encrypt what is written to a persistent store:
const client = new Folkways.Realtime({
url,
authUrl,
store: indexedDbStore(),
cipher: {
encrypt: async (plain) => myEncrypt(plain),
decrypt: async (sealed) => myDecrypt(sealed),
},
});Tuning
| Option | Default | Meaning |
|---|---|---|
cache | { messagesPerTopic: 100, maxBytes: 5 MiB } | How much to cache; false turns the cache off |
outbox.maxAgeMs | 600000 (10 min) | Unsent messages older than this fail instead of being resent |
Your own store
A store is a small key-value interface; methods may return promises:
import type { Store } from '@folkways/realtime';
const myStore: Store = {
persistent: true, // true turns on the outbox and cache
get: (key) => db.get(key),
set: (key, value) => db.set(key, value),
delete: (key) => db.delete(key),
keys: (prefix) => db.keysStartingWith(prefix),
clear: (prefix) => db.deleteStartingWith(prefix),
};