@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
package/dist/state/DType.js
CHANGED
|
@@ -21,7 +21,7 @@ export const DType = {
|
|
|
21
21
|
* SET - Last-Write-Wins
|
|
22
22
|
*/
|
|
23
23
|
set: ((values) => {
|
|
24
|
-
const sorted = [...values].sort((a, b) => b.
|
|
24
|
+
const sorted = [...values].sort((a, b) => b.lt - a.lt);
|
|
25
25
|
return sorted[0].value;
|
|
26
26
|
}),
|
|
27
27
|
/**
|
|
@@ -57,14 +57,14 @@ export const DType = {
|
|
|
57
57
|
* SET - Last-Write-Wins
|
|
58
58
|
*/
|
|
59
59
|
set: ((values) => {
|
|
60
|
-
const sorted = [...values].sort((a, b) => b.
|
|
60
|
+
const sorted = [...values].sort((a, b) => b.lt - a.lt);
|
|
61
61
|
return sorted[0].value;
|
|
62
62
|
}),
|
|
63
63
|
/**
|
|
64
64
|
* CONCAT - Concatenate (ordered by lamport)
|
|
65
65
|
*/
|
|
66
66
|
concat: ((values, separator = '\n') => {
|
|
67
|
-
const sorted = [...values].sort((a, b) => a.
|
|
67
|
+
const sorted = [...values].sort((a, b) => a.lt - b.lt);
|
|
68
68
|
return sorted.map((v) => v.value).join(separator);
|
|
69
69
|
}),
|
|
70
70
|
},
|
|
@@ -76,7 +76,7 @@ export const DType = {
|
|
|
76
76
|
* SET - Last-Write-Wins
|
|
77
77
|
*/
|
|
78
78
|
set: ((values) => {
|
|
79
|
-
const sorted = [...values].sort((a, b) => b.
|
|
79
|
+
const sorted = [...values].sort((a, b) => b.lt - a.lt);
|
|
80
80
|
return sorted[0].value;
|
|
81
81
|
}),
|
|
82
82
|
/**
|
|
@@ -103,7 +103,7 @@ export const DType = {
|
|
|
103
103
|
* SET - Replace entire vector (preserves user intent)
|
|
104
104
|
*/
|
|
105
105
|
set: ((values) => {
|
|
106
|
-
const sorted = [...values].sort((a, b) => b.
|
|
106
|
+
const sorted = [...values].sort((a, b) => b.lt - a.lt);
|
|
107
107
|
return sorted[0].value;
|
|
108
108
|
}),
|
|
109
109
|
/**
|
|
@@ -139,14 +139,14 @@ export const DType = {
|
|
|
139
139
|
* SET - Replace entire quaternion
|
|
140
140
|
*/
|
|
141
141
|
set: ((values) => {
|
|
142
|
-
const sorted = [...values].sort((a, b) => b.
|
|
142
|
+
const sorted = [...values].sort((a, b) => b.lt - a.lt);
|
|
143
143
|
return sorted[0].value;
|
|
144
144
|
}),
|
|
145
145
|
/**
|
|
146
146
|
* MULTIPLY - Quaternion multiplication (composition)
|
|
147
147
|
*/
|
|
148
148
|
multiply: ((values) => {
|
|
149
|
-
const sorted = [...values].sort((a, b) => a.
|
|
149
|
+
const sorted = [...values].sort((a, b) => a.lt - b.lt);
|
|
150
150
|
let result = sorted[0].value;
|
|
151
151
|
for (let i = 1; i < sorted.length; i++) {
|
|
152
152
|
result = multiplyQuaternions(result, sorted[i].value);
|
|
@@ -162,7 +162,7 @@ export const DType = {
|
|
|
162
162
|
* SET - Replace color
|
|
163
163
|
*/
|
|
164
164
|
set: ((values) => {
|
|
165
|
-
const sorted = [...values].sort((a, b) => b.
|
|
165
|
+
const sorted = [...values].sort((a, b) => b.lt - a.lt);
|
|
166
166
|
return sorted[0].value;
|
|
167
167
|
}),
|
|
168
168
|
/**
|
|
@@ -187,7 +187,7 @@ export const DType = {
|
|
|
187
187
|
* SET - Replace entire array
|
|
188
188
|
*/
|
|
189
189
|
set: ((values) => {
|
|
190
|
-
const sorted = [...values].sort((a, b) => b.
|
|
190
|
+
const sorted = [...values].sort((a, b) => b.lt - a.lt);
|
|
191
191
|
return sorted[0].value;
|
|
192
192
|
}),
|
|
193
193
|
/**
|
|
@@ -201,7 +201,7 @@ export const DType = {
|
|
|
201
201
|
* APPEND - Append all (ordered by lamport)
|
|
202
202
|
*/
|
|
203
203
|
append: ((values) => {
|
|
204
|
-
const sorted = [...values].sort((a, b) => a.
|
|
204
|
+
const sorted = [...values].sort((a, b) => a.lt - b.lt);
|
|
205
205
|
return sorted.flatMap((v) => v.value);
|
|
206
206
|
}),
|
|
207
207
|
},
|
|
@@ -213,7 +213,7 @@ export const DType = {
|
|
|
213
213
|
* SET - Replace entire object
|
|
214
214
|
*/
|
|
215
215
|
set: ((values) => {
|
|
216
|
-
const sorted = [...values].sort((a, b) => b.
|
|
216
|
+
const sorted = [...values].sort((a, b) => b.lt - a.lt);
|
|
217
217
|
return sorted[0].value;
|
|
218
218
|
}),
|
|
219
219
|
/**
|
|
@@ -224,9 +224,9 @@ export const DType = {
|
|
|
224
224
|
const latestTimes = {};
|
|
225
225
|
for (const v of values) {
|
|
226
226
|
for (const [key, value] of Object.entries(v.value)) {
|
|
227
|
-
if (!latestTimes[key] || v.
|
|
227
|
+
if (!latestTimes[key] || v.lt > latestTimes[key]) {
|
|
228
228
|
result[key] = value;
|
|
229
|
-
latestTimes[key] = v.
|
|
229
|
+
latestTimes[key] = v.lt;
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
232
|
}
|
|
@@ -242,7 +242,7 @@ export const DType = {
|
|
|
242
242
|
immutable: {
|
|
243
243
|
set: ((values) => {
|
|
244
244
|
// Return first value (creation value)
|
|
245
|
-
const sorted = [...values].sort((a, b) => a.
|
|
245
|
+
const sorted = [...values].sort((a, b) => a.lt - b.lt);
|
|
246
246
|
return sorted[0].value;
|
|
247
247
|
}),
|
|
248
248
|
},
|
package/dist/state/DType.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DType.js","sourceRoot":"","sources":["../../src/state/DType.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgBH;;GAEG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,+CAA+C;IAC/C,aAAa;IACb,+CAA+C;IAE/C;;OAEG;IACH,MAAM,EAAE;QACN;;WAEG;QACH,GAAG,EAAE,CAAC,CAAC,MAA+B,EAAE,EAAE;YACxC,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"DType.js","sourceRoot":"","sources":["../../src/state/DType.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,18 +9,18 @@
|
|
|
9
9
|
export type VectorClock = Record<string, number>;
|
|
10
10
|
export declare class VectorClockManager {
|
|
11
11
|
/**
|
|
12
|
-
* Create a new vector clock for a
|
|
13
|
-
* Initializes the
|
|
12
|
+
* Create a new vector clock for a client
|
|
13
|
+
* Initializes the client's counter to 0
|
|
14
14
|
*/
|
|
15
|
-
create(
|
|
15
|
+
create(client: string): VectorClock;
|
|
16
16
|
/**
|
|
17
|
-
* Increment the counter for a
|
|
17
|
+
* Increment the counter for a client
|
|
18
18
|
* Returns a new clock (immutable)
|
|
19
19
|
*/
|
|
20
|
-
increment(clock: VectorClock,
|
|
20
|
+
increment(clock: VectorClock, client: string): VectorClock;
|
|
21
21
|
/**
|
|
22
22
|
* Merge two vector clocks
|
|
23
|
-
* Takes the maximum value for each
|
|
23
|
+
* Takes the maximum value for each client
|
|
24
24
|
* Used when receiving remote operations
|
|
25
25
|
*/
|
|
26
26
|
merge(clock1: VectorClock, clock2: VectorClock): VectorClock;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VectorClock.d.ts","sourceRoot":"","sources":["../../src/state/VectorClock.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEjD,qBAAa,kBAAkB;IAC7B;;;OAGG;IACH,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"VectorClock.d.ts","sourceRoot":"","sources":["../../src/state/VectorClock.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEjD,qBAAa,kBAAkB;IAC7B;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW;IAInC;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW;IAQ1D;;;;OAIG;IACH,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,WAAW;IAU5D;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM;IAmCzD;;;OAGG;IACH,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO;CAGjE"}
|
|
@@ -8,32 +8,32 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export class VectorClockManager {
|
|
10
10
|
/**
|
|
11
|
-
* Create a new vector clock for a
|
|
12
|
-
* Initializes the
|
|
11
|
+
* Create a new vector clock for a client
|
|
12
|
+
* Initializes the client's counter to 0
|
|
13
13
|
*/
|
|
14
|
-
create(
|
|
15
|
-
return { [
|
|
14
|
+
create(client) {
|
|
15
|
+
return { [client]: 0 };
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
|
-
* Increment the counter for a
|
|
18
|
+
* Increment the counter for a client
|
|
19
19
|
* Returns a new clock (immutable)
|
|
20
20
|
*/
|
|
21
|
-
increment(clock,
|
|
22
|
-
const currentValue = clock[
|
|
21
|
+
increment(clock, client) {
|
|
22
|
+
const currentValue = clock[client] || 0;
|
|
23
23
|
return {
|
|
24
24
|
...clock,
|
|
25
|
-
[
|
|
25
|
+
[client]: currentValue + 1,
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* Merge two vector clocks
|
|
30
|
-
* Takes the maximum value for each
|
|
30
|
+
* Takes the maximum value for each client
|
|
31
31
|
* Used when receiving remote operations
|
|
32
32
|
*/
|
|
33
33
|
merge(clock1, clock2) {
|
|
34
34
|
const merged = { ...clock1 };
|
|
35
|
-
Object.entries(clock2).forEach(([
|
|
36
|
-
merged[
|
|
35
|
+
Object.entries(clock2).forEach(([client, count]) => {
|
|
36
|
+
merged[client] = Math.max(merged[client] || 0, count);
|
|
37
37
|
});
|
|
38
38
|
return merged;
|
|
39
39
|
}
|
|
@@ -52,9 +52,9 @@ export class VectorClockManager {
|
|
|
52
52
|
]);
|
|
53
53
|
let clock1Greater = false;
|
|
54
54
|
let clock2Greater = false;
|
|
55
|
-
allSessionIds.forEach((
|
|
56
|
-
const val1 = clock1[
|
|
57
|
-
const val2 = clock2[
|
|
55
|
+
allSessionIds.forEach((client) => {
|
|
56
|
+
const val1 = clock1[client] || 0;
|
|
57
|
+
const val2 = clock2[client] || 0;
|
|
58
58
|
if (val1 > val2) {
|
|
59
59
|
clock1Greater = true;
|
|
60
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VectorClock.js","sourceRoot":"","sources":["../../src/state/VectorClock.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,OAAO,kBAAkB;IAC7B;;;OAGG;IACH,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"VectorClock.js","sourceRoot":"","sources":["../../src/state/VectorClock.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,OAAO,kBAAkB;IAC7B;;;OAGG;IACH,MAAM,CAAC,MAAc;QACnB,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,SAAS,CAAC,KAAkB,EAAE,MAAc;QAC1C,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxC,OAAO;YACL,GAAG,KAAK;YACR,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,CAAC;SAC3B,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAmB,EAAE,MAAmB;QAC5C,MAAM,MAAM,GAAgB,EAAE,GAAG,MAAM,EAAE,CAAC;QAE1C,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE;YACjD,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,MAAmB,EAAE,MAAmB;QAC9C,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;YAC5B,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;YACtB,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;SACvB,CAAC,CAAC;QAEH,IAAI,aAAa,GAAG,KAAK,CAAC;QAC1B,IAAI,aAAa,GAAG,KAAK,CAAC;QAE1B,aAAa,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACjC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAEjC,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC;gBAChB,aAAa,GAAG,IAAI,CAAC;YACvB,CAAC;YACD,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC;gBAChB,aAAa,GAAG,IAAI,CAAC;YACvB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,qEAAqE;QACrE,IAAI,aAAa,IAAI,CAAC,aAAa,EAAE,CAAC;YACpC,OAAO,CAAC,CAAC;QACX,CAAC;QAED,qEAAqE;QACrE,IAAI,aAAa,IAAI,CAAC,aAAa,EAAE,CAAC;YACpC,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC;QAED,gDAAgD;QAChD,OAAO,CAAC,CAAC;IACX,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,MAAmB,EAAE,MAAmB;QACpD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;CACF"}
|
package/dist/state/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* - VectorClock: Used by client for causal ordering
|
|
5
5
|
* - DType, ConflictResolver: Server-side conflict resolution for concurrent updates
|
|
6
6
|
*
|
|
7
|
-
* Schema-less design: dtype and operation are derived from
|
|
7
|
+
* Schema-less design: dtype and operation are derived from ot (e.g., 'vector3.add').
|
|
8
8
|
*/
|
|
9
9
|
export { VectorClockManager, type VectorClock } from './VectorClock.js';
|
|
10
10
|
export { DType, type ValueWithMeta, type MergeFn } from './DType.js';
|
package/dist/state/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* - VectorClock: Used by client for causal ordering
|
|
5
5
|
* - DType, ConflictResolver: Server-side conflict resolution for concurrent updates
|
|
6
6
|
*
|
|
7
|
-
* Schema-less design: dtype and operation are derived from
|
|
7
|
+
* Schema-less design: dtype and operation are derived from ot (e.g., 'vector3.add').
|
|
8
8
|
*/
|
|
9
9
|
// Vector clock (used by client and server)
|
|
10
10
|
export { VectorClockManager } from './VectorClock.js';
|
|
@@ -20,14 +20,14 @@ console.log('Initial graph:', graph);
|
|
|
20
20
|
|
|
21
21
|
const msg1: CRDTMessage = {
|
|
22
22
|
id: 'msg-001',
|
|
23
|
-
|
|
23
|
+
client: 'session-server',
|
|
24
24
|
clock: { 'session-server': 1 },
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
lt: 1,
|
|
26
|
+
ts: Date.now() / 1000,
|
|
27
27
|
ops: [
|
|
28
28
|
{
|
|
29
29
|
key: 'scene',
|
|
30
|
-
|
|
30
|
+
ot: 'node.insert',
|
|
31
31
|
path: 'scene',
|
|
32
32
|
value: {
|
|
33
33
|
id: 'uuid-scene-001',
|
|
@@ -53,15 +53,15 @@ console.log(' Scene node:', graph.nodes['scene']);
|
|
|
53
53
|
|
|
54
54
|
const msg2: CRDTMessage = {
|
|
55
55
|
id: 'msg-002',
|
|
56
|
-
|
|
56
|
+
client: 'session-alice',
|
|
57
57
|
clock: { 'session-alice': 1 },
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
lt: 2,
|
|
59
|
+
ts: Date.now() / 1000,
|
|
60
60
|
ops: [
|
|
61
61
|
// Insert the cube node and add to scene's children in one operation
|
|
62
62
|
{
|
|
63
63
|
key: 'cube-1',
|
|
64
|
-
|
|
64
|
+
ot: 'node.insert',
|
|
65
65
|
path: 'cube-1',
|
|
66
66
|
parent: 'scene', // Automatically adds to scene's children
|
|
67
67
|
value: {
|
|
@@ -88,14 +88,14 @@ console.log(' Scene children:', graph.nodes['scene'].children);
|
|
|
88
88
|
|
|
89
89
|
const msg3: CRDTMessage = {
|
|
90
90
|
id: 'msg-003',
|
|
91
|
-
|
|
91
|
+
client: 'session-alice',
|
|
92
92
|
clock: { 'session-alice': 2 },
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
lt: 3,
|
|
94
|
+
ts: Date.now() / 1000,
|
|
95
95
|
ops: [
|
|
96
96
|
{
|
|
97
97
|
key: 'cube-1',
|
|
98
|
-
|
|
98
|
+
ot: 'vector3.add',
|
|
99
99
|
path: 'transform.position',
|
|
100
100
|
value: [5, 0, 0], // Move right by 5
|
|
101
101
|
},
|
|
@@ -113,14 +113,14 @@ console.log(' Cube position:', graph.nodes['cube-1']['transform.position']);
|
|
|
113
113
|
|
|
114
114
|
const msg4: CRDTMessage = {
|
|
115
115
|
id: 'msg-004',
|
|
116
|
-
|
|
116
|
+
client: 'session-alice',
|
|
117
117
|
clock: { 'session-alice': 3 },
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
lt: 4,
|
|
119
|
+
ts: Date.now() / 1000,
|
|
120
120
|
ops: [
|
|
121
121
|
{
|
|
122
122
|
key: 'cube-1',
|
|
123
|
-
|
|
123
|
+
ot: 'color.set',
|
|
124
124
|
path: 'color',
|
|
125
125
|
value: '#00ff00', // Change to green
|
|
126
126
|
},
|
|
@@ -16,14 +16,14 @@ let graph = createEmptyGraph();
|
|
|
16
16
|
|
|
17
17
|
const setupMsg: CRDTMessage = {
|
|
18
18
|
id: 'setup',
|
|
19
|
-
|
|
19
|
+
client: 'server',
|
|
20
20
|
clock: { server: 1 },
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
lt: 0,
|
|
22
|
+
ts: Date.now() / 1000,
|
|
23
23
|
ops: [
|
|
24
24
|
{
|
|
25
25
|
key: 'cube',
|
|
26
|
-
|
|
26
|
+
ot: 'node.insert',
|
|
27
27
|
path: 'cube',
|
|
28
28
|
value: {
|
|
29
29
|
key: 'uuid-cube',
|
|
@@ -50,14 +50,14 @@ console.log('\n--- Scenario 1: Concurrent Drag (vector3.add) ---\n');
|
|
|
50
50
|
// Alice drags the cube right by [5, 0, 0]
|
|
51
51
|
const aliceDrag: CRDTMessage = {
|
|
52
52
|
id: 'alice-drag',
|
|
53
|
-
|
|
53
|
+
client: 'alice',
|
|
54
54
|
clock: { alice: 1 },
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
lt: 10,
|
|
56
|
+
ts: Date.now() / 1000,
|
|
57
57
|
ops: [
|
|
58
58
|
{
|
|
59
59
|
key: 'cube',
|
|
60
|
-
|
|
60
|
+
ot: 'vector3.add', // Additive!
|
|
61
61
|
path: 'transform.position',
|
|
62
62
|
value: [5, 0, 0],
|
|
63
63
|
},
|
|
@@ -67,14 +67,14 @@ const aliceDrag: CRDTMessage = {
|
|
|
67
67
|
// Bob drags the cube up by [0, 3, 0] (concurrent with Alice)
|
|
68
68
|
const bobDrag: CRDTMessage = {
|
|
69
69
|
id: 'bob-drag',
|
|
70
|
-
|
|
70
|
+
client: 'bob',
|
|
71
71
|
clock: { bob: 1 },
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
lt: 11,
|
|
73
|
+
ts: Date.now() / 1000,
|
|
74
74
|
ops: [
|
|
75
75
|
{
|
|
76
76
|
key: 'cube',
|
|
77
|
-
|
|
77
|
+
ot: 'vector3.add', // Additive!
|
|
78
78
|
path: 'transform.position',
|
|
79
79
|
value: [0, 3, 0],
|
|
80
80
|
},
|
|
@@ -101,14 +101,14 @@ console.log('\n--- Scenario 2: Concurrent Score Update (number.add) ---\n');
|
|
|
101
101
|
// Alice adds 10 points
|
|
102
102
|
const aliceScore: CRDTMessage = {
|
|
103
103
|
id: 'alice-score',
|
|
104
|
-
|
|
104
|
+
client: 'alice',
|
|
105
105
|
clock: { alice: 2 },
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
lt: 20,
|
|
107
|
+
ts: Date.now() / 1000,
|
|
108
108
|
ops: [
|
|
109
109
|
{
|
|
110
110
|
key: 'cube',
|
|
111
|
-
|
|
111
|
+
ot: 'number.add',
|
|
112
112
|
path: 'score',
|
|
113
113
|
value: 10,
|
|
114
114
|
},
|
|
@@ -118,14 +118,14 @@ const aliceScore: CRDTMessage = {
|
|
|
118
118
|
// Bob adds 5 points (concurrent)
|
|
119
119
|
const bobScore: CRDTMessage = {
|
|
120
120
|
id: 'bob-score',
|
|
121
|
-
|
|
121
|
+
client: 'bob',
|
|
122
122
|
clock: { bob: 2 },
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
lt: 21,
|
|
124
|
+
ts: Date.now() / 1000,
|
|
125
125
|
ops: [
|
|
126
126
|
{
|
|
127
127
|
key: 'cube',
|
|
128
|
-
|
|
128
|
+
ot: 'number.add',
|
|
129
129
|
path: 'score',
|
|
130
130
|
value: 5,
|
|
131
131
|
},
|
|
@@ -151,14 +151,14 @@ console.log('\n--- Scenario 3: Concurrent Color Change (color.set - LWW) ---\n')
|
|
|
151
151
|
// Alice sets color to red (lamport: 30)
|
|
152
152
|
const aliceColor: CRDTMessage = {
|
|
153
153
|
id: 'alice-color',
|
|
154
|
-
|
|
154
|
+
client: 'alice',
|
|
155
155
|
clock: { alice: 3 },
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
lt: 30,
|
|
157
|
+
ts: Date.now() / 1000,
|
|
158
158
|
ops: [
|
|
159
159
|
{
|
|
160
160
|
key: 'cube',
|
|
161
|
-
|
|
161
|
+
ot: 'color.set', // LWW!
|
|
162
162
|
path: 'color',
|
|
163
163
|
value: '#ff0000',
|
|
164
164
|
},
|
|
@@ -168,14 +168,14 @@ const aliceColor: CRDTMessage = {
|
|
|
168
168
|
// Bob sets color to blue (lamport: 31 - higher, so Bob wins)
|
|
169
169
|
const bobColor: CRDTMessage = {
|
|
170
170
|
id: 'bob-color',
|
|
171
|
-
|
|
171
|
+
client: 'bob',
|
|
172
172
|
clock: { bob: 3 },
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
lt: 31, // Higher lamport time
|
|
174
|
+
ts: Date.now() / 1000,
|
|
175
175
|
ops: [
|
|
176
176
|
{
|
|
177
177
|
key: 'cube',
|
|
178
|
-
|
|
178
|
+
ot: 'color.set', // LWW!
|
|
179
179
|
path: 'color',
|
|
180
180
|
value: '#0000ff',
|
|
181
181
|
},
|
|
@@ -204,5 +204,5 @@ console.log(' → Order doesn\'t matter!');
|
|
|
204
204
|
console.log('');
|
|
205
205
|
console.log('LWW operations (*.set): Last write wins');
|
|
206
206
|
console.log(' → Great for: colors, absolute positions, names');
|
|
207
|
-
console.log(' → Higher
|
|
207
|
+
console.log(' → Higher lt wins');
|
|
208
208
|
console.log('─'.repeat(50));
|
|
@@ -19,15 +19,15 @@ console.log('--- Step 1: Create Scene with Multiple Objects ---\n');
|
|
|
19
19
|
|
|
20
20
|
const initScene: CRDTMessage = {
|
|
21
21
|
id: 'init',
|
|
22
|
-
|
|
22
|
+
client: 'server',
|
|
23
23
|
clock: { server: 1 },
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
lt: 1,
|
|
25
|
+
ts: Date.now() / 1000,
|
|
26
26
|
ops: [
|
|
27
27
|
// Scene root (no parent - it's the root)
|
|
28
28
|
{
|
|
29
29
|
key: 'scene',
|
|
30
|
-
|
|
30
|
+
ot: 'node.insert',
|
|
31
31
|
path: 'scene',
|
|
32
32
|
value: {
|
|
33
33
|
id: 'uuid-scene',
|
|
@@ -39,7 +39,7 @@ const initScene: CRDTMessage = {
|
|
|
39
39
|
// Player (parent: scene)
|
|
40
40
|
{
|
|
41
41
|
key: 'player',
|
|
42
|
-
|
|
42
|
+
ot: 'node.insert',
|
|
43
43
|
path: 'player',
|
|
44
44
|
parent: 'scene',
|
|
45
45
|
value: {
|
|
@@ -55,7 +55,7 @@ const initScene: CRDTMessage = {
|
|
|
55
55
|
// Enemy 1 (parent: scene)
|
|
56
56
|
{
|
|
57
57
|
key: 'enemy-1',
|
|
58
|
-
|
|
58
|
+
ot: 'node.insert',
|
|
59
59
|
path: 'enemy-1',
|
|
60
60
|
parent: 'scene',
|
|
61
61
|
value: {
|
|
@@ -70,7 +70,7 @@ const initScene: CRDTMessage = {
|
|
|
70
70
|
// Enemy 2 (parent: scene)
|
|
71
71
|
{
|
|
72
72
|
key: 'enemy-2',
|
|
73
|
-
|
|
73
|
+
ot: 'node.insert',
|
|
74
74
|
path: 'enemy-2',
|
|
75
75
|
parent: 'scene',
|
|
76
76
|
value: {
|
|
@@ -98,15 +98,15 @@ console.log('\n--- Step 2: Reparent Enemies into Group ---\n');
|
|
|
98
98
|
|
|
99
99
|
const reparent: CRDTMessage = {
|
|
100
100
|
id: 'reparent',
|
|
101
|
-
|
|
101
|
+
client: 'alice',
|
|
102
102
|
clock: { alice: 1 },
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
lt: 2,
|
|
104
|
+
ts: Date.now() / 1000,
|
|
105
105
|
ops: [
|
|
106
106
|
// Create enemies group (parent: scene)
|
|
107
107
|
{
|
|
108
108
|
key: 'enemies',
|
|
109
|
-
|
|
109
|
+
ot: 'node.insert',
|
|
110
110
|
path: 'enemies',
|
|
111
111
|
parent: 'scene',
|
|
112
112
|
value: {
|
|
@@ -119,19 +119,19 @@ const reparent: CRDTMessage = {
|
|
|
119
119
|
// Remove enemies from scene and add to group
|
|
120
120
|
{
|
|
121
121
|
key: 'scene',
|
|
122
|
-
|
|
122
|
+
ot: 'array.remove',
|
|
123
123
|
path: 'children',
|
|
124
124
|
value: 'enemy-1',
|
|
125
125
|
},
|
|
126
126
|
{
|
|
127
127
|
key: 'scene',
|
|
128
|
-
|
|
128
|
+
ot: 'array.remove',
|
|
129
129
|
path: 'children',
|
|
130
130
|
value: 'enemy-2',
|
|
131
131
|
},
|
|
132
132
|
{
|
|
133
133
|
key: 'enemies',
|
|
134
|
-
|
|
134
|
+
ot: 'array.set',
|
|
135
135
|
path: 'children',
|
|
136
136
|
value: ['enemy-1', 'enemy-2'],
|
|
137
137
|
},
|
|
@@ -151,20 +151,20 @@ console.log('\n--- Step 3: Batch Update - Damage All Enemies ---\n');
|
|
|
151
151
|
|
|
152
152
|
const damageAll: CRDTMessage = {
|
|
153
153
|
id: 'damage',
|
|
154
|
-
|
|
154
|
+
client: 'player',
|
|
155
155
|
clock: { player: 1 },
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
lt: 3,
|
|
157
|
+
ts: Date.now() / 1000,
|
|
158
158
|
ops: [
|
|
159
159
|
{
|
|
160
160
|
key: 'enemy-1',
|
|
161
|
-
|
|
161
|
+
ot: 'number.add',
|
|
162
162
|
path: 'health',
|
|
163
163
|
value: -30, // Take 30 damage
|
|
164
164
|
},
|
|
165
165
|
{
|
|
166
166
|
key: 'enemy-2',
|
|
167
|
-
|
|
167
|
+
ot: 'number.add',
|
|
168
168
|
path: 'health',
|
|
169
169
|
value: -30, // Take 30 damage
|
|
170
170
|
},
|
|
@@ -185,14 +185,14 @@ console.log('\n--- Step 4: Kill Enemy 1 ---\n');
|
|
|
185
185
|
// More damage to enemy-1
|
|
186
186
|
const killEnemy1: CRDTMessage = {
|
|
187
187
|
id: 'kill',
|
|
188
|
-
|
|
188
|
+
client: 'player',
|
|
189
189
|
clock: { player: 2 },
|
|
190
|
-
|
|
191
|
-
|
|
190
|
+
lt: 4,
|
|
191
|
+
ts: Date.now() / 1000,
|
|
192
192
|
ops: [
|
|
193
193
|
{
|
|
194
194
|
key: 'enemy-1',
|
|
195
|
-
|
|
195
|
+
ot: 'number.add',
|
|
196
196
|
path: 'health',
|
|
197
197
|
value: -20, // Now at 0
|
|
198
198
|
},
|
|
@@ -205,20 +205,20 @@ console.log('Enemy 1 health after damage:', graph.nodes['enemy-1'].health);
|
|
|
205
205
|
// Remove dead enemy
|
|
206
206
|
const removeEnemy1: CRDTMessage = {
|
|
207
207
|
id: 'remove-enemy',
|
|
208
|
-
|
|
208
|
+
client: 'server',
|
|
209
209
|
clock: { server: 2 },
|
|
210
|
-
|
|
211
|
-
|
|
210
|
+
lt: 5,
|
|
211
|
+
ts: Date.now() / 1000,
|
|
212
212
|
ops: [
|
|
213
213
|
{
|
|
214
214
|
key: 'enemies',
|
|
215
|
-
|
|
215
|
+
ot: 'array.remove',
|
|
216
216
|
path: 'children',
|
|
217
217
|
value: 'enemy-1',
|
|
218
218
|
},
|
|
219
219
|
{
|
|
220
220
|
key: 'enemy-1',
|
|
221
|
-
|
|
221
|
+
ot: 'node.remove',
|
|
222
222
|
path: 'enemy-1',
|
|
223
223
|
},
|
|
224
224
|
],
|