UNPKG

2.24 kBJavaScriptView Raw
1import { createStore } from "./store.js";
2export const getCollection = (conn, key, fetchCollection, subscribeUpdates) => {
3 if (conn[key]) {
4 return conn[key];
5 }
6 let active = 0;
7 let unsubProm;
8 let store = createStore();
9 const refresh = () => fetchCollection(conn).then(state => store.setState(state, true));
10 const refreshSwallow = () => refresh().catch((err) => {
11 // Swallow errors if socket is connecting, closing or closed.
12 // We will automatically call refresh again when we re-establish the connection.
13 // Using conn.socket.OPEN instead of WebSocket for better node support
14 if (conn.socket.readyState == conn.socket.OPEN) {
15 throw err;
16 }
17 });
18 conn[key] = {
19 get state() {
20 return store.state;
21 },
22 refresh,
23 subscribe(subscriber) {
24 active++;
25 // If this was the first subscriber, attach collection
26 if (active === 1) {
27 if (subscribeUpdates) {
28 unsubProm = subscribeUpdates(conn, store);
29 }
30 // Fetch when connection re-established.
31 conn.addEventListener("ready", refreshSwallow);
32 refreshSwallow();
33 }
34 const unsub = store.subscribe(subscriber);
35 if (store.state !== undefined) {
36 // Don't call it right away so that caller has time
37 // to initialize all the things.
38 setTimeout(() => subscriber(store.state), 0);
39 }
40 return () => {
41 unsub();
42 active--;
43 if (!active) {
44 // Unsubscribe from changes
45 if (unsubProm)
46 unsubProm.then(unsub => {
47 unsub();
48 });
49 conn.removeEventListener("ready", refresh);
50 }
51 };
52 }
53 };
54 return conn[key];
55};
56// Legacy name. It gets a collection and subscribes.
57export const createCollection = (key, fetchCollection, subscribeUpdates, conn, onChange) => getCollection(conn, key, fetchCollection, subscribeUpdates).subscribe(onChange);