@vuer-ai/vuer-rtc-server 0.2.3 → 0.4.1

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 (104) hide show
  1. package/.env +1 -1
  2. package/README.md +56 -0
  3. package/dist/archive/ArchivalService.js +1 -1
  4. package/dist/archive/ArchivalService.js.map +1 -1
  5. package/dist/broker/InMemoryBroker.d.ts +2 -2
  6. package/dist/broker/InMemoryBroker.d.ts.map +1 -1
  7. package/dist/broker/InMemoryBroker.js +4 -4
  8. package/dist/broker/InMemoryBroker.js.map +1 -1
  9. package/dist/broker/types.d.ts +3 -3
  10. package/dist/broker/types.d.ts.map +1 -1
  11. package/dist/journal/CoalescingService.d.ts.map +1 -1
  12. package/dist/journal/CoalescingService.js +18 -208
  13. package/dist/journal/CoalescingService.js.map +1 -1
  14. package/dist/journal/GraphJournalService.d.ts +127 -0
  15. package/dist/journal/GraphJournalService.d.ts.map +1 -0
  16. package/dist/journal/GraphJournalService.js +491 -0
  17. package/dist/journal/GraphJournalService.js.map +1 -0
  18. package/dist/journal/JournalRLE.d.ts +2 -2
  19. package/dist/journal/JournalRLE.js +14 -14
  20. package/dist/journal/JournalRLE.js.map +1 -1
  21. package/dist/journal/JournalRepository.js +7 -7
  22. package/dist/journal/JournalRepository.js.map +1 -1
  23. package/dist/journal/JournalService.d.ts.map +1 -1
  24. package/dist/journal/JournalService.js +6 -40
  25. package/dist/journal/JournalService.js.map +1 -1
  26. package/dist/journal/RLECompression.d.ts +9 -9
  27. package/dist/journal/RLECompression.d.ts.map +1 -1
  28. package/dist/journal/RLECompression.js +22 -22
  29. package/dist/journal/RLECompression.js.map +1 -1
  30. package/dist/journal/TextJournalService.d.ts +98 -0
  31. package/dist/journal/TextJournalService.d.ts.map +1 -0
  32. package/dist/journal/TextJournalService.js +401 -0
  33. package/dist/journal/TextJournalService.js.map +1 -0
  34. package/dist/journal/index.d.ts +3 -1
  35. package/dist/journal/index.d.ts.map +1 -1
  36. package/dist/journal/index.js +4 -1
  37. package/dist/journal/index.js.map +1 -1
  38. package/dist/journal/rle-demo.js +11 -11
  39. package/dist/journal/rle-demo.js.map +1 -1
  40. package/dist/serve.d.ts +29 -11
  41. package/dist/serve.d.ts.map +1 -1
  42. package/dist/serve.js +558 -93
  43. package/dist/serve.js.map +1 -1
  44. package/dist/transport/RTCServer.d.ts +2 -2
  45. package/dist/transport/RTCServer.d.ts.map +1 -1
  46. package/dist/transport/RTCServer.js +22 -22
  47. package/dist/transport/RTCServer.js.map +1 -1
  48. package/docs/API.md +642 -0
  49. package/examples/compression-example.ts +3 -3
  50. package/package.json +2 -2
  51. package/prisma/schema.prisma +124 -6
  52. package/src/archive/ArchivalService.ts +1 -1
  53. package/src/broker/InMemoryBroker.ts +4 -4
  54. package/src/broker/types.ts +3 -3
  55. package/src/journal/CoalescingService.ts +18 -235
  56. package/src/journal/{JournalService.ts → GraphJournalService.ts} +34 -74
  57. package/src/journal/JournalRLE.ts +15 -15
  58. package/src/journal/JournalRepository.ts +7 -7
  59. package/src/journal/RLECompression.ts +24 -24
  60. package/src/journal/TextJournalService.ts +483 -0
  61. package/src/journal/index.ts +10 -2
  62. package/src/journal/rle-demo.ts +11 -11
  63. package/src/serve.ts +598 -94
  64. package/src/transport/RTCServer.ts +23 -23
  65. package/tests/benchmark/journal-optimization-benchmark.test.ts +14 -14
  66. package/tests/compression/compression.test.ts +8 -8
  67. package/tests/demo.ts +88 -88
  68. package/tests/e2e/convergence.test.ts +9 -9
  69. package/tests/e2e/helpers/assertions.ts +22 -0
  70. package/tests/e2e/helpers/createTestServer.ts +4 -4
  71. package/tests/e2e/latency.test.ts +47 -41
  72. package/tests/e2e/packet-loss.test.ts +6 -6
  73. package/tests/e2e/relay.test.ts +9 -9
  74. package/tests/e2e/sync-perf.test.ts +5 -5
  75. package/tests/e2e/sync-reconciliation.test.ts +6 -6
  76. package/tests/e2e/text-sync.test.ts +14 -14
  77. package/tests/e2e/tombstone-convergence.test.ts +22 -22
  78. package/tests/fixtures/array-ops.jsonl +6 -6
  79. package/tests/fixtures/boolean-ops.jsonl +6 -6
  80. package/tests/fixtures/color-ops.jsonl +4 -4
  81. package/tests/fixtures/edit-buffer.jsonl +3 -3
  82. package/tests/fixtures/messages.jsonl +4 -4
  83. package/tests/fixtures/node-ops.jsonl +6 -6
  84. package/tests/fixtures/number-ops.jsonl +7 -7
  85. package/tests/fixtures/object-ops.jsonl +4 -4
  86. package/tests/fixtures/operations.jsonl +7 -7
  87. package/tests/fixtures/string-ops.jsonl +4 -4
  88. package/tests/fixtures/undo-redo.jsonl +3 -3
  89. package/tests/fixtures/vector-ops.jsonl +9 -9
  90. package/tests/integration/repositories.test.ts +8 -9
  91. package/tests/journal/compaction-load-bug.test.ts +31 -31
  92. package/tests/journal/compaction.test.ts +26 -26
  93. package/tests/journal/journal-rle.test.ts +38 -38
  94. package/tests/journal/journal-service.test.ts +13 -13
  95. package/tests/journal/lww-ordering-bug.test.ts +39 -39
  96. package/tests/journal/rle-compression.test.ts +71 -71
  97. package/tests/journal/text-coalescing.test.ts +34 -34
  98. package/tests/test-data/datatypes.ts +85 -85
  99. package/tests/test-data/operations-example.ts +62 -62
  100. package/tests/test-data/scene-example.ts +11 -11
  101. package/tests/unit/operations.test.ts +7 -7
  102. package/tests/unit/s3-compression.test.ts +5 -3
  103. package/tests/unit/vectorClock.test.ts +2 -2
  104. package/tests/journal/multi-session-coalescing.test.ts +0 -871
@@ -12,13 +12,13 @@
12
12
  * INSERT Operation - Add new node to scene
13
13
  */
14
14
  export const exampleInsertOperation = {
15
- otype: 'insert',
15
+ ot: 'insert',
16
16
  id: 'op-insert-001',
17
17
  target: 'uuid-new-cube',
18
- sessionId: 'session-alice',
18
+ client: 'session-alice',
19
19
  clock: { 'session-alice': 5 },
20
- lamportTime: 100,
21
- timestamp: 1700010000000,
20
+ lt: 100,
21
+ ts: 1700010000000,
22
22
  data: {
23
23
  key: 'cube-1',
24
24
  tag: 'Mesh',
@@ -41,13 +41,13 @@ export const exampleInsertOperation = {
41
41
  * UPDATE Operation - Modify existing node properties
42
42
  */
43
43
  export const exampleUpdatePosition = {
44
- otype: 'update',
44
+ ot: 'update',
45
45
  id: 'op-update-001',
46
46
  target: 'uuid-player-001',
47
- sessionId: 'session-alice',
47
+ client: 'session-alice',
48
48
  clock: { 'session-alice': 6 },
49
- lamportTime: 101,
50
- timestamp: 1700010001000,
49
+ lt: 101,
50
+ ts: 1700010001000,
51
51
  data: {
52
52
  properties: {
53
53
  'transform.position': [5, 0, 3], // New position
@@ -59,13 +59,13 @@ export const exampleUpdatePosition = {
59
59
  * UPDATE Operation - Change color
60
60
  */
61
61
  export const exampleUpdateColor = {
62
- otype: 'update',
62
+ ot: 'update',
63
63
  id: 'op-update-002',
64
64
  target: 'uuid-player-001',
65
- sessionId: 'session-bob',
65
+ client: 'session-bob',
66
66
  clock: { 'session-bob': 3 },
67
- lamportTime: 102,
68
- timestamp: 1700010002000,
67
+ lt: 102,
68
+ ts: 1700010002000,
69
69
  data: {
70
70
  properties: {
71
71
  color: '#00ff00',
@@ -78,13 +78,13 @@ export const exampleUpdateColor = {
78
78
  * UPDATE Operation - Modify children (add child)
79
79
  */
80
80
  export const exampleUpdateAddChild = {
81
- otype: 'update',
81
+ ot: 'update',
82
82
  id: 'op-update-003',
83
83
  target: 'uuid-forest-001',
84
- sessionId: 'session-alice',
84
+ client: 'session-alice',
85
85
  clock: { 'session-alice': 7 },
86
- lamportTime: 103,
87
- timestamp: 1700010003000,
86
+ lt: 103,
87
+ ts: 1700010003000,
88
88
  data: {
89
89
  properties: {
90
90
  children: ['tree-1', 'tree-2', 'tree-3', 'tree-4'], // Added tree-4
@@ -96,13 +96,13 @@ export const exampleUpdateAddChild = {
96
96
  * UPDATE Operation - Reorder children (z-order)
97
97
  */
98
98
  export const exampleUpdateReorderChildren = {
99
- otype: 'update',
99
+ ot: 'update',
100
100
  id: 'op-update-004',
101
101
  target: 'uuid-forest-001',
102
- sessionId: 'session-bob',
102
+ client: 'session-bob',
103
103
  clock: { 'session-bob': 4 },
104
- lamportTime: 104,
105
- timestamp: 1700010004000,
104
+ lt: 104,
105
+ ts: 1700010004000,
106
106
  data: {
107
107
  properties: {
108
108
  children: ['tree-3', 'tree-1', 'tree-2'], // Reordered
@@ -117,13 +117,13 @@ export const exampleUpdateReorderChildren = {
117
117
  export const exampleMoveNodeOperations = [
118
118
  // 1. Add to new parent's children
119
119
  {
120
- otype: 'update',
120
+ ot: 'update',
121
121
  id: 'op-move-001a',
122
122
  target: 'uuid-new-parent',
123
- sessionId: 'session-alice',
123
+ client: 'session-alice',
124
124
  clock: { 'session-alice': 8 },
125
- lamportTime: 105,
126
- timestamp: 1700010005000,
125
+ lt: 105,
126
+ ts: 1700010005000,
127
127
  data: {
128
128
  properties: {
129
129
  children: ['existing-child-1', 'tree-1'], // Added tree-1
@@ -132,13 +132,13 @@ export const exampleMoveNodeOperations = [
132
132
  },
133
133
  // 2. Remove from old parent's children
134
134
  {
135
- otype: 'update',
135
+ ot: 'update',
136
136
  id: 'op-move-001b',
137
137
  target: 'uuid-forest-001',
138
- sessionId: 'session-alice',
138
+ client: 'session-alice',
139
139
  clock: { 'session-alice': 9 },
140
- lamportTime: 106,
141
- timestamp: 1700010005001,
140
+ lt: 106,
141
+ ts: 1700010005001,
142
142
  data: {
143
143
  properties: {
144
144
  children: ['tree-2', 'tree-3'], // Removed tree-1
@@ -151,26 +151,26 @@ export const exampleMoveNodeOperations = [
151
151
  * REMOVE Operation - Soft-delete node
152
152
  */
153
153
  export const exampleRemoveOperation = {
154
- otype: 'remove',
154
+ ot: 'remove',
155
155
  id: 'op-remove-001',
156
156
  target: 'uuid-tree-003',
157
- sessionId: 'session-alice',
157
+ client: 'session-alice',
158
158
  clock: { 'session-alice': 10 },
159
- lamportTime: 107,
160
- timestamp: 1700010006000,
159
+ lt: 107,
160
+ ts: 1700010006000,
161
161
  };
162
162
 
163
163
  /**
164
164
  * SET Operation - Replace entire scene (initial load only)
165
165
  */
166
166
  export const exampleSetOperation = {
167
- otype: 'set',
167
+ ot: 'set',
168
168
  id: 'op-set-001',
169
169
  target: 'scene',
170
- sessionId: 'session-server',
170
+ client: 'session-server',
171
171
  clock: {},
172
- lamportTime: 0,
173
- timestamp: 1700000000000,
172
+ lt: 0,
173
+ ts: 1700000000000,
174
174
  data: {
175
175
  nodes: [
176
176
  {
@@ -182,7 +182,7 @@ export const exampleSetOperation = {
182
182
  transform: { position: [0, 0, 0], rotation: [0, 0, 0, 1], scale: [1, 1, 1] },
183
183
  properties: {},
184
184
  clock: {},
185
- lamportTime: 0,
185
+ lt: 0,
186
186
  createdAt: 1700000000000,
187
187
  updatedAt: 1700000000000,
188
188
  },
@@ -195,7 +195,7 @@ export const exampleSetOperation = {
195
195
  transform: { position: [0, 1, 0], rotation: [0, 0, 0, 1], scale: [1, 1, 1] },
196
196
  properties: { color: '#ffffff' },
197
197
  clock: {},
198
- lamportTime: 0,
198
+ lt: 0,
199
199
  createdAt: 1700000000000,
200
200
  updatedAt: 1700000000000,
201
201
  },
@@ -210,13 +210,13 @@ export const exampleConcurrentUpdates = {
210
210
  // Scenario 1: Different properties (both succeed)
211
211
  differentProperties: [
212
212
  {
213
- otype: 'update',
213
+ ot: 'update',
214
214
  id: 'op-concurrent-001a',
215
215
  target: 'uuid-player-001',
216
- sessionId: 'session-alice',
216
+ client: 'session-alice',
217
217
  clock: { 'session-alice': 11 },
218
- lamportTime: 108,
219
- timestamp: 1700010007000,
218
+ lt: 108,
219
+ ts: 1700010007000,
220
220
  data: {
221
221
  properties: {
222
222
  color: '#ff0000', // Alice changes color
@@ -224,13 +224,13 @@ export const exampleConcurrentUpdates = {
224
224
  },
225
225
  },
226
226
  {
227
- otype: 'update',
227
+ ot: 'update',
228
228
  id: 'op-concurrent-001b',
229
229
  target: 'uuid-player-001',
230
- sessionId: 'session-bob',
230
+ client: 'session-bob',
231
231
  clock: { 'session-bob': 5 },
232
- lamportTime: 109,
233
- timestamp: 1700010007000,
232
+ lt: 109,
233
+ ts: 1700010007000,
234
234
  data: {
235
235
  properties: {
236
236
  health: 80, // Bob changes health
@@ -242,13 +242,13 @@ export const exampleConcurrentUpdates = {
242
242
  // Scenario 2: Same property (LWW - higher lamport wins)
243
243
  sameProperty: [
244
244
  {
245
- otype: 'update',
245
+ ot: 'update',
246
246
  id: 'op-concurrent-002a',
247
247
  target: 'uuid-player-001',
248
- sessionId: 'session-alice',
248
+ client: 'session-alice',
249
249
  clock: { 'session-alice': 12 },
250
- lamportTime: 110,
251
- timestamp: 1700010008000,
250
+ lt: 110,
251
+ ts: 1700010008000,
252
252
  data: {
253
253
  properties: {
254
254
  color: '#ff0000', // Alice sets red
@@ -256,13 +256,13 @@ export const exampleConcurrentUpdates = {
256
256
  },
257
257
  },
258
258
  {
259
- otype: 'update',
259
+ ot: 'update',
260
260
  id: 'op-concurrent-002b',
261
261
  target: 'uuid-player-001',
262
- sessionId: 'session-bob',
262
+ client: 'session-bob',
263
263
  clock: { 'session-bob': 6 },
264
- lamportTime: 111, // Higher lamport time → Bob wins
265
- timestamp: 1700010008000,
264
+ lt: 111, // Higher lamport time → Bob wins
265
+ ts: 1700010008000,
266
266
  data: {
267
267
  properties: {
268
268
  color: '#0000ff', // Bob sets blue
@@ -274,13 +274,13 @@ export const exampleConcurrentUpdates = {
274
274
  // Scenario 3: Additive property (both values added)
275
275
  additiveProperty: [
276
276
  {
277
- otype: 'update',
277
+ ot: 'update',
278
278
  id: 'op-concurrent-003a',
279
279
  target: 'uuid-player-001',
280
- sessionId: 'session-alice',
280
+ client: 'session-alice',
281
281
  clock: { 'session-alice': 13 },
282
- lamportTime: 112,
283
- timestamp: 1700010009000,
282
+ lt: 112,
283
+ ts: 1700010009000,
284
284
  data: {
285
285
  properties: {
286
286
  score: 10, // Alice adds 10 (additive behavior)
@@ -288,13 +288,13 @@ export const exampleConcurrentUpdates = {
288
288
  },
289
289
  },
290
290
  {
291
- otype: 'update',
291
+ ot: 'update',
292
292
  id: 'op-concurrent-003b',
293
293
  target: 'uuid-player-001',
294
- sessionId: 'session-bob',
294
+ client: 'session-bob',
295
295
  clock: { 'session-bob': 7 },
296
- lamportTime: 113,
297
- timestamp: 1700010009000,
296
+ lt: 113,
297
+ ts: 1700010009000,
298
298
  data: {
299
299
  properties: {
300
300
  score: 5, // Bob adds 5 (additive behavior)
@@ -29,7 +29,7 @@ export const exampleScene = {
29
29
  fog: { color: '#ffffff', density: 0.001 },
30
30
  },
31
31
  clock: { 'session-server': 1 },
32
- lamportTime: 1,
32
+ lt: 1,
33
33
  createdAt: 1700000000000,
34
34
  updatedAt: 1700000000000,
35
35
  },
@@ -51,7 +51,7 @@ export const exampleScene = {
51
51
  tags: ['environment', 'nature'],
52
52
  },
53
53
  clock: { 'session-server': 1 },
54
- lamportTime: 2,
54
+ lt: 2,
55
55
  createdAt: 1700000001000,
56
56
  updatedAt: 1700000001000,
57
57
  },
@@ -74,7 +74,7 @@ export const exampleScene = {
74
74
  castShadow: true,
75
75
  },
76
76
  clock: { 'session-server': 1 },
77
- lamportTime: 3,
77
+ lt: 3,
78
78
  createdAt: 1700000002000,
79
79
  updatedAt: 1700000002000,
80
80
  },
@@ -96,7 +96,7 @@ export const exampleScene = {
96
96
  castShadow: true,
97
97
  },
98
98
  clock: { 'session-server': 1 },
99
- lamportTime: 4,
99
+ lt: 4,
100
100
  createdAt: 1700000003000,
101
101
  updatedAt: 1700000003000,
102
102
  },
@@ -118,7 +118,7 @@ export const exampleScene = {
118
118
  castShadow: true,
119
119
  },
120
120
  clock: { 'session-server': 1 },
121
- lamportTime: 5,
121
+ lt: 5,
122
122
  createdAt: 1700000004000,
123
123
  updatedAt: 1700000004000,
124
124
  },
@@ -142,7 +142,7 @@ export const exampleScene = {
142
142
  team: 'blue',
143
143
  },
144
144
  clock: { 'session-alice': 1 },
145
- lamportTime: 6,
145
+ lt: 6,
146
146
  createdAt: 1700000005000,
147
147
  updatedAt: 1700000005000,
148
148
  },
@@ -165,7 +165,7 @@ export const exampleScene = {
165
165
  damage: 25,
166
166
  },
167
167
  clock: { 'session-alice': 1 },
168
- lamportTime: 7,
168
+ lt: 7,
169
169
  createdAt: 1700000006000,
170
170
  updatedAt: 1700000006000,
171
171
  },
@@ -191,7 +191,7 @@ export const exampleSceneWithInstancing = {
191
191
  transform: { position: [0, 0, 0], rotation: [0, 0, 0, 1], scale: [1, 1, 1] },
192
192
  properties: {},
193
193
  clock: { 'session-server': 1 },
194
- lamportTime: 1,
194
+ lt: 1,
195
195
  createdAt: 1700000000000,
196
196
  updatedAt: 1700000000000,
197
197
  },
@@ -205,7 +205,7 @@ export const exampleSceneWithInstancing = {
205
205
  transform: { position: [0, 0, 0], rotation: [0, 0, 0, 1], scale: [1, 1, 1] },
206
206
  properties: {},
207
207
  clock: { 'session-server': 1 },
208
- lamportTime: 2,
208
+ lt: 2,
209
209
  createdAt: 1700000001000,
210
210
  updatedAt: 1700000001000,
211
211
  },
@@ -219,7 +219,7 @@ export const exampleSceneWithInstancing = {
219
219
  transform: { position: [20, 0, 0], rotation: [0, 0, 0, 1], scale: [1, 1, 1] },
220
220
  properties: {},
221
221
  clock: { 'session-server': 1 },
222
- lamportTime: 3,
222
+ lt: 3,
223
223
  createdAt: 1700000002000,
224
224
  updatedAt: 1700000002000,
225
225
  },
@@ -237,7 +237,7 @@ export const exampleSceneWithInstancing = {
237
237
  material: 'wood',
238
238
  },
239
239
  clock: { 'session-server': 1 },
240
- lamportTime: 4,
240
+ lt: 4,
241
241
  createdAt: 1700000003000,
242
242
  updatedAt: 1700000003000,
243
243
  },
@@ -25,13 +25,13 @@ function loadOps(filename: string): OpFixture[] {
25
25
  .map((line) => JSON.parse(line));
26
26
  }
27
27
 
28
- function createMsg(op: Operation, lamport = 1): CRDTMessage {
28
+ function createMsg(op: Operation, lt = 1): CRDTMessage {
29
29
  return {
30
30
  id: `msg-${Math.random().toString(36).slice(2)}`,
31
- sessionId: 'test-session',
32
- clock: { 'test-session': lamport },
33
- lamportTime: lamport,
34
- timestamp: Date.now() / 1000,
31
+ client: 'test-session',
32
+ clock: { 'test-session': lt },
33
+ lt,
34
+ ts: Date.now() / 1000,
35
35
  ops: [op],
36
36
  };
37
37
  }
@@ -44,7 +44,7 @@ async function createNodeWithProps(
44
44
  const { applyMessage } = await import('@vuer-ai/vuer-rtc');
45
45
  const nodeOp: Operation = {
46
46
  key: '',
47
- otype: 'node.insert',
47
+ ot: 'node.insert',
48
48
  path: 'children',
49
49
  value: {
50
50
  key,
@@ -304,7 +304,7 @@ describe('Server Operation Tests', () => {
304
304
  const result = applyMessage(graph, createMsg(removeOp, 3));
305
305
 
306
306
  expect(result.nodes['scene'].children).not.toContain('cube-1');
307
- expect(result.nodes['cube-1']._crdt?.deletedAt).toBeDefined();
307
+ expect(result.tombstones['cube-1']).toBeDefined();
308
308
  });
309
309
  });
310
310
  });
@@ -79,13 +79,15 @@ function createTestSnapshot(nodeCount: number = 100, depth: number = 3): Snapsho
79
79
  graph: {
80
80
  rootKey: 'scene_root',
81
81
  nodes,
82
+ lww: {},
83
+ tombstones: {},
82
84
  },
83
85
  vectorClock: {
84
86
  session1: 100,
85
87
  session2: 50,
86
88
  session3: 75,
87
89
  },
88
- lamportTime: 150,
90
+ lt: 150,
89
91
  journalIndex: 200,
90
92
  };
91
93
  }
@@ -133,9 +135,9 @@ describe('S3 Cold Storage - Compression', () => {
133
135
 
134
136
  it('should handle empty snapshots', () => {
135
137
  const emptySnapshot: Snapshot = {
136
- graph: { rootKey: '', nodes: {} },
138
+ graph: { rootKey: '', nodes: {}, lww: {}, tombstones: {} },
137
139
  vectorClock: {},
138
- lamportTime: 0,
140
+ lt: 0,
139
141
  journalIndex: 0,
140
142
  };
141
143
 
@@ -4,8 +4,8 @@ import { describe, it, expect, beforeEach } from '@jest/globals';
4
4
  type VectorClock = Record<string, number>;
5
5
 
6
6
  interface IVectorClockManager {
7
- create(sessionId: string): VectorClock;
8
- increment(clock: VectorClock, sessionId: string): VectorClock;
7
+ create(client: string): VectorClock;
8
+ increment(clock: VectorClock, client: string): VectorClock;
9
9
  merge(clock1: VectorClock, clock2: VectorClock): VectorClock;
10
10
  compare(clock1: VectorClock, clock2: VectorClock): number;
11
11
  }