DRY/YAGNI/KISS pass: shared navigation registry, hide tracker, press gates - #55
Open
ivanbanov wants to merge 5 commits into
Open
DRY/YAGNI/KISS pass: shared navigation registry, hide tracker, press gates#55ivanbanov wants to merge 5 commits into
ivanbanov wants to merge 5 commits into
Conversation
Duplicate copies of the module (monorepo, micro-frontend) each kept their own registry and popstate listener while sharing the one real session history, so a Back could be answered by the wrong copy. The registry now rendezvouses on a Symbol.for realm global — the same anchoring dom-overlay and dom-scroll-lock already use — and the store remembers the attached listener, since the browser's (type, listener) dedupe can't span copies. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ed() hideOutside and hideExitingLayer each carried a copy of the hide/undo bookkeeping — the author-hidden skip and the exact-restore undo — now written once in a shared tracker. In the layer stack, below() derived "beneath" with a second copy of the depth/open-order ranking; it now slices ordered(), the one ranking rule. No behavior change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…he predicates acceptsBackdropPress / acceptsViewportPress left React and Solid writing the same onClick wrapper by hand. gateBackdropPress / gateViewportPress take the part's normalized bindings and return them with the press gated, so a substrate's contribution stays lifecycle only. Gating rules unchanged: topmost answers, viewport presses must start on the viewport itself. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Aug 28, 2026
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.
A simplicity pass over the DOM layer and the dialog substrates, plus the principles it was held to written into
AGENTS.md.What changed
@dunky.dev/browser-navigation— fix. The guard registry and popstate listener now anchor on a realm-global keyed bySymbol.for, the same anchoringdom-overlayanddom-scroll-lockalready use. Duplicate copies of the module (monorepo, micro-frontend) previously forked the registry while sharing the one real session history, so a Back could be answered by the wrong copy. The store also remembers the attached listener: each copy's function has its own identity, so the browser's(type, listener)dedupe can't span copies. Covered by an anchoring test mirroring the other two packages.@dunky.dev/dom-dialog— press gates replace the predicates (minor).acceptsBackdropPress/acceptsViewportPressleft React and Solid writing the sameonClickwrapper by hand — exactly the shared DOM behavior this package exists to hold.gateBackdropPress(id, bindings)/gateViewportPress(id, bindings)take the part's normalized bindings and return them with the press gated; both substrates' Backdrop/Viewport collapse to a singlemergePropscall. Gating rules unchanged.@dunky.dev/dom-overlay+@dunky.dev/overlay— refactors, no behavior change.hideOutsideandhideExitingLayereach carried a copy of the hide/undo bookkeeping (the author-hidden skip, the exact-restore undo); it's now one shared tracker so the two rules can't drift apart. In the layer stack,below(id)re-implemented the depth/open-order ranking; it now slicesordered()— one ranking rule, written once.AGENTS.md. A Principles table (KISS, DRY, YAGNI, POLA) at the top of the Code section, so the lens this pass applied is the standing contract.Also removed along the way: a stale dist-only leftover at
packages/dom/utils/dialog/(local, gitignored — nothing in the diff).Not changed, deliberately
The forward-reopen half of
closeOnBackis where the repo's complexity concentrates (parked guards, claim watchers, the consumption chain). Whether it earns its keep is a product decision, so this pass left it intact — flagged separately.Verification
282 tests across 16 files, typecheck, and lint all pass.
format:checkstill fails only on files this PR doesn't touch (pre-existing drift inREADME.mdand the react/solid dialog SPECs).🤖 Generated with Claude Code