@vuer-ai/vuer-rtc 0.7.0 → 0.8.2
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.
- package/CLAUDE.md +3 -2
- package/dist/client/EditBuffer.d.ts +4 -4
- package/dist/client/EditBuffer.d.ts.map +1 -1
- package/dist/client/EditBuffer.js +26 -25
- package/dist/client/EditBuffer.js.map +1 -1
- package/dist/client/actions.d.ts +3 -3
- package/dist/client/actions.d.ts.map +1 -1
- package/dist/client/actions.js +71 -70
- package/dist/client/actions.js.map +1 -1
- package/dist/client/coalesceGraphOps.d.ts +4 -4
- package/dist/client/coalesceGraphOps.js +4 -4
- package/dist/client/coalesceTextOperations.d.ts.map +1 -1
- package/dist/client/coalesceTextOperations.js +23 -20
- package/dist/client/coalesceTextOperations.js.map +1 -1
- package/dist/client/coalescence/lwwOperations.js +3 -3
- package/dist/client/coalescence/lwwOperations.js.map +1 -1
- package/dist/client/coalescence/numberOperations.js +2 -2
- package/dist/client/coalescence/numberOperations.js.map +1 -1
- package/dist/client/coalescence/registry.d.ts +3 -3
- package/dist/client/coalescence/registry.d.ts.map +1 -1
- package/dist/client/coalescence/registry.js +11 -11
- package/dist/client/coalescence/registry.js.map +1 -1
- package/dist/client/coalescence/textDeletes.d.ts +8 -7
- package/dist/client/coalescence/textDeletes.d.ts.map +1 -1
- package/dist/client/coalescence/textDeletes.js +11 -11
- package/dist/client/coalescence/textDeletes.js.map +1 -1
- package/dist/client/coalescence/textInserts.d.ts +8 -5
- package/dist/client/coalescence/textInserts.d.ts.map +1 -1
- package/dist/client/coalescence/textInserts.js +32 -12
- package/dist/client/coalescence/textInserts.js.map +1 -1
- package/dist/client/coalescence/utils.d.ts +3 -9
- package/dist/client/coalescence/utils.d.ts.map +1 -1
- package/dist/client/coalescence/utils.js +10 -8
- package/dist/client/coalescence/utils.js.map +1 -1
- package/dist/client/coalescence/vector3Operations.js +2 -2
- package/dist/client/coalescence/vector3Operations.js.map +1 -1
- package/dist/client/createGraph.d.ts +2 -2
- package/dist/client/createGraph.js +4 -4
- package/dist/client/createGraph.js.map +1 -1
- package/dist/client/createTextDocument.d.ts +1 -1
- package/dist/client/createTextDocument.js +3 -3
- package/dist/client/createTextDocument.js.map +1 -1
- package/dist/client/hooks.d.ts +3 -3
- package/dist/client/hooks.d.ts.map +1 -1
- package/dist/client/hooks.js +4 -4
- package/dist/client/hooks.js.map +1 -1
- package/dist/client/textActions.d.ts +2 -2
- package/dist/client/textActions.d.ts.map +1 -1
- package/dist/client/textActions.js +47 -47
- package/dist/client/textActions.js.map +1 -1
- package/dist/client/textTypes.d.ts +8 -8
- package/dist/client/textTypes.d.ts.map +1 -1
- package/dist/client/types.d.ts +4 -4
- package/dist/client/types.d.ts.map +1 -1
- package/dist/crdt/GraphTextCRDT.d.ts +2 -2
- package/dist/crdt/GraphTextCRDT.d.ts.map +1 -1
- package/dist/crdt/GraphTextCRDT.js +6 -6
- package/dist/crdt/GraphTextCRDT.js.map +1 -1
- package/dist/crdt/Rope.d.ts +13 -14
- package/dist/crdt/Rope.d.ts.map +1 -1
- package/dist/crdt/Rope.js +130 -59
- package/dist/crdt/Rope.js.map +1 -1
- package/dist/crdt/index.d.ts +1 -1
- package/dist/crdt/index.d.ts.map +1 -1
- package/dist/crdt/index.js +1 -1
- package/dist/crdt/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/operations/OperationTypes.d.ts +45 -48
- package/dist/operations/OperationTypes.d.ts.map +1 -1
- package/dist/operations/OperationValidator.js +11 -11
- package/dist/operations/OperationValidator.js.map +1 -1
- package/dist/operations/apply/node.js +3 -3
- package/dist/operations/apply/node.js.map +1 -1
- package/dist/operations/apply/text.d.ts.map +1 -1
- package/dist/operations/apply/text.js +35 -32
- package/dist/operations/apply/text.js.map +1 -1
- package/dist/operations/apply/types.d.ts +4 -4
- package/dist/operations/apply/types.d.ts.map +1 -1
- package/dist/operations/apply/types.js +8 -8
- package/dist/operations/apply/types.js.map +1 -1
- package/dist/operations/dispatcher.d.ts.map +1 -1
- package/dist/operations/dispatcher.js +52 -13
- package/dist/operations/dispatcher.js.map +1 -1
- package/dist/serdes.d.ts +1 -1
- package/dist/serdes.d.ts.map +1 -1
- package/dist/state/ConflictResolver.d.ts +9 -9
- package/dist/state/ConflictResolver.d.ts.map +1 -1
- package/dist/state/ConflictResolver.js +20 -20
- package/dist/state/ConflictResolver.js.map +1 -1
- package/dist/state/DType.d.ts +2 -2
- package/dist/state/DType.d.ts.map +1 -1
- package/dist/state/DType.js +14 -14
- package/dist/state/DType.js.map +1 -1
- package/dist/state/VectorClock.d.ts +6 -6
- package/dist/state/VectorClock.d.ts.map +1 -1
- package/dist/state/VectorClock.js +14 -14
- package/dist/state/VectorClock.js.map +1 -1
- package/dist/state/index.d.ts +1 -1
- package/dist/state/index.js +1 -1
- package/examples/01-basic-usage.ts +16 -16
- package/examples/02-concurrent-edits.ts +29 -29
- package/examples/03-scene-building.ts +28 -28
- package/examples/04-conflict-resolution.ts +56 -56
- package/examples/05-coalescence-usage.ts +23 -23
- package/examples/README.md +12 -12
- package/package.json +1 -1
- package/src/client/EditBuffer.ts +28 -27
- package/src/client/TEXT_DOCUMENT_API.md +9 -9
- package/src/client/actions.ts +74 -70
- package/src/client/coalesceGraphOps.ts +4 -4
- package/src/client/coalesceTextOperations.ts +26 -22
- package/src/client/coalescence/lwwOperations.ts +3 -3
- package/src/client/coalescence/numberOperations.ts +2 -2
- package/src/client/coalescence/registry.ts +13 -12
- package/src/client/coalescence/textDeletes.ts +22 -18
- package/src/client/coalescence/textInserts.ts +49 -25
- package/src/client/coalescence/utils.ts +14 -11
- package/src/client/coalescence/vector3Operations.ts +2 -2
- package/src/client/createGraph.ts +4 -4
- package/src/client/createTextDocument.ts +3 -3
- package/src/client/hooks.tsx +5 -5
- package/src/client/textActions.ts +47 -47
- package/src/client/textTypes.ts +8 -8
- package/src/client/types.ts +4 -4
- package/src/crdt/GraphTextCRDT.ts +6 -6
- package/src/crdt/Rope.ts +156 -71
- package/src/crdt/index.ts +2 -0
- package/src/index.ts +2 -0
- package/src/operations/OperationTypes.ts +47 -47
- package/src/operations/OperationValidator.ts +11 -11
- package/src/operations/apply/node.ts +3 -3
- package/src/operations/apply/text.ts +38 -32
- package/src/operations/apply/types.ts +11 -11
- package/src/operations/dispatcher.ts +57 -13
- package/src/serdes.ts +1 -1
- package/src/state/ConflictResolver.ts +23 -23
- package/src/state/DType.ts +16 -16
- package/src/state/VectorClock.ts +14 -14
- package/src/state/index.ts +1 -1
- package/tests/client/actions.test.ts +76 -76
- package/tests/client/coalesce-graph-operations.test.ts +84 -84
- package/tests/client/coalesce-text-operations.test.ts +91 -114
- package/tests/client/compaction.test.ts +18 -18
- package/tests/client/delete-coalescence-bug.test.ts +34 -34
- package/tests/client/edit-buffer.test.ts +27 -30
- package/tests/client/graph-coalescence-phase1.test.ts +66 -66
- package/tests/client/graph-coalescence.test.ts +50 -50
- package/tests/client/journal-benchmark.test.ts +5 -5
- package/tests/crdt/graph-text-crdt.test.ts +60 -64
- package/tests/crdt/rope.test.ts +9 -8
- package/tests/crdt/text-operations.test.ts +28 -28
- package/tests/fixtures/array-ops.jsonl +6 -6
- package/tests/fixtures/boolean-ops.jsonl +6 -6
- package/tests/fixtures/color-ops.jsonl +4 -4
- package/tests/fixtures/edit-buffer.jsonl +3 -3
- package/tests/fixtures/node-ops.jsonl +6 -6
- package/tests/fixtures/number-ops.jsonl +7 -7
- package/tests/fixtures/object-ops.jsonl +4 -4
- package/tests/fixtures/operations.jsonl +7 -7
- package/tests/fixtures/string-ops.jsonl +4 -4
- package/tests/fixtures/undo-redo.jsonl +3 -3
- package/tests/fixtures/vector-ops.jsonl +17 -17
- package/tests/operations/collections.test.ts +4 -4
- package/tests/operations/nodes.test.ts +5 -5
- package/tests/operations/operation-ordering.test.ts +406 -0
- package/tests/operations/primitives.test.ts +4 -4
- package/tests/operations/unified-schema.test.ts +27 -27
- package/tests/operations/vectors.test.ts +4 -4
- package/tests/sync/digest.test.ts +5 -5
|
@@ -34,9 +34,9 @@ describe('Delete Coalescence Bug', () => {
|
|
|
34
34
|
const deleteOp = remove(rope, 0, 5);
|
|
35
35
|
|
|
36
36
|
// FIXED: Now we get 1 deletion with length 5 instead of 5 separate deletions!
|
|
37
|
-
expect(deleteOp.
|
|
38
|
-
expect(deleteOp.
|
|
39
|
-
expect(deleteOp.
|
|
37
|
+
expect(deleteOp.rm).toHaveLength(1);
|
|
38
|
+
expect(deleteOp.rm[0][1]).toBe(5);
|
|
39
|
+
expect(deleteOp.rm[0][0]).toMatch(/alice:\d+/);
|
|
40
40
|
|
|
41
41
|
// This is efficient - we're sending 1 deletion entry instead of 5
|
|
42
42
|
});
|
|
@@ -59,11 +59,11 @@ describe('Delete Coalescence Bug', () => {
|
|
|
59
59
|
const delete5 = remove(rope, 0, 1); // Delete 'H'
|
|
60
60
|
|
|
61
61
|
// Each delete creates 1 deletion entry (expected - only deleting 1 char each time)
|
|
62
|
-
expect(delete1.
|
|
63
|
-
expect(delete2.
|
|
64
|
-
expect(delete3.
|
|
65
|
-
expect(delete4.
|
|
66
|
-
expect(delete5.
|
|
62
|
+
expect(delete1.rm).toHaveLength(1);
|
|
63
|
+
expect(delete2.rm).toHaveLength(1);
|
|
64
|
+
expect(delete3.rm).toHaveLength(1);
|
|
65
|
+
expect(delete4.rm).toHaveLength(1);
|
|
66
|
+
expect(delete5.rm).toHaveLength(1);
|
|
67
67
|
|
|
68
68
|
// Note: These are 5 separate delete OPERATIONS, each with 1 deletion
|
|
69
69
|
// Operation-level coalescence (in coalesceTextOperations) will merge these
|
|
@@ -78,9 +78,9 @@ describe('Delete Coalescence Bug', () => {
|
|
|
78
78
|
|
|
79
79
|
// Simulate receiving a coalesced operation from Alice
|
|
80
80
|
const coalescedOp: InsertOp = {
|
|
81
|
+
ot: 'insert',
|
|
81
82
|
id: 'alice:1',
|
|
82
|
-
|
|
83
|
-
parentId: null,
|
|
83
|
+
value: [null, 'Hello'],
|
|
84
84
|
seq: 1,
|
|
85
85
|
ts: 1000.0,
|
|
86
86
|
};
|
|
@@ -93,9 +93,9 @@ describe('Delete Coalescence Bug', () => {
|
|
|
93
93
|
const deleteOp = remove(rope, 0, 5);
|
|
94
94
|
|
|
95
95
|
// GOOD: Only 1 deletion with length 5 (because it's a single item)
|
|
96
|
-
expect(deleteOp.
|
|
97
|
-
expect(deleteOp.
|
|
98
|
-
expect(deleteOp.
|
|
96
|
+
expect(deleteOp.rm).toHaveLength(1);
|
|
97
|
+
expect(deleteOp.rm[0][0]).toBe('alice:1');
|
|
98
|
+
expect(deleteOp.rm[0][1]).toBe(5);
|
|
99
99
|
});
|
|
100
100
|
});
|
|
101
101
|
|
|
@@ -117,13 +117,13 @@ describe('Delete Coalescence Bug', () => {
|
|
|
117
117
|
|
|
118
118
|
// Coalescence merged 5 ops into 1 op
|
|
119
119
|
expect(coalesced).toHaveLength(1);
|
|
120
|
-
expect((coalesced[0] as any).
|
|
120
|
+
expect((coalesced[0] as any).value[1]).toBe('Hello');
|
|
121
121
|
|
|
122
122
|
// The local rope still has 5 separate items (coalescence doesn't modify the rope)
|
|
123
123
|
// BUT remove() now optimizes the deletions array!
|
|
124
124
|
const deleteOp = remove(rope, 0, 5);
|
|
125
|
-
expect(deleteOp.
|
|
126
|
-
expect(deleteOp.
|
|
125
|
+
expect(deleteOp.rm).toHaveLength(1); // FIXED: 1 deletion instead of 5!
|
|
126
|
+
expect(deleteOp.rm[0][1]).toBe(5);
|
|
127
127
|
|
|
128
128
|
// This is the fix: even though rope has 5 items, remove() merges consecutive
|
|
129
129
|
// deletions from the same agent into a single deletion entry
|
|
@@ -144,9 +144,9 @@ describe('Delete Coalescence Bug', () => {
|
|
|
144
144
|
// Delete all 5 characters
|
|
145
145
|
const deleteOp = remove(rope, 0, 5);
|
|
146
146
|
|
|
147
|
-
// FIXED: deletions = [
|
|
148
|
-
expect(deleteOp.
|
|
149
|
-
expect(deleteOp.
|
|
147
|
+
// FIXED: deletions = [['alice:0', 5]] (merged consecutive IDs)
|
|
148
|
+
expect(deleteOp.rm).toHaveLength(1);
|
|
149
|
+
expect(deleteOp.rm[0][1]).toBe(5);
|
|
150
150
|
});
|
|
151
151
|
|
|
152
152
|
it('should handle mixed local and remote items correctly', () => {
|
|
@@ -158,9 +158,9 @@ describe('Delete Coalescence Bug', () => {
|
|
|
158
158
|
|
|
159
159
|
// Bob types "ey" (received as coalesced op)
|
|
160
160
|
const bobOp: InsertOp = {
|
|
161
|
+
ot: 'insert',
|
|
161
162
|
id: 'bob:1',
|
|
162
|
-
|
|
163
|
-
parentId: 'alice:1',
|
|
163
|
+
value: ['alice:1', 'ey'],
|
|
164
164
|
seq: 3,
|
|
165
165
|
ts: 1000.0,
|
|
166
166
|
};
|
|
@@ -178,14 +178,14 @@ describe('Delete Coalescence Bug', () => {
|
|
|
178
178
|
// FIXED: 2 deletions (can't merge across agents, but alice's chars are merged)
|
|
179
179
|
// - alice:0-1 merged → 1 deletion with length 2
|
|
180
180
|
// - bob:1 → 1 deletion with length 2
|
|
181
|
-
expect(deleteOp.
|
|
181
|
+
expect(deleteOp.rm).toHaveLength(2);
|
|
182
182
|
|
|
183
183
|
// Both deletions should be multi-char
|
|
184
|
-
expect(deleteOp.
|
|
185
|
-
expect(deleteOp.
|
|
184
|
+
expect(deleteOp.rm[0][1]).toBe(2);
|
|
185
|
+
expect(deleteOp.rm[1][1]).toBe(2);
|
|
186
186
|
|
|
187
187
|
// One from alice, one from bob
|
|
188
|
-
const agents = deleteOp.
|
|
188
|
+
const agents = deleteOp.rm.map(d => d[0].split(':')[0]);
|
|
189
189
|
expect(agents).toContain('alice');
|
|
190
190
|
expect(agents).toContain('bob');
|
|
191
191
|
});
|
|
@@ -206,9 +206,9 @@ describe('Delete Coalescence Bug', () => {
|
|
|
206
206
|
const deleteOp = remove(rope, 0, 7);
|
|
207
207
|
|
|
208
208
|
// FIXED: Creates 1 deletion entry with length 7
|
|
209
|
-
expect(deleteOp.
|
|
210
|
-
expect(deleteOp.
|
|
211
|
-
expect(deleteOp.
|
|
209
|
+
expect(deleteOp.rm).toHaveLength(1);
|
|
210
|
+
expect(deleteOp.rm[0][1]).toBe(7);
|
|
211
|
+
expect(deleteOp.rm[0][0]).toMatch(/Alice:\d+/);
|
|
212
212
|
|
|
213
213
|
// This is now efficient - 1 deletion entry instead of 7
|
|
214
214
|
});
|
|
@@ -233,17 +233,17 @@ describe('Delete Coalescence Bug', () => {
|
|
|
233
233
|
|
|
234
234
|
// Operation-level coalescence works: 7 ops → 1 op
|
|
235
235
|
expect(coalesced).toHaveLength(1);
|
|
236
|
-
expect(coalesced[0].
|
|
236
|
+
expect(coalesced[0].ot).toBe('delete');
|
|
237
237
|
|
|
238
238
|
// FIXED in v0.5.4: coalesceTextOperations now sorts and optimizes deletions!
|
|
239
239
|
// Each individual remove() creates 1 deletion (only deleting 1 char)
|
|
240
240
|
// When coalesceTextOperations merges the 7 ops, it:
|
|
241
|
-
// 1. Combines the deletions arrays: [
|
|
242
|
-
// 2. Sorts them: [
|
|
243
|
-
// 3. Optimizes them: [
|
|
241
|
+
// 1. Combines the deletions arrays: [['Alice:6',1], ..., ['Alice:0',1]]
|
|
242
|
+
// 2. Sorts them: [['Alice:0',1], ..., ['Alice:6',1]]
|
|
243
|
+
// 3. Optimizes them: [['Alice:0',7]]
|
|
244
244
|
const coalescedOp = coalesced[0] as any;
|
|
245
|
-
expect(coalescedOp.
|
|
246
|
-
expect(coalescedOp.
|
|
245
|
+
expect(coalescedOp.rm).toHaveLength(1);
|
|
246
|
+
expect(coalescedOp.rm[0]).toEqual(['Alice:0', 7]);
|
|
247
247
|
});
|
|
248
248
|
});
|
|
249
249
|
});
|
|
@@ -105,7 +105,7 @@ describe('EditBuffer', () => {
|
|
|
105
105
|
const buffer = new EditBufferImpl();
|
|
106
106
|
buffer.add({
|
|
107
107
|
key: 'cube-1',
|
|
108
|
-
|
|
108
|
+
ot: 'number.set',
|
|
109
109
|
path: 'opacity',
|
|
110
110
|
value: 0.5,
|
|
111
111
|
});
|
|
@@ -119,26 +119,24 @@ describe('EditBuffer', () => {
|
|
|
119
119
|
it('should NOT coalesce text inserts with CRDT metadata', () => {
|
|
120
120
|
const ops: Operation[] = [
|
|
121
121
|
{
|
|
122
|
-
|
|
122
|
+
ot: 'text.insert',
|
|
123
123
|
key: 'text-doc',
|
|
124
124
|
path: 'content',
|
|
125
125
|
position: 0,
|
|
126
|
-
value: 'a',
|
|
127
|
-
id:
|
|
128
|
-
content: 'a',
|
|
129
|
-
parentId: null,
|
|
126
|
+
value: [null, 'a'],
|
|
127
|
+
id: 'session-1:1',
|
|
130
128
|
seq: 1,
|
|
129
|
+
ts: 1000.0,
|
|
131
130
|
} as any,
|
|
132
131
|
{
|
|
133
|
-
|
|
132
|
+
ot: 'text.insert',
|
|
134
133
|
key: 'text-doc',
|
|
135
134
|
path: 'content',
|
|
136
135
|
position: 1,
|
|
137
|
-
value: 'b',
|
|
138
|
-
id:
|
|
139
|
-
content: 'b',
|
|
140
|
-
parentId: { agent: 'session-1', seq: 1 },
|
|
136
|
+
value: ['session-1:1', 'b'],
|
|
137
|
+
id: 'session-1:2',
|
|
141
138
|
seq: 2,
|
|
139
|
+
ts: 1000.0,
|
|
142
140
|
} as any,
|
|
143
141
|
];
|
|
144
142
|
|
|
@@ -146,23 +144,23 @@ describe('EditBuffer', () => {
|
|
|
146
144
|
|
|
147
145
|
// Should NOT coalesce - each operation keeps its CRDT metadata
|
|
148
146
|
expect(result).toHaveLength(2);
|
|
149
|
-
expect((result[0] as any).id).
|
|
150
|
-
expect((result[0] as any).value).toBe('a');
|
|
151
|
-
expect((result[1] as any).id).
|
|
152
|
-
expect((result[1] as any).value).toBe('b');
|
|
147
|
+
expect((result[0] as any).id).toBe('session-1:1');
|
|
148
|
+
expect((result[0] as any).value[1]).toBe('a');
|
|
149
|
+
expect((result[1] as any).id).toBe('session-1:2');
|
|
150
|
+
expect((result[1] as any).value[1]).toBe('b');
|
|
153
151
|
});
|
|
154
152
|
|
|
155
153
|
it('should coalesce position-based text inserts without CRDT metadata', () => {
|
|
156
154
|
const ops: Operation[] = [
|
|
157
155
|
{
|
|
158
|
-
|
|
156
|
+
ot: 'text.insert',
|
|
159
157
|
key: 'text-doc',
|
|
160
158
|
path: 'content',
|
|
161
159
|
position: 0,
|
|
162
160
|
value: 'a',
|
|
163
161
|
} as any,
|
|
164
162
|
{
|
|
165
|
-
|
|
163
|
+
ot: 'text.insert',
|
|
166
164
|
key: 'text-doc',
|
|
167
165
|
path: 'content',
|
|
168
166
|
position: 1,
|
|
@@ -182,20 +180,20 @@ describe('EditBuffer', () => {
|
|
|
182
180
|
it('should NOT coalesce text deletes with CRDT metadata', () => {
|
|
183
181
|
const ops: Operation[] = [
|
|
184
182
|
{
|
|
185
|
-
|
|
183
|
+
ot: 'text.delete',
|
|
186
184
|
key: 'text-doc',
|
|
187
185
|
path: 'content',
|
|
188
186
|
position: 0,
|
|
189
187
|
length: 1,
|
|
190
|
-
|
|
188
|
+
value: [['session-1:1', 1]],
|
|
191
189
|
} as any,
|
|
192
190
|
{
|
|
193
|
-
|
|
191
|
+
ot: 'text.delete',
|
|
194
192
|
key: 'text-doc',
|
|
195
193
|
path: 'content',
|
|
196
194
|
position: 0,
|
|
197
195
|
length: 1,
|
|
198
|
-
|
|
196
|
+
value: [['session-1:2', 1]],
|
|
199
197
|
} as any,
|
|
200
198
|
];
|
|
201
199
|
|
|
@@ -203,32 +201,31 @@ describe('EditBuffer', () => {
|
|
|
203
201
|
|
|
204
202
|
// Should NOT coalesce - each operation keeps its CRDT metadata
|
|
205
203
|
expect(result).toHaveLength(2);
|
|
206
|
-
expect((result[0] as any).
|
|
207
|
-
expect((result[1] as any).
|
|
204
|
+
expect((result[0] as any).value).toEqual([['session-1:1', 1]]);
|
|
205
|
+
expect((result[1] as any).value).toEqual([['session-1:2', 1]]);
|
|
208
206
|
});
|
|
209
207
|
|
|
210
208
|
it('should preserve CRDT metadata through mixed operations', () => {
|
|
211
209
|
const ops: Operation[] = [
|
|
212
210
|
{
|
|
213
|
-
|
|
211
|
+
ot: 'text.insert',
|
|
214
212
|
key: 'text-doc',
|
|
215
213
|
path: 'content',
|
|
216
214
|
position: 0,
|
|
217
215
|
value: 'hello',
|
|
218
216
|
} as any,
|
|
219
217
|
{
|
|
220
|
-
|
|
218
|
+
ot: 'text.insert',
|
|
221
219
|
key: 'text-doc',
|
|
222
220
|
path: 'content',
|
|
223
221
|
position: 5,
|
|
224
222
|
value: ' ',
|
|
225
|
-
id:
|
|
226
|
-
content: ' ',
|
|
227
|
-
parentId: null,
|
|
223
|
+
id: 'session-1:1',
|
|
228
224
|
seq: 1,
|
|
225
|
+
ts: 1000.0,
|
|
229
226
|
} as any,
|
|
230
227
|
{
|
|
231
|
-
|
|
228
|
+
ot: 'text.insert',
|
|
232
229
|
key: 'text-doc',
|
|
233
230
|
path: 'content',
|
|
234
231
|
position: 6,
|
|
@@ -245,7 +242,7 @@ describe('EditBuffer', () => {
|
|
|
245
242
|
expect((result[0] as any).value).toBe('hello');
|
|
246
243
|
expect((result[0] as any).id).toBeUndefined();
|
|
247
244
|
expect((result[1] as any).value).toBe(' ');
|
|
248
|
-
expect((result[1] as any).id).
|
|
245
|
+
expect((result[1] as any).id).toBe('session-1:1');
|
|
249
246
|
expect((result[2] as any).value).toBe('world');
|
|
250
247
|
expect((result[2] as any).id).toBeUndefined();
|
|
251
248
|
});
|