Skip to content

fix(boot): preserve reentrant root lifetimes during cleanup - #398

Merged
smiggleworth merged 2 commits into
mainfrom
fix/root-lifetime-cleanup
Sep 6, 2026
Merged

fix(boot): preserve reentrant root lifetimes during cleanup#398
smiggleworth merged 2 commits into
mainfrom
fix/root-lifetime-cleanup

Conversation

@smiggleworth

@smiggleworth smiggleworth commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Root cleanup could erase a replacement mounted by a cleanup callback: the old cleanup continued deleting the element's registration after the new mount completed. A stale callback unsubscribe could clear the new lifetime's callbacks, and the intercepted innerHTML = '' setter could remove the replacement DOM after cleanup returned.

Retire the root registration and capture its callbacks before teardown invokes user code. Restore a reusable instance only when no replacement claimed the root; a reentrant mount supersedes an interrupted update or DOM clear. Callback unsubscription checks collection identity. Shared root initialization and default portal cleanup registration are consolidated; public signatures and the bundle limit are unchanged.

Validation:

  • Six baseline regressions and three additional stale-innerHTML regressions demonstrated red before remediation. All 11 lifetime cases now pass in jsdom and native Chromium, including ordinary DOM clearing without a replacement.
  • Component cleanup, ref(null), root callbacks, and strict throwing cleanup preserve replacement DOM, click listeners, registration, and resource signals. Replacement cleanup runs exactly once and aborts its own signal.
  • Format, lint/typecheck, build, full unit/repository/DOM/browser suites, public types, and 21 packed-consumer tests pass on the rebased candidate. Lint retains one pre-existing unused-parameter warning.
  • The SSG hydration fixture passes its unchanged 256 KiB budget.
  • The component-depth benchmark passes its 10000-component regression and 1000-component mount/cleanup workload. This is a local benchmark run, not a speedup claim.

@smiggleworth
smiggleworth force-pushed the fix/root-lifetime-cleanup branch from fe52868 to 232c968 Compare September 6, 2026 20:31
@smiggleworth
smiggleworth merged commit 3cbdd68 into main Sep 6, 2026
7 checks passed
@smiggleworth
smiggleworth deleted the fix/root-lifetime-cleanup branch September 6, 2026 20:40
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