json-diff-ts 5.0.0-alpha.8 → 5.0.0

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 CHANGED
@@ -70,10 +70,22 @@ Apply forward to get the new state, or revert to restore the original:
70
70
 
71
71
  ```typescript
72
72
  // Clone before applying — applyAtom mutates the input object
73
- const updated = applyAtom(structuredClone(before), atom); // updated === after
73
+ const updated = applyAtom(structuredClone(before), atom); // updated values; existing array order retained
74
74
  const restored = revertAtom(structuredClone(updated), atom); // restored === before
75
75
  ```
76
76
 
77
+ ## Version 5
78
+
79
+ JSON Atom is available in the stable v5 release:
80
+
81
+ ```sh
82
+ npm install json-diff-ts@5
83
+ # Pin the release explicitly:
84
+ npm install json-diff-ts@5.0.0
85
+ ```
86
+
87
+ Version 5 adds JSON Atom diff/apply/undo, move/copy operations, workflow helpers, and `keysToInclude`. It fixes atomic path round-trips for special property names and array apply/revert ordering. JSON Atom consumers use typed filters and reject malformed paths, missing or ambiguous targets, and invalid JSON payloads.
88
+
77
89
  ## Quick Start
78
90
 
79
91
  ```typescript
@@ -257,9 +269,26 @@ interface AtomOptions extends Options {
257
269
  reversible?: boolean; // Include oldValue for undo. Default: true
258
270
  arrayIdentityKeys?: Record<string, string | FunctionKey>;
259
271
  keysToSkip?: readonly string[];
272
+ keysToInclude?: readonly string[];
260
273
  }
261
274
  ```
262
275
 
276
+ ### Include only selected paths
277
+
278
+ `diff` and `diffAtom` accept `keysToInclude` to compare selected fields or entire subtrees. Paths use dot notation and omit array indices and identity values, so one entry selects the field in every array element.
279
+
280
+ ```typescript
281
+ const atom = diffAtom(oldOrder, newOrder, {
282
+ arrayIdentityKeys: { positions: 'id', 'positions.deliveries': 'id' },
283
+ keysToInclude: ['positions.quantity', 'positions.deliveries'],
284
+ keysToSkip: ['positions.deliveries.internalNotes'],
285
+ });
286
+ ```
287
+
288
+ Each included path selects itself and its descendants. Unrelated branches are skipped before their values are read. `keysToSkip` takes precedence. Omit `keysToInclude` to compare everything; pass `[]` to produce no changes.
289
+
290
+ Structural changes (adding, removing, or replacing an entire ancestor object or array element) retain the complete value, as with `keysToSkip`. This keeps operations applicable and reversible, including the identity fields needed to locate new array elements. Selection controls traversal of existing branches; it does not redact operation payloads.
291
+
263
292
  ### Atom Workflow Helpers
264
293
 
265
294
  Transform, inspect, and compact atoms for workflow automation.
@@ -650,6 +679,7 @@ interface Options {
650
679
  /** @deprecated Use arrayIdentityKeys instead */
651
680
  embeddedObjKeys?: Record<string, string | FunctionKey> | Map<string | RegExp, string | FunctionKey>;
652
681
  keysToSkip?: readonly string[];
682
+ keysToInclude?: readonly string[];
653
683
  treatTypeChangeAsReplace?: boolean; // default: true
654
684
  }
655
685
  ```
@@ -658,11 +688,15 @@ interface Options {
658
688
 
659
689
  ## Migration from v4
660
690
 
661
- 1. **No action required** -- all v4 APIs work identically in v5.
662
- 2. **Adopt JSON Atom** -- use `diffAtom()` / `applyAtom()` for new code.
663
- 3. **Bridge existing data** -- `toAtom()` / `fromAtom()` for interop with stored v4 changesets.
664
- 4. **Rename `embeddedObjKeys` to `arrayIdentityKeys`** -- the old name still works, but `arrayIdentityKeys` is the preferred name going forward.
665
- 5. Both formats coexist. No forced migration.
691
+ 1. **Existing APIs remain available.** `diff`, `applyChangeset`, `revertChangeset`, and the atomic conversion helpers are still exported. Fixes include array revert ordering and preserving the input changeset during revert.
692
+ 2. **Adopt JSON Atom** with `diffAtom()` / `applyAtom()` for new code. Atom values must be JSON-safe. Serialize Date and other JavaScript-only values before diffing. Root creation/removal uses `null` as the empty-document value.
693
+ 3. **Use typed identity values.** `1` and `'1'` are different filter values. `toAtom()` is a best-effort bridge: legacy paths contain string literals and cannot recover numeric or boolean identity types. Recompute with `diffAtom()` when typed identity is needed. `fromAtom()` does not support move/copy.
694
+ 4. **Identity keys must be unique.** Duplicate identities now throw instead of silently dropping elements. The diff producer also rejects identities that collide after string conversion (for example `1` and `'1'` in one array). Applying externally produced atoms supports strict typed identities.
695
+ 5. **Invalid operations throw.** Add cannot overwrite an existing object property; remove/replace require an existing target; filters must identify exactly one element. Move/copy follow add rules, including the root-null precondition. Failed moves preserve the source. Earlier successful operations in a failed multi-operation atom may already have been applied.
696
+ 6. **Array identity is order-independent.** Key/value identity does not reproduce arbitrary reorderings or original insertion positions on undo. Use index-based diffing when exact array order matters.
697
+ 7. **Rename `embeddedObjKeys` to `arrayIdentityKeys`.** The alias remains supported. `keysToInclude` and `keysToSkip` select traversal, not payload redaction; structural changes preserve complete values.
698
+ 8. **Package entry points are explicit.** ESM, CommonJS, and their TypeScript declarations resolve through conditional exports. Import from `json-diff-ts`; deep imports into `dist/` are not public entry points.
699
+
666
700
 
667
701
  ---
668
702
 
@@ -675,7 +709,7 @@ interface Options {
675
709
  | Dependencies | Zero | Few | Many | Varies |
676
710
  | ESM Support | Native | CJS only | CJS only | Varies |
677
711
  | Array Identity | Key-based | Index only | Configurable | Index only |
678
- | Wire Format | JSON Atom (standardized) | Proprietary | Proprietary | JSON Pointer |
712
+ | Wire Format | JSON Atom (draft specification) | Proprietary | Proprietary | JSON Pointer |
679
713
  | Reversibility | Built-in (`oldValue`) | Manual | Plugin | Not built-in |
680
714
 
681
715
  ## FAQ