Drop empty paragraphs from canonical document projection
An empty Lexical paragraph exported as an empty MDAST paragraph, which serializes as an extra blank line that parsing discards. Rooms persisted that non-canonical source, and document-summary jobs then failed with "Document source is not canonical." Projection now drops empty paragraphs at every depth, matching the blocks that addressable() and digests() already count. Checkpoints written before this change still store the former blank lines, so restore accepts a stored source whose canonical form matches the projection. Closes #211 Assistant-model: Claude Opus 5.5 Assistant-workflow: inline Assistant-duration: 15m converged, estimated none given Assistant-verification: bun test unit passed: 1659 pass, 2 skip, 0 fail; new convert and room regression tests failed before the fix Assistant-verification: bun run test:postgres passed: 59 pass Assistant-verification: bun run types passed: all workspaces and E2E Assistant-verification: bun run ci passed: dprint, oxlint, tokens, type scale, Impeccable Assistant-verification: bun run e2e passed: 236 Chromium tests Assistant-verification: agent-browser E2E passed: typing text and two Enters stores canonical "…strings.\n" on this branch versus non-canonical "…strings.\n\n\n\n" on main; a document written by main opens, edits, and re-persists canonically on this branch Co-authored-by: Alex Lavaee <lavaman131@github.com>
Parent6bd3e01
4 files changed+70-5
StackedSplit