-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathUnifiedApi.re
112 lines (99 loc) · 2.83 KB
/
UnifiedApi.re
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/** Demonstration of provided binding API that emulates more idiomatic functional usage (has no assignment in [change] function). It uses Automerge JS implementation under the hood right now, but the interface should be universal enough to stay the same even for a purely functional implementation.
THIS API IS RECOMMENDED for general usage.
*/;
open InfixRe;
module MActorId = {
type t = string;
let ofString = t => Some(t);
let toString = t => t;
let ofStringExn = t => t;
};
module UniAM = Automerge.UniJs.Make(MActorId);
let d1 =
UniAM.(
make(MActorId.ofStringExn("aaaaaaaa"))
|> change("test", root =>
Json.(
root
|> Map.add(
"ufoo",
List.(
create()
|> prepend(int(19))
|> prepend(int(11))
|> prepend(int(20))
|> prepend(int(42))
|> toJson
),
)
|> Map.add("asdf", string("asdf"))
)
)
);
let merge = (d1, d2) =>
UniAM.(d2 |> applyChanges(d1 |> getChangesFromTime(d2 |> getClock)));
let d2a =
UniAM.(
make(MActorId.ofStringExn("bbbbbbbb"))
|> merge(d1)
|> change("get crazy", root => {
open Json;
let newRoot = root |> Map.add("asdf", string("paulus"));
switch (root |> Map.get("ufoo") |?> List.ofJson) {
| Some(ufoo) =>
newRoot
|> Map.add("ufoo", ufoo |> List.set(2, int(15)) |> List.toJson)
| None => newRoot
};
})
);
let d2b =
UniAM.(
d1
|> change("get dizzy", root => {
open Json;
let newRoot = root |> Map.add("asdf", string("omangus"));
switch (root |> Map.get("ufoo") |?> List.ofJson) {
| Some(ufoo) =>
newRoot
|> Map.add("ufoo", ufoo |> List.set(2, int(9)) |> List.toJson)
| None => newRoot
};
})
);
let merged = merge(d2a, d2b);
let clockForRemote = d2a |> UniAM.getClock;
let changesFromRemote = d2b |> UniAM.getChangesFromTime(clockForRemote);
let merged2 = d2a |> UniAM.applyChanges(changesFromRemote);
/* switch (merged |> UniAM.root |> UniAM.Json.Map.get("ufoo")) {
| Some(ufoo) =>
let conflicts = ufoo->UniAM.getArrayConflicts;
Js.log(conflicts);
();
| None => ()
}; */
Js.log2("merged2", merged2);
UniAM.(
merged2
|> root
|> Json.Map.getC("asdf")
|?>> (
conflictable => {
let conflictingValues =
switch (conflictable.conflicts) {
| Some(conflicts) =>
Json.ConflictValues.fold(
(_actorId, value, lst) => [value, ...lst],
conflicts,
[],
)
| None => []
};
Js.log(
[conflictable.value, ...conflictingValues]
->Belt.List.keepMap(Json.asString),
);
}
)
|? ()
);