fix(vue): accept a parsed document in a defined component - #408
Conversation
`defineMarkdownComponent` hand-copied `<Markdown>`'s prop table, and the two had
drifted: `value` was declared `String` only, so passing an already parsed
document warned `Invalid prop: type check failed`, and `data` and `documentKey`
were missing entirely. `documentKey` never reached `<MarkdownDocument>` at all,
which is what its live-update subscription reads.
Both components now export their prop table and the wrappers reuse it, so the
two cannot drift again. `<Markdown>` declares and forwards `documentKey`.
Also replaces `Exclude<ParserOptions, 'plugins'>` with `Omit` in the six places
it appeared. `Exclude` filters union members, so on an object type it was a
no-op that resolved to plain `ParserOptions`, which let
`:options="{ plugins: [x] }"` type-check and then be silently discarded.
◈ PR Lens
Architecture 9 components touched across 3 lanes. Inside the changed components — 1 viewComponent view — Vue 3 adapter Runtime prop sharing and prop forwarding across Vue factories and components Data flow
View
Tip Set 🪧 More tips
Thanks for using PR Lens! It's built by Coldtea, free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What
defineMarkdownComponentanddefineMarkdownDocumentComponentnow reuse the prop tables exported by<Markdown>and<MarkdownDocument>instead of hand-copying them. That fixes the reportedInvalid prop: type check failedwarning when passing an already parsed document, plus two forwarding gaps, and makes the drift structurally impossible.Note
Based on #407 so the parser rebuild is a one-line
computedrather than an expensive rebuild on every prop change. Review that one first.Why
Reported from ui.nuxt.com:
<Markdown>acceptsvalue: [String, Object]and short-circuits onisMarkdownDocument, but the componentdefineMarkdownComponentreturns declaredvalue: { type: String }, so passing a parsed document warned even though it rendered correctly. The underlying cause is that the wrapper carried its own copy of the prop table, and the two had drifted three times. Fixing justvaluewould leave the next drift to be found the same way.Walkthrough
One prop table
markdownPropsandmarkdownDocumentPropsare exported from the components and the wrappers use them directly. The render calls spreadpropsrather than listing each one.A React-style spread alone would not have been enough here: in Vue, spreading
propsonly spreads declared props, sodataanddocumentKeywould still have been missed. Sharing the declaration is what actually fixes it.The three gaps this closes
valueinherits[String, Object], so a parsed document no longer warns.datais declared rather than relying on attribute fallthrough.documentKeyis declared on<Markdown>and forwarded to<MarkdownDocument>, which has been waiting for it. It is what theglobalThis.comarkContextlive-update subscription reads, and it previously needed two fallthrough hops through a component that setsclassexplicitly.Worth noting for review:
datadid already arrive via fallthrough, so only thevaluewarning anddocumentKeywere visibly broken. I verified that by reverting the change and watching exactly those two tests fail.datais pinned anyway, since fallthrough is not something to depend on.Excludewas a no-opExclude<ParserOptions, 'plugins'>appeared in six places.Excludefilters union members, so on an object type it resolves to plainParserOptions.Omitis what was meant, and it surfaces a real bug::options="{ plugins: [x] }"type-checked and was then silently discarded, because the component passesplugins: props.pluginsseparately.This is a type-level breaking change for anyone who was relying on the accident, but it only rejects code that never worked at runtime.