CodeVetter · Repo Unpack · Behavior traces
immerjs/immer
Source inspection followed ordinary production, manual drafting, and patch replay end-to-end, plus startup, snapshots, collections, and array reordering. These traces describe execution order and meaningful branches rather than observed runtime results. They show where drafts are created, how outputs are finalized, and when user callbacks execute.
- Startup: src/immer.ts creates new Immer(), exposing its methods; instance defaults are autoFreeze_=true, useStrictShallowCopy_=false, and useStrictIteration_=false, while optional plugins require explicit enable calls.
- Recipe update: produce → isDraftable → enterScope → createProxy → createProxyProxy → recipe(proxy); nested reads draft lazily and writes call prepareCopy → markChanged → handleCrossReference.
- Recipe completion: successful execution leaves the scope, enables requested patch collection, then processResult → finalize → callback cleanup/patch generation → maybeFreeze → revokeScope → patchListener; a thrown recipe instead revokes in finally.
- Manual lifecycle: createDraft validates the base, snapshots it with current if already drafted, enters a scope, creates and marks a manual proxy, then leaves; finishDraft retrieves its owning scope and calls processResult.
- Patch round trip: produceWithPatches → produce with a listener → tuple capture; applyPatches scans backward for the last root replacement, skips earlier patches, then applies through the plugin directly to a draft or inside another produce.
- Snapshot: current rejects non-drafts, returns unchanged bases directly, temporarily marks modified drafts finalized to suppress drafting during copying, recursively snapshots children, and restores finalized_=false.
- Map update: createProxy selects proxyMap_ → DraftMap; get(key) lazily creates and caches a child draft, set(key,value) prepares a Map copy and records modification, and finalization callbacks replace nested draft references.
- Array reordering: objectTraps.get selects createMethodInterceptor → enterOperation → handleReorderingOperation → executeArrayMethod → native copy sort/reverse → markAllIndicesReassigned; later element reads detect relocated base references, and finally clears operationMethod.