@cr_docs_t/dts 0.24.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/dts/Fugue/FNode.d.ts +2 -4
  2. package/dist/dts/Fugue/FNode.d.ts.map +1 -1
  3. package/dist/dts/Fugue/FNode.js +2 -2
  4. package/dist/dts/Fugue/FugueList.d.ts +1 -1
  5. package/dist/dts/Fugue/FugueList.d.ts.map +1 -1
  6. package/dist/dts/Fugue/FugueList.js +10 -15
  7. package/dist/dts/Fugue/index.d.ts +0 -1
  8. package/dist/dts/Fugue/index.d.ts.map +1 -1
  9. package/dist/dts/Fugue/index.js +1 -1
  10. package/dist/dts/FugueTree/FTree.d.ts +147 -0
  11. package/dist/dts/FugueTree/FTree.d.ts.map +1 -0
  12. package/dist/dts/FugueTree/FTree.js +467 -0
  13. package/dist/dts/FugueTree/FugueTree.d.ts +127 -0
  14. package/dist/dts/FugueTree/FugueTree.d.ts.map +1 -0
  15. package/dist/dts/FugueTree/FugueTree.js +351 -0
  16. package/dist/dts/FugueTree/index.d.ts +3 -0
  17. package/dist/dts/FugueTree/index.d.ts.map +1 -0
  18. package/dist/dts/FugueTree/index.js +2 -0
  19. package/dist/dts/Serailizers/Fugue/Message.d.ts +1 -1
  20. package/dist/dts/Serailizers/Fugue/Message.d.ts.map +1 -1
  21. package/dist/dts/Serailizers/Fugue/Message.js +12 -4
  22. package/dist/dts/Serailizers/Fugue/State.d.ts +1 -1
  23. package/dist/dts/Serailizers/Fugue/State.d.ts.map +1 -1
  24. package/dist/dts/Serailizers/FugueTree/Message.d.ts +13 -0
  25. package/dist/dts/Serailizers/FugueTree/Message.d.ts.map +1 -0
  26. package/dist/dts/Serailizers/FugueTree/Message.js +21 -0
  27. package/dist/dts/Serailizers/FugueTree/State.d.ts +9 -0
  28. package/dist/dts/Serailizers/FugueTree/State.d.ts.map +1 -0
  29. package/dist/dts/Serailizers/FugueTree/State.js +16 -0
  30. package/dist/dts/Serailizers/FugueTree/index.d.ts +3 -0
  31. package/dist/dts/Serailizers/FugueTree/index.d.ts.map +1 -0
  32. package/dist/dts/Serailizers/FugueTree/index.js +2 -0
  33. package/dist/dts/Serailizers/index.d.ts +1 -1
  34. package/dist/dts/Serailizers/index.d.ts.map +1 -1
  35. package/dist/dts/Serailizers/index.js +2 -1
  36. package/dist/dts/TotalOrder/StringTotalOrder.d.ts +2 -2
  37. package/dist/dts/TotalOrder/StringTotalOrder.d.ts.map +1 -1
  38. package/dist/dts/index.d.ts +2 -1
  39. package/dist/dts/index.d.ts.map +1 -1
  40. package/dist/dts/index.js +2 -1
  41. package/dist/tests/FugueTree.test.d.ts +2 -0
  42. package/dist/tests/FugueTree.test.d.ts.map +1 -0
  43. package/dist/tests/FugueTree.test.js +8 -0
  44. package/dist/tests/mocks.d.ts +2 -1
  45. package/dist/tests/mocks.d.ts.map +1 -1
  46. package/dist/tests/mocks.js +2 -1
  47. package/dist/types/Fugue/Fugue.d.ts +2 -2
  48. package/dist/types/Fugue/Fugue.d.ts.map +1 -1
  49. package/dist/types/FugueTree/Message.d.ts +42 -0
  50. package/dist/types/FugueTree/Message.d.ts.map +1 -0
  51. package/dist/types/FugueTree/Message.js +27 -0
  52. package/dist/types/FugueTree/index.d.ts +2 -0
  53. package/dist/types/FugueTree/index.d.ts.map +1 -0
  54. package/dist/types/FugueTree/index.js +1 -0
  55. package/dist/types/Models/Schema.d.ts +18 -0
  56. package/dist/types/Models/Schema.d.ts.map +1 -1
  57. package/dist/types/Models/Schema.js +7 -0
  58. package/dist/types/index.d.ts +1 -1
  59. package/dist/types/index.d.ts.map +1 -1
  60. package/dist/types/index.js +2 -1
  61. package/dist/utils/index.d.ts.map +1 -1
  62. package/package.json +1 -1
@@ -0,0 +1,351 @@
1
+ import { Operation } from "../../types/FugueTree/Message.js";
2
+ import { randomString } from "../../utils/index.js";
3
+ import { FugueMessageSerialzier } from "../Serailizers/FugueTree/index.js";
4
+ import { FTree } from "./FTree.js";
5
+ /**
6
+ * A Fugue Tree CRDT, with insert and delete operations.
7
+ */
8
+ export class FugueTree {
9
+ constructor(ws, documentID, userIdentity) {
10
+ this.counter = 0;
11
+ this.replicaID = randomString(3);
12
+ this.pendingMsgs = new Map();
13
+ // Tentative
14
+ this.batchSize = 100;
15
+ this.ws = ws;
16
+ this.documentID = documentID;
17
+ this.userIdentity = userIdentity;
18
+ this.tree = new FTree();
19
+ }
20
+ /**
21
+ * Make msg key for pending messages map
22
+ * @param msg - the message to make key for
23
+ * @returns the key for the message in pending messages map
24
+ */
25
+ makeMsgKey(msg) {
26
+ return `${msg.replicaId}-${msg.id.counter}`;
27
+ }
28
+ /**
29
+ * Propagates message or messages to replicas
30
+ * @param msg - Message or messages to propagate to replicas
31
+ */
32
+ propagate(msg) {
33
+ if (!this.ws)
34
+ return;
35
+ const allMsgs = Array.isArray(msg) ? msg : [msg];
36
+ const serializedFugueMsg = FugueMessageSerialzier.serialize(allMsgs);
37
+ this.ws.send(serializedFugueMsg);
38
+ }
39
+ /**
40
+ * Inserts a value at the given index and returns the corresponding FugueMessage.
41
+ * @param index - the index to insert the value at
42
+ * @param value - the value to insert
43
+ * @returns the FugueMessage representing the insert operation
44
+ */
45
+ insertImpl(index, value) {
46
+ const id = { sender: this.replicaID, counter: this.counter };
47
+ // PERF: optimize by caching the last accessed node and its index,
48
+ // so that if the next insert is nearby, we can start from there instead of the root
49
+ this.counter++;
50
+ const leftOrigin = index === 0 ? this.tree.root : this.tree.getByIndex(this.tree.root, index - 1);
51
+ let msg;
52
+ if (leftOrigin.rightChildren.length === 0) {
53
+ // leftOrigin has no right children, so the new node becomes
54
+ // a right child of leftOrigin.
55
+ msg = {
56
+ userIdentity: this.userIdentity,
57
+ operation: Operation.INSERT,
58
+ id,
59
+ data: value,
60
+ parent: leftOrigin.id,
61
+ side: "R",
62
+ replicaId: this.replicaId(),
63
+ documentID: this.documentID,
64
+ };
65
+ // rightOrigin is the node after leftOrigin in the tree traversal,
66
+ // given that leftOrigin has no right descendants.
67
+ const rightOrigin = this.tree.nextNonDescendant(leftOrigin);
68
+ msg.rightOrigin = rightOrigin === null ? undefined : rightOrigin.id;
69
+ }
70
+ else {
71
+ // Otherwise, the new node is added as a left child of rightOrigin, which
72
+ // is the next node after leftOrigin including deleted nodes.
73
+ // In this case, rightOrigin is the leftmost descendant of leftOrigin's
74
+ // first right child.
75
+ const rightOrigin = this.tree.leftmostDescendant(leftOrigin.rightChildren[0]);
76
+ msg = {
77
+ userIdentity: this.userIdentity,
78
+ operation: Operation.INSERT,
79
+ id,
80
+ data: value,
81
+ parent: rightOrigin.id,
82
+ side: "L",
83
+ replicaId: this.replicaId(),
84
+ documentID: this.documentID,
85
+ };
86
+ }
87
+ msg.userIdentity = this.userIdentity;
88
+ return msg;
89
+ }
90
+ /**
91
+ * Inserts multiple values starting at the given index. This is optimized for batch inserts, such as pasting a large chunk of text.
92
+ * @param index - the index to start inserting values at
93
+ * @param values - the string of values to insert, where each character is inserted as a separate node in the tree
94
+ */
95
+ insertMultiple(index, values) {
96
+ let msgs = [];
97
+ let returnedMsgs = []; //we need this to return messages whether or not we're online
98
+ for (let i = 0; i < values.length; i++) {
99
+ const val = values[i];
100
+ const idx = index + i;
101
+ const msg = this.insertImpl(idx, val);
102
+ this.tree.addNode(msg.id, val, this.tree.getByID(msg.parent), msg.side, msg.rightOrigin);
103
+ msgs.push(msg);
104
+ returnedMsgs.push(msg);
105
+ // Propagate this batch
106
+ if (msgs.length >= this.batchSize) {
107
+ if (this.ws?.readyState === WebSocket.OPEN) {
108
+ this.propagate(msgs);
109
+ msgs = [];
110
+ }
111
+ }
112
+ }
113
+ // Propagate any remaining messages that didn't fill up the last batch
114
+ if (msgs.length > 0) {
115
+ if (this.ws?.readyState === WebSocket.OPEN) {
116
+ this.propagate(msgs);
117
+ msgs = [];
118
+ }
119
+ }
120
+ return returnedMsgs;
121
+ }
122
+ /**
123
+ * Inserts a value at the given index and propagates the corresponding FugueMessage to replicas.
124
+ * @param index - the index to insert the value at
125
+ * @param value - the value to insert
126
+ */
127
+ insert(index, value) {
128
+ const msg = this.insertImpl(index, value);
129
+ this.tree.addNode(msg.id, value, this.tree.getByID(msg.parent), msg.side, msg.rightOrigin);
130
+ this.propagate(msg);
131
+ }
132
+ /**
133
+ * Deletes the value at the given index and returns the corresponding FugueMessage.
134
+ * @param index - the index to delete the value at
135
+ * @returns the FugueMessage representing the delete operation
136
+ */
137
+ deleteImpl(index) {
138
+ const node = this.tree.getByIndex(this.tree.root, index);
139
+ if (!node.isDeleted) {
140
+ node.value = null;
141
+ node.isDeleted = true;
142
+ this.tree.updateSize(node, -1);
143
+ }
144
+ const msg = {
145
+ operation: Operation.DELETE,
146
+ documentID: this.documentID,
147
+ replicaId: this.replicaID,
148
+ userIdentity: this.userIdentity,
149
+ id: node.id,
150
+ data: null,
151
+ side: "R",
152
+ };
153
+ return msg;
154
+ }
155
+ /**
156
+ * Deletes multiple values starting at the given index. This is optimized for batch deletes, such as deleting a large chunk of text.
157
+ * @param index - the index to start deleting values at
158
+ * @param length - the number of characters to delete, starting from the index
159
+ */
160
+ deleteMultiple(index, length) {
161
+ let msgs = [];
162
+ let returnedMsgs = [];
163
+ for (let i = 0; i < length; i++) {
164
+ const msg = this.deleteImpl(index);
165
+ msgs.push(msg);
166
+ returnedMsgs.push(msg);
167
+ // Propagate this batch
168
+ if (msgs.length >= this.batchSize) {
169
+ if (this.ws?.readyState === WebSocket.OPEN) {
170
+ this.propagate(msgs);
171
+ msgs = [];
172
+ }
173
+ }
174
+ }
175
+ // Propagate any remaining messages that didn't fill up the last batch
176
+ if (msgs.length > 0) {
177
+ if (this.ws?.readyState === WebSocket.OPEN) {
178
+ this.propagate(msgs);
179
+ msgs = [];
180
+ }
181
+ }
182
+ return returnedMsgs;
183
+ }
184
+ /**
185
+ * Deletes the value at the given index and propagates the corresponding FugueMessage to replicas.
186
+ * @param index - the index to delete the value at
187
+ */
188
+ delete(index) {
189
+ const msg = this.deleteImpl(index);
190
+ this.propagate(msg);
191
+ }
192
+ /**
193
+ * Applies a FugueMessage to the tree. Returns true if the message was successfully applied,
194
+ * or false if it could not be applied due to missing dependencies (e.g. parent node for an insert).
195
+ * @param msg - the FugueMessage to apply to the tree
196
+ */
197
+ applyToTree(msg) {
198
+ const { operation, data, id, parent, side, rightOrigin } = msg;
199
+ switch (operation) {
200
+ case Operation.INSERT:
201
+ try {
202
+ if (!data)
203
+ throw Error("Data is required for Operation.INSERT");
204
+ if (!parent)
205
+ throw Error("Parent is required for Operation.INSERT");
206
+ this.tree.addNode(id, data, this.tree.getByID(parent), side, rightOrigin);
207
+ return true;
208
+ }
209
+ catch (e) {
210
+ return false;
211
+ }
212
+ case Operation.DELETE:
213
+ try {
214
+ const node = this.tree.getByID(id);
215
+ if (!node.isDeleted) {
216
+ node.value = null;
217
+ node.isDeleted = true;
218
+ this.tree.updateSize(node, -1);
219
+ }
220
+ return true;
221
+ }
222
+ catch (e) {
223
+ return false;
224
+ }
225
+ default:
226
+ throw Error("Invalid operation");
227
+ }
228
+ }
229
+ /**
230
+ * Processes pending messages that may now be applicable after applying new messages.
231
+ * This is called after successfully applying new messages, to check if any pending messages can now be applied due to their dependencies being satisfied.
232
+ * @param applied - the list of messages that were just applied, which may have satisfied dependencies for pending messages
233
+ */
234
+ processPending(applied) {
235
+ let changed = true;
236
+ // Iteratively try to apply pending messages until no more can be applied
237
+ // This avoids recursion and handles deep causal chains (A -> B -> C)
238
+ while (changed && this.pendingMsgs.size > 0) {
239
+ changed = false;
240
+ for (const [id, msg] of this.pendingMsgs) {
241
+ if (this.applyToTree(msg)) {
242
+ applied.push(msg);
243
+ this.pendingMsgs.delete(id);
244
+ changed = true;
245
+ }
246
+ }
247
+ }
248
+ }
249
+ /**
250
+ * Applies effect messages to the list
251
+ * @param msg - Message or messages to apply effect for, can be batched
252
+ * @returns the list of messages that were successfully applied
253
+ */
254
+ effect(msg) {
255
+ const applied = [];
256
+ const msgs = Array.isArray(msg) ? msg : [msg];
257
+ for (const msg of msgs) {
258
+ // Skip messages from this replica
259
+ if (msg.replicaId == this.replicaId())
260
+ continue;
261
+ const succ = this.applyToTree(msg);
262
+ if (succ) {
263
+ applied.push(msg);
264
+ }
265
+ else {
266
+ // Deduplication of pending messages
267
+ if (!this.pendingMsgs.has(this.makeMsgKey(msg)))
268
+ this.pendingMsgs.set(this.makeMsgKey(msg), msg);
269
+ }
270
+ }
271
+ if (applied.length > 0) {
272
+ this.processPending(applied);
273
+ }
274
+ return applied;
275
+ }
276
+ /**
277
+ * Gets the value at the given index in the visible string.
278
+ * @param index - the index to get the value at, where the index is based on the visible string
279
+ * @returns the value at the given index in the visible string
280
+ */
281
+ get(index) {
282
+ if (index < 0 || index >= this.length()) {
283
+ throw new Error("Index out of bounds");
284
+ }
285
+ const node = this.tree.getByIndex(this.tree.root, index);
286
+ return node.value;
287
+ }
288
+ /**
289
+ * Gets the length of the visible string, which is the number of non-deleted nodes in the tree.
290
+ * @returns the length of the visible string
291
+ */
292
+ length() {
293
+ return this.tree.root.size;
294
+ }
295
+ /**
296
+ * Returns the visible string by traversing the tree and concatenating the values of non-deleted nodes.
297
+ * @returns the visible string represented by the tree, which is the concatenation of values of non-deleted nodes in traversal order
298
+ */
299
+ observe() {
300
+ // PERF: find a way to just use the iterator without concatenating the whole string,
301
+ // since that can be expensive for large documents and we may only need to observe a
302
+ // portion of the document at a time (e.g. for rendering a viewport).
303
+ let res = "";
304
+ for (const t of this.tree.traverse(this.tree.root)) {
305
+ res += t;
306
+ }
307
+ return res;
308
+ }
309
+ /**
310
+ * Serializes the tree into a Uint8Array.
311
+ * @returns a Uint8Array representing the serialized tree.
312
+ */
313
+ save() {
314
+ const bytes = this.tree.save();
315
+ return bytes;
316
+ }
317
+ /**
318
+ * Loads the tree from a Uint8Array. This replaces the current tree with the loaded tree.
319
+ * @param data - a Uint8Array representing the serialized tree to load.
320
+ */
321
+ load(data) {
322
+ if (!data)
323
+ return;
324
+ this.tree.load(data);
325
+ }
326
+ /**
327
+ * Gets the replica ID of this FugueTree instance, which is a unique identifier for this replica in the distributed system.
328
+ * The replica ID is used in messages to identify the source of operations and to ensure that operations from the same replica
329
+ * are applied in order.
330
+ * @returns
331
+ */
332
+ replicaId() {
333
+ return this.replicaID;
334
+ }
335
+ /**
336
+ * Gets the FNode corresponding to the given ID.
337
+ * @param id - the ID of the node to retrieve
338
+ * @returns the FNode corresponding to the given ID, or null if no such node exists in the tree
339
+ */
340
+ getById(id) {
341
+ return this.tree.getByID(id);
342
+ }
343
+ /**
344
+ * Gets the index of the given node in the visible string.
345
+ * @param node - the FNode to get the visible index of
346
+ * @returns the index of the given node in the visible string
347
+ */
348
+ getVisibleIndex(node) {
349
+ return this.tree.getVisibleIndex(node);
350
+ }
351
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./FTree.js";
2
+ export * from "./FugueTree.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dts/FugueTree/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./FTree.js";
2
+ export * from "./FugueTree.js";
@@ -1,4 +1,4 @@
1
- import { FugueMessageType } from "../../../types/index.js";
1
+ import { FugueMessageType } from "../../../types/Fugue/index.js";
2
2
  declare function serialize<P>(msgs: FugueMessageType<P>[]): Uint8Array<ArrayBuffer>;
3
3
  declare function deserialize<P>(data: Uint8Array): FugueMessageType<P>[];
4
4
  export declare const FugueMessageSerialzier: {
@@ -1 +1 @@
1
- {"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../../../src/dts/Serailizers/Fugue/Message.ts"],"names":[],"mappings":"AACA,OAAO,EAGH,gBAAgB,EAInB,MAAM,yBAAyB,CAAC;AAEjC,iBAAS,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,2BAEhD;AAED,iBAAS,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAM/D;AAqDD,eAAO,MAAM,sBAAsB;;;CAGlC,CAAC"}
1
+ {"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../../../src/dts/Serailizers/Fugue/Message.ts"],"names":[],"mappings":"AACA,OAAO,EAGH,gBAAgB,EAInB,MAAM,+BAA+B,CAAC;AAEvC,iBAAS,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,2BAEhD;AAED,iBAAS,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAM/D;AA6DD,eAAO,MAAM,sBAAsB;;;CAGlC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { encode, decode } from "@msgpack/msgpack";
2
- import { Operation, } from "../../../types/index.js";
2
+ import { Operation, } from "../../../types/Fugue/index.js";
3
3
  function serialize(msgs) {
4
4
  return encode(msgs.map((m) => toTuple(m)));
5
5
  }
@@ -14,7 +14,15 @@ function toTuple(msg) {
14
14
  // Check if msg is of FugueJoinMessage type
15
15
  switch (msg.operation) {
16
16
  case Operation.JOIN:
17
- return [msg.operation, msg.documentID, msg.state, msg.userIdentity, msg.collaborators, msg.offlineChanges, msg.replicaId];
17
+ return [
18
+ msg.operation,
19
+ msg.documentID,
20
+ msg.state,
21
+ msg.userIdentity,
22
+ msg.collaborators,
23
+ msg.offlineChanges,
24
+ msg.replicaId,
25
+ ];
18
26
  case Operation.INSERT:
19
27
  case Operation.DELETE:
20
28
  return [msg.operation, msg.documentID, msg.replicaId, msg.position, msg.data, msg.userIdentity];
@@ -35,7 +43,7 @@ function fromTuple(tuple) {
35
43
  userIdentity: tuple[3],
36
44
  collaborators: tuple[4],
37
45
  offlineChanges: tuple[5],
38
- replicaId: tuple[6]
46
+ replicaId: tuple[6],
39
47
  };
40
48
  case Operation.INSERT:
41
49
  case Operation.DELETE:
@@ -54,7 +62,7 @@ function fromTuple(tuple) {
54
62
  case Operation.LEAVE:
55
63
  return {
56
64
  operation: tuple[0],
57
- userIdentity: tuple[1]
65
+ userIdentity: tuple[1],
58
66
  };
59
67
  }
60
68
  throw new Error("Unknown tuple format");
@@ -1,4 +1,4 @@
1
- import { FugueState } from "../../../types/index.js";
1
+ import { FugueState } from "../../../types/Fugue/index.js";
2
2
  declare function serialize(state: FugueState<string>): Uint8Array<ArrayBufferLike>;
3
3
  declare function deserialize(compressed: Uint8Array<ArrayBufferLike>): FugueState<string>;
4
4
  export declare const FugueStateSerializer: {
@@ -1 +1 @@
1
- {"version":3,"file":"State.d.ts","sourceRoot":"","sources":["../../../../src/dts/Serailizers/Fugue/State.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,iBAAS,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,eAAe,CAAC,CAKzE;AAED,iBAAS,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC,eAAe,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAIhF;AAED,eAAO,MAAM,oBAAoB;;;CAGhC,CAAC"}
1
+ {"version":3,"file":"State.d.ts","sourceRoot":"","sources":["../../../../src/dts/Serailizers/Fugue/State.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,iBAAS,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,eAAe,CAAC,CAKzE;AAED,iBAAS,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC,eAAe,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAIhF;AAED,eAAO,MAAM,oBAAoB;;;CAGhC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { BaseFugueMessage, FugueMessageType } from "../../../types/FugueTree/index.js";
2
+ declare function serialize(msgs: BaseFugueMessage[]): Uint8Array<ArrayBuffer>;
3
+ declare function serializeSingleMessage(msg: FugueMessageType): Uint8Array<ArrayBuffer>;
4
+ declare function deserialize(data: Uint8Array): BaseFugueMessage[];
5
+ declare function deserializeSingleMessage(data: Uint8Array): BaseFugueMessage;
6
+ export declare const FugueMessageSerialzier: {
7
+ serialize: typeof serialize;
8
+ serializeSingleMessage: typeof serializeSingleMessage;
9
+ deserialize: typeof deserialize;
10
+ deserializeSingleMessage: typeof deserializeSingleMessage;
11
+ };
12
+ export {};
13
+ //# sourceMappingURL=Message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../../../src/dts/Serailizers/FugueTree/Message.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAEvF,iBAAS,SAAS,CAAC,IAAI,EAAE,gBAAgB,EAAE,2BAE1C;AAED,iBAAS,sBAAsB,CAAC,GAAG,EAAE,gBAAgB,2BAEpD;AAED,iBAAS,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,gBAAgB,EAAE,CAGzD;AAED,iBAAS,wBAAwB,CAAC,IAAI,EAAE,UAAU,GAAG,gBAAgB,CAGpE;AAED,eAAO,MAAM,sBAAsB;;;;;CAKlC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { encode, decode } from "@msgpack/msgpack";
2
+ function serialize(msgs) {
3
+ return encode(msgs);
4
+ }
5
+ function serializeSingleMessage(msg) {
6
+ return encode(msg);
7
+ }
8
+ function deserialize(data) {
9
+ const dec = decode(data);
10
+ return dec;
11
+ }
12
+ function deserializeSingleMessage(data) {
13
+ const dec = decode(data);
14
+ return dec;
15
+ }
16
+ export const FugueMessageSerialzier = {
17
+ serialize,
18
+ serializeSingleMessage,
19
+ deserialize,
20
+ deserializeSingleMessage,
21
+ };
@@ -0,0 +1,9 @@
1
+ import { FTree } from "../../FugueTree/index.js";
2
+ declare function serialize(state: FTree): Uint8Array<ArrayBufferLike>;
3
+ declare function deserialize(compressed: Uint8Array<ArrayBufferLike>): FTree;
4
+ export declare const FugueStateSerializer: {
5
+ serialize: typeof serialize;
6
+ deserialize: typeof deserialize;
7
+ };
8
+ export {};
9
+ //# sourceMappingURL=State.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"State.d.ts","sourceRoot":"","sources":["../../../../src/dts/Serailizers/FugueTree/State.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAEjD,iBAAS,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,UAAU,CAAC,eAAe,CAAC,CAG5D;AAED,iBAAS,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC,eAAe,CAAC,GAAG,KAAK,CAMnE;AAED,eAAO,MAAM,oBAAoB;;;CAGhC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { FTree } from "../../FugueTree/index.js";
2
+ function serialize(state) {
3
+ // return compress(state.save())
4
+ return state.save();
5
+ }
6
+ function deserialize(compressed) {
7
+ // const raw = decompress(compressed);
8
+ const raw = compressed;
9
+ const state = new FTree();
10
+ state.load(raw);
11
+ return state;
12
+ }
13
+ export const FugueStateSerializer = {
14
+ serialize,
15
+ deserialize,
16
+ };
@@ -0,0 +1,3 @@
1
+ export * from "./Message.js";
2
+ export * from "./State.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/dts/Serailizers/FugueTree/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./Message.js";
2
+ export * from "./State.js";
@@ -1,2 +1,2 @@
1
- export * from "./Fugue/index.js";
1
+ export * from "./FugueTree/index.js";
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dts/Serailizers/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dts/Serailizers/index.ts"],"names":[],"mappings":"AACA,cAAc,sBAAsB,CAAC"}
@@ -1 +1,2 @@
1
- export * from "./Fugue/index.js";
1
+ // export * from "./Fugue/index.js";
2
+ export * from "./FugueTree/index.js";
@@ -4,8 +4,8 @@ export declare class StringTotalOrder implements UniquelyDenseTotalOrder<StringP
4
4
  readonly replicaID: string;
5
5
  private counter;
6
6
  getReplicaId(): string;
7
- compare(a: string, b: string): number;
7
+ compare(a: StringPosition, b: StringPosition): number;
8
8
  constructor(replicaID: string);
9
- createBetween(a?: string, b?: string): string;
9
+ createBetween(a?: StringPosition, b?: StringPosition): string;
10
10
  }
11
11
  //# sourceMappingURL=StringTotalOrder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"StringTotalOrder.d.ts","sourceRoot":"","sources":["../../../src/dts/TotalOrder/StringTotalOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAEpC,qBAAa,gBAAiB,YAAW,uBAAuB,CAAC,cAAc,CAAC;IAC5E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,OAAO,CAAK;IAEpB,YAAY,IAAI,MAAM;IAItB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;gBAIzB,SAAS,EAAE,MAAM;IAI7B,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;CA6BhD"}
1
+ {"version":3,"file":"StringTotalOrder.d.ts","sourceRoot":"","sources":["../../../src/dts/TotalOrder/StringTotalOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAEpC,qBAAa,gBAAiB,YAAW,uBAAuB,CAAC,cAAc,CAAC;IAC5E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,OAAO,CAAK;IAEpB,YAAY,IAAI,MAAM;IAItB,OAAO,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,cAAc,GAAG,MAAM;gBAIzC,SAAS,EAAE,MAAM;IAI7B,aAAa,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM;CA6BhE"}
@@ -1,5 +1,6 @@
1
1
  export * from "./CausalTree/index.js";
2
- export * from "./Fugue/index.js";
3
2
  export * from "./Serailizers/index.js";
4
3
  export * from "./TotalOrder/index.js";
4
+ export * from "./Fugue/index.js";
5
+ export * from "./FugueTree/index.js";
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dts/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dts/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
package/dist/dts/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./CausalTree/index.js";
2
- export * from "./Fugue/index.js";
3
2
  export * from "./Serailizers/index.js";
4
3
  export * from "./TotalOrder/index.js";
4
+ export * from "./Fugue/index.js";
5
+ export * from "./FugueTree/index.js";
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=FugueTree.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FugueTree.test.d.ts","sourceRoot":"","sources":["../../src/tests/FugueTree.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import { emptyFugueTree } from "./mocks.js";
2
+ describe("Fugue Tree Tests", () => {
3
+ describe("Given a Fugue tree ", () => {
4
+ test("Empty Fugue treee has an empty string", () => {
5
+ expect(emptyFugueTree.observe()).toBe("");
6
+ });
7
+ });
8
+ });
@@ -1,3 +1,4 @@
1
- import { FugueList } from "../dts/index.js";
1
+ import { FugueList, FugueTree } from "../dts/index.js";
2
2
  export declare const emptyFugueList: FugueList<string>;
3
+ export declare const emptyFugueTree: FugueTree;
3
4
  //# sourceMappingURL=mocks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mocks.d.ts","sourceRoot":"","sources":["../../src/tests/mocks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAoB,MAAM,iBAAiB,CAAC;AAG9D,eAAO,MAAM,cAAc,mBAI1B,CAAC"}
1
+ {"version":3,"file":"mocks.d.ts","sourceRoot":"","sources":["../../src/tests/mocks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAoB,MAAM,iBAAiB,CAAC;AAGzE,eAAO,MAAM,cAAc,mBAI1B,CAAC;AAEF,eAAO,MAAM,cAAc,WAA2E,CAAC"}
@@ -1,3 +1,4 @@
1
- import { FugueList, StringTotalOrder } from "../dts/index.js";
1
+ import { FugueList, FugueTree, StringTotalOrder } from "../dts/index.js";
2
2
  import crypto from "crypto";
3
3
  export const emptyFugueList = new FugueList(new StringTotalOrder(crypto.randomBytes(3).toString("hex")), null, crypto.randomBytes(24).toString("hex"));
4
+ export const emptyFugueTree = new FugueTree(null, crypto.randomBytes(24).toString("hex"), "test-tree");
@@ -1,3 +1,3 @@
1
- import { FNode } from "../../dts/index.js";
2
- export type FugueState<P> = FNode<P>[][];
1
+ import { FListNode } from "../../dts/Fugue/FNode.js";
2
+ export type FugueState<P> = FListNode<P>[][];
3
3
  //# sourceMappingURL=Fugue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Fugue.d.ts","sourceRoot":"","sources":["../../../src/types/Fugue/Fugue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC"}
1
+ {"version":3,"file":"Fugue.d.ts","sourceRoot":"","sources":["../../../src/types/Fugue/Fugue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC"}