CodeVetter · Repo Unpack · Data flow
immerjs/immer
Inputs enter as application-owned state and executable recipes, then become scope-owned drafts with lazily allocated copies. Writes record assignments and propagate modification flags toward parents; finalization substitutes ordinary values and preserves unchanged base references. Results and optional patch arrays leave through returns and listeners, with persistence delegated to the calling application in these inspected API paths.
- The draftability boundary accepts plain objects, arrays, marked instances or constructors, Maps, and Sets; other truthy object inputs to produce reach die(1).
- createProxy selects collection plugins or createProxyProxy, registers the draft in its scope, and shares the parent's callback array while recording the child's key.
- objectTraps.get reads latest(state), creates a child draft only for eligible base or relocated references, and caches that draft in copy_; merely reading can allocate a copy without marking a change.
- objectTraps.set ignores equal-value assignments under its presence checks, otherwise prepares a copy, marks ancestors changed, records assigned_ entries, and registers cross-reference handling.
- Finalization returns base_ for unmodified drafts, drains registered callbacks for modified drafts, and updates parent references to finalized values before returning copy_.
- Patch generation uses assignment records for objects and Maps, index comparisons for arrays, and membership changes for Sets, producing corresponding inverse operations.
- applyPatches clones draftable patch values before dispatching writes; arrays use splice or push, Maps use set/delete, Sets use add/delete, and ordinary objects use property assignment/deletion.
- processResult optionally deep-freezes eligible root results, revokes drafts, invokes the patch listener, and returns state; these core output boundaries contain no persistence operation.