Skip to content

DRY/YAGNI/KISS pass: shared navigation registry, hide tracker, press gates - #55

Open
ivanbanov wants to merge 5 commits into
mainfrom
chore/dry-yagni-kiss-pass
Open

DRY/YAGNI/KISS pass: shared navigation registry, hide tracker, press gates#55
ivanbanov wants to merge 5 commits into
mainfrom
chore/dry-yagni-kiss-pass

Conversation

@ivanbanov

@ivanbanov ivanbanov commented Aug 27, 2026

Copy link
Copy Markdown
Member

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 by Symbol.for, the same anchoring dom-overlay and dom-scroll-lock already 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 / acceptsViewportPress left React and Solid writing the same onClick wrapper 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 single mergeProps call. Gating rules unchanged.

@dunky.dev/dom-overlay + @dunky.dev/overlay — refactors, no behavior change. hideOutside and hideExitingLayer each 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 slices ordered() — 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 closeOnBack is 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:check still fails only on files this PR doesn't touch (pre-existing drift in README.md and the react/solid dialog SPECs).

🤖 Generated with Claude Code

ivanbanov and others added 5 commits August 27, 2026 23:14
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>
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