@earendil-works/chord 0.87.1 → 0.99.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.
- package/README.md +80 -27
- package/dist/api.d.ts +6 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +8 -3
- package/dist/api.js.map +1 -1
- package/dist/bundler.d.ts.map +1 -1
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js.map +1 -1
- package/dist/delta/apply-immutable-trusted.d.ts +4 -0
- package/dist/delta/apply-immutable-trusted.d.ts.map +1 -0
- package/dist/delta/apply-immutable-trusted.js +127 -0
- package/dist/delta/apply-immutable-trusted.js.map +1 -0
- package/dist/{state → delta}/diff.d.ts +1 -1
- package/dist/delta/diff.d.ts.map +1 -0
- package/dist/delta/diff.js +433 -0
- package/dist/delta/diff.js.map +1 -0
- package/dist/delta/draft.d.ts +5 -0
- package/dist/delta/draft.d.ts.map +1 -0
- package/dist/delta/draft.js +2 -0
- package/dist/delta/draft.js.map +1 -0
- package/dist/delta/index.d.ts +11 -21
- package/dist/delta/index.d.ts.map +1 -1
- package/dist/delta/index.js +43 -1341
- package/dist/delta/index.js.map +1 -1
- package/dist/delta/revision-validator.d.ts +7 -0
- package/dist/delta/revision-validator.d.ts.map +1 -0
- package/dist/delta/revision-validator.js +71 -0
- package/dist/delta/revision-validator.js.map +1 -0
- package/dist/delta/tracker.d.ts +26 -0
- package/dist/delta/tracker.d.ts.map +1 -0
- package/dist/delta/tracker.js +2069 -0
- package/dist/delta/tracker.js.map +1 -0
- package/dist/facets/host.d.ts.map +1 -1
- package/dist/facets/host.js.map +1 -1
- package/dist/facets/loader.d.ts.map +1 -1
- package/dist/facets/loader.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/json.d.ts +6 -0
- package/dist/json.d.ts.map +1 -1
- package/dist/json.js +73 -6
- package/dist/json.js.map +1 -1
- package/dist/node/bundle-loader.d.ts.map +1 -1
- package/dist/node/bundle-loader.js.map +1 -1
- package/dist/node/bundle.d.ts.map +1 -1
- package/dist/node/bundle.js.map +1 -1
- package/dist/node/manifest.d.ts.map +1 -1
- package/dist/node/package.d.ts.map +1 -1
- package/dist/node/package.js.map +1 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/services/consumer.d.ts.map +1 -1
- package/dist/services/consumer.js +49 -1
- package/dist/services/consumer.js.map +1 -1
- package/dist/services/errors.d.ts.map +1 -1
- package/dist/services/errors.js.map +1 -1
- package/dist/services/handle.d.ts.map +1 -1
- package/dist/services/handle.js +3 -1
- package/dist/services/handle.js.map +1 -1
- package/dist/services/instances.d.ts +1 -0
- package/dist/services/instances.d.ts.map +1 -1
- package/dist/services/instances.js +3 -0
- package/dist/services/instances.js.map +1 -1
- package/dist/services/loopback.d.ts.map +1 -1
- package/dist/services/loopback.js.map +1 -1
- package/dist/services/provider.d.ts.map +1 -1
- package/dist/services/provider.js +48 -29
- package/dist/services/provider.js.map +1 -1
- package/dist/services/state-codec.d.ts.map +1 -1
- package/dist/services/state-codec.js +18 -0
- package/dist/services/state-codec.js.map +1 -1
- package/dist/services/state-internals.d.ts +5 -2
- package/dist/services/state-internals.d.ts.map +1 -1
- package/dist/services/state-internals.js.map +1 -1
- package/dist/services/state.d.ts +8 -3
- package/dist/services/state.d.ts.map +1 -1
- package/dist/services/state.js +288 -88
- package/dist/services/state.js.map +1 -1
- package/dist/services/wire.d.ts +3 -0
- package/dist/services/wire.d.ts.map +1 -1
- package/dist/services/wire.js +13 -0
- package/dist/services/wire.js.map +1 -1
- package/dist/types.d.ts +74 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +3 -3
- package/src/delta/README.md +143 -360
- package/dist/state/diff.d.ts.map +0 -1
- package/dist/state/diff.js +0 -259
- package/dist/state/diff.js.map +0 -1
- package/dist/state/draft.d.ts +0 -13
- package/dist/state/draft.d.ts.map +0 -1
- package/dist/state/draft.js +0 -540
- package/dist/state/draft.js.map +0 -1
- package/dist/state/value.d.ts +0 -9
- package/dist/state/value.d.ts.map +0 -1
- package/dist/state/value.js +0 -175
- package/dist/state/value.js.map +0 -1
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
import { overlap, RESERVED_SEGMENTS } from "./index.js";
|
|
2
|
+
const DEFAULT_OVERLAP_SCAN = 65_536;
|
|
3
|
+
const MAX_DELTA_OPERATIONS = 4_096;
|
|
4
|
+
const overflowedBatches = new WeakSet();
|
|
5
|
+
const emitOperation = (operations, operation) => {
|
|
6
|
+
if (overflowedBatches.has(operations))
|
|
7
|
+
return;
|
|
8
|
+
if (operations.length >= MAX_DELTA_OPERATIONS) {
|
|
9
|
+
overflowedBatches.add(operations);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
operations.push(operation);
|
|
13
|
+
};
|
|
14
|
+
const isContainer = (value) => value !== null && typeof value === "object";
|
|
15
|
+
const emitSet = (path, value, operations) => {
|
|
16
|
+
if (path.length === 0)
|
|
17
|
+
emitOperation(operations, ["r", value]);
|
|
18
|
+
else
|
|
19
|
+
emitOperation(operations, ["s", path, value]);
|
|
20
|
+
};
|
|
21
|
+
const equalJson = (left, right) => {
|
|
22
|
+
if (left === right)
|
|
23
|
+
return true;
|
|
24
|
+
if (!isContainer(left) || !isContainer(right) || Array.isArray(left) !== Array.isArray(right))
|
|
25
|
+
return false;
|
|
26
|
+
if (Array.isArray(left)) {
|
|
27
|
+
const other = right;
|
|
28
|
+
if (left.length !== other.length)
|
|
29
|
+
return false;
|
|
30
|
+
for (let index = 0; index < left.length; index++) {
|
|
31
|
+
if (!equalJson(left[index], other[index]))
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
const other = right;
|
|
37
|
+
const keys = Object.keys(left);
|
|
38
|
+
if (keys.length !== Object.keys(other).length)
|
|
39
|
+
return false;
|
|
40
|
+
for (const key of keys) {
|
|
41
|
+
if (!Object.hasOwn(other, key) || !equalJson(left[key], other[key]))
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
};
|
|
46
|
+
const permutation = (before, after) => {
|
|
47
|
+
if (before.length !== after.length)
|
|
48
|
+
return undefined;
|
|
49
|
+
const positions = new Map();
|
|
50
|
+
for (let index = 0; index < before.length; index++) {
|
|
51
|
+
const value = before[index];
|
|
52
|
+
const entry = positions.get(value);
|
|
53
|
+
if (entry === undefined)
|
|
54
|
+
positions.set(value, { indices: [index], used: 0 });
|
|
55
|
+
else
|
|
56
|
+
entry.indices.push(index);
|
|
57
|
+
}
|
|
58
|
+
const result = new Array(after.length);
|
|
59
|
+
for (let index = 0; index < after.length; index++) {
|
|
60
|
+
const entry = positions.get(after[index]);
|
|
61
|
+
if (entry === undefined || entry.used === entry.indices.length)
|
|
62
|
+
return undefined;
|
|
63
|
+
result[index] = entry.indices[entry.used++];
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
};
|
|
67
|
+
const emitString = (before, after, path, operations) => {
|
|
68
|
+
if (before === after)
|
|
69
|
+
return;
|
|
70
|
+
if (after.length > before.length && after.slice(0, before.length) === before) {
|
|
71
|
+
emitOperation(operations, ["a", path, after.slice(before.length)]);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const shared = overlap(before, after, DEFAULT_OVERLAP_SCAN);
|
|
75
|
+
if (shared === 0) {
|
|
76
|
+
emitOperation(operations, ["s", path, after]);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
emitOperation(operations, ["t", path, before.length - shared]);
|
|
80
|
+
if (after.length > shared)
|
|
81
|
+
emitOperation(operations, ["a", path, after.slice(shared)]);
|
|
82
|
+
};
|
|
83
|
+
const MAX_IDENTITY_CANDIDATES = 200_000;
|
|
84
|
+
const MAX_SEMANTIC_CELLS = 65_536;
|
|
85
|
+
const sameValue = (left, right) => left === right || equalJson(left, right);
|
|
86
|
+
const lcsMatches = (before, after, equal, maxCells) => {
|
|
87
|
+
if (before.length === 0 || after.length === 0)
|
|
88
|
+
return [];
|
|
89
|
+
if (before.length * after.length > maxCells)
|
|
90
|
+
return undefined;
|
|
91
|
+
const width = after.length + 1;
|
|
92
|
+
const lengths = new Uint32Array((before.length + 1) * width);
|
|
93
|
+
for (let left = before.length - 1; left >= 0; left--) {
|
|
94
|
+
for (let right = after.length - 1; right >= 0; right--) {
|
|
95
|
+
const at = left * width + right;
|
|
96
|
+
lengths[at] = equal(before[left], after[right])
|
|
97
|
+
? lengths[(left + 1) * width + right + 1] + 1
|
|
98
|
+
: Math.max(lengths[(left + 1) * width + right], lengths[left * width + right + 1]);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const matches = [];
|
|
102
|
+
let left = 0;
|
|
103
|
+
let right = 0;
|
|
104
|
+
while (left < before.length && right < after.length) {
|
|
105
|
+
if (equal(before[left], after[right]) &&
|
|
106
|
+
lengths[left * width + right] === lengths[(left + 1) * width + right + 1] + 1) {
|
|
107
|
+
matches.push([left++, right++]);
|
|
108
|
+
}
|
|
109
|
+
else if (lengths[(left + 1) * width + right] >= lengths[left * width + right + 1])
|
|
110
|
+
left += 1;
|
|
111
|
+
else
|
|
112
|
+
right += 1;
|
|
113
|
+
}
|
|
114
|
+
return matches;
|
|
115
|
+
};
|
|
116
|
+
const semanticallyAligned = (left, right) => {
|
|
117
|
+
if (sameValue(left, right))
|
|
118
|
+
return true;
|
|
119
|
+
if (!isContainer(left) || !isContainer(right) || Array.isArray(left) !== Array.isArray(right))
|
|
120
|
+
return false;
|
|
121
|
+
if (Array.isArray(left) && Array.isArray(right)) {
|
|
122
|
+
if (left.length !== right.length)
|
|
123
|
+
return false;
|
|
124
|
+
return left.some((value, index) => isContainer(value) && value === right[index]);
|
|
125
|
+
}
|
|
126
|
+
const leftObject = left;
|
|
127
|
+
const rightObject = right;
|
|
128
|
+
for (const key of Object.keys(leftObject)) {
|
|
129
|
+
const value = leftObject[key];
|
|
130
|
+
if (isContainer(value) && Object.hasOwn(rightObject, key) && value === rightObject[key])
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
return false;
|
|
134
|
+
};
|
|
135
|
+
const lowerBound = (values, value) => {
|
|
136
|
+
let low = 0;
|
|
137
|
+
let high = values.length;
|
|
138
|
+
while (low < high) {
|
|
139
|
+
const middle = (low + high) >>> 1;
|
|
140
|
+
if (values[middle] < value)
|
|
141
|
+
low = middle + 1;
|
|
142
|
+
else
|
|
143
|
+
high = middle;
|
|
144
|
+
}
|
|
145
|
+
return low;
|
|
146
|
+
};
|
|
147
|
+
const identitySubsequence = (before, beforeStart, beforeEnd, after, afterStart, afterEnd) => {
|
|
148
|
+
const beforeCount = beforeEnd - beforeStart;
|
|
149
|
+
const afterCount = afterEnd - afterStart;
|
|
150
|
+
const matches = [];
|
|
151
|
+
if (afterCount < beforeCount) {
|
|
152
|
+
let beforeIndex = beforeStart;
|
|
153
|
+
for (let afterIndex = afterStart; afterIndex < afterEnd; afterIndex++) {
|
|
154
|
+
while (beforeIndex < beforeEnd && before[beforeIndex] !== after[afterIndex])
|
|
155
|
+
beforeIndex += 1;
|
|
156
|
+
if (beforeIndex === beforeEnd)
|
|
157
|
+
return undefined;
|
|
158
|
+
matches.push([beforeIndex++, afterIndex]);
|
|
159
|
+
}
|
|
160
|
+
return matches;
|
|
161
|
+
}
|
|
162
|
+
if (beforeCount < afterCount) {
|
|
163
|
+
let afterIndex = afterStart;
|
|
164
|
+
for (let beforeIndex = beforeStart; beforeIndex < beforeEnd; beforeIndex++) {
|
|
165
|
+
while (afterIndex < afterEnd && before[beforeIndex] !== after[afterIndex])
|
|
166
|
+
afterIndex += 1;
|
|
167
|
+
if (afterIndex === afterEnd)
|
|
168
|
+
return undefined;
|
|
169
|
+
matches.push([beforeIndex, afterIndex++]);
|
|
170
|
+
}
|
|
171
|
+
return matches;
|
|
172
|
+
}
|
|
173
|
+
return undefined;
|
|
174
|
+
};
|
|
175
|
+
const greedyIdentityAnchors = (positions, after, afterStart, afterEnd) => {
|
|
176
|
+
const matches = [];
|
|
177
|
+
let previous = -1;
|
|
178
|
+
for (let afterIndex = afterStart; afterIndex < afterEnd; afterIndex++) {
|
|
179
|
+
const candidates = positions.get(after[afterIndex]);
|
|
180
|
+
if (candidates === undefined)
|
|
181
|
+
continue;
|
|
182
|
+
const at = lowerBound(candidates, previous + 1);
|
|
183
|
+
const beforeIndex = candidates[at];
|
|
184
|
+
if (beforeIndex === undefined)
|
|
185
|
+
continue;
|
|
186
|
+
matches.push([beforeIndex, afterIndex]);
|
|
187
|
+
previous = beforeIndex;
|
|
188
|
+
}
|
|
189
|
+
return matches;
|
|
190
|
+
};
|
|
191
|
+
const identityAnchors = (before, beforeStart, beforeEnd, after, afterStart, afterEnd) => {
|
|
192
|
+
const positions = new Map();
|
|
193
|
+
for (let index = beforeStart; index < beforeEnd; index++) {
|
|
194
|
+
const value = before[index];
|
|
195
|
+
const existing = positions.get(value);
|
|
196
|
+
if (existing === undefined)
|
|
197
|
+
positions.set(value, [index]);
|
|
198
|
+
else
|
|
199
|
+
existing.push(index);
|
|
200
|
+
}
|
|
201
|
+
let candidateCount = 0;
|
|
202
|
+
for (let index = afterStart; index < afterEnd; index++) {
|
|
203
|
+
candidateCount += positions.get(after[index])?.length ?? 0;
|
|
204
|
+
if (candidateCount > MAX_IDENTITY_CANDIDATES) {
|
|
205
|
+
return greedyIdentityAnchors(positions, after, afterStart, afterEnd);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (candidateCount === 0)
|
|
209
|
+
return [];
|
|
210
|
+
const candidates = [];
|
|
211
|
+
const tails = [];
|
|
212
|
+
const tailValues = [];
|
|
213
|
+
for (let afterIndex = afterStart; afterIndex < afterEnd; afterIndex++) {
|
|
214
|
+
const beforePositions = positions.get(after[afterIndex]);
|
|
215
|
+
if (beforePositions === undefined)
|
|
216
|
+
continue;
|
|
217
|
+
for (let index = beforePositions.length - 1; index >= 0; index--) {
|
|
218
|
+
const beforeIndex = beforePositions[index];
|
|
219
|
+
const at = lowerBound(tailValues, beforeIndex);
|
|
220
|
+
const candidateIndex = candidates.length;
|
|
221
|
+
candidates.push({ before: beforeIndex, after: afterIndex, previous: at === 0 ? -1 : tails[at - 1] });
|
|
222
|
+
tails[at] = candidateIndex;
|
|
223
|
+
tailValues[at] = beforeIndex;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
const matches = [];
|
|
227
|
+
let candidateIndex = tails[tails.length - 1] ?? -1;
|
|
228
|
+
while (candidateIndex >= 0) {
|
|
229
|
+
const candidate = candidates[candidateIndex];
|
|
230
|
+
matches.push([candidate.before, candidate.after]);
|
|
231
|
+
candidateIndex = candidate.previous;
|
|
232
|
+
}
|
|
233
|
+
matches.reverse();
|
|
234
|
+
return matches;
|
|
235
|
+
};
|
|
236
|
+
const processArrayMatches = (before, after, path, operations, beforeStart, beforeEnd, afterStart, afterEnd, outputStart, matches) => {
|
|
237
|
+
let beforeAt = beforeStart;
|
|
238
|
+
let afterAt = afterStart;
|
|
239
|
+
let outputAt = outputStart;
|
|
240
|
+
for (const [beforeMatch, afterMatch] of matches) {
|
|
241
|
+
if (overflowedBatches.has(operations))
|
|
242
|
+
return;
|
|
243
|
+
diffArrayRegion(before, after, path, operations, beforeAt, beforeMatch, afterAt, afterMatch, outputAt);
|
|
244
|
+
outputAt += afterMatch - afterAt;
|
|
245
|
+
if (!sameValue(before[beforeMatch], after[afterMatch])) {
|
|
246
|
+
diffValue(before[beforeMatch], after[afterMatch], [...path, outputAt], operations);
|
|
247
|
+
}
|
|
248
|
+
outputAt += 1;
|
|
249
|
+
beforeAt = beforeMatch + 1;
|
|
250
|
+
afterAt = afterMatch + 1;
|
|
251
|
+
}
|
|
252
|
+
if (!overflowedBatches.has(operations)) {
|
|
253
|
+
diffArrayRegion(before, after, path, operations, beforeAt, beforeEnd, afterAt, afterEnd, outputAt);
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
function diffArrayRegion(before, after, path, operations, beforeStart, beforeEnd, afterStart, afterEnd, outputStart) {
|
|
257
|
+
if (overflowedBatches.has(operations))
|
|
258
|
+
return;
|
|
259
|
+
while (beforeStart < beforeEnd && afterStart < afterEnd && sameValue(before[beforeStart], after[afterStart])) {
|
|
260
|
+
beforeStart += 1;
|
|
261
|
+
afterStart += 1;
|
|
262
|
+
outputStart += 1;
|
|
263
|
+
}
|
|
264
|
+
while (beforeStart < beforeEnd && afterStart < afterEnd && sameValue(before[beforeEnd - 1], after[afterEnd - 1])) {
|
|
265
|
+
beforeEnd -= 1;
|
|
266
|
+
afterEnd -= 1;
|
|
267
|
+
}
|
|
268
|
+
const beforeCount = beforeEnd - beforeStart;
|
|
269
|
+
const afterCount = afterEnd - afterStart;
|
|
270
|
+
if (beforeCount === 0 && afterCount === 0)
|
|
271
|
+
return;
|
|
272
|
+
if (beforeCount === 0 || afterCount === 0) {
|
|
273
|
+
emitOperation(operations, ["p", path, outputStart, beforeCount, after.slice(afterStart, afterEnd)]);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
if (beforeCount === afterCount) {
|
|
277
|
+
const positional = [];
|
|
278
|
+
for (let offset = 0; offset < beforeCount; offset++) {
|
|
279
|
+
if (sameValue(before[beforeStart + offset], after[afterStart + offset])) {
|
|
280
|
+
positional.push([beforeStart + offset, afterStart + offset]);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (positional.length > 0) {
|
|
284
|
+
processArrayMatches(before, after, path, operations, beforeStart, beforeEnd, afterStart, afterEnd, outputStart, positional);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
const subsequence = identitySubsequence(before, beforeStart, beforeEnd, after, afterStart, afterEnd);
|
|
289
|
+
if (subsequence !== undefined && subsequence.length > 0) {
|
|
290
|
+
processArrayMatches(before, after, path, operations, beforeStart, beforeEnd, afterStart, afterEnd, outputStart, subsequence);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
const identity = identityAnchors(before, beforeStart, beforeEnd, after, afterStart, afterEnd);
|
|
294
|
+
if (identity.length > 0) {
|
|
295
|
+
processArrayMatches(before, after, path, operations, beforeStart, beforeEnd, afterStart, afterEnd, outputStart, identity);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
const semantic = lcsMatches(before.slice(beforeStart, beforeEnd), after.slice(afterStart, afterEnd), semanticallyAligned, MAX_SEMANTIC_CELLS);
|
|
299
|
+
if (semantic !== undefined && semantic.length > 0) {
|
|
300
|
+
const absolute = semantic.map(([beforeIndex, afterIndex]) => [beforeStart + beforeIndex, afterStart + afterIndex]);
|
|
301
|
+
processArrayMatches(before, after, path, operations, beforeStart, beforeEnd, afterStart, afterEnd, outputStart, absolute);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (beforeCount === 1 && afterCount === 1) {
|
|
305
|
+
diffValue(before[beforeStart], after[afterStart], [...path, outputStart], operations);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
emitOperation(operations, ["p", path, outputStart, beforeCount, after.slice(afterStart, afterEnd)]);
|
|
309
|
+
}
|
|
310
|
+
const diffArray = (before, after, path, operations) => {
|
|
311
|
+
if (before === after || equalJson(before, after))
|
|
312
|
+
return;
|
|
313
|
+
if (before.length === after.length &&
|
|
314
|
+
before.length > 1 &&
|
|
315
|
+
!sameValue(before[0], after[0]) &&
|
|
316
|
+
!sameValue(before[before.length - 1], after[after.length - 1])) {
|
|
317
|
+
const order = permutation(before, after);
|
|
318
|
+
if (order !== undefined) {
|
|
319
|
+
emitOperation(operations, ["m", path, order]);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
diffArrayRegion(before, after, path, operations, 0, before.length, 0, after.length, 0);
|
|
324
|
+
};
|
|
325
|
+
const diffObject = (before, after, path, operations) => {
|
|
326
|
+
const beforeKeys = Object.keys(before);
|
|
327
|
+
const afterKeys = Object.keys(after);
|
|
328
|
+
if ([...beforeKeys, ...afterKeys].some((key) => RESERVED_SEGMENTS.has(key))) {
|
|
329
|
+
if (!equalJson(before, after))
|
|
330
|
+
emitSet(path, after, operations);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
for (const key of afterKeys) {
|
|
334
|
+
if (overflowedBatches.has(operations))
|
|
335
|
+
return;
|
|
336
|
+
if (Object.hasOwn(before, key))
|
|
337
|
+
diffValue(before[key], after[key], [...path, key], operations);
|
|
338
|
+
else
|
|
339
|
+
emitSet([...path, key], after[key], operations);
|
|
340
|
+
}
|
|
341
|
+
for (const key of beforeKeys) {
|
|
342
|
+
if (overflowedBatches.has(operations))
|
|
343
|
+
return;
|
|
344
|
+
if (!Object.hasOwn(after, key))
|
|
345
|
+
emitOperation(operations, ["d", [...path, key]]);
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
const diffValue = (before, after, path, operations) => {
|
|
349
|
+
if (before === after || overflowedBatches.has(operations))
|
|
350
|
+
return;
|
|
351
|
+
if (typeof before === "string" && typeof after === "string" && path.length > 0) {
|
|
352
|
+
emitString(before, after, path, operations);
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
if (Array.isArray(before) && Array.isArray(after)) {
|
|
356
|
+
diffArray(before, after, path, operations);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (isContainer(before) && isContainer(after) && !Array.isArray(before) && !Array.isArray(after)) {
|
|
360
|
+
diffObject(before, after, path, operations);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
emitSet(path, after, operations);
|
|
364
|
+
};
|
|
365
|
+
const jsonCost = (value) => {
|
|
366
|
+
if (value === null)
|
|
367
|
+
return 4;
|
|
368
|
+
if (typeof value === "string")
|
|
369
|
+
return value.length + 2;
|
|
370
|
+
if (typeof value === "number")
|
|
371
|
+
return String(value).length;
|
|
372
|
+
if (typeof value === "boolean")
|
|
373
|
+
return value ? 4 : 5;
|
|
374
|
+
if (Array.isArray(value)) {
|
|
375
|
+
let cost = 2;
|
|
376
|
+
for (let index = 0; index < value.length; index++)
|
|
377
|
+
cost += jsonCost(value[index]) + (index === 0 ? 0 : 1);
|
|
378
|
+
return cost;
|
|
379
|
+
}
|
|
380
|
+
let cost = 2;
|
|
381
|
+
let index = 0;
|
|
382
|
+
for (const key of Object.keys(value)) {
|
|
383
|
+
cost += key.length + 3 + jsonCost(value[key]) + (index++ === 0 ? 0 : 1);
|
|
384
|
+
}
|
|
385
|
+
return cost;
|
|
386
|
+
};
|
|
387
|
+
const pathCost = (path) => {
|
|
388
|
+
let cost = 2;
|
|
389
|
+
for (let index = 0; index < path.length; index++) {
|
|
390
|
+
const segment = path[index];
|
|
391
|
+
cost += (typeof segment === "string" ? segment.length + 2 : String(segment).length) + (index === 0 ? 0 : 1);
|
|
392
|
+
}
|
|
393
|
+
return cost;
|
|
394
|
+
};
|
|
395
|
+
const operationCost = (operation) => {
|
|
396
|
+
switch (operation[0]) {
|
|
397
|
+
case "r":
|
|
398
|
+
return 6 + jsonCost(operation[1]);
|
|
399
|
+
case "s":
|
|
400
|
+
return 7 + pathCost(operation[1]) + jsonCost(operation[2]);
|
|
401
|
+
case "d":
|
|
402
|
+
return 6 + pathCost(operation[1]);
|
|
403
|
+
case "a":
|
|
404
|
+
return 7 + pathCost(operation[1]) + operation[2].length + 2;
|
|
405
|
+
case "t":
|
|
406
|
+
return 7 + pathCost(operation[1]) + String(operation[2]).length;
|
|
407
|
+
case "p":
|
|
408
|
+
return (10 +
|
|
409
|
+
pathCost(operation[1]) +
|
|
410
|
+
String(operation[2]).length +
|
|
411
|
+
String(operation[3]).length +
|
|
412
|
+
jsonCost(operation[4]));
|
|
413
|
+
case "m":
|
|
414
|
+
return 7 + pathCost(operation[1]) + jsonCost(operation[2]);
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
/** Compute a compact operation batch from two immutable JSON revisions. */
|
|
418
|
+
export function diffRevisions(before, after) {
|
|
419
|
+
const operations = [];
|
|
420
|
+
diffValue(before, after, [], operations);
|
|
421
|
+
if (overflowedBatches.has(operations))
|
|
422
|
+
return [["r", after]];
|
|
423
|
+
if (operations.length === 0 || operations[0]?.[0] === "r")
|
|
424
|
+
return operations;
|
|
425
|
+
let deltaCost = 2;
|
|
426
|
+
for (const operation of operations)
|
|
427
|
+
deltaCost += operationCost(operation) + 1;
|
|
428
|
+
if (deltaCost < 65_536)
|
|
429
|
+
return operations;
|
|
430
|
+
const snapshotCost = jsonCost(after) + 6;
|
|
431
|
+
return deltaCost >= snapshotCost ? [["r", after]] : operations;
|
|
432
|
+
}
|
|
433
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/delta/diff.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JsonValue } from \"../types.ts\";\nimport { type NonEmptyPath, type Op, overlap, type Path, RESERVED_SEGMENTS, type Seg } from \"./index.ts\";\n\nconst DEFAULT_OVERLAP_SCAN = 65_536;\nconst MAX_DELTA_OPERATIONS = 4_096;\nconst overflowedBatches = new WeakSet<Op[]>();\n\nconst emitOperation = (operations: Op[], operation: Op): void => {\n\tif (overflowedBatches.has(operations)) return;\n\tif (operations.length >= MAX_DELTA_OPERATIONS) {\n\t\toverflowedBatches.add(operations);\n\t\treturn;\n\t}\n\toperations.push(operation);\n};\n\nconst isContainer = (value: JsonValue): value is JsonValue[] | Record<string, JsonValue> =>\n\tvalue !== null && typeof value === \"object\";\n\nconst emitSet = (path: Path, value: JsonValue, operations: Op[]): void => {\n\tif (path.length === 0) emitOperation(operations, [\"r\", value]);\n\telse emitOperation(operations, [\"s\", path as NonEmptyPath, value]);\n};\n\nconst equalJson = (left: JsonValue, right: JsonValue): boolean => {\n\tif (left === right) return true;\n\tif (!isContainer(left) || !isContainer(right) || Array.isArray(left) !== Array.isArray(right)) return false;\n\tif (Array.isArray(left)) {\n\t\tconst other = right as JsonValue[];\n\t\tif (left.length !== other.length) return false;\n\t\tfor (let index = 0; index < left.length; index++) {\n\t\t\tif (!equalJson(left[index]!, other[index]!)) return false;\n\t\t}\n\t\treturn true;\n\t}\n\tconst other = right as Record<string, JsonValue>;\n\tconst keys = Object.keys(left);\n\tif (keys.length !== Object.keys(other).length) return false;\n\tfor (const key of keys) {\n\t\tif (!Object.hasOwn(other, key) || !equalJson(left[key]!, other[key]!)) return false;\n\t}\n\treturn true;\n};\n\nconst permutation = (before: readonly JsonValue[], after: readonly JsonValue[]): number[] | undefined => {\n\tif (before.length !== after.length) return undefined;\n\tconst positions = new Map<JsonValue, { indices: number[]; used: number }>();\n\tfor (let index = 0; index < before.length; index++) {\n\t\tconst value = before[index]!;\n\t\tconst entry = positions.get(value);\n\t\tif (entry === undefined) positions.set(value, { indices: [index], used: 0 });\n\t\telse entry.indices.push(index);\n\t}\n\tconst result = new Array<number>(after.length);\n\tfor (let index = 0; index < after.length; index++) {\n\t\tconst entry = positions.get(after[index]!);\n\t\tif (entry === undefined || entry.used === entry.indices.length) return undefined;\n\t\tresult[index] = entry.indices[entry.used++]!;\n\t}\n\treturn result;\n};\n\nconst emitString = (before: string, after: string, path: NonEmptyPath, operations: Op[]): void => {\n\tif (before === after) return;\n\tif (after.length > before.length && after.slice(0, before.length) === before) {\n\t\temitOperation(operations, [\"a\", path, after.slice(before.length)]);\n\t\treturn;\n\t}\n\tconst shared = overlap(before, after, DEFAULT_OVERLAP_SCAN);\n\tif (shared === 0) {\n\t\temitOperation(operations, [\"s\", path, after]);\n\t\treturn;\n\t}\n\temitOperation(operations, [\"t\", path, before.length - shared]);\n\tif (after.length > shared) emitOperation(operations, [\"a\", path, after.slice(shared)]);\n};\n\ntype ArrayMatch = readonly [before: number, after: number];\n\ntype MatchCandidate = {\n\tbefore: number;\n\tafter: number;\n\tprevious: number;\n};\n\nconst MAX_IDENTITY_CANDIDATES = 200_000;\nconst MAX_SEMANTIC_CELLS = 65_536;\n\nconst sameValue = (left: JsonValue, right: JsonValue): boolean => left === right || equalJson(left, right);\n\nconst lcsMatches = (\n\tbefore: readonly JsonValue[],\n\tafter: readonly JsonValue[],\n\tequal: (left: JsonValue, right: JsonValue) => boolean,\n\tmaxCells: number,\n): ArrayMatch[] | undefined => {\n\tif (before.length === 0 || after.length === 0) return [];\n\tif (before.length * after.length > maxCells) return undefined;\n\tconst width = after.length + 1;\n\tconst lengths = new Uint32Array((before.length + 1) * width);\n\tfor (let left = before.length - 1; left >= 0; left--) {\n\t\tfor (let right = after.length - 1; right >= 0; right--) {\n\t\t\tconst at = left * width + right;\n\t\t\tlengths[at] = equal(before[left]!, after[right]!)\n\t\t\t\t? lengths[(left + 1) * width + right + 1]! + 1\n\t\t\t\t: Math.max(lengths[(left + 1) * width + right]!, lengths[left * width + right + 1]!);\n\t\t}\n\t}\n\tconst matches: ArrayMatch[] = [];\n\tlet left = 0;\n\tlet right = 0;\n\twhile (left < before.length && right < after.length) {\n\t\tif (\n\t\t\tequal(before[left]!, after[right]!) &&\n\t\t\tlengths[left * width + right] === lengths[(left + 1) * width + right + 1]! + 1\n\t\t) {\n\t\t\tmatches.push([left++, right++]);\n\t\t} else if (lengths[(left + 1) * width + right]! >= lengths[left * width + right + 1]!) left += 1;\n\t\telse right += 1;\n\t}\n\treturn matches;\n};\n\nconst semanticallyAligned = (left: JsonValue, right: JsonValue): boolean => {\n\tif (sameValue(left, right)) return true;\n\tif (!isContainer(left) || !isContainer(right) || Array.isArray(left) !== Array.isArray(right)) return false;\n\tif (Array.isArray(left) && Array.isArray(right)) {\n\t\tif (left.length !== right.length) return false;\n\t\treturn left.some((value, index) => isContainer(value) && value === right[index]);\n\t}\n\tconst leftObject = left as Record<string, JsonValue>;\n\tconst rightObject = right as Record<string, JsonValue>;\n\tfor (const key of Object.keys(leftObject)) {\n\t\tconst value = leftObject[key];\n\t\tif (isContainer(value) && Object.hasOwn(rightObject, key) && value === rightObject[key]) return true;\n\t}\n\treturn false;\n};\n\nconst lowerBound = (values: readonly number[], value: number): number => {\n\tlet low = 0;\n\tlet high = values.length;\n\twhile (low < high) {\n\t\tconst middle = (low + high) >>> 1;\n\t\tif (values[middle]! < value) low = middle + 1;\n\t\telse high = middle;\n\t}\n\treturn low;\n};\n\nconst identitySubsequence = (\n\tbefore: readonly JsonValue[],\n\tbeforeStart: number,\n\tbeforeEnd: number,\n\tafter: readonly JsonValue[],\n\tafterStart: number,\n\tafterEnd: number,\n): ArrayMatch[] | undefined => {\n\tconst beforeCount = beforeEnd - beforeStart;\n\tconst afterCount = afterEnd - afterStart;\n\tconst matches: ArrayMatch[] = [];\n\tif (afterCount < beforeCount) {\n\t\tlet beforeIndex = beforeStart;\n\t\tfor (let afterIndex = afterStart; afterIndex < afterEnd; afterIndex++) {\n\t\t\twhile (beforeIndex < beforeEnd && before[beforeIndex] !== after[afterIndex]) beforeIndex += 1;\n\t\t\tif (beforeIndex === beforeEnd) return undefined;\n\t\t\tmatches.push([beforeIndex++, afterIndex]);\n\t\t}\n\t\treturn matches;\n\t}\n\tif (beforeCount < afterCount) {\n\t\tlet afterIndex = afterStart;\n\t\tfor (let beforeIndex = beforeStart; beforeIndex < beforeEnd; beforeIndex++) {\n\t\t\twhile (afterIndex < afterEnd && before[beforeIndex] !== after[afterIndex]) afterIndex += 1;\n\t\t\tif (afterIndex === afterEnd) return undefined;\n\t\t\tmatches.push([beforeIndex, afterIndex++]);\n\t\t}\n\t\treturn matches;\n\t}\n\treturn undefined;\n};\n\nconst greedyIdentityAnchors = (\n\tpositions: ReadonlyMap<JsonValue, readonly number[]>,\n\tafter: readonly JsonValue[],\n\tafterStart: number,\n\tafterEnd: number,\n): ArrayMatch[] => {\n\tconst matches: ArrayMatch[] = [];\n\tlet previous = -1;\n\tfor (let afterIndex = afterStart; afterIndex < afterEnd; afterIndex++) {\n\t\tconst candidates = positions.get(after[afterIndex]!);\n\t\tif (candidates === undefined) continue;\n\t\tconst at = lowerBound(candidates, previous + 1);\n\t\tconst beforeIndex = candidates[at];\n\t\tif (beforeIndex === undefined) continue;\n\t\tmatches.push([beforeIndex, afterIndex]);\n\t\tprevious = beforeIndex;\n\t}\n\treturn matches;\n};\n\nconst identityAnchors = (\n\tbefore: readonly JsonValue[],\n\tbeforeStart: number,\n\tbeforeEnd: number,\n\tafter: readonly JsonValue[],\n\tafterStart: number,\n\tafterEnd: number,\n): ArrayMatch[] => {\n\tconst positions = new Map<JsonValue, number[]>();\n\tfor (let index = beforeStart; index < beforeEnd; index++) {\n\t\tconst value = before[index]!;\n\t\tconst existing = positions.get(value);\n\t\tif (existing === undefined) positions.set(value, [index]);\n\t\telse existing.push(index);\n\t}\n\tlet candidateCount = 0;\n\tfor (let index = afterStart; index < afterEnd; index++) {\n\t\tcandidateCount += positions.get(after[index]!)?.length ?? 0;\n\t\tif (candidateCount > MAX_IDENTITY_CANDIDATES) {\n\t\t\treturn greedyIdentityAnchors(positions, after, afterStart, afterEnd);\n\t\t}\n\t}\n\tif (candidateCount === 0) return [];\n\n\tconst candidates: MatchCandidate[] = [];\n\tconst tails: number[] = [];\n\tconst tailValues: number[] = [];\n\tfor (let afterIndex = afterStart; afterIndex < afterEnd; afterIndex++) {\n\t\tconst beforePositions = positions.get(after[afterIndex]!);\n\t\tif (beforePositions === undefined) continue;\n\t\tfor (let index = beforePositions.length - 1; index >= 0; index--) {\n\t\t\tconst beforeIndex = beforePositions[index]!;\n\t\t\tconst at = lowerBound(tailValues, beforeIndex);\n\t\t\tconst candidateIndex = candidates.length;\n\t\t\tcandidates.push({ before: beforeIndex, after: afterIndex, previous: at === 0 ? -1 : tails[at - 1]! });\n\t\t\ttails[at] = candidateIndex;\n\t\t\ttailValues[at] = beforeIndex;\n\t\t}\n\t}\n\tconst matches: ArrayMatch[] = [];\n\tlet candidateIndex = tails[tails.length - 1] ?? -1;\n\twhile (candidateIndex >= 0) {\n\t\tconst candidate = candidates[candidateIndex]!;\n\t\tmatches.push([candidate.before, candidate.after]);\n\t\tcandidateIndex = candidate.previous;\n\t}\n\tmatches.reverse();\n\treturn matches;\n};\n\nconst processArrayMatches = (\n\tbefore: JsonValue[],\n\tafter: JsonValue[],\n\tpath: Path,\n\toperations: Op[],\n\tbeforeStart: number,\n\tbeforeEnd: number,\n\tafterStart: number,\n\tafterEnd: number,\n\toutputStart: number,\n\tmatches: readonly ArrayMatch[],\n): void => {\n\tlet beforeAt = beforeStart;\n\tlet afterAt = afterStart;\n\tlet outputAt = outputStart;\n\tfor (const [beforeMatch, afterMatch] of matches) {\n\t\tif (overflowedBatches.has(operations)) return;\n\t\tdiffArrayRegion(before, after, path, operations, beforeAt, beforeMatch, afterAt, afterMatch, outputAt);\n\t\toutputAt += afterMatch - afterAt;\n\t\tif (!sameValue(before[beforeMatch]!, after[afterMatch]!)) {\n\t\t\tdiffValue(before[beforeMatch]!, after[afterMatch]!, [...path, outputAt], operations);\n\t\t}\n\t\toutputAt += 1;\n\t\tbeforeAt = beforeMatch + 1;\n\t\tafterAt = afterMatch + 1;\n\t}\n\tif (!overflowedBatches.has(operations)) {\n\t\tdiffArrayRegion(before, after, path, operations, beforeAt, beforeEnd, afterAt, afterEnd, outputAt);\n\t}\n};\n\nfunction diffArrayRegion(\n\tbefore: JsonValue[],\n\tafter: JsonValue[],\n\tpath: Path,\n\toperations: Op[],\n\tbeforeStart: number,\n\tbeforeEnd: number,\n\tafterStart: number,\n\tafterEnd: number,\n\toutputStart: number,\n): void {\n\tif (overflowedBatches.has(operations)) return;\n\twhile (beforeStart < beforeEnd && afterStart < afterEnd && sameValue(before[beforeStart]!, after[afterStart]!)) {\n\t\tbeforeStart += 1;\n\t\tafterStart += 1;\n\t\toutputStart += 1;\n\t}\n\twhile (beforeStart < beforeEnd && afterStart < afterEnd && sameValue(before[beforeEnd - 1]!, after[afterEnd - 1]!)) {\n\t\tbeforeEnd -= 1;\n\t\tafterEnd -= 1;\n\t}\n\tconst beforeCount = beforeEnd - beforeStart;\n\tconst afterCount = afterEnd - afterStart;\n\tif (beforeCount === 0 && afterCount === 0) return;\n\tif (beforeCount === 0 || afterCount === 0) {\n\t\temitOperation(operations, [\"p\", path, outputStart, beforeCount, after.slice(afterStart, afterEnd)]);\n\t\treturn;\n\t}\n\n\tif (beforeCount === afterCount) {\n\t\tconst positional: ArrayMatch[] = [];\n\t\tfor (let offset = 0; offset < beforeCount; offset++) {\n\t\t\tif (sameValue(before[beforeStart + offset]!, after[afterStart + offset]!)) {\n\t\t\t\tpositional.push([beforeStart + offset, afterStart + offset]);\n\t\t\t}\n\t\t}\n\t\tif (positional.length > 0) {\n\t\t\tprocessArrayMatches(\n\t\t\t\tbefore,\n\t\t\t\tafter,\n\t\t\t\tpath,\n\t\t\t\toperations,\n\t\t\t\tbeforeStart,\n\t\t\t\tbeforeEnd,\n\t\t\t\tafterStart,\n\t\t\t\tafterEnd,\n\t\t\t\toutputStart,\n\t\t\t\tpositional,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tconst subsequence = identitySubsequence(before, beforeStart, beforeEnd, after, afterStart, afterEnd);\n\tif (subsequence !== undefined && subsequence.length > 0) {\n\t\tprocessArrayMatches(\n\t\t\tbefore,\n\t\t\tafter,\n\t\t\tpath,\n\t\t\toperations,\n\t\t\tbeforeStart,\n\t\t\tbeforeEnd,\n\t\t\tafterStart,\n\t\t\tafterEnd,\n\t\t\toutputStart,\n\t\t\tsubsequence,\n\t\t);\n\t\treturn;\n\t}\n\n\tconst identity = identityAnchors(before, beforeStart, beforeEnd, after, afterStart, afterEnd);\n\tif (identity.length > 0) {\n\t\tprocessArrayMatches(\n\t\t\tbefore,\n\t\t\tafter,\n\t\t\tpath,\n\t\t\toperations,\n\t\t\tbeforeStart,\n\t\t\tbeforeEnd,\n\t\t\tafterStart,\n\t\t\tafterEnd,\n\t\t\toutputStart,\n\t\t\tidentity,\n\t\t);\n\t\treturn;\n\t}\n\n\tconst semantic = lcsMatches(\n\t\tbefore.slice(beforeStart, beforeEnd),\n\t\tafter.slice(afterStart, afterEnd),\n\t\tsemanticallyAligned,\n\t\tMAX_SEMANTIC_CELLS,\n\t);\n\tif (semantic !== undefined && semantic.length > 0) {\n\t\tconst absolute = semantic.map(\n\t\t\t([beforeIndex, afterIndex]) => [beforeStart + beforeIndex, afterStart + afterIndex] as const,\n\t\t);\n\t\tprocessArrayMatches(\n\t\t\tbefore,\n\t\t\tafter,\n\t\t\tpath,\n\t\t\toperations,\n\t\t\tbeforeStart,\n\t\t\tbeforeEnd,\n\t\t\tafterStart,\n\t\t\tafterEnd,\n\t\t\toutputStart,\n\t\t\tabsolute,\n\t\t);\n\t\treturn;\n\t}\n\n\tif (beforeCount === 1 && afterCount === 1) {\n\t\tdiffValue(before[beforeStart]!, after[afterStart]!, [...path, outputStart], operations);\n\t\treturn;\n\t}\n\temitOperation(operations, [\"p\", path, outputStart, beforeCount, after.slice(afterStart, afterEnd)]);\n}\n\nconst diffArray = (before: JsonValue[], after: JsonValue[], path: Path, operations: Op[]): void => {\n\tif (before === after || equalJson(before, after)) return;\n\tif (\n\t\tbefore.length === after.length &&\n\t\tbefore.length > 1 &&\n\t\t!sameValue(before[0]!, after[0]!) &&\n\t\t!sameValue(before[before.length - 1]!, after[after.length - 1]!)\n\t) {\n\t\tconst order = permutation(before, after);\n\t\tif (order !== undefined) {\n\t\t\temitOperation(operations, [\"m\", path, order]);\n\t\t\treturn;\n\t\t}\n\t}\n\tdiffArrayRegion(before, after, path, operations, 0, before.length, 0, after.length, 0);\n};\n\nconst diffObject = (\n\tbefore: Record<string, JsonValue>,\n\tafter: Record<string, JsonValue>,\n\tpath: Path,\n\toperations: Op[],\n): void => {\n\tconst beforeKeys = Object.keys(before);\n\tconst afterKeys = Object.keys(after);\n\tif ([...beforeKeys, ...afterKeys].some((key) => RESERVED_SEGMENTS.has(key))) {\n\t\tif (!equalJson(before, after)) emitSet(path, after, operations);\n\t\treturn;\n\t}\n\tfor (const key of afterKeys) {\n\t\tif (overflowedBatches.has(operations)) return;\n\t\tif (Object.hasOwn(before, key)) diffValue(before[key]!, after[key]!, [...path, key], operations);\n\t\telse emitSet([...path, key], after[key]!, operations);\n\t}\n\tfor (const key of beforeKeys) {\n\t\tif (overflowedBatches.has(operations)) return;\n\t\tif (!Object.hasOwn(after, key)) emitOperation(operations, [\"d\", [...path, key] as unknown as NonEmptyPath]);\n\t}\n};\n\nconst diffValue = (before: JsonValue, after: JsonValue, path: Path, operations: Op[]): void => {\n\tif (before === after || overflowedBatches.has(operations)) return;\n\tif (typeof before === \"string\" && typeof after === \"string\" && path.length > 0) {\n\t\temitString(before, after, path as NonEmptyPath, operations);\n\t\treturn;\n\t}\n\tif (Array.isArray(before) && Array.isArray(after)) {\n\t\tdiffArray(before, after, path, operations);\n\t\treturn;\n\t}\n\tif (isContainer(before) && isContainer(after) && !Array.isArray(before) && !Array.isArray(after)) {\n\t\tdiffObject(before, after, path, operations);\n\t\treturn;\n\t}\n\temitSet(path, after, operations);\n};\n\nconst jsonCost = (value: JsonValue): number => {\n\tif (value === null) return 4;\n\tif (typeof value === \"string\") return value.length + 2;\n\tif (typeof value === \"number\") return String(value).length;\n\tif (typeof value === \"boolean\") return value ? 4 : 5;\n\tif (Array.isArray(value)) {\n\t\tlet cost = 2;\n\t\tfor (let index = 0; index < value.length; index++) cost += jsonCost(value[index]!) + (index === 0 ? 0 : 1);\n\t\treturn cost;\n\t}\n\tlet cost = 2;\n\tlet index = 0;\n\tfor (const key of Object.keys(value)) {\n\t\tcost += key.length + 3 + jsonCost(value[key]!) + (index++ === 0 ? 0 : 1);\n\t}\n\treturn cost;\n};\n\nconst pathCost = (path: Path): number => {\n\tlet cost = 2;\n\tfor (let index = 0; index < path.length; index++) {\n\t\tconst segment: Seg = path[index]!;\n\t\tcost += (typeof segment === \"string\" ? segment.length + 2 : String(segment).length) + (index === 0 ? 0 : 1);\n\t}\n\treturn cost;\n};\n\nconst operationCost = (operation: Op): number => {\n\tswitch (operation[0]) {\n\t\tcase \"r\":\n\t\t\treturn 6 + jsonCost(operation[1]);\n\t\tcase \"s\":\n\t\t\treturn 7 + pathCost(operation[1]) + jsonCost(operation[2]);\n\t\tcase \"d\":\n\t\t\treturn 6 + pathCost(operation[1]);\n\t\tcase \"a\":\n\t\t\treturn 7 + pathCost(operation[1]) + operation[2].length + 2;\n\t\tcase \"t\":\n\t\t\treturn 7 + pathCost(operation[1]) + String(operation[2]).length;\n\t\tcase \"p\":\n\t\t\treturn (\n\t\t\t\t10 +\n\t\t\t\tpathCost(operation[1]) +\n\t\t\t\tString(operation[2]).length +\n\t\t\t\tString(operation[3]).length +\n\t\t\t\tjsonCost(operation[4])\n\t\t\t);\n\t\tcase \"m\":\n\t\t\treturn 7 + pathCost(operation[1]) + jsonCost(operation[2]);\n\t}\n};\n\n/** Compute a compact operation batch from two immutable JSON revisions. */\nexport function diffRevisions(before: JsonValue, after: JsonValue): Op[] {\n\tconst operations: Op[] = [];\n\tdiffValue(before, after, [], operations);\n\tif (overflowedBatches.has(operations)) return [[\"r\", after]];\n\tif (operations.length === 0 || operations[0]?.[0] === \"r\") return operations;\n\tlet deltaCost = 2;\n\tfor (const operation of operations) deltaCost += operationCost(operation) + 1;\n\tif (deltaCost < 65_536) return operations;\n\tconst snapshotCost = jsonCost(after) + 6;\n\treturn deltaCost >= snapshotCost ? [[\"r\", after]] : operations;\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** A mutable transaction-scoped view of a JSON value, preserving tuple positions. */
|
|
2
|
+
export type Draft<T, Depth extends readonly unknown[] = []> = Depth["length"] extends 8 ? T : T extends null | boolean | number | string ? T : T extends (...args: never[]) => unknown ? T : T extends object ? {
|
|
3
|
+
-readonly [Key in keyof T]: Draft<T[Key], [...Depth, unknown]>;
|
|
4
|
+
} : T;
|
|
5
|
+
//# sourceMappingURL=draft.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft.d.ts","sourceRoot":"","sources":["../../src/delta/draft.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,KAAK,SAAS,SAAS,OAAO,EAAE,GAAG,EAAE,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,GACpF,CAAC,GACD,CAAC,SAAS,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GACzC,CAAC,GACD,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,GACtC,CAAC,GACD,CAAC,SAAS,MAAM,GACf;IAAE,CAAC,UAAU,GAAG,IAAI,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,OAAO,CAAC,CAAC;CAAE,GAClE,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft.js","sourceRoot":"","sources":["../../src/delta/draft.ts"],"names":[],"mappings":"","sourcesContent":["/** A mutable transaction-scoped view of a JSON value, preserving tuple positions. */\nexport type Draft<T, Depth extends readonly unknown[] = []> = Depth[\"length\"] extends 8\n\t? T\n\t: T extends null | boolean | number | string\n\t\t? T\n\t\t: T extends (...args: never[]) => unknown\n\t\t\t? T\n\t\t\t: T extends object\n\t\t\t\t? { -readonly [Key in keyof T]: Draft<T[Key], [...Depth, unknown]> }\n\t\t\t\t: T;\n"]}
|
package/dist/delta/index.d.ts
CHANGED
|
@@ -44,26 +44,9 @@ export declare const isBase: (ops: readonly (Op | WireOp)[]) => boolean;
|
|
|
44
44
|
* Always correct: the returned n satisfies a.slice(a.length - n) === b.slice(0, n).
|
|
45
45
|
*/
|
|
46
46
|
export declare function overlap(a: string, b: string, scan: number, probe?: number, maxCandidates?: number): number;
|
|
47
|
-
export
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
export interface Tracker<T extends object> {
|
|
51
|
-
/**
|
|
52
|
-
* The tracked value. Mutate and read state only through this proxy. Values
|
|
53
|
-
* inserted into it are adopted: callers may retain read-only references, but
|
|
54
|
-
* must not mutate them outside this proxy.
|
|
55
|
-
*/
|
|
56
|
-
state: T;
|
|
57
|
-
/** The untracked current value. Mutating it bypasses change tracking. */
|
|
58
|
-
readonly target: T;
|
|
59
|
-
flush(): Op[];
|
|
60
|
-
/** Make the next flush a complete base batch without changing the value. */
|
|
61
|
-
rebase(): void;
|
|
62
|
-
/** Accept pending mutations locally without emitting them. */
|
|
63
|
-
discard(): void;
|
|
64
|
-
readonly dirty: boolean;
|
|
65
|
-
}
|
|
66
|
-
export declare function track<T extends object>(root: T, options?: TrackerOptions): Tracker<T>;
|
|
47
|
+
export { diffRevisions } from "./diff.ts";
|
|
48
|
+
export type { Draft } from "./draft.ts";
|
|
49
|
+
export { type Change, type Prepared, type Tracker, track } from "./tracker.ts";
|
|
67
50
|
/**
|
|
68
51
|
* Segments that reach the prototype chain.
|
|
69
52
|
*
|
|
@@ -104,8 +87,15 @@ export declare class PathError extends Error {
|
|
|
104
87
|
* `decode` first if the ops came from a boundary.
|
|
105
88
|
*/
|
|
106
89
|
export declare function apply<T>(target: T | undefined, ops: readonly Op[]): T;
|
|
107
|
-
/** Apply decoded
|
|
90
|
+
/** Apply one decoded operation batch without mutating the previous immutable value. */
|
|
108
91
|
export declare function applyImmutable<T>(target: T | undefined, ops: readonly Op[]): T;
|
|
92
|
+
/**
|
|
93
|
+
* Apply decoded operation batches as one final-result-only replay.
|
|
94
|
+
*
|
|
95
|
+
* Containers copied for an earlier batch may be mutated while applying a later
|
|
96
|
+
* batch, so this deliberately exposes no intermediate revisions.
|
|
97
|
+
*/
|
|
98
|
+
export declare function applyImmutableBatches<T>(target: T | undefined, batches: Iterable<readonly Op[]>): T;
|
|
109
99
|
export interface Encoder {
|
|
110
100
|
encode(ops: readonly Op[]): WireOp[];
|
|
111
101
|
}
|