Skip to content

fix(editor): persist page-setup changes on save (data-loss bug) - #168

Merged
mhurhangee merged 2 commits into
mainfrom
fix/editor-page-setup-selective-save
Jul 1, 2026
Merged

mhurhangee merged 2 commits into
mainfrom
fix/editor-page-setup-selective-save

Conversation

@mhurhangee

Copy link
Copy Markdown
Owner

Fixes the high-priority data-loss bug from SCRATCHPAD: margin/orientation/size changes were silently dropped on save.

Root cause

Page setup writes to the model-level finalSectionProperties, but it isn't a ProseMirror transaction — so the change tracker never sees it, changedParaIds is empty, and the default selective save (useFileIOtoBuffer({ selective })attemptSelectiveSave) only patches changed paragraphs and never re-emits the body sectPr. Only a full repack serializes it. Confirmed by inspection + user report.

Fix

  • usePageSetupControls flips a sectionPropsDirtyRef when page setup is applied (the single apply path).
  • useFileIO ORs it into structuralChange, forcing attemptSelectiveSave to bail → full repack (mirrors the existing hasInjectedReplies force), then resets the flag after a successful save (stays set if the save failed).
  • Ref threaded through the god file (declared once, passed to both hooks).

Test

New regression test in selectiveSave.test.ts that documents the bug (selective save with a changed pageWidth + empty changedParaIds reopens with the original width) and confirms the fix's mechanism (forcing structuralChangerepackDocx reopens with the new width). It passes — i.e. it reproduced the drop and verified the repack path persists.

Verification

pnpm check green · bun test 1740 pass (+1).

Interim fix per SCRATCHPAD; the proper fix (PM-native section properties, which also makes it Ctrl+Z-undoable) remains logged.

…tive save)

A page-setup change (size/orientation/margins) writes to the model-level
finalSectionProperties, but it's not a ProseMirror transaction — so the change
tracker never sees it, changedParaIds is empty, and the selective save path
(the default) never re-emits the body sectPr. Result: the change was silently
lost on reopen. Only a full repack serializes finalSectionProperties.

Fix: usePageSetupControls flips a sectionPropsDirtyRef when page setup is applied;
useFileIO ORs it into structuralChange, forcing attemptSelectiveSave to bail to a
full repack (mirrors the existing hasInjectedReplies force), then resets the flag
after a successful save. Regression test in selectiveSave.test.ts documents the
bug (selective drops the sectPr change) and confirms the fix's mechanism (forcing
structuralChange → repack persists it).

Interim fix per SCRATCHPAD; the proper fix (PM-native section properties) remains.
@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
patrick-web Skipped Skipped Jul 1, 2026 3:25pm

… save race)

Review of #168 found the flag was reset AFTER the awaited toBuffer: a page-setup
change applied during an in-flight autosave would have its dirty flag clobbered by
the late reset and get dropped on the next save. Consume + reset the flag
synchronously before the await (a set flag already forces this save to repack),
and restore it if the save fails. Mirrors the mutateChart no-await-between rule.

Also add a usePageSetupControls test guarding the producer side of the wiring
(applying page setup dirties the flag; a read-only apply does not) — the earlier
core test only covered the selective-save mechanism, not the React wiring.
@mhurhangee
mhurhangee merged commit 679740a into main Jul 1, 2026
3 checks passed
@mhurhangee
mhurhangee deleted the fix/editor-page-setup-selective-save branch July 1, 2026 15:27

This branch was previously deployed

1 inactive deployment
Preview 290f3ca3 Deployed Jul 1, 2026 by vercel[bot]
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