-
Notifications
You must be signed in to change notification settings - Fork 0
/
worker.ts
71 lines (60 loc) · 1.66 KB
/
worker.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import {
from,
init,
applyChanges,
getAllChanges,
change,
initSyncState,
generateSyncMessage,
receiveSyncMessage,
SyncState,
} from "@livingspec/automerge-wasm";
import { applySlateOps, RootWithCursors, toSync } from "../automerge-slate";
let doc: RootWithCursors;
let docSyncState: SyncState;
let remoteDoc = init();
let remoteDocSyncState: SyncState;
onmessage = (message) => {
if (message.data.type === "init") {
doc = from({ cursors: {}, children: [toSync(message.data.state)] });
} else if (message.data.type === "operation") {
doc = change(doc, applySlateOps(message.data.operations));
// simulate re-hydrating, which we have to do at a certain point due to high memory usage
applyChanges(init(), getAllChanges(doc));
// simulate sync
[doc, remoteDoc, docSyncState, remoteDocSyncState] = sync(
doc,
remoteDoc,
docSyncState,
remoteDocSyncState
);
}
};
function sync(
a,
b,
aSyncState = initSyncState(),
bSyncState = initSyncState()
) {
const MAX_ITER = 10;
let aToBmsg = null;
let bToAmsg = null;
let i = 0;
do {
[aSyncState, aToBmsg] = generateSyncMessage(a, aSyncState);
[bSyncState, bToAmsg] = generateSyncMessage(b, bSyncState);
if (aToBmsg) {
[b, bSyncState] = receiveSyncMessage(b, bSyncState, aToBmsg);
}
if (bToAmsg) {
[a, aSyncState] = receiveSyncMessage(a, aSyncState, bToAmsg);
}
if (i++ > MAX_ITER) {
throw new Error(
`Did not synchronize within ${MAX_ITER} iterations. Do you have a bug causing an infinite loop?`
);
}
} while (aToBmsg || bToAmsg);
return [a, b, aSyncState, bSyncState];
}
postMessage("ping");