Skip to content

docs: recommend helpers that change a draft in place for create() on a draft - #188

Merged
unadlib merged 1 commit into
mainfrom
docs/create-on-draft-helpers
Oct 6, 2026
Merged

unadlib merged 1 commit into
mainfrom
docs/create-on-draft-helpers

Conversation

@unadlib

@unadlib unadlib commented Oct 6, 2026

Copy link
Copy Markdown
Owner

Refs #160. Part of #168. Replaces #187.

Summary

#186 documented that a helper calling create() on a draft returns a result whose unchanged values are objects of the base state, so writing to them after the result is assigned back changes the base state. #187 then proposed an opt-in cloneDraftBase option that deep-copies such a base before drafting it. Measuring the pattern of #160 showed that users do not need the option, and that it is not the approach to recommend:

  • A helper that changes a draft in place, and calls create() only on other values, leaves the base state unchanged and keeps the references of the values it does not change, without any option. It is also the fastest approach below.
  • A helper whose result must not share objects with the base state can give create() a deep copy itself: create(structuredClone(current(draft)), recipe) does what the option did.
  • The option would only have applied to creators made by makeCreator(), so it could not reach helpers in other packages that import create. It would have added a permanent v2 API, 55 B and an error-driven retry inside create() for what one line in a helper does.

This PR documents both patterns instead; the library code is unchanged.

Changes

  1. docs: recommend helpers that change a draft in place for create() on a draft. README and create.md: the "create() on a draft" section now states the problem and shows its example first. It then recommends a helper that changes a draft in place, noting that it changes the outer draft even if the caller discards its result. The other ways follow: make such changes in the helper's recipe or through the outer draft; give create() a deep copy with create(structuredClone(current(draft)), recipe), which costs a copy per call and new references for unchanged values, while structuredClone turns class instances into plain objects and throws on functions; and enable enableAutoFreeze in development.

Measurements

The pattern of #160 runs over 1,000 nodes: draft.nodes = draft.nodes.map(...) with a helper that renames each node, then a write to the helper's result. The table shows the median time in ms, from one process per approach over 3 rounds, on main:

Helper Small nodes Nodes with 10 children
Calls create() on the draft (changes the base state) 1.3 8.3
Gives create() a deep copy of the draft 2.3 16.7
Changes a draft in place 0.69 0.69
Immer 11.1.18 produce, auto-freeze off / on 3.8 / 4.0 4.5 / 5.0

Verification

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown

Coverage after merging docs/create-on-draft-helpers into main will be

100.00%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   apply.ts100%100%100%100%
   array.ts100%100%100%100%
   constant.ts100%100%100%100%
   create.ts100%100%100%100%
   current.ts100%100%100%100%
   draft.ts100%100%100%100%
   draftify.ts100%100%100%100%
   error.ts100%100%100%100%
   index.ts100%100%100%100%
   interface.ts100%100%100%100%
   internal.ts100%100%100%100%
   makeCreator.ts100%100%100%100%
   map.ts100%100%100%100%
   original.ts100%100%100%100%
   patch.ts100%100%100%100%
   rawReturn.ts100%100%100%100%
   set.ts100%100%100%100%
   unsafe.ts100%100%100%100%
src/utils
   cast.ts100%100%100%100%
   copy.ts100%100%100%100%
   deepFreeze.ts100%100%100%100%
   draft.ts100%100%100%100%
   finalize.ts100%100%100%100%
   forEach.ts100%100%100%100%
   index.ts100%100%100%100%
   mark.ts100%100%100%100%
   marker.ts100%100%100%100%
   proto.ts100%100%100%100%

@unadlib
unadlib merged commit be0cc87 into main Oct 6, 2026
4 checks passed
@unadlib
unadlib deleted the docs/create-on-draft-helpers branch October 6, 2026 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant