Skip to content

Fix cached MarkdownHooks tree mutation during rendering - #944

Closed
OskarEichler wants to merge 6 commits into
remarkjs:mainfrom
OskarEichler:codex/hooks-render-purity
Closed

Fix cached MarkdownHooks tree mutation during rendering#944
OskarEichler wants to merge 6 commits into
remarkjs:mainfrom
OskarEichler:codex/hooks-render-purity

Conversation

@OskarEichler

Copy link
Copy Markdown

Fix

Keep the cached HAST tree in MarkdownHooks intact across renders.

post mutates URL properties and removes/unwraps nodes. Calling it directly on hook state makes a URL transform such as url => '/proxy' + url run on its previous output on every rerender. Removed elements also cannot reappear when filtering options change, and Strict Mode exposes the repeated mutation immediately.

Copy the tree's mutable nodes, child arrays, and element property objects before processing a cached hook result. Metadata remains shared; the change does not require serializing custom data or rerunning async plugins. Synchronous Markdown and server MarkdownAsync retain their existing paths, so this introduces no extra copy there.

No new dependencies, public API changes, or breaking changes. This is a correctness fix, not a claimed performance improvement: MarkdownHooks now performs an additional linear tree copy per render.

Verification

  • All 91 existing API tests pass.
  • Targeted XO lint and Prettier checks pass; type coverage remains 100%.
  • Source-only TypeScript checking passes. The full build reports four pre-existing type mismatches in test.jsx with the resolved HAST types; the same four errors were reproduced on unmodified source. No test files or dependency ranges were changed.
  • Real React/JSDOM checks cover repeated URL transformations in normal/Strict Mode, restoring nodes after four filtering configurations, and restoring raw HTML after changing skipHtml.
  • React Doctor reports three existing warnings: broad options closure dependency analysis and an error state incorrectly classified as handler-only. The processor/file dependencies cover the fields those functions read, and the error state is thrown during render. No suppressions or tooling configuration changes are included.
  • git diff --check passes. No test files were added or changed.

@github-actions github-actions Bot added the 👋 phase/new Post is being triaged automatically label Aug 27, 2026
@github-actions

Copy link
Copy Markdown

Hi! It seems you removed the template which we require. Here are our templates (pick the one you want to use and click *raw* to see its source):

I won’t send you any further notifications about this, but I’ll keep on updating this comment, and hide it when done!

Thanks,
— bb

@remcohaszing remcohaszing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue you’re describing makes sense, but I don’t think copying the tree is the right approach. Better would be to turn this transform into a proper rehype plugin and adding that in createProcessor.

Can you also provide a test case that broke before, but is now fixed?

Also, don’t be a meat proxy. While I suspect you have good intentions, you clearly didn’t follow the pull request template. Instead, you pasted some LLM output over it.

@OskarEichler

Copy link
Copy Markdown
Author

Understood. This contribution was AI-assisted and I did not follow the repository pull request template. I am closing it rather than asking you to review the rewritten version.

@github-actions

Copy link
Copy Markdown

Hi! This was closed. Team: If this was merged, please describe when this is likely to be released. Otherwise, please add one of the no/* labels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

👋 phase/new Post is being triaged automatically

Development

Successfully merging this pull request may close these issues.

2 participants