@sanity/diff 6.7.0-next.36 → 6.7.0-next.5

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/lib/index.js CHANGED
@@ -1,645 +1,663 @@
1
- import { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, cleanupSemantic, makeDiff } from "@sanity/diff-match-patch";
1
+ import { cleanupSemantic, makeDiff, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL } from "@sanity/diff-match-patch";
2
2
  function replaceProperty(parent, prop, value) {
3
- return delete parent[prop], parent[prop] = value, value;
3
+ return delete parent[prop], parent[prop] = value, value;
4
4
  }
5
5
  function getLongestCommonSubsequence(previous, next) {
6
- return backtrack(getLengthMatrix(previous, next), previous, next);
6
+ const matrix = getLengthMatrix(previous, next);
7
+ return backtrack(matrix, previous, next);
7
8
  }
8
9
  function getLengthMatrix(previous, next) {
9
- let len1 = previous.length, len2 = next.length, x = 0, y = 0, matrix = Array(len1 + 1);
10
- for (x = 0; x < len1 + 1; x++) for (matrix[x] = [len2 + 1], y = 0; y < len2 + 1; y++) matrix[x][y] = 0;
11
- for (x = 1; x < len1 + 1; x++) for (y = 1; y < len2 + 1; y++) previous[x - 1] === next[y - 1] ? matrix[x][y] = matrix[x - 1][y - 1] + 1 : matrix[x][y] = Math.max(matrix[x - 1][y], matrix[x][y - 1]);
12
- return matrix;
10
+ const len1 = previous.length, len2 = next.length;
11
+ let x = 0, y = 0;
12
+ const matrix = new Array(len1 + 1);
13
+ for (x = 0; x < len1 + 1; x++)
14
+ for (matrix[x] = [len2 + 1], y = 0; y < len2 + 1; y++)
15
+ matrix[x][y] = 0;
16
+ for (x = 1; x < len1 + 1; x++)
17
+ for (y = 1; y < len2 + 1; y++)
18
+ previous[x - 1] === next[y - 1] ? matrix[x][y] = matrix[x - 1][y - 1] + 1 : matrix[x][y] = Math.max(matrix[x - 1][y], matrix[x][y - 1]);
19
+ return matrix;
13
20
  }
14
21
  function backtrack(matrix, previous, next) {
15
- let prevIndex = previous.length, nextIndex = next.length, subsequence = {
16
- sequence: [],
17
- prevIndices: [],
18
- nextIndices: []
19
- };
20
- for (; prevIndex !== 0 && nextIndex !== 0;) previous[prevIndex - 1] === next[nextIndex - 1] ? (subsequence.sequence.unshift(previous[prevIndex - 1]), subsequence.prevIndices.unshift(prevIndex - 1), subsequence.nextIndices.unshift(nextIndex - 1), --prevIndex, --nextIndex) : matrix[prevIndex][nextIndex - 1] > matrix[prevIndex - 1][nextIndex] ? --nextIndex : --prevIndex;
21
- return subsequence;
22
+ let prevIndex = previous.length, nextIndex = next.length;
23
+ const subsequence = {
24
+ sequence: [],
25
+ prevIndices: [],
26
+ nextIndices: []
27
+ };
28
+ for (; prevIndex !== 0 && nextIndex !== 0; )
29
+ if (previous[prevIndex - 1] === next[nextIndex - 1])
30
+ subsequence.sequence.unshift(previous[prevIndex - 1]), subsequence.prevIndices.unshift(prevIndex - 1), subsequence.nextIndices.unshift(nextIndex - 1), --prevIndex, --nextIndex;
31
+ else {
32
+ const valueAtMatrixAbove = matrix[prevIndex][nextIndex - 1], valueAtMatrixLeft = matrix[prevIndex - 1][nextIndex];
33
+ valueAtMatrixAbove > valueAtMatrixLeft ? --nextIndex : --prevIndex;
34
+ }
35
+ return subsequence;
22
36
  }
23
37
  function diffArray(fromInput, toInput, options) {
24
- if (fromInput === toInput) return {
25
- type: "array",
26
- action: "unchanged",
27
- isChanged: !1,
28
- fromValue: fromInput.value,
29
- toValue: toInput.value,
30
- get items() {
31
- let items = diffExactByPosition(fromInput, toInput, options);
32
- if (!items) throw Error("invariant broken: equivalent input, but diff detected");
33
- return replaceProperty(this, "items", items);
34
- }
35
- };
36
- let keyedA = indexByKey(fromInput), keyedB = indexByKey(toInput);
37
- if (keyedA && keyedB) return diffArrayByKey(fromInput, keyedA, toInput, keyedB, options);
38
- let items = diffExactByPosition(fromInput, toInput, options);
39
- return items ? buildArrayDiff(fromInput, toInput, items, !1) : diffArrayByReinsert(fromInput, toInput, options);
38
+ if (fromInput === toInput) {
39
+ const fromValue = fromInput.value, toValue = toInput.value;
40
+ return {
41
+ type: "array",
42
+ action: "unchanged",
43
+ isChanged: !1,
44
+ fromValue,
45
+ toValue,
46
+ get items() {
47
+ const items2 = diffExactByPosition(fromInput, toInput, options);
48
+ if (!items2) throw new Error("invariant broken: equivalent input, but diff detected");
49
+ return replaceProperty(this, "items", items2);
50
+ }
51
+ };
52
+ }
53
+ const keyedA = indexByKey(fromInput), keyedB = indexByKey(toInput);
54
+ if (keyedA && keyedB)
55
+ return diffArrayByKey(fromInput, keyedA, toInput, keyedB);
56
+ const items = diffExactByPosition(fromInput, toInput, options);
57
+ return items ? buildArrayDiff(fromInput, toInput, items, !1) : diffArrayByReinsert(fromInput, toInput);
40
58
  }
41
59
  function buildArrayDiff(fromInput, toInput, items, isChanged) {
42
- let fromValue = fromInput.value, toValue = toInput.value;
43
- return isChanged ? {
44
- type: "array",
45
- action: "changed",
46
- isChanged: !0,
47
- fromValue,
48
- toValue,
49
- items,
50
- annotation: toInput.annotation
51
- } : {
52
- type: "array",
53
- action: "unchanged",
54
- isChanged: !1,
55
- fromValue,
56
- toValue,
57
- items
58
- };
59
- }
60
- /**
61
- * Diffes the two arrays by position. Returns an `items` array if they are unchanged, or undefined
62
- * if there are any changes anywhere.
63
- */
60
+ const fromValue = fromInput.value, toValue = toInput.value;
61
+ return isChanged ? {
62
+ type: "array",
63
+ action: "changed",
64
+ isChanged: !0,
65
+ fromValue,
66
+ toValue,
67
+ items,
68
+ annotation: toInput.annotation
69
+ } : {
70
+ type: "array",
71
+ action: "unchanged",
72
+ isChanged: !1,
73
+ fromValue,
74
+ toValue,
75
+ items
76
+ };
77
+ }
64
78
  function diffExactByPosition(fromInput, toInput, options) {
65
- if (fromInput.length !== toInput.length) return;
66
- let items = [];
67
- for (let idx = 0; idx < fromInput.length; idx++) {
68
- let diff = diffInput(fromInput.at(idx), toInput.at(idx), options);
69
- if (diff.isChanged) return;
70
- items.push({
71
- fromIndex: idx,
72
- toIndex: idx,
73
- hasMoved: !1,
74
- diff,
75
- annotation: toInput.annotationAt(idx)
76
- });
77
- }
78
- return items;
79
+ if (fromInput.length !== toInput.length)
80
+ return;
81
+ const items = [];
82
+ for (let idx = 0; idx < fromInput.length; idx++) {
83
+ const diff = diffInput(fromInput.at(idx), toInput.at(idx), options);
84
+ if (diff.isChanged)
85
+ return;
86
+ items.push({
87
+ fromIndex: idx,
88
+ toIndex: idx,
89
+ hasMoved: !1,
90
+ diff,
91
+ annotation: toInput.annotationAt(idx)
92
+ });
93
+ }
94
+ return items;
79
95
  }
80
96
  function diffArrayByReinsert(fromInput, toInput, options) {
81
- let items = [];
82
- for (let idx = 0; idx < toInput.length; idx++) {
83
- let input = toInput.at(idx);
84
- items.push({
85
- fromIndex: void 0,
86
- toIndex: idx,
87
- hasMoved: !1,
88
- diff: addedInput(input, void 0, options),
89
- annotation: input.annotation
90
- });
91
- }
92
- for (let idx = 0; idx < fromInput.length; idx++) {
93
- let input = fromInput.at(idx);
94
- items.push({
95
- fromIndex: idx,
96
- toIndex: void 0,
97
- hasMoved: !1,
98
- diff: removedInput(input, void 0, options),
99
- annotation: input.annotation
100
- });
101
- }
102
- return buildArrayDiff(fromInput, toInput, items, !0);
103
- }
104
- /**
105
- * Diff an array when all the elements have _key in the same position.
106
- */
97
+ const items = [];
98
+ for (let idx = 0; idx < toInput.length; idx++) {
99
+ const input = toInput.at(idx);
100
+ items.push({
101
+ fromIndex: void 0,
102
+ toIndex: idx,
103
+ hasMoved: !1,
104
+ diff: addedInput(input, void 0),
105
+ annotation: input.annotation
106
+ });
107
+ }
108
+ for (let idx = 0; idx < fromInput.length; idx++) {
109
+ const input = fromInput.at(idx);
110
+ items.push({
111
+ fromIndex: idx,
112
+ toIndex: void 0,
113
+ hasMoved: !1,
114
+ diff: removedInput(input, void 0),
115
+ annotation: input.annotation
116
+ });
117
+ }
118
+ return buildArrayDiff(fromInput, toInput, items, !0);
119
+ }
107
120
  function diffArrayByKey(fromArray, fromKeyIndex, toArray, toKeyIndex, options) {
108
- let items = [], isChanged = !1;
109
- function diffCommon(key, fromIndex, toIndex, hasMoved) {
110
- deletePositionInIndex(fromKeyIndex.index, key, fromIndex), deletePositionInIndex(toKeyIndex.index, key, toIndex);
111
- let diff = diffInput(fromArray.at(fromIndex), toArray.at(toIndex));
112
- items.push({
113
- fromIndex,
114
- toIndex,
115
- hasMoved,
116
- diff,
117
- annotation: toArray.annotationAt(toIndex)
118
- }), (diff.isChanged || fromIndex !== toIndex) && (isChanged = !0);
119
- }
120
- let lcs = getLongestCommonSubsequence(fromKeyIndex.keys, toKeyIndex.keys);
121
- for (let fromIndex = 0; fromIndex < fromKeyIndex.keys.length; fromIndex++) {
122
- let key = fromKeyIndex.keys[fromIndex], subsequenceIdx = lcs.prevIndices.indexOf(fromIndex);
123
- if (subsequenceIdx !== -1) {
124
- diffCommon(key, fromIndex, lcs.nextIndices[subsequenceIdx], !1);
125
- continue;
126
- }
127
- let toIndexes = toKeyIndex.index.get(key), toIndex = toIndexes && toIndexes.find((idx) => !lcs.nextIndices.includes(idx));
128
- if (toIndex !== void 0) {
129
- diffCommon(key, fromIndex, toIndex, !0);
130
- continue;
131
- }
132
- let input = fromArray.at(fromIndex);
133
- items.push({
134
- fromIndex,
135
- toIndex: void 0,
136
- hasMoved: !1,
137
- diff: removedInput(input, void 0, options),
138
- annotation: fromArray.annotationAt(fromIndex)
139
- }), isChanged = !0;
140
- }
141
- for (let positions of toKeyIndex.index.values()) {
142
- for (let toIndex of positions) {
143
- let input = toArray.at(toIndex);
144
- items.push({
145
- fromIndex: void 0,
146
- toIndex,
147
- hasMoved: !1,
148
- diff: addedInput(input, void 0, options),
149
- annotation: toArray.annotationAt(toIndex)
150
- });
151
- }
152
- isChanged = !0;
153
- }
154
- return items.sort(compareItemDiff), buildArrayDiff(fromArray, toArray, items, isChanged);
121
+ const items = [];
122
+ let isChanged = !1;
123
+ function diffCommon(key, fromIndex, toIndex, hasMoved) {
124
+ deletePositionInIndex(fromKeyIndex.index, key, fromIndex), deletePositionInIndex(toKeyIndex.index, key, toIndex);
125
+ const fromInput = fromArray.at(fromIndex), toInput = toArray.at(toIndex), diff = diffInput(fromInput, toInput);
126
+ items.push({
127
+ fromIndex,
128
+ toIndex,
129
+ hasMoved,
130
+ diff,
131
+ annotation: toArray.annotationAt(toIndex)
132
+ }), (diff.isChanged || fromIndex !== toIndex) && (isChanged = !0);
133
+ }
134
+ const lcs = getLongestCommonSubsequence(fromKeyIndex.keys, toKeyIndex.keys);
135
+ for (let fromIndex = 0; fromIndex < fromKeyIndex.keys.length; fromIndex++) {
136
+ const key = fromKeyIndex.keys[fromIndex], subsequenceIdx = lcs.prevIndices.indexOf(fromIndex);
137
+ if (subsequenceIdx !== -1) {
138
+ diffCommon(key, fromIndex, lcs.nextIndices[subsequenceIdx], !1);
139
+ continue;
140
+ }
141
+ const toIndexes = toKeyIndex.index.get(key), toIndex = toIndexes && toIndexes.find((idx) => !lcs.nextIndices.includes(idx));
142
+ if (toIndex !== void 0) {
143
+ diffCommon(key, fromIndex, toIndex, !0);
144
+ continue;
145
+ }
146
+ const input = fromArray.at(fromIndex);
147
+ items.push({
148
+ fromIndex,
149
+ toIndex: void 0,
150
+ hasMoved: !1,
151
+ diff: removedInput(input, void 0),
152
+ annotation: fromArray.annotationAt(fromIndex)
153
+ }), isChanged = !0;
154
+ }
155
+ for (const positions of toKeyIndex.index.values()) {
156
+ for (const toIndex of positions) {
157
+ const input = toArray.at(toIndex);
158
+ items.push({
159
+ fromIndex: void 0,
160
+ toIndex,
161
+ hasMoved: !1,
162
+ diff: addedInput(input, void 0),
163
+ annotation: toArray.annotationAt(toIndex)
164
+ });
165
+ }
166
+ isChanged = !0;
167
+ }
168
+ return items.sort(compareItemDiff), buildArrayDiff(fromArray, toArray, items, isChanged);
155
169
  }
156
170
  function compareItemDiff(a, b) {
157
- if (a.toIndex !== void 0 && b.toIndex !== void 0) return a.toIndex - b.toIndex;
158
- if (a.fromIndex !== void 0 && b.fromIndex !== void 0) return a.fromIndex - b.fromIndex;
159
- if (a.fromIndex !== void 0 && b.toIndex !== void 0) return -1;
160
- if (a.toIndex !== void 0 && b.fromIndex !== void 0) return 1;
161
- throw Error("invalid item diff comparison");
171
+ if (a.toIndex !== void 0 && b.toIndex !== void 0)
172
+ return a.toIndex - b.toIndex;
173
+ if (a.fromIndex !== void 0 && b.fromIndex !== void 0)
174
+ return a.fromIndex - b.fromIndex;
175
+ if (a.fromIndex !== void 0 && b.toIndex !== void 0)
176
+ return -1;
177
+ if (a.toIndex !== void 0 && b.fromIndex !== void 0)
178
+ return 1;
179
+ throw new Error("invalid item diff comparison");
162
180
  }
163
181
  function deletePositionInIndex(index, key, pos) {
164
- let positions = index.get(key);
165
- deleteArrayValue(positions, pos), positions.length === 0 && index.delete(key);
182
+ const positions = index.get(key);
183
+ deleteArrayValue(positions, pos), positions.length === 0 && index.delete(key);
166
184
  }
167
185
  function deleteArrayValue(arr, value) {
168
- let idx = arr.indexOf(value);
169
- if (idx === -1) throw Error("value not found");
170
- arr.splice(idx, 1);
171
- }
172
- /**
173
- * Indexes the array by a key. This handles cases where the items are:
174
- *
175
- * - Objects with _key
176
- * - Strings
177
- * - Numbers
178
- */
186
+ const idx = arr.indexOf(value);
187
+ if (idx === -1) throw new Error("value not found");
188
+ arr.splice(idx, 1);
189
+ }
179
190
  function indexByKey(arr) {
180
- let index = /* @__PURE__ */ new Map(), keys = [], length = arr.length;
181
- for (let i = 0; i < length; i++) {
182
- let item = arr.at(i), key = null;
183
- switch (item.type) {
184
- case "string":
185
- key = `s${item.value}`;
186
- break;
187
- case "number":
188
- key = item.value;
189
- break;
190
- case "boolean":
191
- key = item.value;
192
- break;
193
- case "null":
194
- key = "n";
195
- break;
196
- case "object":
197
- {
198
- let keyField = item.get("_key");
199
- if (keyField && keyField.type === "string" && (key = `k${keyField.value}`, index.has(key))) return;
200
- }
201
- break;
202
- default:
203
- }
204
- if (key === null) return;
205
- keys.push(key);
206
- let positions = index.get(key);
207
- positions || (positions = [], index.set(key, positions)), positions.push(i);
208
- }
209
- return {
210
- keys,
211
- index
212
- };
191
+ const index = /* @__PURE__ */ new Map(), keys = [], length = arr.length;
192
+ for (let i = 0; i < length; i++) {
193
+ const item = arr.at(i);
194
+ let key = null;
195
+ switch (item.type) {
196
+ case "string":
197
+ key = `s${item.value}`;
198
+ break;
199
+ case "number":
200
+ key = item.value;
201
+ break;
202
+ case "boolean":
203
+ key = item.value;
204
+ break;
205
+ case "null":
206
+ key = "n";
207
+ break;
208
+ case "object":
209
+ {
210
+ const keyField = item.get("_key");
211
+ if (keyField && keyField.type === "string" && (key = `k${keyField.value}`, index.has(key)))
212
+ return;
213
+ }
214
+ break;
215
+ }
216
+ if (key === null) return;
217
+ keys.push(key);
218
+ let positions = index.get(key);
219
+ positions || (positions = [], index.set(key, positions)), positions.push(i);
220
+ }
221
+ return { keys, index };
213
222
  }
214
223
  function removedArray(input, toValue, options) {
215
- return {
216
- type: "array",
217
- action: "removed",
218
- isChanged: !0,
219
- fromValue: input.value,
220
- toValue,
221
- annotation: input.annotation,
222
- get items() {
223
- let items = [];
224
- for (let i = 0; i < input.length; i++) {
225
- let item = input.at(i);
226
- items.push({
227
- fromIndex: i,
228
- toIndex: void 0,
229
- hasMoved: !1,
230
- diff: removedInput(item, void 0, options),
231
- annotation: input.annotationAt(i)
232
- });
233
- }
234
- return replaceProperty(this, "items", items);
235
- }
236
- };
224
+ return {
225
+ type: "array",
226
+ action: "removed",
227
+ isChanged: !0,
228
+ fromValue: input.value,
229
+ toValue,
230
+ annotation: input.annotation,
231
+ get items() {
232
+ const items = [];
233
+ for (let i = 0; i < input.length; i++) {
234
+ const item = input.at(i);
235
+ items.push({
236
+ fromIndex: i,
237
+ toIndex: void 0,
238
+ hasMoved: !1,
239
+ diff: removedInput(item, void 0),
240
+ annotation: input.annotationAt(i)
241
+ });
242
+ }
243
+ return replaceProperty(this, "items", items);
244
+ }
245
+ };
237
246
  }
238
247
  function addedArray(input, fromValue, options) {
239
- return {
240
- type: "array",
241
- action: "added",
242
- isChanged: !0,
243
- fromValue,
244
- toValue: input.value,
245
- annotation: input.annotation,
246
- get items() {
247
- let items = [];
248
- for (let i = 0; i < input.length; i++) {
249
- let item = input.at(i);
250
- items.push({
251
- fromIndex: void 0,
252
- toIndex: i,
253
- hasMoved: !1,
254
- diff: addedInput(item, void 0, options),
255
- annotation: input.annotationAt(i)
256
- });
257
- }
258
- return replaceProperty(this, "items", items);
259
- }
260
- };
261
- }
262
- const ignoredFields = /* @__PURE__ */ new Set([
263
- "_id",
264
- "_type",
265
- "_createdAt",
266
- "_updatedAt",
267
- "_rev",
268
- "_weak"
269
- ]);
248
+ return {
249
+ type: "array",
250
+ action: "added",
251
+ isChanged: !0,
252
+ fromValue,
253
+ toValue: input.value,
254
+ annotation: input.annotation,
255
+ get items() {
256
+ const items = [];
257
+ for (let i = 0; i < input.length; i++) {
258
+ const item = input.at(i);
259
+ items.push({
260
+ fromIndex: void 0,
261
+ toIndex: i,
262
+ hasMoved: !1,
263
+ diff: addedInput(item, void 0),
264
+ annotation: input.annotationAt(i)
265
+ });
266
+ }
267
+ return replaceProperty(this, "items", items);
268
+ }
269
+ };
270
+ }
271
+ const ignoredFields = /* @__PURE__ */ new Set(["_id", "_type", "_createdAt", "_updatedAt", "_rev", "_weak"]);
270
272
  function diffObject(fromInput, toInput, options) {
271
- let fields = {}, isChanged = !1;
272
- for (let key of fromInput.keys) {
273
- if (ignoredFields.has(key)) continue;
274
- let fromField = fromInput.get(key), toField = toInput.get(key);
275
- if (toField) {
276
- let fieldDiff = diffInput(fromField, toField, options);
277
- fields[key] = fieldDiff, fieldDiff.isChanged && (isChanged = !0);
278
- } else fields[key] = removedInput(fromField, void 0, options), isChanged = !0;
279
- }
280
- for (let key of toInput.keys) ignoredFields.has(key) || fromInput.get(key) || (fields[key] = addedInput(toInput.get(key), void 0, options), isChanged = !0);
281
- let fromValue = fromInput.value, toValue = toInput.value;
282
- return isChanged ? {
283
- type: "object",
284
- action: "changed",
285
- isChanged: !0,
286
- fromValue,
287
- toValue,
288
- fields,
289
- annotation: toInput.annotation
290
- } : {
291
- type: "object",
292
- action: "unchanged",
293
- isChanged: !1,
294
- fromValue,
295
- toValue,
296
- fields
297
- };
273
+ const fields = {};
274
+ let isChanged = !1;
275
+ for (const key of fromInput.keys) {
276
+ if (ignoredFields.has(key)) continue;
277
+ const fromField = fromInput.get(key), toField = toInput.get(key);
278
+ if (toField) {
279
+ const fieldDiff = diffInput(fromField, toField, options);
280
+ fields[key] = fieldDiff, fieldDiff.isChanged && (isChanged = !0);
281
+ } else
282
+ fields[key] = removedInput(fromField, void 0), isChanged = !0;
283
+ }
284
+ for (const key of toInput.keys) {
285
+ if (ignoredFields.has(key) || fromInput.get(key)) continue;
286
+ const toField = toInput.get(key);
287
+ fields[key] = addedInput(toField, void 0), isChanged = !0;
288
+ }
289
+ const fromValue = fromInput.value, toValue = toInput.value;
290
+ return isChanged ? {
291
+ type: "object",
292
+ action: "changed",
293
+ isChanged: !0,
294
+ fromValue,
295
+ toValue,
296
+ fields,
297
+ annotation: toInput.annotation
298
+ } : {
299
+ type: "object",
300
+ action: "unchanged",
301
+ isChanged: !1,
302
+ fromValue,
303
+ toValue,
304
+ fields
305
+ };
298
306
  }
299
307
  function removedObject(input, toValue, options) {
300
- return {
301
- type: "object",
302
- action: "removed",
303
- isChanged: !0,
304
- fromValue: input.value,
305
- toValue,
306
- annotation: input.annotation,
307
- get fields() {
308
- let fields = {};
309
- for (let key of input.keys) fields[key] = removedInput(input.get(key), void 0, options);
310
- return replaceProperty(this, "fields", fields);
311
- }
312
- };
308
+ return {
309
+ type: "object",
310
+ action: "removed",
311
+ isChanged: !0,
312
+ fromValue: input.value,
313
+ toValue,
314
+ annotation: input.annotation,
315
+ get fields() {
316
+ const fields = {};
317
+ for (const key of input.keys) {
318
+ const value = input.get(key);
319
+ fields[key] = removedInput(value, void 0);
320
+ }
321
+ return replaceProperty(this, "fields", fields);
322
+ }
323
+ };
313
324
  }
314
325
  function addedObject(input, fromValue, options) {
315
- return {
316
- type: "object",
317
- action: "added",
318
- isChanged: !0,
319
- fromValue,
320
- toValue: input.value,
321
- annotation: input.annotation,
322
- get fields() {
323
- let fields = {};
324
- for (let key of input.keys) fields[key] = addedInput(input.get(key), void 0, options);
325
- return replaceProperty(this, "fields", fields);
326
- }
327
- };
326
+ return {
327
+ type: "object",
328
+ action: "added",
329
+ isChanged: !0,
330
+ fromValue,
331
+ toValue: input.value,
332
+ annotation: input.annotation,
333
+ get fields() {
334
+ const fields = {};
335
+ for (const key of input.keys) {
336
+ const value = input.get(key);
337
+ fields[key] = addedInput(value, void 0);
338
+ }
339
+ return replaceProperty(this, "fields", fields);
340
+ }
341
+ };
328
342
  }
329
343
  function diffNumber(fromInput, toInput, options) {
330
- let fromValue = fromInput.value, toValue = toInput.value, type = fromInput.type;
331
- return fromValue === toValue ? {
332
- type,
333
- action: "unchanged",
334
- fromValue,
335
- toValue,
336
- isChanged: !1
337
- } : {
338
- type: fromInput.type,
339
- action: "changed",
340
- isChanged: !0,
341
- fromValue,
342
- toValue,
343
- annotation: toInput.annotation
344
- };
344
+ const fromValue = fromInput.value, toValue = toInput.value, type = fromInput.type;
345
+ return fromValue === toValue ? {
346
+ type,
347
+ action: "unchanged",
348
+ fromValue,
349
+ toValue,
350
+ isChanged: !1
351
+ } : {
352
+ type: fromInput.type,
353
+ action: "changed",
354
+ isChanged: !0,
355
+ fromValue,
356
+ toValue,
357
+ annotation: toInput.annotation
358
+ };
345
359
  }
346
360
  function diffBoolean(fromInput, toInput, options) {
347
- let fromValue = fromInput.value, toValue = toInput.value, type = fromInput.type;
348
- return fromValue === toValue ? {
349
- type,
350
- action: "unchanged",
351
- fromValue,
352
- toValue,
353
- isChanged: !1
354
- } : {
355
- type: fromInput.type,
356
- action: "changed",
357
- isChanged: !0,
358
- fromValue,
359
- toValue,
360
- annotation: toInput.annotation
361
- };
361
+ const fromValue = fromInput.value, toValue = toInput.value, type = fromInput.type;
362
+ return fromValue === toValue ? {
363
+ type,
364
+ action: "unchanged",
365
+ fromValue,
366
+ toValue,
367
+ isChanged: !1
368
+ } : {
369
+ type: fromInput.type,
370
+ action: "changed",
371
+ isChanged: !0,
372
+ fromValue,
373
+ toValue,
374
+ annotation: toInput.annotation
375
+ };
362
376
  }
363
377
  function diffString(fromInput, toInput, options) {
364
- let fromValue = fromInput.value, toValue = toInput.value;
365
- return fromValue === toValue ? {
366
- type: "string",
367
- action: "unchanged",
368
- isChanged: !1,
369
- fromValue,
370
- toValue,
371
- segments: [{
372
- type: "stringSegment",
373
- action: "unchanged",
374
- text: fromValue
375
- }]
376
- } : {
377
- type: "string",
378
- action: "changed",
379
- isChanged: !0,
380
- fromValue,
381
- toValue,
382
- annotation: toInput.annotation,
383
- get segments() {
384
- let segments = buildSegments(fromInput, toInput);
385
- return replaceProperty(this, "segments", segments);
386
- }
387
- };
378
+ const fromValue = fromInput.value, toValue = toInput.value;
379
+ return fromValue === toValue ? {
380
+ type: "string",
381
+ action: "unchanged",
382
+ isChanged: !1,
383
+ fromValue,
384
+ toValue,
385
+ segments: [{ type: "stringSegment", action: "unchanged", text: fromValue }]
386
+ } : {
387
+ type: "string",
388
+ action: "changed",
389
+ isChanged: !0,
390
+ fromValue,
391
+ toValue,
392
+ annotation: toInput.annotation,
393
+ // Compute and memoize string segments only when accessed
394
+ get segments() {
395
+ const segments = buildSegments(fromInput, toInput);
396
+ return replaceProperty(this, "segments", segments);
397
+ }
398
+ };
388
399
  }
389
400
  function buildSegments(fromInput, toInput) {
390
- let segments = [], dmpDiffs = cleanupSemantic(makeDiff(fromInput.value, toInput.value)), fromIdx = 0, toIdx = 0;
391
- for (let [op, text] of dmpDiffs) switch (op) {
392
- case DIFF_EQUAL:
393
- segments.push({
394
- type: "stringSegment",
395
- action: "unchanged",
396
- text
397
- }), fromIdx += text.length, toIdx += text.length;
398
- break;
399
- case DIFF_DELETE:
400
- for (let segment of fromInput.sliceAnnotation(fromIdx, fromIdx + text.length)) segments.push({
401
- type: "stringSegment",
402
- action: "removed",
403
- text: segment.text,
404
- annotation: segment.annotation
405
- });
406
- fromIdx += text.length;
407
- break;
408
- case DIFF_INSERT:
409
- for (let segment of toInput.sliceAnnotation(toIdx, toIdx + text.length)) segments.push({
410
- type: "stringSegment",
411
- action: "added",
412
- text: segment.text,
413
- annotation: segment.annotation
414
- });
415
- toIdx += text.length;
416
- break;
417
- default: throw Error(`Unhandled diff-match-patch operation "${op}"`);
418
- }
419
- return segments;
401
+ const segments = [], dmpDiffs = cleanupSemantic(makeDiff(fromInput.value, toInput.value));
402
+ let fromIdx = 0, toIdx = 0;
403
+ for (const [op, text] of dmpDiffs)
404
+ switch (op) {
405
+ case DIFF_EQUAL:
406
+ segments.push({ type: "stringSegment", action: "unchanged", text }), fromIdx += text.length, toIdx += text.length;
407
+ break;
408
+ case DIFF_DELETE:
409
+ for (const segment of fromInput.sliceAnnotation(fromIdx, fromIdx + text.length))
410
+ segments.push({
411
+ type: "stringSegment",
412
+ action: "removed",
413
+ text: segment.text,
414
+ annotation: segment.annotation
415
+ });
416
+ fromIdx += text.length;
417
+ break;
418
+ case DIFF_INSERT:
419
+ for (const segment of toInput.sliceAnnotation(toIdx, toIdx + text.length))
420
+ segments.push({
421
+ type: "stringSegment",
422
+ action: "added",
423
+ text: segment.text,
424
+ annotation: segment.annotation
425
+ });
426
+ toIdx += text.length;
427
+ break;
428
+ default:
429
+ throw new Error(`Unhandled diff-match-patch operation "${op}"`);
430
+ }
431
+ return segments;
420
432
  }
421
433
  function removedString(input, toValue, options) {
422
- return {
423
- type: "string",
424
- action: "removed",
425
- isChanged: !0,
426
- fromValue: input.value,
427
- toValue,
428
- annotation: input.annotation,
429
- get segments() {
430
- let segments = input.sliceAnnotation(0, input.value.length).map((segment) => ({
431
- type: "stringSegment",
432
- action: "removed",
433
- ...segment
434
- }));
435
- return replaceProperty(this, "segments", segments);
436
- }
437
- };
434
+ return {
435
+ type: "string",
436
+ action: "removed",
437
+ isChanged: !0,
438
+ fromValue: input.value,
439
+ toValue,
440
+ annotation: input.annotation,
441
+ get segments() {
442
+ const segments = input.sliceAnnotation(0, input.value.length).map((segment) => ({ type: "stringSegment", action: "removed", ...segment }));
443
+ return replaceProperty(this, "segments", segments);
444
+ }
445
+ };
438
446
  }
439
447
  function addedString(input, fromValue, options) {
440
- return {
441
- type: "string",
442
- action: "added",
443
- isChanged: !0,
444
- fromValue,
445
- toValue: input.value,
446
- annotation: input.annotation,
447
- get segments() {
448
- let segments = input.sliceAnnotation(0, input.value.length).map((segment) => ({
449
- type: "stringSegment",
450
- action: "added",
451
- ...segment
452
- }));
453
- return replaceProperty(this, "segments", segments);
454
- }
455
- };
448
+ return {
449
+ type: "string",
450
+ action: "added",
451
+ isChanged: !0,
452
+ fromValue,
453
+ toValue: input.value,
454
+ annotation: input.annotation,
455
+ get segments() {
456
+ const segments = input.sliceAnnotation(0, input.value.length).map((segment) => ({ type: "stringSegment", action: "added", ...segment }));
457
+ return replaceProperty(this, "segments", segments);
458
+ }
459
+ };
456
460
  }
457
461
  function diffTypeChange(fromInput, toInput, options) {
458
- return {
459
- type: "typeChange",
460
- action: "changed",
461
- isChanged: !0,
462
- fromType: fromInput.type,
463
- fromValue: fromInput.value,
464
- fromDiff: removedInput(fromInput, void 0, options),
465
- toType: toInput.type,
466
- toValue: toInput.value,
467
- toDiff: addedInput(toInput, void 0, options),
468
- annotation: toInput.annotation
469
- };
470
- }
471
- /**
472
- * Takes a `from` and `to` input and calulates a diff between the two
473
- *
474
- * @param fromInput - The source (`from`) input - use {@link wrap | the wrap() method} to generate an "input"
475
- * @param toInput - The destination (`to`) input - use {@link wrap | the wrap() method} to generate an "input"
476
- * @param options - Options for the diffing process - currently no options are defined
477
- * @returns A diff object representing the change
478
- * @public
479
- */
462
+ return {
463
+ type: "typeChange",
464
+ action: "changed",
465
+ isChanged: !0,
466
+ fromType: fromInput.type,
467
+ fromValue: fromInput.value,
468
+ fromDiff: removedInput(fromInput, void 0),
469
+ toType: toInput.type,
470
+ toValue: toInput.value,
471
+ toDiff: addedInput(toInput, void 0),
472
+ annotation: toInput.annotation
473
+ };
474
+ }
480
475
  function diffInput(fromInput, toInput, options = {}) {
481
- return fromInput.type === toInput.type ? diffWithType(fromInput.type, fromInput, toInput, options) : fromInput.type === "null" ? addedInput(toInput, null, options) : toInput.type === "null" ? removedInput(fromInput, null, options) : diffTypeChange(fromInput, toInput, options);
476
+ return fromInput.type !== toInput.type ? fromInput.type === "null" ? addedInput(toInput, null) : toInput.type === "null" ? removedInput(fromInput, null) : diffTypeChange(fromInput, toInput) : diffWithType(fromInput.type, fromInput, toInput, options);
482
477
  }
483
478
  function diffWithType(type, fromInput, toInput, options) {
484
- switch (type) {
485
- case "null": return {
486
- type: "null",
487
- action: "unchanged",
488
- isChanged: !1,
489
- toValue: null,
490
- fromValue: null
491
- };
492
- case "boolean": return diffBoolean(fromInput, toInput, options);
493
- case "number": return diffNumber(fromInput, toInput, options);
494
- case "string": return diffString(fromInput, toInput, options);
495
- case "array": return diffArray(fromInput, toInput, options);
496
- case "object": return diffObject(fromInput, toInput, options);
497
- default: throw Error(`Unhandled diff type "${type}"`);
498
- }
479
+ switch (type) {
480
+ case "null":
481
+ return {
482
+ type: "null",
483
+ action: "unchanged",
484
+ isChanged: !1,
485
+ toValue: null,
486
+ fromValue: null
487
+ };
488
+ case "boolean":
489
+ return diffBoolean(fromInput, toInput);
490
+ case "number":
491
+ return diffNumber(fromInput, toInput);
492
+ case "string":
493
+ return diffString(fromInput, toInput);
494
+ case "array":
495
+ return diffArray(fromInput, toInput, options);
496
+ case "object":
497
+ return diffObject(fromInput, toInput, options);
498
+ default:
499
+ throw new Error(`Unhandled diff type "${type}"`);
500
+ }
499
501
  }
500
502
  function removedInput(input, toValue, options) {
501
- switch (input.type) {
502
- case "null": return {
503
- type: "null",
504
- action: "removed",
505
- isChanged: !0,
506
- fromValue: null,
507
- toValue,
508
- annotation: input.annotation
509
- };
510
- case "boolean": return {
511
- type: "boolean",
512
- action: "removed",
513
- isChanged: !0,
514
- fromValue: input.value,
515
- toValue,
516
- annotation: input.annotation
517
- };
518
- case "number": return {
519
- type: "number",
520
- action: "removed",
521
- isChanged: !0,
522
- fromValue: input.value,
523
- toValue,
524
- annotation: input.annotation
525
- };
526
- case "string": return removedString(input, toValue, options);
527
- case "array": return removedArray(input, toValue, options);
528
- case "object": return removedObject(input, toValue, options);
529
- default: throw Error("Unhandled diff type");
530
- }
503
+ switch (input.type) {
504
+ case "null":
505
+ return {
506
+ type: "null",
507
+ action: "removed",
508
+ isChanged: !0,
509
+ fromValue: null,
510
+ toValue,
511
+ annotation: input.annotation
512
+ };
513
+ case "boolean":
514
+ return {
515
+ type: "boolean",
516
+ action: "removed",
517
+ isChanged: !0,
518
+ fromValue: input.value,
519
+ toValue,
520
+ annotation: input.annotation
521
+ };
522
+ case "number":
523
+ return {
524
+ type: "number",
525
+ action: "removed",
526
+ isChanged: !0,
527
+ fromValue: input.value,
528
+ toValue,
529
+ annotation: input.annotation
530
+ };
531
+ case "string":
532
+ return removedString(input, toValue);
533
+ case "array":
534
+ return removedArray(input, toValue);
535
+ case "object":
536
+ return removedObject(input, toValue);
537
+ default:
538
+ throw new Error("Unhandled diff type");
539
+ }
531
540
  }
532
541
  function addedInput(input, fromValue, options) {
533
- switch (input.type) {
534
- case "null": return {
535
- type: "null",
536
- action: "added",
537
- isChanged: !0,
538
- fromValue,
539
- toValue: null,
540
- annotation: input.annotation
541
- };
542
- case "boolean": return {
543
- type: "boolean",
544
- action: "added",
545
- isChanged: !0,
546
- fromValue,
547
- toValue: input.value,
548
- annotation: input.annotation
549
- };
550
- case "number": return {
551
- type: "number",
552
- action: "added",
553
- isChanged: !0,
554
- fromValue,
555
- toValue: input.value,
556
- annotation: input.annotation
557
- };
558
- case "string": return addedString(input, fromValue, options);
559
- case "array": return addedArray(input, fromValue, options);
560
- case "object": return addedObject(input, fromValue, options);
561
- default: throw Error("Unhandled diff type");
562
- }
563
- }
564
- var ArrayWrapper = class {
565
- type = "array";
566
- length;
567
- value;
568
- annotation;
569
- elements = [];
570
- constructor(value, annotation) {
571
- this.annotation = annotation, this.value = value, this.length = value.length;
572
- }
573
- at(idx) {
574
- if (idx >= this.length) throw Error("out of bounds");
575
- return this.elements[idx] || (this.elements[idx] = wrap(this.value[idx], this.annotation));
576
- }
577
- annotationAt() {
578
- return this.annotation;
579
- }
580
- }, BasicWrapper = class {
581
- type;
582
- value;
583
- annotation;
584
- constructor(type, value, annotation) {
585
- this.type = type, this.value = value, this.annotation = annotation;
586
- }
587
- }, ObjectWrapper = class {
588
- type = "object";
589
- value;
590
- keys;
591
- annotation;
592
- fields = {};
593
- constructor(value, annotation) {
594
- this.value = filterUndefinedEntries(value), this.annotation = annotation, this.keys = Object.keys(this.value);
595
- }
596
- get(key) {
597
- let input = this.fields[key];
598
- if (input) return input;
599
- if (!this.value.hasOwnProperty(key)) return;
600
- let raw = this.value[key];
601
- return this.fields[key] = wrap(raw, this.annotation);
602
- }
603
- };
542
+ switch (input.type) {
543
+ case "null":
544
+ return {
545
+ type: "null",
546
+ action: "added",
547
+ isChanged: !0,
548
+ fromValue,
549
+ toValue: null,
550
+ annotation: input.annotation
551
+ };
552
+ case "boolean":
553
+ return {
554
+ type: "boolean",
555
+ action: "added",
556
+ isChanged: !0,
557
+ fromValue,
558
+ toValue: input.value,
559
+ annotation: input.annotation
560
+ };
561
+ case "number":
562
+ return {
563
+ type: "number",
564
+ action: "added",
565
+ isChanged: !0,
566
+ fromValue,
567
+ toValue: input.value,
568
+ annotation: input.annotation
569
+ };
570
+ case "string":
571
+ return addedString(input, fromValue);
572
+ case "array":
573
+ return addedArray(input, fromValue);
574
+ case "object":
575
+ return addedObject(input, fromValue);
576
+ default:
577
+ throw new Error("Unhandled diff type");
578
+ }
579
+ }
580
+ class ArrayWrapper {
581
+ type = "array";
582
+ length;
583
+ value;
584
+ annotation;
585
+ elements = [];
586
+ constructor(value, annotation) {
587
+ this.annotation = annotation, this.value = value, this.length = value.length;
588
+ }
589
+ at(idx) {
590
+ if (idx >= this.length) throw new Error("out of bounds");
591
+ return this.elements[idx] || (this.elements[idx] = wrap(this.value[idx], this.annotation));
592
+ }
593
+ annotationAt() {
594
+ return this.annotation;
595
+ }
596
+ }
597
+ class BasicWrapper {
598
+ type;
599
+ value;
600
+ annotation;
601
+ constructor(type, value, annotation) {
602
+ this.type = type, this.value = value, this.annotation = annotation;
603
+ }
604
+ }
605
+ class ObjectWrapper {
606
+ type = "object";
607
+ value;
608
+ keys;
609
+ annotation;
610
+ fields = {};
611
+ constructor(value, annotation) {
612
+ this.value = filterUndefinedEntries(value), this.annotation = annotation, this.keys = Object.keys(this.value);
613
+ }
614
+ get(key) {
615
+ const input = this.fields[key];
616
+ if (input)
617
+ return input;
618
+ if (!this.value.hasOwnProperty(key))
619
+ return;
620
+ const raw = this.value[key];
621
+ return this.fields[key] = wrap(raw, this.annotation);
622
+ }
623
+ }
604
624
  function filterUndefinedEntries(value) {
605
- return Object.fromEntries(Object.entries(value).filter(([, entryValue]) => entryValue !== void 0));
606
- }
607
- var StringWrapper = class {
608
- type = "string";
609
- value;
610
- annotation;
611
- constructor(value, annotation) {
612
- this.value = value, this.annotation = annotation;
613
- }
614
- sliceAnnotation(start, end) {
615
- return [{
616
- text: this.value.slice(start, end),
617
- annotation: this.annotation
618
- }];
619
- }
620
- };
621
- /**
622
- * Takes an input (any JSON-serializable value) and an annotation, and generates an input
623
- * object for it, to be used with {@link diffInput | the diffInput() method} and others.
624
- *
625
- * @param input - The value to wrap in an input object
626
- * @param annotation - Annotation attached to the input - will be bound to generated diffs
627
- * @returns A input object
628
- * @throws if `input` is not a JSON-serializable type
629
- * @public
630
- */
625
+ return Object.fromEntries(
626
+ Object.entries(value).filter(([, entryValue]) => typeof entryValue < "u")
627
+ );
628
+ }
629
+ class StringWrapper {
630
+ type = "string";
631
+ value;
632
+ annotation;
633
+ constructor(value, annotation) {
634
+ this.value = value, this.annotation = annotation;
635
+ }
636
+ sliceAnnotation(start, end) {
637
+ return [{ text: this.value.slice(start, end), annotation: this.annotation }];
638
+ }
639
+ }
631
640
  function wrap(input, annotation) {
632
- if (Array.isArray(input)) return new ArrayWrapper(input, annotation);
633
- if (input === null) return new BasicWrapper("null", input, annotation);
634
- let type = typeof input;
635
- switch (type) {
636
- case "number": return new BasicWrapper(type, input, annotation);
637
- case "boolean": return new BasicWrapper(type, input, annotation);
638
- case "object": return new ObjectWrapper(input, annotation);
639
- case "string": return new StringWrapper(input, annotation);
640
- default: throw Error(`cannot wrap value of type: ${type}`);
641
- }
642
- }
643
- export { diffInput, wrap };
644
-
645
- //# sourceMappingURL=index.js.map
641
+ if (Array.isArray(input))
642
+ return new ArrayWrapper(input, annotation);
643
+ if (input === null)
644
+ return new BasicWrapper("null", input, annotation);
645
+ const type = typeof input;
646
+ switch (type) {
647
+ case "number":
648
+ return new BasicWrapper(type, input, annotation);
649
+ case "boolean":
650
+ return new BasicWrapper(type, input, annotation);
651
+ case "object":
652
+ return new ObjectWrapper(input, annotation);
653
+ case "string":
654
+ return new StringWrapper(input, annotation);
655
+ default:
656
+ throw new Error(`cannot wrap value of type: ${type}`);
657
+ }
658
+ }
659
+ export {
660
+ diffInput,
661
+ wrap
662
+ };
663
+ //# sourceMappingURL=index.js.map