explorer: collapse dual mode state to single source of truth (#208 step 1)#213
Conversation
…sorg#208 step 1) Step 1 of the isamplesorg#208 state-management refactor. The closure-private \`mode\` variable in the zoomWatcher OJS cell duplicated \`viewer._globeState.mode\`; both were updated together but the duplication caused transient sync mismatches during boot (the URL round-trip harness's iter 1 captures this — \`waitReadyAndPointMode\` succeeds against \`_globeState.mode\` then the snapshot sees a brief cluster state shortly after). Codex's retrospective on PR isamplesorg#203 recommended making \`_globeState.mode\` the single source of truth and wrapping mode transitions in one setter. This change does exactly that: - **\`getMode()\` getter** reads from \`viewer._globeState.mode\`. All former \`mode === ...\` reads in the zoomWatcher cell (10 sites: tryEnterPointModeIfNeeded, source-filter handler, facet-filter handler, camera-changed handler targetMode + transitions + stats guard, hashchange post-flight reconciliation) now go through it. - **\`setExplorerMode(next)\` setter** is the only writer. Used by \`enterPointMode\` and \`exitPointMode\`, which previously did the redundant \`mode = X; viewer._globeState.mode = X;\` pair. - **Closure \`let mode = 'cluster';\` removed.** This is foundation work for step 2 (introduce \`writeGlobeHash\` / \`reconcileCameraState\` and centralize the URL writers — Codex smell 1). Verification: \`url_roundtrip_investigation.js\` — 5/6 iterations green. The iter 1 anomaly ("mode A=cluster B=point" on no-op flight) is the same pre-existing boot-transition timing that Codex flagged in the original retrospective; it's neither caused nor worsened by this refactor and will be addressed when the camera reconciliation path is centralized in step 2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codex review — round 1Verbatim Codex review (no shared context). LGTM, ready to merge in a single round. One factual correction noted: Codex counted 11 reads (not 10 as the PR description says). The commit message lists "10 former bare- SummaryNo blocking issues found. The refactor does collapse runtime mode state to One correction: the author’s count is off. I count 11 reads + 2 writes, not 10 reads + 2 writes. Per-ask response1. CompletenessComplete. In explorer.qmd, old runtime I count 11 reads:
Writes are both routed through 2. Initialization GapFine. explorer.qmd initializes 3. Behavioral PreservationPreserved for 4. External WritesI found no external 5. PR #214 Spec InteractionConfirmed. Specs polling 6.
|
Step 1 of the #208 state-management refactor. Foundational.
Problem
The zoomWatcher OJS cell carried explorer mode in two places:
Both were updated together (`mode = 'point'; viewer._globeState.mode = 'point';`), but the duplication caused transient sync mismatches during boot. The URL round-trip harness captures this: `waitReadyAndPointMode` succeeds against `_globeState.mode` then a snapshot moments later sees a brief cluster state — the harness's iter 1 "mode A=cluster B=point" anomaly.
Codex's retrospective on PR #203 (item 7) recommended making `_globeState.mode` the single source of truth and wrapping transitions in one setter.
What this changes
20 insertions, 16 deletions. No behavioral changes intended — just collapses the duplication.
Verification
Risks
Sequencing reminder
Per Codex's recommended sequence (in #208):
Each step gets its own PR with Codex review.
Test plan
🤖 Generated with Claude Code