fix: evict mountedRoots on unmount; ManualTimers tests; PersistentStore host warn#265
Merged
Conversation
📦 Bundle size
✅ Within budget (≤5% growth allowed). Baseline: Swift 6.3, WASM SDK 6.3-RELEASE, measured 2026-06-18. |
…re host warn Three B13 hygiene items from the modularization audit: - The driver's mountedRoots map (selector→root node) had no evict path: a root unmounted and never remounted pinned its detached node forever, and the node stayed in the DOM. Swift's teardown now signals the driver via a new unmount(selector) op that detaches the root and drops the entry; HMR teardown clears the map alongside its two siblings. mountedRoots deliberately survives a bare destroyNode (replaceMount's resync ordering depends on it), so the evict is an explicit unmount signal, not a destroyNode side effect. - SwiflowTiming had no direct tests — ManualTimers was exercised only through ToastTests. New SwiflowTimingTests owns the process-global seam (.serialized) and pins schedule/advance/cancel/reset, deinit auto-cancel, due-order, in-body reschedule, and the FP-residue tolerance. - PersistentStore's host stub silently no-ops save/load; the first host save now emits a one-time DEBUG warn so a test asserting persistence against the default registry gets a signal instead of silence. Two audit items deliberately deferred: the @State/@persisted didSet prologue extraction (assertMacroExpansion pins byte-exact output and SwiftSyntax multiline interpolation flattens the nesting — not worth churning ~10 goldens for a stable 6-line block), and the callback @mainactor unification (a source-breaking public-API change that belongs in an intentional breaking batch, invisible on the wasm target). js-driver: 105 tests. Whole-package swift test: 1916 green. EmbeddedDriver + example copies regenerated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Audit backlog B13 (Part-2/Part-6 Lows) — the hygiene items with behavior.
mountedRootshad no evict path. The driver's selector→root-node map was populated on mount/replaceMount but never cleaned: a root unmounted (Swiflow.unmount(into:)) and never remounted pinned its detached node forever, and the node stayed attached to the DOM. Fix: a newunmount(selector)driver op detaches the root and drops the entry, called fromRenderer.teardown(); HMR teardown clears the map alongsidenodes/listeners. Crucially,mountedRootsdeliberately survives a baredestroyNode(the resync-batch ordering emits the old root'sdestroyNodebeforereplaceMount, which needs the entry to detach the old node) — so the evict is an explicit unmount signal, not adestroyNodeside effect. Two js-driver tests pin both halves.ManualTimerswas covered only through ToastTests. NewSwiflowTimingTestsowns the process-global seam (.serialized) and pins schedule/advance/cancel/reset, theisolated deinitauto-cancel, due-order firing, in-body reschedule, and the 1e-9 FP-residue tolerance.savenow emits a one-time DEBUGswiflowWarn, so a test asserting persistence against the default registry (instead of injectingMemoryStorage) gets a signal instead of a silent pass/fail.Deliberately deferred (documented in the commit): the
@State/@PersisteddidSet-prologue extraction (assertMacroExpansion pins byte-exact output; SwiftSyntax multiline interpolation flattens the nesting — not worth churning ~10 goldens for a stable 6-line block) and the callback@MainActorunification (a source-breaking public-API change that belongs in an intentional breaking batch, and is invisible on the wasm target).Verification: js-driver 105 tests, 0 fail. Whole-package
swift test: 1916 green.EmbeddedDriver.swift+ 22 example copies regenerated.🤖 Generated with Claude Code