@vuer-ai/vuer-rtc 0.8.2 → 0.8.3
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/dist/operations/OperationTypes.d.ts +22 -16
- package/dist/operations/OperationTypes.d.ts.map +1 -1
- package/dist/operations/apply/text.d.ts.map +1 -1
- package/dist/operations/apply/text.js +18 -20
- package/dist/operations/apply/text.js.map +1 -1
- package/package.json +1 -1
- package/src/operations/OperationTypes.ts +25 -16
- package/src/operations/apply/text.ts +20 -23
|
@@ -81,25 +81,31 @@ export interface TextInitOp extends BaseOp {
|
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
83
|
* Insert text - supports two formats:
|
|
84
|
-
* 1. Position-based (for local operations): { position, value }
|
|
85
|
-
* 2. CRDT metadata (for network sync): { id,
|
|
84
|
+
* 1. Position-based (for local operations): { position, value: string }
|
|
85
|
+
* 2. CRDT metadata (for network sync): { id, value: [anchor, content], seq, ts }
|
|
86
|
+
*
|
|
87
|
+
* The value field changes type based on format:
|
|
88
|
+
* - Position-based: value is string ("hello")
|
|
89
|
+
* - CRDT: value is [anchor, content] tuple (["client:42", "hello"])
|
|
86
90
|
*/
|
|
87
91
|
export interface TextInsertOp extends BaseOp {
|
|
88
92
|
key: string;
|
|
89
93
|
ot: 'text.insert';
|
|
90
94
|
path: string;
|
|
91
95
|
position?: number;
|
|
92
|
-
value?: string;
|
|
96
|
+
value?: string | [string | null, string];
|
|
93
97
|
id?: string;
|
|
94
|
-
content?: string;
|
|
95
|
-
parentId?: string | null;
|
|
96
98
|
seq?: number;
|
|
97
99
|
ts?: number;
|
|
100
|
+
_lastCharId?: string;
|
|
98
101
|
}
|
|
99
102
|
/**
|
|
100
103
|
* Delete text - supports two formats:
|
|
101
104
|
* 1. Position-based (for local operations): { position, length }
|
|
102
|
-
* 2. CRDT metadata (for network sync): {
|
|
105
|
+
* 2. CRDT metadata (for network sync): { rm }
|
|
106
|
+
*
|
|
107
|
+
* rm format: Array of [itemId, count] tuples
|
|
108
|
+
* Example: rm: [["client:42", 5], ["client:48", 3]]
|
|
103
109
|
*/
|
|
104
110
|
export interface TextDeleteOp extends BaseOp {
|
|
105
111
|
key: string;
|
|
@@ -107,12 +113,17 @@ export interface TextDeleteOp extends BaseOp {
|
|
|
107
113
|
path: string;
|
|
108
114
|
position?: number;
|
|
109
115
|
length?: number;
|
|
110
|
-
|
|
116
|
+
rm?: Array<[string, number]>;
|
|
111
117
|
}
|
|
112
118
|
/**
|
|
113
119
|
* Replace text - atomic delete + insert (for select-and-type)
|
|
114
|
-
*
|
|
115
|
-
*
|
|
120
|
+
*
|
|
121
|
+
* Position-based: { position, length, value: string }
|
|
122
|
+
* CRDT metadata: { rm, id, value: [anchor, content], seq, ts }
|
|
123
|
+
*
|
|
124
|
+
* The value field changes type based on format:
|
|
125
|
+
* - Position-based: value is string ("hello")
|
|
126
|
+
* - CRDT: value is [anchor, content] tuple (["client:42", "hello"])
|
|
116
127
|
*/
|
|
117
128
|
export interface TextReplaceOp extends BaseOp {
|
|
118
129
|
key: string;
|
|
@@ -120,14 +131,9 @@ export interface TextReplaceOp extends BaseOp {
|
|
|
120
131
|
path: string;
|
|
121
132
|
position?: number;
|
|
122
133
|
length?: number;
|
|
123
|
-
value?: string;
|
|
124
|
-
|
|
125
|
-
id: string;
|
|
126
|
-
length: number;
|
|
127
|
-
}>;
|
|
134
|
+
value?: string | [string | null, string];
|
|
135
|
+
rm?: Array<[string, number]>;
|
|
128
136
|
id?: string;
|
|
129
|
-
content?: string;
|
|
130
|
-
parentId?: string | null;
|
|
131
137
|
seq?: number;
|
|
132
138
|
ts?: number;
|
|
133
139
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OperationTypes.d.ts","sourceRoot":"","sources":["../../src/operations/OperationTypes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,WAAW;IAE1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IAGX,GAAG,EAAE,SAAS,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAMD,MAAM,WAAW,WAAY,SAAQ,MAAM;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,YAAY,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAY,SAAQ,MAAM;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,YAAY,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAiB,SAAQ,MAAM;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,iBAAiB,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAY,SAAQ,MAAM;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,YAAY,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAY,SAAQ,MAAM;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,YAAY,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAMD,MAAM,WAAW,WAAY,SAAQ,MAAM;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,YAAY,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAe,SAAQ,MAAM;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,eAAe,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;GAGG;AACH,MAAM,WAAW,UAAW,SAAQ,MAAM;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,WAAW,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED
|
|
1
|
+
{"version":3,"file":"OperationTypes.d.ts","sourceRoot":"","sources":["../../src/operations/OperationTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/operations/apply/text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EACV,UAAU,EAEV,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAUL,QAAQ,EAET,MAAM,oBAAoB,CAAC;AAwD5B;;GAEG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,MAAM,GACX,IAAI,CAWN;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,MAAM,GACX,IAAI,CA6BN;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,MAAM,GACX,IAAI,
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/operations/apply/text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EACV,UAAU,EAEV,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAUL,QAAQ,EAET,MAAM,oBAAoB,CAAC;AAwD5B;;GAEG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,MAAM,GACX,IAAI,CAWN;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,MAAM,GACX,IAAI,CA6BN;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,MAAM,GACX,IAAI,CAmBN;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,aAAa,EACjB,IAAI,EAAE,MAAM,GACX,IAAI,CAgCN;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,QAAQ,GAAG,SAAS,CAItB"}
|
|
@@ -83,26 +83,26 @@ export function TextInsert(draft, op, meta) {
|
|
|
83
83
|
if (!node)
|
|
84
84
|
return;
|
|
85
85
|
const rope = getOrCreateRope(node, op.path, meta.client);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
//
|
|
86
|
+
// Check if value is already a tuple (CRDT format)
|
|
87
|
+
const isTupleFormat = Array.isArray(op.value) && op.value.length === 2;
|
|
88
|
+
if (op.id !== undefined && isTupleFormat && op.seq !== undefined) {
|
|
89
|
+
// CRDT metadata format (from network) - value is already [anchor, content] tuple
|
|
90
90
|
apply(rope, {
|
|
91
91
|
ot: 'insert',
|
|
92
92
|
id: op.id,
|
|
93
|
-
value, //
|
|
93
|
+
value: op.value, // Already tuple format
|
|
94
94
|
seq: op.seq,
|
|
95
95
|
ts: op.ts ?? Date.now() / 1000,
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
|
-
else if (op.position !== undefined && op.value
|
|
98
|
+
else if (op.position !== undefined && typeof op.value === 'string') {
|
|
99
99
|
// Position-based format (local edit) → convert to CRDT metadata in-place
|
|
100
100
|
const crdtOp = insertWithSplit(rope, op.position, op.value, meta.client);
|
|
101
101
|
op.id = crdtOp.id;
|
|
102
|
-
|
|
103
|
-
op.value = crdtOp.value;
|
|
102
|
+
op.value = crdtOp.value; // Store as tuple [anchor, content]
|
|
104
103
|
op.seq = crdtOp.seq;
|
|
105
104
|
op.ts = crdtOp.ts;
|
|
105
|
+
op._lastCharId = crdtOp._lastCharId; // Preserve multi-char metadata
|
|
106
106
|
}
|
|
107
107
|
// node[path] is the mutated TextRope (React will call .toString())
|
|
108
108
|
}
|
|
@@ -116,11 +116,10 @@ export function TextDelete(draft, op, meta) {
|
|
|
116
116
|
const rope = getRope(node, op.path);
|
|
117
117
|
if (!rope)
|
|
118
118
|
return;
|
|
119
|
-
|
|
120
|
-
if (deletionsArray !== undefined) {
|
|
119
|
+
if (op.rm !== undefined) {
|
|
121
120
|
// CRDT metadata format (replay from journal)
|
|
122
121
|
// rm is already in tuple format: [[id, len], ...]
|
|
123
|
-
applyDelete(rope, { ot: 'delete', rm:
|
|
122
|
+
applyDelete(rope, { ot: 'delete', rm: op.rm });
|
|
124
123
|
}
|
|
125
124
|
else if (op.position !== undefined && op.length !== undefined) {
|
|
126
125
|
// Position-based format (local edit) → convert to CRDT metadata in-place
|
|
@@ -138,28 +137,27 @@ export function TextReplace(draft, op, meta) {
|
|
|
138
137
|
if (!node)
|
|
139
138
|
return;
|
|
140
139
|
const rope = getOrCreateRope(node, op.path, meta.client);
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
if (
|
|
140
|
+
// Check if value is already a tuple (CRDT format)
|
|
141
|
+
const isTupleFormat = Array.isArray(op.value) && op.value.length === 2;
|
|
142
|
+
if (op.rm !== undefined && op.id !== undefined && isTupleFormat && op.seq !== undefined) {
|
|
144
143
|
// CRDT metadata format (replay from journal)
|
|
145
144
|
// Value is already [anchor, content] tuple
|
|
146
145
|
applyReplace(rope, {
|
|
147
146
|
ot: 'replace',
|
|
148
|
-
rm:
|
|
147
|
+
rm: op.rm,
|
|
149
148
|
id: op.id,
|
|
150
|
-
value: value
|
|
149
|
+
value: op.value, // Already tuple format
|
|
151
150
|
seq: op.seq,
|
|
152
151
|
ts: op.ts ?? Date.now() / 1000,
|
|
153
152
|
});
|
|
154
153
|
}
|
|
155
|
-
else if (op.position !== undefined && op.length !== undefined && op.value
|
|
154
|
+
else if (op.position !== undefined && op.length !== undefined && typeof op.value === 'string') {
|
|
156
155
|
// Position-based format (local edit) → convert to CRDT metadata in-place
|
|
157
156
|
const crdtOp = replace(rope, op.position, op.length, op.value, meta.client);
|
|
158
|
-
//
|
|
157
|
+
// Store CRDT metadata in tuple format
|
|
159
158
|
op.rm = crdtOp.rm;
|
|
160
159
|
op.id = crdtOp.id;
|
|
161
|
-
|
|
162
|
-
op.value = crdtOp.value;
|
|
160
|
+
op.value = crdtOp.value; // Store as tuple [anchor, content]
|
|
163
161
|
op.seq = crdtOp.seq;
|
|
164
162
|
op.ts = crdtOp.ts;
|
|
165
163
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/operations/apply/text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAWH,OAAO,EACL,MAAM,EAEN,MAAM,EACN,eAAe,EACf,MAAM,EACN,OAAO,EACP,KAAK,EACL,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,IAAe,EAAE,IAAY,EAAE,OAAe;IACrE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAEzB,kCAAkC;IAClC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qBAAqB;IACrB,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,+EAA+E;IAC/E,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;YAChC,+DAA+D;YAC/D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YAClB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,4DAA4D;YAC5D,OAAO,CAAC,IAAI,CAAC,iCAAiC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7B,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,OAAO,CAAC,IAAe,EAAE,IAAY;IAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,OAAO,KAAK,YAAY,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAiB,EACjB,EAAc,EACd,IAAY;IAEZ,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI;QAAE,OAAO;IAElB,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAEzD,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED,0CAA0C;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CACxB,KAAiB,EACjB,EAAgB,EAChB,IAAY;IAEZ,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI;QAAE,OAAO;IAElB,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAEzD,MAAM,KAAK,
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/operations/apply/text.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -108,8 +108,12 @@ export interface TextInitOp extends BaseOp {
|
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
110
|
* Insert text - supports two formats:
|
|
111
|
-
* 1. Position-based (for local operations): { position, value }
|
|
112
|
-
* 2. CRDT metadata (for network sync): { id,
|
|
111
|
+
* 1. Position-based (for local operations): { position, value: string }
|
|
112
|
+
* 2. CRDT metadata (for network sync): { id, value: [anchor, content], seq, ts }
|
|
113
|
+
*
|
|
114
|
+
* The value field changes type based on format:
|
|
115
|
+
* - Position-based: value is string ("hello")
|
|
116
|
+
* - CRDT: value is [anchor, content] tuple (["client:42", "hello"])
|
|
113
117
|
*/
|
|
114
118
|
export interface TextInsertOp extends BaseOp {
|
|
115
119
|
key: string;
|
|
@@ -117,19 +121,21 @@ export interface TextInsertOp extends BaseOp {
|
|
|
117
121
|
path: string;
|
|
118
122
|
// Position-based format (local convenience)
|
|
119
123
|
position?: number;
|
|
120
|
-
value?: string;
|
|
124
|
+
value?: string | [string | null, string]; // string for position-based, tuple for CRDT
|
|
121
125
|
// CRDT metadata format (network sync)
|
|
122
|
-
id?: string; // ItemId string format: "
|
|
123
|
-
content?: string;
|
|
124
|
-
parentId?: string | null; // ItemId string format
|
|
126
|
+
id?: string; // ItemId string format: "client:seq"
|
|
125
127
|
seq?: number; // Lamport timestamp
|
|
126
128
|
ts?: number; // Wall-clock time (seconds) for tie-breaking
|
|
129
|
+
_lastCharId?: string; // Last character ID (for multi-char inserts)
|
|
127
130
|
}
|
|
128
131
|
|
|
129
132
|
/**
|
|
130
133
|
* Delete text - supports two formats:
|
|
131
134
|
* 1. Position-based (for local operations): { position, length }
|
|
132
|
-
* 2. CRDT metadata (for network sync): {
|
|
135
|
+
* 2. CRDT metadata (for network sync): { rm }
|
|
136
|
+
*
|
|
137
|
+
* rm format: Array of [itemId, count] tuples
|
|
138
|
+
* Example: rm: [["client:42", 5], ["client:48", 3]]
|
|
133
139
|
*/
|
|
134
140
|
export interface TextDeleteOp extends BaseOp {
|
|
135
141
|
key: string;
|
|
@@ -139,13 +145,18 @@ export interface TextDeleteOp extends BaseOp {
|
|
|
139
145
|
position?: number;
|
|
140
146
|
length?: number;
|
|
141
147
|
// CRDT metadata format (network sync) - compressed tuple format
|
|
142
|
-
|
|
148
|
+
rm?: Array<[string, number]>; // [[itemId, length], ...]
|
|
143
149
|
}
|
|
144
150
|
|
|
145
151
|
/**
|
|
146
152
|
* Replace text - atomic delete + insert (for select-and-type)
|
|
147
|
-
*
|
|
148
|
-
*
|
|
153
|
+
*
|
|
154
|
+
* Position-based: { position, length, value: string }
|
|
155
|
+
* CRDT metadata: { rm, id, value: [anchor, content], seq, ts }
|
|
156
|
+
*
|
|
157
|
+
* The value field changes type based on format:
|
|
158
|
+
* - Position-based: value is string ("hello")
|
|
159
|
+
* - CRDT: value is [anchor, content] tuple (["client:42", "hello"])
|
|
149
160
|
*/
|
|
150
161
|
export interface TextReplaceOp extends BaseOp {
|
|
151
162
|
key: string;
|
|
@@ -154,13 +165,11 @@ export interface TextReplaceOp extends BaseOp {
|
|
|
154
165
|
// Position-based format (local convenience)
|
|
155
166
|
position?: number;
|
|
156
167
|
length?: number; // chars to delete
|
|
157
|
-
value?: string;
|
|
168
|
+
value?: string | [string | null, string]; // string for position-based, tuple for CRDT
|
|
158
169
|
// CRDT metadata format (network sync)
|
|
159
|
-
|
|
160
|
-
id?: string; // ItemId string format
|
|
161
|
-
|
|
162
|
-
parentId?: string | null; // ItemId string format
|
|
163
|
-
seq?: number;
|
|
170
|
+
rm?: Array<[string, number]>; // [[itemId, length], ...] deletions
|
|
171
|
+
id?: string; // ItemId string format: "client:seq"
|
|
172
|
+
seq?: number; // Lamport timestamp
|
|
164
173
|
ts?: number; // Wall-clock time (seconds) for tie-breaking
|
|
165
174
|
}
|
|
166
175
|
|
|
@@ -123,26 +123,26 @@ export function TextInsert(
|
|
|
123
123
|
|
|
124
124
|
const rope = getOrCreateRope(node, op.path, meta.client);
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
// Check if value is already a tuple (CRDT format)
|
|
127
|
+
const isTupleFormat = Array.isArray(op.value) && op.value.length === 2;
|
|
127
128
|
|
|
128
|
-
if (op.id !== undefined &&
|
|
129
|
-
// CRDT metadata format (
|
|
130
|
-
// Value is already [anchor, content] tuple
|
|
129
|
+
if (op.id !== undefined && isTupleFormat && op.seq !== undefined) {
|
|
130
|
+
// CRDT metadata format (from network) - value is already [anchor, content] tuple
|
|
131
131
|
apply(rope, {
|
|
132
132
|
ot: 'insert',
|
|
133
133
|
id: op.id,
|
|
134
|
-
value, //
|
|
134
|
+
value: op.value as [string | null, string], // Already tuple format
|
|
135
135
|
seq: op.seq,
|
|
136
136
|
ts: op.ts ?? Date.now() / 1000,
|
|
137
137
|
});
|
|
138
|
-
} else if (op.position !== undefined && op.value
|
|
138
|
+
} else if (op.position !== undefined && typeof op.value === 'string') {
|
|
139
139
|
// Position-based format (local edit) → convert to CRDT metadata in-place
|
|
140
140
|
const crdtOp = insertWithSplit(rope, op.position, op.value, meta.client);
|
|
141
141
|
op.id = crdtOp.id;
|
|
142
|
-
|
|
143
|
-
(op as any).value = crdtOp.value;
|
|
142
|
+
op.value = crdtOp.value; // Store as tuple [anchor, content]
|
|
144
143
|
op.seq = crdtOp.seq;
|
|
145
144
|
op.ts = crdtOp.ts;
|
|
145
|
+
(op as any)._lastCharId = (crdtOp as any)._lastCharId; // Preserve multi-char metadata
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
// node[path] is the mutated TextRope (React will call .toString())
|
|
@@ -162,17 +162,15 @@ export function TextDelete(
|
|
|
162
162
|
const rope = getRope(node, op.path);
|
|
163
163
|
if (!rope) return;
|
|
164
164
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (deletionsArray !== undefined) {
|
|
165
|
+
if (op.rm !== undefined) {
|
|
168
166
|
// CRDT metadata format (replay from journal)
|
|
169
167
|
// rm is already in tuple format: [[id, len], ...]
|
|
170
|
-
applyDelete(rope, { ot: 'delete', rm:
|
|
168
|
+
applyDelete(rope, { ot: 'delete', rm: op.rm });
|
|
171
169
|
} else if (op.position !== undefined && op.length !== undefined) {
|
|
172
170
|
// Position-based format (local edit) → convert to CRDT metadata in-place
|
|
173
171
|
const crdtOp = remove(rope, op.position, op.length);
|
|
174
172
|
// rm is already in tuple format from remove()
|
|
175
|
-
|
|
173
|
+
op.rm = crdtOp.rm;
|
|
176
174
|
}
|
|
177
175
|
|
|
178
176
|
// node[path] is the mutated TextRope
|
|
@@ -191,28 +189,27 @@ export function TextReplace(
|
|
|
191
189
|
|
|
192
190
|
const rope = getOrCreateRope(node, op.path, meta.client);
|
|
193
191
|
|
|
194
|
-
|
|
195
|
-
const
|
|
192
|
+
// Check if value is already a tuple (CRDT format)
|
|
193
|
+
const isTupleFormat = Array.isArray(op.value) && op.value.length === 2;
|
|
196
194
|
|
|
197
|
-
if (
|
|
195
|
+
if (op.rm !== undefined && op.id !== undefined && isTupleFormat && op.seq !== undefined) {
|
|
198
196
|
// CRDT metadata format (replay from journal)
|
|
199
197
|
// Value is already [anchor, content] tuple
|
|
200
198
|
applyReplace(rope, {
|
|
201
199
|
ot: 'replace',
|
|
202
|
-
rm:
|
|
200
|
+
rm: op.rm,
|
|
203
201
|
id: op.id,
|
|
204
|
-
value: value
|
|
202
|
+
value: op.value as [string | null, string], // Already tuple format
|
|
205
203
|
seq: op.seq,
|
|
206
204
|
ts: op.ts ?? Date.now() / 1000,
|
|
207
205
|
});
|
|
208
|
-
} else if (op.position !== undefined && op.length !== undefined && op.value
|
|
206
|
+
} else if (op.position !== undefined && op.length !== undefined && typeof op.value === 'string') {
|
|
209
207
|
// Position-based format (local edit) → convert to CRDT metadata in-place
|
|
210
208
|
const crdtOp = replace(rope, op.position, op.length, op.value, meta.client);
|
|
211
|
-
//
|
|
212
|
-
|
|
209
|
+
// Store CRDT metadata in tuple format
|
|
210
|
+
op.rm = crdtOp.rm;
|
|
213
211
|
op.id = crdtOp.id;
|
|
214
|
-
|
|
215
|
-
(op as any).value = crdtOp.value;
|
|
212
|
+
op.value = crdtOp.value; // Store as tuple [anchor, content]
|
|
216
213
|
op.seq = crdtOp.seq;
|
|
217
214
|
op.ts = crdtOp.ts;
|
|
218
215
|
}
|