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

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,663 +1,645 @@
1
- import { cleanupSemantic, makeDiff, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL } from "@sanity/diff-match-patch";
1
+ import { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, cleanupSemantic, makeDiff } 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
- const matrix = getLengthMatrix(previous, next);
7
- return backtrack(matrix, previous, next);
6
+ return backtrack(getLengthMatrix(previous, next), previous, next);
8
7
  }
9
8
  function getLengthMatrix(previous, next) {
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;
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;
20
13
  }
21
14
  function backtrack(matrix, previous, next) {
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;
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;
36
22
  }
37
23
  function diffArray(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);
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);
58
40
  }
59
41
  function buildArrayDiff(fromInput, toInput, items, isChanged) {
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
- }
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
+ */
78
64
  function diffExactByPosition(fromInput, toInput, options) {
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;
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;
95
79
  }
96
80
  function diffArrayByReinsert(fromInput, toInput, options) {
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
- }
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
+ */
120
107
  function diffArrayByKey(fromArray, fromKeyIndex, toArray, toKeyIndex, options) {
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);
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);
169
155
  }
170
156
  function compareItemDiff(a, b) {
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");
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");
180
162
  }
181
163
  function deletePositionInIndex(index, key, pos) {
182
- const positions = index.get(key);
183
- deleteArrayValue(positions, pos), positions.length === 0 && index.delete(key);
164
+ let positions = index.get(key);
165
+ deleteArrayValue(positions, pos), positions.length === 0 && index.delete(key);
184
166
  }
185
167
  function deleteArrayValue(arr, value) {
186
- const idx = arr.indexOf(value);
187
- if (idx === -1) throw new Error("value not found");
188
- arr.splice(idx, 1);
189
- }
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
+ */
190
179
  function indexByKey(arr) {
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 };
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
+ };
222
213
  }
223
214
  function removedArray(input, toValue, options) {
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
- };
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
+ };
246
237
  }
247
238
  function addedArray(input, fromValue, options) {
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"]);
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
+ ]);
272
270
  function diffObject(fromInput, toInput, options) {
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
- };
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
+ };
306
298
  }
307
299
  function removedObject(input, toValue, options) {
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
- };
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
+ };
324
313
  }
325
314
  function addedObject(input, fromValue, options) {
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
- };
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
+ };
342
328
  }
343
329
  function diffNumber(fromInput, toInput, options) {
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
- };
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
+ };
359
345
  }
360
346
  function diffBoolean(fromInput, toInput, options) {
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
- };
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
+ };
376
362
  }
377
363
  function diffString(fromInput, toInput, options) {
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
- };
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
+ };
399
388
  }
400
389
  function buildSegments(fromInput, toInput) {
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;
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;
432
420
  }
433
421
  function removedString(input, toValue, options) {
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
- };
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
+ };
446
438
  }
447
439
  function addedString(input, fromValue, options) {
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
- };
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
+ };
460
456
  }
461
457
  function diffTypeChange(fromInput, toInput, options) {
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
- }
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
+ */
475
480
  function diffInput(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);
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);
477
482
  }
478
483
  function diffWithType(type, fromInput, toInput, options) {
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
- }
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
+ }
501
499
  }
502
500
  function removedInput(input, toValue, options) {
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
- }
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
+ }
540
531
  }
541
532
  function addedInput(input, fromValue, options) {
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
- }
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
+ };
624
604
  function filterUndefinedEntries(value) {
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
- }
640
- function wrap(input, annotation) {
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
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
+ }
662
620
  };
663
- //# sourceMappingURL=index.js.map
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
+ */
631
+ 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