PRODUCTS

Real-time Sync

Keep devices and users in step. Channels carry messages between everyone using your app, and the client keeps your data working while the connection comes and goes.

  • Channels. Publish to a named channel and every subscriber gets the message, whichever key they use: chat, presence, live cursors, "this changed, reload it".
  • Offline queueing. Writes made without a connection are queued on the device and sent when it's back. Reads of the same key keep working from the local copy.
  • Optimistic updates. Show a change right away and let the client confirm it with the server, or roll it back if the server refuses it.
  • Sync events. One listener tells you when something was queued, pushed, confirmed or rolled back.

Channels are polled (every 3 seconds by default), and messages are kept for 3 days: use them for live updates, and the regular read and write calls for anything you need to keep. Anyone who knows a channel's name can use it, so give it a name that's hard to guess.


1// load prefsdb.channels.v1.min.js after prefsdb.v1.min.js
2const db = await PrefsDB.getkey("my-app", words);
3const room = db.channel("my-app-room-42");
4 
5// every subscriber sees every message, oldest first
6const stop = room.subscribe((msg) => {
7 show(msg.sender, msg.value);
8});
9 
10await room.publish({ text: "hello" });
11 
12// later
13stop();
1const db = await PrefsDB.getkey("my-app", words);
2 
3// offline? the write is queued on the device
4// and replayed when the connection comes back
5await db.key("draft").write(text);
6 
7// reads of that key are served from the local copy
8const draft = await db.key("draft").read();
9 
10PrefsDB.onSyncEvent((e) => {
11 if (e.phase === "pushed") markSaved(e.key);
12});
1const db = await PrefsDB.getkey("my-app", words);
2 
3// apply locally now, confirm with the server after
4await db.key("likes")
5 .write(likes + 1, { optimistic: true });
6 
7PrefsDB.onSyncEvent((e) => {
8 if (e.phase === "optimistic-rollback") {
9 // the server refused it: the old value is back
10 render();
11 }
12});
1# publish to a channel
2curl -s -X POST "https://prefsdb.com/api/v1/channel/publish/?channel=my-app-room-42" \
3 -H "X-Authorization: Token $KEY" -b cookies.txt \
4 -H "Content-Type: text/plain" --data "hello"
5 
6# fetch messages after cursor 0
7curl -s "https://prefsdb.com/api/v1/channel/poll/?channel=my-app-room-42&since=0" \
8 -H "X-Authorization: Token $KEY" -b cookies.txt
9 
10# => { "success": true, "cursor": "17",
11# "messages": [{ "id": "17", "sender": "...", "value": "hello" }] }