Back to Plate

Phase 4 Markdown Execution

docs/plans/2026-03-14-phase-4-markdown-execution.md

53.0.53.4 KB
Original Source

Phase 4 Markdown Execution

Goal

Complete the phase-4 markdown slice only. Add high-ROI non-React logic coverage for parser and serializer helpers plus incomplete-MDX fallback behavior.

Checklist

  • [completed] Audit current markdown seams and existing tests
  • [completed] Add focused helper specs for markdown lib utilities
  • [completed] Add focused markdownToSlateNodesSafely behavior specs
  • [completed] Fix any real runtime bug exposed by the new specs
  • [completed] Run markdown package verification
  • [completed] Record learnings and final results

Findings

  • markdown already has broad deserializer/serializer coverage, but several helper seams are still only covered indirectly.
  • High-ROI direct seams are:
    • stripMarkdown*
    • parseAttributes / propsToAttributes
    • tagRemarkPlugin / getRemarkPluginsWithoutMdx
    • getCustomMark
    • markdownToSlateNodesSafely
  • markdownToSlateNodesSafely currently drops already-parsed content when the last complete block is void and the input ends with incomplete MDX. Example probe: "<hr /><u>" returns only a paragraph with "<u>", losing the horizontal rule.

Progress

  • Re-read the phase-4 plan, task.mdc, testing.mdc, planning-with-files, tdd, and changeset guidance.
  • Audited markdown package structure, existing specs, and helper/test harnesses.
  • Probed live markdownToSlateNodesSafely output with a temporary Bun script to identify public behavior and confirm a likely fallback bug.
  • Added focused markdown helper specs for:
    • stripMarkdown*
    • parseAttributes / propsToAttributes
    • tagRemarkPlugin / getRemarkPluginsWithoutMdx
    • getCustomMark
  • Added a focused markdownToSlateNodesSafely suite covering:
    • normal markdown passthrough
    • incomplete MDX appended to a non-void block
    • no-complete-block fallback
    • void-block preservation
  • Fixed markdownToSlateNodesSafely so incomplete-MDX fallback appends a new paragraph after a complete void block instead of dropping the already-parsed node.
  • Added a patch changeset for @platejs/markdown.

Verification

  • bun test packages/markdown/src/lib/deserializer/utils/stripMarkdown.spec.ts packages/markdown/src/lib/rules/utils/parseAttributes.spec.ts packages/markdown/src/lib/utils/getRemarkPluginsWithoutMdx.spec.ts packages/markdown/src/lib/serializer/utils/getCustomMark.spec.ts packages/markdown/src/lib/deserializer/utils/markdownToSlateNodesSafely.spec.tsx
  • bun test packages/markdown/src
  • bun run test:slowest -- --top 15 packages/markdown/src
  • pnpm install
  • pnpm turbo build --filter=./packages/markdown
    • failed before package code execution in rolldown / Node 20.12.1 with ERR_INVALID_ARG_VALUE from node:util.styleText
  • NO_COLOR=1 pnpm turbo build --filter=./packages/markdown
    • failed with the same external tooling error
  • pnpm lint:fix
  • bun test packages/markdown/src (post-lint rerun)

Learnings

  • package reality: markdownToSlateNodesSafely had a real content-loss bug on the incomplete-MDX fallback path when the fully parsed prefix ended in a void node.
  • package reality: the safe fallback should preserve complete parsed output and append the fallback paragraph, not replace the whole result set.
  • verification blocker: package build is currently blocked outside slice scope by a rolldown + Node 20.12.1 styleText call that passes ['underline', 'gray'] where Node expects a single format string.