Computes the list of **dotted leaf paths** that changed between two values.
The algorithm performs a deep structural comparison with special handling for:
- **Primitives / null** → treated as leafs (change = current path; two NaNs are equal)
- **Date** → compares getTime()
- **RegExp** → compares source and flags
- **Map, Set and binary values** (typed arrays, DataView, ArrayBuffer) → one value at their
own path, compared by reference
- **Arrays** → compared element by element, producing paths like "items.0.title"; when the
lengths differ, the array path itself is reported too, along with each index present on one
side only
- **Objects** → compares by the **union of keys**, recursing into shared keys and marking
added/removed keys as changed at their **full path**
Cycles are handled by tracking the (old, new) pairs currently on the **recursion path**
(added on entry, removed on unwind). A pair is skipped only when it is a genuine ancestor of
itself (a real cycle), a pair that merely appears again at a *sibling* path (legitimate
aliasing, e.g. the same object referenced from two keys) is still diffed, so real changes at
the second site are never dropped.
Parameters
Name
Type
Description
oldState
any
Previous value to diff.
Name
Type
Description
newState
any
Next value to diff.
Name
Type
Description
path
string
Current dotted path (callers pass "" for root; recursion appends segments).
Name
Type
Description
ancestors
Map<object, Set<object>>
(Advanced) Pairs on the current recursion path, for cycle detection. You
generally never pass this.
Returns
string[], An array of **dotted leaf paths** that changed. Paths use "." as a separator and
indices for arrays (e.g., "todos.0.title"). If nothing changed, returns [].