diff --git a/packages/comark-ansi/src/render.ts b/packages/comark-ansi/src/render.ts index eadb99fa..e2139e4f 100644 --- a/packages/comark-ansi/src/render.ts +++ b/packages/comark-ansi/src/render.ts @@ -33,7 +33,10 @@ export interface RenderANSIOptions extends RenderOptions { * console.log(renderANSI(tree)) * ``` */ -export async function renderANSI(tree: ComarkTree, options?: RenderANSIOptions): Promise { +export async function renderANSI( + tree: ComarkTree | { nodes: ComarkTree['nodes'] }, + options?: RenderANSIOptions +): Promise { const colors = options?.colors ?? (typeof process !== 'undefined' ? !process.env.NO_COLOR : true) const width = options?.width ?? 80 diff --git a/packages/comark-html/src/render.ts b/packages/comark-html/src/render.ts index 79c8919a..c9ed6b07 100644 --- a/packages/comark-html/src/render.ts +++ b/packages/comark-html/src/render.ts @@ -36,6 +36,9 @@ export type ComponentRenderFn = (element: ComarkElement, ctx: RenderHTMLContext) * }) * ``` */ -export async function renderHTML(tree: ComarkTree, options?: RenderOptions): Promise { +export async function renderHTML( + tree: ComarkTree | { nodes: ComarkTree['nodes'] }, + options?: RenderOptions +): Promise { return (await render(tree, { blockSeparator: '\n', format: 'text/html', ...options })).trim() } diff --git a/packages/comark-react/src/components/ComarkRenderer.tsx b/packages/comark-react/src/components/ComarkRenderer.tsx index 96e3a4d1..e1725ec4 100644 --- a/packages/comark-react/src/components/ComarkRenderer.tsx +++ b/packages/comark-react/src/components/ComarkRenderer.tsx @@ -259,9 +259,11 @@ function renderNode( export interface ComarkRendererProps { /** - * The Comark tree to render + * The Comark tree to render — either a full `ComarkTree` or a bare + * `ComarkNode[]`. When a node array is passed, frontmatter and meta + * default to `{}` and runtime data should be supplied via `data`. */ - tree: ComarkTree + tree: ComarkTree | { nodes: ComarkTree['nodes'] } /** * Custom component mappings for element tags @@ -343,8 +345,9 @@ export const ComarkRenderer: React.FC = ({ } const renderData: NodeRenderData = { - frontmatter: tree.frontmatter, - meta: tree.meta, + frontmatter: + (tree as ComarkTree).frontmatter || (tree as unknown as { data: Record }).data || {}, + meta: (tree as ComarkTree).meta || {}, data: data || {}, props: {}, } diff --git a/packages/comark-svelte/src/components/ComarkRenderer.svelte b/packages/comark-svelte/src/components/ComarkRenderer.svelte index de35a093..3b0ef9a4 100644 --- a/packages/comark-svelte/src/components/ComarkRenderer.svelte +++ b/packages/comark-svelte/src/components/ComarkRenderer.svelte @@ -32,7 +32,7 @@ Supports custom component mappings and a streaming caret indicator. data, class: className = '', }: { - tree: ComarkTree + tree: ComarkTree | { nodes: ComarkTree['nodes'] } components?: Record componentsManifest?: ComponentManifest resolver?: ComponentResolver @@ -49,8 +49,8 @@ Supports custom component mappings and a streaming caret indicator. ) let renderData = $derived({ - frontmatter: tree.frontmatter, - meta: tree.meta, + frontmatter: (tree as ComarkTree).frontmatter || (tree as unknown as { data: Record }).data || {}, + meta: (tree as ComarkTree).meta || {}, data: data || {}, props: {}, }) diff --git a/packages/comark-vue/src/components/ComarkRenderer.ts b/packages/comark-vue/src/components/ComarkRenderer.ts index 59dab93b..8ec4d7bd 100644 --- a/packages/comark-vue/src/components/ComarkRenderer.ts +++ b/packages/comark-vue/src/components/ComarkRenderer.ts @@ -237,9 +237,11 @@ function renderNode( */ export interface ComarkRendererProps { /** - * The Comark tree to render + * The Comark tree to render — either a full `ComarkTree` or a bare + * `ComarkNode[]`. When a node array is passed, frontmatter and meta + * default to `{}` and runtime data should be supplied via `data`. */ - tree: ComarkTree + tree: ComarkTree | { nodes: ComarkTree['nodes'] } /** * Custom component mappings for element tags @@ -302,7 +304,7 @@ export const ComarkRenderer: ComarkRendererComponent = defineComponent({ * The Comark tree to render */ tree: { - type: Object as PropType, + type: Object as PropType, required: true, }, @@ -385,7 +387,8 @@ export const ComarkRenderer: ComarkRendererComponent = defineComponent({ return () => { // Render all nodes from the tree value - const nodes = toRaw(props.tree.nodes || []) || [] + const rawTree = toRaw(props.tree) + const nodes = [...(rawTree.nodes || [])] if (props.streaming && caret.value && nodes.length > 0) { const hasStreamCaret = findLastTextNodeAndAppendNode(nodes[nodes.length - 1] as ComarkElement, caret.value) @@ -395,8 +398,9 @@ export const ComarkRenderer: ComarkRendererComponent = defineComponent({ } const renderData: NodeRenderData = { - frontmatter: props.tree.frontmatter, - meta: props.tree.meta, + frontmatter: + (rawTree as ComarkTree).frontmatter || (rawTree as unknown as { data: Record }).data || {}, + meta: (rawTree as ComarkTree).meta || {}, data: props.data || {}, props: {}, } diff --git a/packages/comark/src/render.ts b/packages/comark/src/render.ts index 5cb5c003..2d30a246 100644 --- a/packages/comark/src/render.ts +++ b/packages/comark/src/render.ts @@ -17,8 +17,11 @@ export { resolveAttributes, resolveAttribute } from './internal/stringify/attrib * @param context - The context of the renderer * @returns The string representation of the Comark tree */ -export async function render(tree: ComarkTree, context: RenderOptions = {}): Promise { - const state = createState({ ...context, tree, handlers: context.components }) +export async function render( + tree: ComarkTree | { nodes: ComarkTree['nodes'] }, + context: RenderOptions = {} +): Promise { + const state = createState({ ...context, tree: tree as ComarkTree, handlers: context.components }) let result = '' for (const child of tree.nodes) { @@ -34,7 +37,10 @@ export async function render(tree: ComarkTree, context: RenderOptions = {}): Pro * @param options - Optional rendering options * @returns The markdown string with optional frontmatter */ -export async function renderMarkdown(tree: ComarkTree, options?: RenderMarkdownOptions): Promise { +export async function renderMarkdown( + tree: ComarkTree | { nodes: ComarkTree['nodes'] }, + options?: RenderMarkdownOptions +): Promise { const content = await render(tree, { format: 'markdown/comark', ...options }) - return renderFrontmatter(tree.frontmatter, content, options?.frontmatterOptions) + return renderFrontmatter((tree as ComarkTree).frontmatter || {}, content, options?.frontmatterOptions) } diff --git a/test/bundle.test.ts b/test/bundle.test.ts index c6b10345..294feff7 100644 --- a/test/bundle.test.ts +++ b/test/bundle.test.ts @@ -70,12 +70,12 @@ describe.skipIf(stubbed || process.env.SKIP_BUNDLE_SIZE === 'true')('package bun expect(report).toMatchInlineSnapshot(` { - "@comark/ansi": "34.3k (82 files)", + "@comark/ansi": "34.4k (82 files)", "@comark/html": "16.2k (42 files)", "@comark/nuxt": "10.1k (42 files)", - "@comark/react": "36.9k (56 files)", - "@comark/svelte": "39.0k (66 files)", - "@comark/vue": "54.5k (62 files)", + "@comark/react": "37.2k (56 files)", + "@comark/svelte": "39.2k (66 files)", + "@comark/vue": "54.8k (62 files)", "comark": "344k (132 files)", } `)