json-diff-ts 5.0.0-alpha.0 → 5.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +144 -1
- package/dist/index.cjs +197 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +86 -1
- package/dist/index.d.ts +86 -1
- package/dist/index.js +186 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -129,7 +129,15 @@ const { diffDelta, applyDelta, revertDelta } = require('json-diff-ts');
|
|
|
129
129
|
|
|
130
130
|
## What is JSON Delta?
|
|
131
131
|
|
|
132
|
-
[JSON Delta](https://github.com/ltwlf/json-delta-format) is a specification for representing atomic changes to JSON documents. json-diff-ts is the originating implementation from which the spec was derived.
|
|
132
|
+
[JSON Delta](https://github.com/ltwlf/json-delta-format) is a specification for representing atomic changes to JSON documents. json-diff-ts is the originating implementation from which the spec was derived.
|
|
133
|
+
|
|
134
|
+
```text
|
|
135
|
+
json-delta-format (specification)
|
|
136
|
+
├── json-diff-ts (TypeScript implementation) ← this package
|
|
137
|
+
└── json-delta-py (Python implementation)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The specification defines the wire format. Each language implementation produces and consumes compatible deltas.
|
|
133
141
|
|
|
134
142
|
A delta is a self-describing JSON document you can store, transmit, and consume in any language:
|
|
135
143
|
|
|
@@ -230,6 +238,15 @@ const { valid, errors } = validateDelta(maybeDelta);
|
|
|
230
238
|
| `validateDelta` | `(delta) => { valid, errors }` | Structural validation |
|
|
231
239
|
| `toDelta` | `(changeset, options?) => IJsonDelta` | Bridge: v4 changeset to JSON Delta |
|
|
232
240
|
| `fromDelta` | `(delta) => IAtomicChange[]` | Bridge: JSON Delta to v4 atomic changes |
|
|
241
|
+
| `squashDeltas` | `(source, deltas, options?) => IJsonDelta` | Compact multiple deltas into one net-effect delta |
|
|
242
|
+
| `deltaMap` | `(delta, fn) => IJsonDelta` | Transform each operation in a delta |
|
|
243
|
+
| `deltaStamp` | `(delta, extensions) => IJsonDelta` | Set extension properties on all operations |
|
|
244
|
+
| `deltaGroupBy` | `(delta, keyFn) => Record<string, IJsonDelta>` | Group operations into sub-deltas |
|
|
245
|
+
| `operationSpecDict` | `(op) => IDeltaOperation` | Strip extension properties from operation |
|
|
246
|
+
| `operationExtensions` | `(op) => Record<string, any>` | Get extension properties from operation |
|
|
247
|
+
| `deltaSpecDict` | `(delta) => IJsonDelta` | Strip all extensions from delta |
|
|
248
|
+
| `deltaExtensions` | `(delta) => Record<string, any>` | Get envelope extensions from delta |
|
|
249
|
+
| `leafProperty` | `(op) => string \| null` | Terminal property name from operation path |
|
|
233
250
|
|
|
234
251
|
### DeltaOptions
|
|
235
252
|
|
|
@@ -243,6 +260,125 @@ interface DeltaOptions extends Options {
|
|
|
243
260
|
}
|
|
244
261
|
```
|
|
245
262
|
|
|
263
|
+
### Delta Workflow Helpers
|
|
264
|
+
|
|
265
|
+
Transform, inspect, and compact deltas for workflow automation.
|
|
266
|
+
|
|
267
|
+
#### `squashDeltas` -- Compact Multiple Deltas
|
|
268
|
+
|
|
269
|
+
Combine a sequence of deltas into a single net-effect delta. Useful for compacting audit logs or collapsing undo history:
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
import { diffDelta, applyDelta, squashDeltas } from 'json-diff-ts';
|
|
273
|
+
|
|
274
|
+
const source = { name: 'Alice', role: 'viewer' };
|
|
275
|
+
const d1 = diffDelta(source, { name: 'Bob', role: 'viewer' });
|
|
276
|
+
const d2 = diffDelta({ name: 'Bob', role: 'viewer' }, { name: 'Bob', role: 'admin' });
|
|
277
|
+
|
|
278
|
+
const squashed = squashDeltas(source, [d1, d2]);
|
|
279
|
+
// squashed.operations => [
|
|
280
|
+
// { op: 'replace', path: '$.name', value: 'Bob', oldValue: 'Alice' },
|
|
281
|
+
// { op: 'replace', path: '$.role', value: 'admin', oldValue: 'viewer' }
|
|
282
|
+
// ]
|
|
283
|
+
|
|
284
|
+
// Verify: applying the squashed delta equals applying both sequentially
|
|
285
|
+
const result = applyDelta(structuredClone(source), squashed);
|
|
286
|
+
// result => { name: 'Bob', role: 'admin' }
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Options: `reversible`, `arrayIdentityKeys`, `target` (pre-computed final state), `verifyTarget` (default: true).
|
|
290
|
+
|
|
291
|
+
#### `deltaMap` / `deltaStamp` / `deltaGroupBy` -- Delta Transformations
|
|
292
|
+
|
|
293
|
+
All transforms are immutable — they return new deltas without modifying the original:
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
import { diffDelta, deltaMap, deltaStamp, deltaGroupBy } from 'json-diff-ts';
|
|
297
|
+
|
|
298
|
+
const delta = diffDelta(
|
|
299
|
+
{ name: 'Alice', age: 30, role: 'viewer' },
|
|
300
|
+
{ name: 'Bob', age: 31, status: 'active' }
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
// Stamp metadata onto every operation
|
|
304
|
+
const stamped = deltaStamp(delta, { x_author: 'system', x_ts: Date.now() });
|
|
305
|
+
|
|
306
|
+
// Transform operations
|
|
307
|
+
const prefixed = deltaMap(delta, (op) => ({
|
|
308
|
+
...op,
|
|
309
|
+
path: op.path.replace('$', '$.data'),
|
|
310
|
+
}));
|
|
311
|
+
|
|
312
|
+
// Group by operation type
|
|
313
|
+
const groups = deltaGroupBy(delta, (op) => op.op);
|
|
314
|
+
// groups => { replace: IJsonDelta, add: IJsonDelta, remove: IJsonDelta }
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
#### `operationSpecDict` / `deltaSpecDict` -- Spec Introspection
|
|
318
|
+
|
|
319
|
+
Separate spec-defined fields from extension properties:
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
import { operationSpecDict, operationExtensions, deltaSpecDict } from 'json-diff-ts';
|
|
323
|
+
|
|
324
|
+
const op = { op: 'replace', path: '$.name', value: 'Bob', x_author: 'system' };
|
|
325
|
+
operationSpecDict(op); // { op: 'replace', path: '$.name', value: 'Bob' }
|
|
326
|
+
operationExtensions(op); // { x_author: 'system' }
|
|
327
|
+
|
|
328
|
+
// Strip all extensions from a delta
|
|
329
|
+
const clean = deltaSpecDict(delta);
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
#### `leafProperty` -- Path Introspection
|
|
333
|
+
|
|
334
|
+
Extract the terminal property name from an operation's path:
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
import { leafProperty } from 'json-diff-ts';
|
|
338
|
+
|
|
339
|
+
leafProperty({ op: 'replace', path: '$.user.name' }); // 'name'
|
|
340
|
+
leafProperty({ op: 'add', path: '$.items[?(@.id==1)]' }); // null (filter)
|
|
341
|
+
leafProperty({ op: 'replace', path: '$' }); // null (root)
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Comparison Serialization
|
|
347
|
+
|
|
348
|
+
Serialize enriched comparison trees to plain objects or flat change lists.
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
import { compare, comparisonToDict, comparisonToFlatList } from 'json-diff-ts';
|
|
352
|
+
|
|
353
|
+
const result = compare(
|
|
354
|
+
{ name: 'Alice', age: 30, role: 'viewer' },
|
|
355
|
+
{ name: 'Bob', age: 30, status: 'active' }
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
// Recursive plain object
|
|
359
|
+
const dict = comparisonToDict(result);
|
|
360
|
+
// {
|
|
361
|
+
// type: 'CONTAINER',
|
|
362
|
+
// value: {
|
|
363
|
+
// name: { type: 'UPDATE', value: 'Bob', oldValue: 'Alice' },
|
|
364
|
+
// age: { type: 'UNCHANGED', value: 30 },
|
|
365
|
+
// role: { type: 'REMOVE', oldValue: 'viewer' },
|
|
366
|
+
// status: { type: 'ADD', value: 'active' }
|
|
367
|
+
// }
|
|
368
|
+
// }
|
|
369
|
+
|
|
370
|
+
// Flat list of leaf changes with paths
|
|
371
|
+
const flat = comparisonToFlatList(result);
|
|
372
|
+
// [
|
|
373
|
+
// { path: '$.name', type: 'UPDATE', value: 'Bob', oldValue: 'Alice' },
|
|
374
|
+
// { path: '$.role', type: 'REMOVE', oldValue: 'viewer' },
|
|
375
|
+
// { path: '$.status', type: 'ADD', value: 'active' }
|
|
376
|
+
// ]
|
|
377
|
+
|
|
378
|
+
// Include unchanged entries
|
|
379
|
+
const all = comparisonToFlatList(result, { includeUnchanged: true });
|
|
380
|
+
```
|
|
381
|
+
|
|
246
382
|
---
|
|
247
383
|
|
|
248
384
|
## Practical Examples
|
|
@@ -503,6 +639,8 @@ diff(old, new, { treatTypeChangeAsReplace: false });
|
|
|
503
639
|
| --- | --- |
|
|
504
640
|
| `compare(oldObj, newObj)` | Create enriched comparison object |
|
|
505
641
|
| `enrich(obj)` | Create enriched representation |
|
|
642
|
+
| `comparisonToDict(node)` | Serialize comparison tree to plain object |
|
|
643
|
+
| `comparisonToFlatList(node, options?)` | Flatten comparison to leaf change list |
|
|
506
644
|
|
|
507
645
|
### Options
|
|
508
646
|
|
|
@@ -561,6 +699,11 @@ Use `$value` as the identity key: `{ arrayIdentityKeys: { tags: '$value' } }`. E
|
|
|
561
699
|
|
|
562
700
|
## Release Notes
|
|
563
701
|
|
|
702
|
+
- **v5.0.0-alpha.2:**
|
|
703
|
+
- Delta workflow helpers: `squashDeltas`, `deltaMap`, `deltaStamp`, `deltaGroupBy`
|
|
704
|
+
- Delta/operation introspection: `operationSpecDict`, `operationExtensions`, `deltaSpecDict`, `deltaExtensions`, `leafProperty`
|
|
705
|
+
- Comparison serialization: `comparisonToDict`, `comparisonToFlatList`
|
|
706
|
+
|
|
564
707
|
- **v5.0.0-alpha.0:**
|
|
565
708
|
- JSON Delta API: `diffDelta`, `applyDelta`, `revertDelta`, `invertDelta`, `toDelta`, `fromDelta`, `validateDelta`
|
|
566
709
|
- Canonical path production with typed filter literals
|
package/dist/index.cjs
CHANGED
|
@@ -28,8 +28,15 @@ __export(index_exports, {
|
|
|
28
28
|
atomizeChangeset: () => atomizeChangeset,
|
|
29
29
|
buildDeltaPath: () => buildDeltaPath,
|
|
30
30
|
compare: () => compare2,
|
|
31
|
+
comparisonToDict: () => comparisonToDict,
|
|
32
|
+
comparisonToFlatList: () => comparisonToFlatList,
|
|
31
33
|
createContainer: () => createContainer,
|
|
32
34
|
createValue: () => createValue,
|
|
35
|
+
deltaExtensions: () => deltaExtensions,
|
|
36
|
+
deltaGroupBy: () => deltaGroupBy,
|
|
37
|
+
deltaMap: () => deltaMap,
|
|
38
|
+
deltaSpecDict: () => deltaSpecDict,
|
|
39
|
+
deltaStamp: () => deltaStamp,
|
|
33
40
|
diff: () => diff,
|
|
34
41
|
diffDelta: () => diffDelta,
|
|
35
42
|
enrich: () => enrich,
|
|
@@ -37,10 +44,14 @@ __export(index_exports, {
|
|
|
37
44
|
fromDelta: () => fromDelta,
|
|
38
45
|
getTypeOfObj: () => getTypeOfObj,
|
|
39
46
|
invertDelta: () => invertDelta,
|
|
47
|
+
leafProperty: () => leafProperty,
|
|
48
|
+
operationExtensions: () => operationExtensions,
|
|
49
|
+
operationSpecDict: () => operationSpecDict,
|
|
40
50
|
parseDeltaPath: () => parseDeltaPath,
|
|
41
51
|
parseFilterLiteral: () => parseFilterLiteral,
|
|
42
52
|
revertChangeset: () => revertChangeset,
|
|
43
53
|
revertDelta: () => revertDelta,
|
|
54
|
+
squashDeltas: () => squashDeltas,
|
|
44
55
|
toDelta: () => toDelta,
|
|
45
56
|
unatomizeChangeset: () => unatomizeChangeset,
|
|
46
57
|
validateDelta: () => validateDelta
|
|
@@ -783,6 +794,74 @@ var compare2 = (oldObject, newObject) => {
|
|
|
783
794
|
}
|
|
784
795
|
return applyChangelist(enrich(oldObject), atomizeChangeset(diff(oldObject, newObject)));
|
|
785
796
|
};
|
|
797
|
+
var comparisonToDict = (node) => {
|
|
798
|
+
const result = { type: node.type };
|
|
799
|
+
if (node.type === "CONTAINER" /* CONTAINER */) {
|
|
800
|
+
if (Array.isArray(node.value)) {
|
|
801
|
+
const children = node.value;
|
|
802
|
+
const serialized = new Array(children.length);
|
|
803
|
+
for (let i = 0; i < children.length; i++) {
|
|
804
|
+
const child = children[i];
|
|
805
|
+
serialized[i] = child != null ? comparisonToDict(child) : null;
|
|
806
|
+
}
|
|
807
|
+
result.value = serialized;
|
|
808
|
+
} else if (node.value && typeof node.value === "object") {
|
|
809
|
+
const obj = /* @__PURE__ */ Object.create(null);
|
|
810
|
+
for (const [key, child] of Object.entries(
|
|
811
|
+
node.value
|
|
812
|
+
)) {
|
|
813
|
+
if (child == null) continue;
|
|
814
|
+
obj[key] = comparisonToDict(child);
|
|
815
|
+
}
|
|
816
|
+
result.value = obj;
|
|
817
|
+
}
|
|
818
|
+
} else {
|
|
819
|
+
if (node.type === "UNCHANGED" /* UNCHANGED */ || node.type === "ADD" /* ADD */ || node.type === "UPDATE" /* UPDATE */) {
|
|
820
|
+
result.value = node.value;
|
|
821
|
+
}
|
|
822
|
+
if (node.type === "REMOVE" /* REMOVE */ || node.type === "UPDATE" /* UPDATE */) {
|
|
823
|
+
result.oldValue = node.oldValue;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
return result;
|
|
827
|
+
};
|
|
828
|
+
var IDENT_RE = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
829
|
+
var comparisonToFlatList = (node, options = {}) => {
|
|
830
|
+
const results = [];
|
|
831
|
+
flattenNode(node, "$", options.includeUnchanged ?? false, results);
|
|
832
|
+
return results;
|
|
833
|
+
};
|
|
834
|
+
function flattenNode(node, path, includeUnchanged, results) {
|
|
835
|
+
if (node.type === "CONTAINER" /* CONTAINER */) {
|
|
836
|
+
if (Array.isArray(node.value)) {
|
|
837
|
+
for (let i = 0; i < node.value.length; i++) {
|
|
838
|
+
const child = node.value[i];
|
|
839
|
+
if (child == null) continue;
|
|
840
|
+
flattenNode(child, `${path}[${i}]`, includeUnchanged, results);
|
|
841
|
+
}
|
|
842
|
+
} else if (node.value && typeof node.value === "object") {
|
|
843
|
+
for (const [key, child] of Object.entries(
|
|
844
|
+
node.value
|
|
845
|
+
)) {
|
|
846
|
+
if (child == null) continue;
|
|
847
|
+
const childPath = IDENT_RE.test(key) ? `${path}.${key}` : `${path}['${key.replace(/'/g, "''")}']`;
|
|
848
|
+
flattenNode(child, childPath, includeUnchanged, results);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
if (node.type === "UNCHANGED" /* UNCHANGED */ && !includeUnchanged) {
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
const entry = { path, type: node.type };
|
|
857
|
+
if (node.type === "UNCHANGED" /* UNCHANGED */ || node.type === "ADD" /* ADD */ || node.type === "UPDATE" /* UPDATE */) {
|
|
858
|
+
entry.value = node.value;
|
|
859
|
+
}
|
|
860
|
+
if (node.type === "REMOVE" /* REMOVE */ || node.type === "UPDATE" /* UPDATE */) {
|
|
861
|
+
entry.oldValue = node.oldValue;
|
|
862
|
+
}
|
|
863
|
+
results.push(entry);
|
|
864
|
+
}
|
|
786
865
|
|
|
787
866
|
// src/deltaPath.ts
|
|
788
867
|
function formatFilterLiteral(value) {
|
|
@@ -1511,6 +1590,113 @@ function revertDelta(obj, delta) {
|
|
|
1511
1590
|
const inverse = invertDelta(delta);
|
|
1512
1591
|
return applyDelta(obj, inverse);
|
|
1513
1592
|
}
|
|
1593
|
+
|
|
1594
|
+
// src/deltaHelpers.ts
|
|
1595
|
+
var OP_SPEC_KEYS = /* @__PURE__ */ new Set(["op", "path", "value", "oldValue"]);
|
|
1596
|
+
var DELTA_SPEC_KEYS = /* @__PURE__ */ new Set(["format", "version", "operations"]);
|
|
1597
|
+
function operationSpecDict(op) {
|
|
1598
|
+
const result = { op: op.op, path: op.path };
|
|
1599
|
+
if ("value" in op) result.value = op.value;
|
|
1600
|
+
if ("oldValue" in op) result.oldValue = op.oldValue;
|
|
1601
|
+
return result;
|
|
1602
|
+
}
|
|
1603
|
+
function operationExtensions(op) {
|
|
1604
|
+
const result = /* @__PURE__ */ Object.create(null);
|
|
1605
|
+
for (const key of Object.keys(op)) {
|
|
1606
|
+
if (!OP_SPEC_KEYS.has(key)) {
|
|
1607
|
+
result[key] = op[key];
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
return result;
|
|
1611
|
+
}
|
|
1612
|
+
function leafProperty(op) {
|
|
1613
|
+
const segments = parseDeltaPath(op.path);
|
|
1614
|
+
if (segments.length === 0) return null;
|
|
1615
|
+
const last = segments[segments.length - 1];
|
|
1616
|
+
return last.type === "property" ? last.name : null;
|
|
1617
|
+
}
|
|
1618
|
+
function deltaSpecDict(delta) {
|
|
1619
|
+
return {
|
|
1620
|
+
format: delta.format,
|
|
1621
|
+
version: delta.version,
|
|
1622
|
+
operations: delta.operations.map(operationSpecDict)
|
|
1623
|
+
};
|
|
1624
|
+
}
|
|
1625
|
+
function deltaExtensions(delta) {
|
|
1626
|
+
const result = /* @__PURE__ */ Object.create(null);
|
|
1627
|
+
for (const key of Object.keys(delta)) {
|
|
1628
|
+
if (!DELTA_SPEC_KEYS.has(key)) {
|
|
1629
|
+
result[key] = delta[key];
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
return result;
|
|
1633
|
+
}
|
|
1634
|
+
function deltaMap(delta, fn) {
|
|
1635
|
+
return { ...delta, operations: delta.operations.map((op, i) => fn(op, i)) };
|
|
1636
|
+
}
|
|
1637
|
+
function deltaStamp(delta, extensions) {
|
|
1638
|
+
return deltaMap(delta, (op) => ({ ...op, ...extensions }));
|
|
1639
|
+
}
|
|
1640
|
+
function deltaGroupBy(delta, keyFn) {
|
|
1641
|
+
const groups = /* @__PURE__ */ Object.create(null);
|
|
1642
|
+
for (const op of delta.operations) {
|
|
1643
|
+
const k = keyFn(op);
|
|
1644
|
+
if (!groups[k]) groups[k] = [];
|
|
1645
|
+
groups[k].push(op);
|
|
1646
|
+
}
|
|
1647
|
+
const envelope = /* @__PURE__ */ Object.create(null);
|
|
1648
|
+
for (const key of Object.keys(delta)) {
|
|
1649
|
+
if (key !== "operations") {
|
|
1650
|
+
envelope[key] = delta[key];
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
const result = /* @__PURE__ */ Object.create(null);
|
|
1654
|
+
for (const [k, ops] of Object.entries(groups)) {
|
|
1655
|
+
result[k] = { ...envelope, operations: ops };
|
|
1656
|
+
}
|
|
1657
|
+
return result;
|
|
1658
|
+
}
|
|
1659
|
+
function deepClone(obj) {
|
|
1660
|
+
return JSON.parse(JSON.stringify(obj));
|
|
1661
|
+
}
|
|
1662
|
+
function squashDeltas(source, deltas, options = {}) {
|
|
1663
|
+
const { target, verifyTarget = true, ...diffOptions } = options;
|
|
1664
|
+
let final;
|
|
1665
|
+
if (target !== void 0 && deltas.length > 0 && verifyTarget) {
|
|
1666
|
+
let computed = deepClone(source);
|
|
1667
|
+
for (const d of deltas) {
|
|
1668
|
+
computed = applyDelta(computed, d);
|
|
1669
|
+
}
|
|
1670
|
+
const verification = diffDelta(computed, target, diffOptions);
|
|
1671
|
+
if (verification.operations.length > 0) {
|
|
1672
|
+
throw new Error(
|
|
1673
|
+
"squashDeltas: provided target does not match sequential application of deltas to source"
|
|
1674
|
+
);
|
|
1675
|
+
}
|
|
1676
|
+
final = target;
|
|
1677
|
+
} else if (target !== void 0) {
|
|
1678
|
+
final = target;
|
|
1679
|
+
} else {
|
|
1680
|
+
final = deepClone(source);
|
|
1681
|
+
for (const d of deltas) {
|
|
1682
|
+
final = applyDelta(final, d);
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
const result = diffDelta(source, final, diffOptions);
|
|
1686
|
+
for (const d of deltas) {
|
|
1687
|
+
for (const key of Object.keys(d)) {
|
|
1688
|
+
if (!DELTA_SPEC_KEYS.has(key)) {
|
|
1689
|
+
Object.defineProperty(result, key, {
|
|
1690
|
+
value: d[key],
|
|
1691
|
+
writable: true,
|
|
1692
|
+
enumerable: true,
|
|
1693
|
+
configurable: true
|
|
1694
|
+
});
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
return result;
|
|
1699
|
+
}
|
|
1514
1700
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1515
1701
|
0 && (module.exports = {
|
|
1516
1702
|
CompareOperation,
|
|
@@ -1521,8 +1707,15 @@ function revertDelta(obj, delta) {
|
|
|
1521
1707
|
atomizeChangeset,
|
|
1522
1708
|
buildDeltaPath,
|
|
1523
1709
|
compare,
|
|
1710
|
+
comparisonToDict,
|
|
1711
|
+
comparisonToFlatList,
|
|
1524
1712
|
createContainer,
|
|
1525
1713
|
createValue,
|
|
1714
|
+
deltaExtensions,
|
|
1715
|
+
deltaGroupBy,
|
|
1716
|
+
deltaMap,
|
|
1717
|
+
deltaSpecDict,
|
|
1718
|
+
deltaStamp,
|
|
1526
1719
|
diff,
|
|
1527
1720
|
diffDelta,
|
|
1528
1721
|
enrich,
|
|
@@ -1530,10 +1723,14 @@ function revertDelta(obj, delta) {
|
|
|
1530
1723
|
fromDelta,
|
|
1531
1724
|
getTypeOfObj,
|
|
1532
1725
|
invertDelta,
|
|
1726
|
+
leafProperty,
|
|
1727
|
+
operationExtensions,
|
|
1728
|
+
operationSpecDict,
|
|
1533
1729
|
parseDeltaPath,
|
|
1534
1730
|
parseFilterLiteral,
|
|
1535
1731
|
revertChangeset,
|
|
1536
1732
|
revertDelta,
|
|
1733
|
+
squashDeltas,
|
|
1537
1734
|
toDelta,
|
|
1538
1735
|
unatomizeChangeset,
|
|
1539
1736
|
validateDelta
|