Unify single-child same-id assignment on continuity#28
Merged
Conversation
A single `var child: M` property replaced its child on any different-instance assignment, while `[Model]` and `Model?` properties treat a same-Identifiable-id assignment as continuity (keep the live child, ignore the new instance's state). Bring the single-Model write path in line: identity is the Identifiable `.id`, so a same-id assignment reuses the existing child's context (skip removeChild -> updateContext reuses it) and only a different `.id` is a genuine replacement. The write-skip is keyed by `.id` so a same-id assignment fires no spurious observation, matching the collection/optional paths. Only affects @model types with an explicit, reusable `id`; for a default-id model `.id == modelID`, so every distinct instance still replaces exactly as before. Validated: full suite green on serial and parallel (782 tests, only the documented known-issue flakes). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
e0f1ec9 to
5ad4c9e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #26. Makes the single
@Modelchild write path consistent with the collection ([Model]) and optional (Model?) paths for same-idassignment.Before this PR, the three child shapes disagreed on what
child = NewInstance(sameId)means for a@Modelwith an explicit, reusableid:var child: Mvar child: M?var items: [M]This unifies them on continuity, so there is one rule across all shapes:
Change
In the single-Model write path (
ModelSourceBoxsubscript<T: Model>set):.id(child.id != newValue.id); a same-idassignment leaves the existing context registered soupdateContextreuses it (continuity)..id(wasmodelID) so a same-idassignment fires no spurious observation, matching the collection/optional paths.Two-line functional change.
Scope / compatibility
@Modeltypes that declare an explicit, reusableid. For a default-idmodel.id == modelID, so every distinct instance still replaces exactly as before — no behavior change.id.No DEBUG "you replaced instead of mutating" notice was added: the framework cannot distinguish "replace to update state" from "pass a fresh same-id instance for continuity" (the latter is the legitimate, tested pattern in
ActivateTests.testChildrenCaseActivation), so such a notice would false-positive on correct usage. The contract is documented in the CHANGELOG instead.Validation
Full suite green on serial and parallel (782 tests; only the documented known-issue flakes). CHANGELOG
[Unreleased]updated;ExplicitIdReplacementTestsupdated to assert single-child continuity plus a different-idreplacement control.🤖 Generated with Claude Code