a proof of concept realtime collaborative todo list
1.3 kB
48 lines
1// One Jetstream subscription, filtered server-side to the DIDs + collections
2// we care about. Each commit comes through as JSON with the record inline, so
3// we don't need to re-fetch.
4
5export function subscribe({ dids, collections, onCommit }) {
6 const url = new URL("wss://jetstream1.us-east.bsky.network/subscribe");
7 for (const d of dids) url.searchParams.append("wantedDids", d);
8 for (const c of collections) url.searchParams.append("wantedCollections", c);
9
10 let ws;
11 let closed = false;
12 let retry = 0;
13
14 const open = () => {
15 if (closed) return;
16 ws = new WebSocket(url);
17 ws.onopen = () => (retry = 0);
18 ws.onmessage = (e) => {
19 let msg;
20 try {
21 msg = JSON.parse(e.data);
22 } catch {
23 return;
24 }
25 if (msg.kind !== "commit" || !msg.commit) return;
26 onCommit({
27 did: msg.did,
28 collection: msg.commit.collection,
29 rkey: msg.commit.rkey,
30 cid: msg.commit.cid ?? null,
31 action: msg.commit.operation,
32 record: msg.commit.record ?? null,
33 });
34 };
35 ws.onclose = () => {
36 if (closed) return;
37 retry++;
38 setTimeout(open, Math.min(1000 * 2 ** retry, 30000));
39 };
40 ws.onerror = () => {};
41 };
42
43 open();
44 return () => {
45 closed = true;
46 ws?.close();
47 };
48}