Skip to content

Step history on the single-crystal and PDF pages (+ PDF reopen-result fix, uniform Reset) - #14

Merged
drthyang merged 1 commit into
mainfrom
claude/step-history-sc-pdf
Sep 28, 2026
Merged

drthyang merged 1 commit into
mainfrom
claude/step-history-sc-pdf

Conversation

@drthyang

Copy link
Copy Markdown
Owner

Follows #13 (powder step history).

What

  • One binding for all three engines. A single stepHistory binding (src/app/historyBinding.ts) serves the powder, single-crystal and PDF engines, and the History card takes it directly.
    • The shell snapshots whichever engine is active, exactly as Save does.
    • Going back reuses the Open path, which remounts the single-crystal or PDF engine from the step.
  • What records a step:
    • Single crystal: Refine, guided refine, Prefit, Escape minimum, applying or removing a magnetic model, and Reset.
    • PDF: Refine, Prefit, Escape minimum, adopting a boxcar box, distortion modes (parent CIF, subgroup, mode activation), adopting, showing or removing a spin model, and Reset.
    • Both: loading new data starts a new history.
  • Steps are recorded one tick after they render. An engine that settles its state in its own effects, like the PDF spec-swap carryover, is then captured settled, not half-updated.
  • Reset is uniform. On single crystal and PDF it now restores the starting values and keeps every row and its free/fixed choice, as powder does. The single-crystal Reset used to rebuild from the fresh spec, which dropped applied moment rows while the magnetic model stayed set.

Fix found by the history

A reopened PDF project lost its last result in development. main.tsx runs under StrictMode, which runs mount effects twice. The spec-swap effect's second run took the mount spec for a model change and cleared the result. The effect is now idempotent per spec object. The history exposed this as phantom "No change" steps. Production builds don't run effects twice, so users there were unaffected.

Evidence

  • In the browser (dev server):
    • PDF demo: Refine → back → forward gave exactly 2 steps (demo, Refine), with the result restored at s2.
    • PDF re-open: a saved-and-reopened PDF project keeps its lastResult. It didn't before the fix.
    • Single crystal: loading the Eu₃In₂Te₄ .int from data/ (with its CIF) → Refine → Reset → back/forward gave 3 steps (load, Refine, Reset), with the result back at s2 and no phantom steps.
    • Powder: unchanged. Demo → Refine → back → forward gave 2 steps, with the result restored.
  • Full suite: 194 files, 1,474 tests pass. tsc -b and eslint . are clean.

Notes

  • "Other branches" lists branch ends only. From the end of a branch, back and forward walk along it.
  • Unexplained reloads (environment). Twice during testing, the browser pane navigated the tab (performance navigation type navigate, no Vite reload). Both times the pane's viewport emulation was on. The app has no navigation code, and autosave restored the session both times. Documented here in case anyone sees it outside the pane.

🤖 Generated with Claude Code

One `stepHistory` binding (historyBinding.ts) now serves all three engines;
the shell snapshots whichever engine is active, as Save does, and going back
reuses the Open path (which remounts the SC / PDF engine from the step).

- SC: refine / guided / prefit / escape, magnetic model applied or removed,
  Reset. PDF: refine / prefit / escape, boxcar-box adopt, distortion modes
  (parent CIF, subgroup, mode activation), spin model adopted / shown /
  removed, Reset. Loading SC or PDF data starts a new history.
- Requested steps are recorded a tick after they render, so an engine that
  settles its state in its own effects (the PDF spec-swap carryover) is
  captured settled, not half-updated.
- Reset on SC and PDF now restores starting values and keeps every row and
  free/fixed choice, as powder does. SC Reset used to rebuild from the fresh
  spec, dropping applied moment rows while the magnetic model stayed set.

Fix: a reopened PDF project lost its last result in development. StrictMode
runs a mount effect twice; the spec-swap effect's second run took the mount
spec for a model change and cleared the result. The effect is now idempotent
per spec. The history exposed it as phantom "No change" steps.

Verified in the browser: PDF demo → Refine → back → forward gives exactly 2
steps with the result restored; a saved-and-reopened PDF project keeps its
result; SC (Eu3In2Te4 .int) load → Refine → Reset → back/forward gives 3
steps and the result returns at s2; powder unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@drthyang
drthyang merged commit 3be8837 into main Sep 28, 2026
2 checks passed
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