From 08b0fdf4877390e4d49b02e05d11a7b78504b56b Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Sat, 22 Aug 2026 20:42:34 -0400 Subject: [PATCH 01/12] refactor(ui): item-owned reveal machine, transplanted onto the merged #9475 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #9475 was squash-merged (e431d249e0), orphaning this stacked branch's history, so this is a transplant rather than a rebase: one commit that re-applies the branch's semantic delta on top of main's merged state — including the parts of #9475 this branch predated (session disposal, the restored socket suite, and the hook + happy-dom test architecture from its final round). What this branch changes, restated against main: - Selections carry identity instead of being inferred by comparing names. $gallerySelection publishes {name, generation, isAutoSwitch} from one store listener; the auto-switch mark is set immediately before the handoff dispatches its selection and spent by that selection alone. The name-keyed marker module and its settle listener are deleted. - The reveal is a state machine (idle | deferred | awaiting-media | revealing) owned by the viewer context — one instance for both preview components, so a click that switches media type is just another selection. The shared previous-item ref and its cleared-selection sentinel are gone. Re-picking the item already on screen now reveals: it changes no state and no rendered name, only the generation, which the old comparison could not see. - The machine owns the revealed flag and its timers exclusively; the provider settles selections that land while neither preview is mounted and resets the machine on teardown. - useSelectedItemReveal keeps its mounted happy-dom coverage, now asserting the machine wiring: one reveal running across a component swap on its original clock, attach making the provider's settle a no-op while mounted, the repeat-click reveal, media readiness from a real