{"version":3,"sources":["../../../src/pm/react/index.ts","../../../src/pm/extensionRenderer.ts","../../../src/helpers.ts","../../../src/pm/react/react.ts","../../../src/json/react/react.ts","../../../src/json/renderer.ts"],"sourcesContent":["export * from '../extensionRenderer.js'\nexport * from './react.js'\n","/* oslint-disable no-plusplus */\n/* oslint-disableno-explicit-any */\n\nimport type {\n  ExtensionAttribute,\n  Extensions,\n  JSONContent,\n  Mark as MarkExtension,\n  MarkConfig,\n  Node as NodeExtension,\n  NodeConfig,\n} from '@tiptap/core'\nimport {\n  extensions as coreExtensions,\n  getAttributesFromExtensions,\n  getExtensionField,\n  getSchemaByResolvedExtensions,\n  resolveExtensions,\n  splitExtensions,\n} from '@tiptap/core'\nimport type { DOMOutputSpec, Mark } from '@tiptap/pm/model'\nimport { Node } from '@tiptap/pm/model'\n\nimport { getHTMLAttributes } from '../helpers.js'\nimport type { MarkProps, NodeProps, TiptapStaticRendererOptions } from '../json/renderer.js'\n\nexport type DomOutputSpecToElement<T> = (content: DOMOutputSpec) => (children?: T | T[]) => T\n\n/**\n * Options that mirror a subset of `EditorOptions` and affect rendered output.\n * Kept narrow on purpose: only options whose effect is reproducible without an\n * `Editor` instance belong here.\n */\nexport type StaticEditorOptions = {\n  /**\n   * Sets the text direction for all non-text nodes. Matches the `textDirection`\n   * editor option on `Editor`. The configured `TextDirection` extension is\n   * prepended to the user-supplied `extensions`; if a user-supplied\n   * `TextDirection` is also present, the user's wins (last-defined precedence —\n   * same as Editor).\n   */\n  textDirection?: 'ltr' | 'rtl' | 'auto'\n}\n\n/**\n * Apply editor-level options to the user's extension array.\n *\n * Mirrors `new Editor({ textDirection })`: the option-driven `TextDirection`\n * extension is prepended so a user-supplied `TextDirection` (which comes after)\n * can override it via tiptap's last-defined precedence for duplicate extensions.\n *\n * Known limitation: this only inspects top-level extensions. A `TextDirection`\n * bundled inside a kit (e.g. `StarterKit`) is not detected for override\n * purposes — today no shipped kit includes `TextDirection`, so this is purely\n * theoretical.\n */\nexport function applyStaticEditorOptionsToExtensions(\n  extensions: Extensions,\n  options?: StaticEditorOptions,\n): Extensions {\n  if (!options?.textDirection) {\n    return extensions\n  }\n\n  return [\n    coreExtensions.TextDirection.configure({ direction: options.textDirection }),\n    ...extensions,\n  ]\n}\n\n/**\n * This takes a NodeExtension and maps it to a React component\n * @param extension The node extension to map to a React component\n * @param extensionAttributes All available extension attributes\n * @returns A tuple with the name of the extension and a React component that renders the extension\n */\nexport function mapNodeExtensionToReactNode<T>(\n  domOutputSpecToElement: DomOutputSpecToElement<T>,\n  extension: NodeExtension,\n  extensionAttributes: ExtensionAttribute[],\n  options?: Partial<Pick<TiptapStaticRendererOptions<T, Mark, Node>, 'unhandledNode'>>,\n): [string, (props: NodeProps<Node, T | T[]>) => T] {\n  const context = {\n    name: extension.name,\n    options: extension.options,\n    storage: extension.storage,\n    parent: extension.parent,\n  }\n\n  const renderToHTML = getExtensionField<NodeConfig['renderHTML']>(extension, 'renderHTML', context)\n\n  if (!renderToHTML) {\n    if (options?.unhandledNode) {\n      return [extension.name, options.unhandledNode]\n    }\n    return [\n      extension.name,\n      () => {\n        throw new Error(\n          `[tiptap error]: Node ${extension.name} cannot be rendered, it is missing a \"renderToHTML\" method, please implement it or override the corresponding \"nodeMapping\" method to have a custom rendering`,\n        )\n      },\n    ]\n  }\n\n  return [\n    extension.name,\n    ({ node, children }) => {\n      try {\n        return domOutputSpecToElement(\n          renderToHTML({\n            node,\n            HTMLAttributes: getHTMLAttributes(node, extensionAttributes),\n          }),\n        )(children)\n      } catch (e) {\n        throw new Error(\n          `[tiptap error]: Node ${\n            extension.name\n          } cannot be rendered, it's \"renderToHTML\" method threw an error: ${(e as Error).message}`,\n          { cause: e },\n        )\n      }\n    },\n  ]\n}\n\n/**\n * This takes a MarkExtension and maps it to a React component\n * @param extension The mark extension to map to a React component\n * @param extensionAttributes All available extension attributes\n * @returns A tuple with the name of the extension and a React component that renders the extension\n */\nexport function mapMarkExtensionToReactNode<T>(\n  domOutputSpecToElement: DomOutputSpecToElement<T>,\n  extension: MarkExtension,\n  extensionAttributes: ExtensionAttribute[],\n  options?: Partial<Pick<TiptapStaticRendererOptions<T, Mark, Node>, 'unhandledMark'>>,\n): [string, (props: MarkProps<Mark, T | T[]>) => T] {\n  const context = {\n    name: extension.name,\n    options: extension.options,\n    storage: extension.storage,\n    parent: extension.parent,\n  }\n\n  const renderToHTML = getExtensionField<MarkConfig['renderHTML']>(extension, 'renderHTML', context)\n\n  if (!renderToHTML) {\n    if (options?.unhandledMark) {\n      return [extension.name, options.unhandledMark]\n    }\n    return [\n      extension.name,\n      () => {\n        throw new Error(\n          `Node ${extension.name} cannot be rendered, it is missing a \"renderToHTML\" method`,\n        )\n      },\n    ]\n  }\n\n  return [\n    extension.name,\n    ({ mark, children }) => {\n      try {\n        return domOutputSpecToElement(\n          renderToHTML({\n            mark,\n            HTMLAttributes: getHTMLAttributes(mark, extensionAttributes),\n          }),\n        )(children)\n      } catch (e) {\n        throw new Error(\n          `[tiptap error]: Mark ${\n            extension.name\n          } cannot be rendered, it's \"renderToHTML\" method threw an error: ${(e as Error).message}`,\n          { cause: e },\n        )\n      }\n    },\n  ]\n}\n\n/**\n * This function will statically render a Prosemirror Node to a target element type using the given extensions\n * @param renderer The renderer to use to render the Prosemirror Node to the target element type\n * @param domOutputSpecToElement A function that takes a Prosemirror DOMOutputSpec and returns a function that takes children and returns the target element type\n * @param mapDefinedTypes An object with functions to map the doc and text types to the target element type\n * @param content The Prosemirror Node to render\n * @param extensions The extensions to use to render the Prosemirror Node\n * @param options Additional options to pass to the renderer that can override the default behavior\n * @returns The rendered target element type\n */\nexport function renderToElement<T>({\n  renderer,\n  domOutputSpecToElement,\n  mapDefinedTypes,\n  content,\n  extensions,\n  options,\n}: {\n  renderer: (options: TiptapStaticRendererOptions<T, Mark, Node>) => (ctx: { content: Node }) => T\n  domOutputSpecToElement: DomOutputSpecToElement<T>\n  mapDefinedTypes: {\n    doc: (props: NodeProps<Node, T | T[]>) => T\n    text: (props: NodeProps<Node, T | T[]>) => T\n  }\n  content: Node | JSONContent\n  extensions: Extensions\n  options?: Partial<TiptapStaticRendererOptions<T, Mark, Node>>\n}): T {\n  // get all extensions in order & split them into nodes and marks\n  extensions = resolveExtensions(extensions)\n  const extensionAttributes = getAttributesFromExtensions(extensions)\n  const { nodeExtensions, markExtensions } = splitExtensions(extensions)\n\n  if (!(content instanceof Node)) {\n    content = Node.fromJSON(getSchemaByResolvedExtensions(extensions), content)\n  }\n\n  return renderer({\n    ...options,\n    nodeMapping: {\n      ...Object.fromEntries(\n        nodeExtensions\n          .filter(e => {\n            if (e.name in mapDefinedTypes) {\n              // These are predefined types that we don't need to map\n              return false\n            }\n            // No need to generate mappings for nodes that are already mapped\n            if (options?.nodeMapping) {\n              return !(e.name in options.nodeMapping)\n            }\n            return true\n          })\n          .map(nodeExtension =>\n            mapNodeExtensionToReactNode<T>(\n              domOutputSpecToElement,\n              nodeExtension,\n              extensionAttributes,\n              options,\n            ),\n          ),\n      ),\n      ...mapDefinedTypes,\n      ...options?.nodeMapping,\n    },\n    markMapping: {\n      ...Object.fromEntries(\n        markExtensions\n          .filter(e => {\n            // No need to generate mappings for marks that are already mapped\n            if (options?.markMapping) {\n              return !(e.name in options.markMapping)\n            }\n            return true\n          })\n          .map(mark =>\n            mapMarkExtensionToReactNode<T>(\n              domOutputSpecToElement,\n              mark,\n              extensionAttributes,\n              options,\n            ),\n          ),\n      ),\n      ...options?.markMapping,\n    },\n  })({ content })\n}\n","/* oslint-disableno-explicit-any */\nimport {\n  type ExtensionAttribute,\n  type MarkType,\n  type NodeType,\n  mergeAttributes,\n} from '@tiptap/core'\n\n/**\n * This function returns the attributes of a node or mark that are defined by the given extension attributes.\n * @param nodeOrMark The node or mark to get the attributes from\n * @param extensionAttributes The extension attributes to use\n * @param onlyRenderedAttributes If true, only attributes that are rendered in the HTML are returned\n */\nexport function getAttributes(\n  nodeOrMark: NodeType | MarkType,\n  extensionAttributes: ExtensionAttribute[],\n  onlyRenderedAttributes?: boolean,\n): Record<string, any> {\n  const nodeOrMarkAttributes = nodeOrMark.attrs\n\n  if (!nodeOrMarkAttributes) {\n    return {}\n  }\n\n  return extensionAttributes\n    .filter(item => {\n      if (\n        item.type !== (typeof nodeOrMark.type === 'string' ? nodeOrMark.type : nodeOrMark.type.name)\n      ) {\n        return false\n      }\n      if (onlyRenderedAttributes) {\n        return item.attribute.rendered\n      }\n      return true\n    })\n    .map(item => {\n      if (!item.attribute.renderHTML) {\n        return {\n          [item.name]:\n            item.name in nodeOrMarkAttributes\n              ? nodeOrMarkAttributes[item.name]\n              : item.attribute.default,\n        }\n      }\n\n      return (\n        item.attribute.renderHTML(nodeOrMarkAttributes) || {\n          [item.name]:\n            item.name in nodeOrMarkAttributes\n              ? nodeOrMarkAttributes[item.name]\n              : item.attribute.default,\n        }\n      )\n    })\n    .reduce((attributes, attribute) => mergeAttributes(attributes, attribute), {})\n}\n\n/**\n * This function returns the HTML attributes of a node or mark that are defined by the given extension attributes.\n * @param nodeOrMark The node or mark to get the attributes from\n * @param extensionAttributes The extension attributes to use\n */\nexport function getHTMLAttributes(\n  nodeOrMark: NodeType | MarkType,\n  extensionAttributes: ExtensionAttribute[],\n) {\n  return getAttributes(nodeOrMark, extensionAttributes, true)\n}\n","/* oslint-disable no-plusplus,no-explicit-any */\nimport type { DOMOutputSpecArray, Extensions, JSONContent } from '@tiptap/core'\nimport type { DOMOutputSpec, Mark, Node } from '@tiptap/pm/model'\nimport React from 'react'\n\nimport { renderJSONContentToReactElement } from '../../json/react/react.js'\nimport type { TiptapStaticRendererOptions } from '../../json/renderer.js'\nimport type { StaticEditorOptions } from '../extensionRenderer.js'\nimport { applyStaticEditorOptionsToExtensions, renderToElement } from '../extensionRenderer.js'\n\n/**\n * This function maps the attributes of a node or mark to HTML attributes\n * @param attrs The attributes to map\n * @param key The key to use for the React element\n * @returns The mapped HTML attributes as an object\n */\nexport function mapAttrsToHTMLAttributes(\n  attrs?: Record<string, any>,\n  key?: string,\n): Record<string, any> {\n  if (!attrs) {\n    return { key }\n  }\n  return Object.entries(attrs).reduce(\n    (acc, [name, value]) => {\n      if (name === 'class') {\n        return Object.assign(acc, { className: value })\n      }\n\n      // React expects styles to be a object\n      // so we need to convert it from string to object\n      if (name === 'style' && typeof value === 'string') {\n        const styleObject: Record<string, string> = {}\n        value.split(';').forEach(style => {\n          const [styleKey, val] = style.split(':')\n          if (styleKey && val) {\n            // we need to turn the key into camelCase\n            const camelCaseKey = styleKey.trim().replace(/-([a-z])/g, g => g[1].toUpperCase())\n            styleObject[camelCaseKey] = val.trim()\n          }\n        })\n\n        return Object.assign(acc, { style: styleObject })\n      }\n\n      return Object.assign(acc, { [name]: value })\n    },\n    { key },\n  )\n}\n\n/**\n * Take a DOMOutputSpec and return a function that can render it to a React element\n * @param content The DOMOutputSpec to convert to a React element\n * @returns A function that can render the DOMOutputSpec to a React element\n */\nexport function domOutputSpecToReactElement(\n  content: DOMOutputSpec,\n  key = 0,\n): (children?: React.ReactNode) => React.ReactNode {\n  if (typeof content === 'string') {\n    return () => content\n  }\n  if (typeof content === 'object' && 'length' in content) {\n    // oxlint-disable-next-line prefer-const\n    let [tag, attrs, children, ...rest] = content as DOMOutputSpecArray\n    const parts = tag.split(' ')\n\n    if (parts.length > 1) {\n      tag = parts[1]\n      if (attrs === undefined) {\n        attrs = {\n          xmlns: parts[0],\n        }\n      }\n      if (attrs === 0) {\n        attrs = {\n          xmlns: parts[0],\n        }\n        children = 0\n      }\n      if (typeof attrs === 'object') {\n        attrs = Object.assign(attrs, { xmlns: parts[0] })\n      }\n    }\n\n    if (attrs === undefined) {\n      return () => React.createElement(tag, mapAttrsToHTMLAttributes(undefined, key.toString()))\n    }\n    if (attrs === 0) {\n      return child =>\n        React.createElement(tag, mapAttrsToHTMLAttributes(undefined, key.toString()), child)\n    }\n    if (typeof attrs === 'object') {\n      if (Array.isArray(attrs)) {\n        if (children === undefined) {\n          return child =>\n            React.createElement(\n              tag,\n              mapAttrsToHTMLAttributes(undefined, key.toString()),\n              domOutputSpecToReactElement(attrs as DOMOutputSpecArray, key++)(child),\n            )\n        }\n        if (children === 0) {\n          return child =>\n            React.createElement(\n              tag,\n              mapAttrsToHTMLAttributes(undefined, key.toString()),\n              domOutputSpecToReactElement(attrs as DOMOutputSpecArray, key++)(child),\n            )\n        }\n        return child =>\n          React.createElement(\n            tag,\n            mapAttrsToHTMLAttributes(undefined, key.toString()),\n            domOutputSpecToReactElement(attrs as DOMOutputSpecArray)(child),\n            [children]\n              .concat(rest)\n              .map(outputSpec => domOutputSpecToReactElement(outputSpec, key++)(child)),\n          )\n      }\n      if (children === undefined) {\n        return () => React.createElement(tag, mapAttrsToHTMLAttributes(attrs, key.toString()))\n      }\n      if (children === 0) {\n        return child =>\n          React.createElement(tag, mapAttrsToHTMLAttributes(attrs, key.toString()), child)\n      }\n\n      return child =>\n        React.createElement(\n          tag,\n          mapAttrsToHTMLAttributes(attrs, key.toString()),\n          [children]\n            .concat(rest)\n            .map(outputSpec => domOutputSpecToReactElement(outputSpec, key++)(child)),\n        )\n    }\n  }\n\n  // TODO support DOM elements? How to handle them?\n  throw new Error(\n    '[tiptap error]: Unsupported DomOutputSpec type, check the `renderHTML` method output or implement a node mapping',\n    {\n      cause: content,\n    },\n  )\n}\n\n/**\n * This function will statically render a Prosemirror Node to a React component using the given extensions.\n *\n * Limitations: see `renderToHTMLString` — extensions that mutate the document\n * via plugins/onCreate (UniqueID, TableOfContents) need to be pre-processed.\n *\n * @param content The content to render to a React component\n * @param extensions The extensions to use for rendering\n * @param staticEditorOptions Optional editor-level options that affect rendered output — mirrors a subset of `EditorOptions`.\n * @param options The options to use for rendering\n * @returns The React element that represents the rendered content\n */\nexport function renderToReactElement({\n  content,\n  extensions,\n  staticEditorOptions,\n  options,\n}: {\n  content: Node | JSONContent\n  extensions: Extensions\n  staticEditorOptions?: StaticEditorOptions\n  options?: Partial<TiptapStaticRendererOptions<React.ReactNode, Mark, Node>>\n}): React.ReactNode {\n  return renderToElement<React.ReactNode>({\n    renderer: renderJSONContentToReactElement,\n    domOutputSpecToElement: domOutputSpecToReactElement,\n    mapDefinedTypes: {\n      // Map a doc node to concatenated children\n      doc: ({ children }) => React.createElement(React.Fragment, {}, children),\n      // Map a text node to its text content\n      text: ({ node }) => node.text ?? '',\n    },\n    content,\n    extensions: applyStaticEditorOptionsToExtensions(extensions, staticEditorOptions),\n    options,\n  })\n}\n","/* oslint-disableno-explicit-any */\n\nimport React from 'react'\n\nimport type { JSONMarkType, JSONNodeType, TiptapStaticRendererOptions } from '../renderer.js'\nimport { TiptapStaticRenderer } from '../renderer.js'\n\nexport function renderJSONContentToReactElement<\n  /**\n   * A mark type is either a JSON representation of a mark or a Prosemirror mark instance\n   */\n  TMarkType extends { type: any } = JSONMarkType,\n  /**\n   * A node type is either a JSON representation of a node or a Prosemirror node instance\n   */\n  TNodeType extends {\n    content?: { forEach: (cb: (node: TNodeType) => void) => void }\n    marks?: readonly TMarkType[]\n    type?: string | { name: string }\n  } = JSONNodeType<TMarkType>,\n>(options: TiptapStaticRendererOptions<React.ReactNode, TMarkType, TNodeType>) {\n  let key = 0\n\n  return TiptapStaticRenderer<React.ReactNode, TMarkType, TNodeType>(\n    ({ component, props: { children, ...props } }) => {\n      return React.createElement(\n        component as React.FC<typeof props>,\n        // oxlint-disable-next-line no-plusplus\n        Object.assign(props, { key: key++ }),\n        ([] as React.ReactNode[]).concat(children),\n      )\n    },\n    options,\n  )\n}\n","/* oslint-disableno-explicit-any */\nimport type { JSONContent } from '@tiptap/core'\n\n/**\n * A JSON representation of a mark (a Tiptap/ProseMirror mark serialized to JSON).\n */\nexport type JSONMarkType = NonNullable<JSONContent['marks']>[number]\n\n/**\n * A JSON representation of a node (a Tiptap/ProseMirror node serialized to JSON).\n *\n * `marks` is tied to the `TMark` type parameter so the node<->mark relationship\n * stays sound. This is also why we cannot simply default `TNodeType` to\n * `JSONContent`: the generic constraint references `TMarkType` via\n * `marks?: readonly TMarkType[]`, and `JSONContent.marks` is a *concrete* array,\n * which TypeScript rejects (\"TMarkType could be instantiated with a different\n * subtype of constraint\"). Parameterizing the node type by the same `TMark`\n * avoids that bivariance error. Please don't \"simplify\" this back to\n * `JSONContent` — it won't type-check.\n */\nexport type JSONNodeType<TMark extends { type: string | { name: string } } = JSONMarkType> = {\n  type?: string\n  attrs?: Record<string, any>\n  content?: JSONNodeType<TMark>[]\n  marks?: readonly TMark[]\n  text?: string\n  [key: string]: any\n}\n\n/**\n * Props for a node renderer\n */\nexport type NodeProps<TNodeType = any, TChildren = any> = {\n  /**\n   * The current node to render\n   */\n  node: TNodeType\n  /**\n   * Unless the node is the root node, this will always be defined\n   */\n  parent?: TNodeType\n  /**\n   * The children of the current node\n   */\n  children?: TChildren\n  /**\n   * Render a child element\n   */\n  renderElement: (props: {\n    /**\n     * Tiptap JSON content to render\n     */\n    content: TNodeType\n    /**\n     * The parent node of the current node\n     */\n    parent?: TNodeType\n  }) => TChildren\n}\n\n/**\n * Props for a mark renderer\n */\nexport type MarkProps<TMarkType = any, TChildren = any, TNodeType = any> = {\n  /**\n   * The current mark to render\n   */\n  mark: TMarkType\n  /**\n   * The children of the current mark\n   */\n  children?: TChildren\n  /**\n   * The node the current mark is applied to\n   */\n  node: TNodeType\n  /**\n   * The node the current mark is applied to\n   */\n  parent?: TNodeType\n}\n\nexport type TiptapStaticRendererOptions<\n  /**\n   * The return type of the render function (e.g. React.ReactNode, string)\n   */\n  TReturnType,\n  /**\n   * A mark type is either a JSON representation of a mark or a Prosemirror mark instance\n   */\n  TMarkType extends { type: any } = JSONMarkType,\n  /**\n   * A node type is either a JSON representation of a node or a Prosemirror node instance\n   */\n  TNodeType extends {\n    content?: { forEach: (cb: (node: TNodeType) => void) => void }\n    marks?: readonly TMarkType[]\n    type?: string | { name: string }\n  } = JSONNodeType<TMarkType>,\n  /**\n   * A node renderer is a function that takes a node and its children and returns the rendered output\n   */\n  TNodeRender extends (ctx: NodeProps<TNodeType, TReturnType | TReturnType[]>) => TReturnType = (\n    ctx: NodeProps<TNodeType, TReturnType | TReturnType[]>,\n  ) => TReturnType,\n  /**\n   * A mark renderer is a function that takes a mark and its children and returns the rendered output\n   */\n  TMarkRender extends (\n    ctx: MarkProps<TMarkType, TReturnType | TReturnType[], TNodeType>,\n  ) => TReturnType = (\n    ctx: MarkProps<TMarkType, TReturnType | TReturnType[], TNodeType>,\n  ) => TReturnType,\n> = {\n  /**\n   * Mapping of node types to react components\n   */\n  nodeMapping: Record<string, NoInfer<TNodeRender>>\n  /**\n   * Mapping of mark types to react components\n   */\n  markMapping: Record<string, NoInfer<TMarkRender>>\n  /**\n   * Component to render if a node type is not handled\n   */\n  unhandledNode?: NoInfer<TNodeRender>\n  /**\n   * Component to render if a mark type is not handled\n   */\n  unhandledMark?: NoInfer<TMarkRender>\n}\n\n/**\n * Tiptap Static Renderer\n * ----------------------\n *\n * This function is a basis to allow for different renderers to be created.\n * Generic enough to be able to statically render Prosemirror JSON or Prosemirror Nodes.\n *\n * Using this function, you can create a renderer that takes a JSON representation of a Prosemirror document\n * and renders it using a mapping of node types to React components or even to a string.\n * This function is used as the basis to create the `reactRenderer` and `stringRenderer` functions.\n */\nexport function TiptapStaticRenderer<\n  /**\n   * The return type of the render function (e.g. React.ReactNode, string)\n   */\n  TReturnType,\n  /**\n   * A mark type is either a JSON representation of a mark or a Prosemirror mark instance\n   */\n  TMarkType extends { type: string | { name: string } } = JSONMarkType,\n  /**\n   * A node type is either a JSON representation of a node or a Prosemirror node instance\n   */\n  TNodeType extends {\n    content?: { forEach: (cb: (node: TNodeType) => void) => void }\n    marks?: readonly TMarkType[]\n    type?: string | { name: string }\n  } = JSONNodeType<TMarkType>,\n  /**\n   * A node renderer is a function that takes a node and its children and returns the rendered output\n   */\n  TNodeRender extends (ctx: NodeProps<TNodeType, TReturnType | TReturnType[]>) => TReturnType = (\n    ctx: NodeProps<TNodeType, TReturnType | TReturnType[]>,\n  ) => TReturnType,\n  /**\n   * A mark renderer is a function that takes a mark and its children and returns the rendered output\n   */\n  TMarkRender extends (\n    ctx: MarkProps<TMarkType, TReturnType | TReturnType[], TNodeType>,\n  ) => TReturnType = (\n    ctx: MarkProps<TMarkType, TReturnType | TReturnType[], TNodeType>,\n  ) => TReturnType,\n>(\n  /**\n   * The function that actually renders the component\n   */\n  renderComponent: (\n    ctx:\n      | {\n          component: TNodeRender\n          props: NodeProps<TNodeType, TReturnType | TReturnType[]>\n        }\n      | {\n          component: TMarkRender\n          props: MarkProps<TMarkType, TReturnType | TReturnType[], TNodeType>\n        },\n  ) => TReturnType,\n  {\n    nodeMapping,\n    markMapping,\n    unhandledNode,\n    unhandledMark,\n  }: TiptapStaticRendererOptions<TReturnType, TMarkType, TNodeType, TNodeRender, TMarkRender>,\n) {\n  /**\n   * Render Tiptap JSON and all its children using the provided node and mark mappings.\n   */\n  return function renderContent({\n    content,\n    parent,\n  }: {\n    /**\n     * Tiptap JSON content to render\n     */\n    content: TNodeType\n    /**\n     * The parent node of the current node\n     */\n    parent?: TNodeType\n  }): TReturnType {\n    const nodeType = typeof content.type === 'string' ? content.type : (content.type?.name ?? '')\n    const NodeHandler = nodeMapping[nodeType] ?? unhandledNode\n\n    if (!NodeHandler) {\n      throw new Error(`missing handler for node type ${nodeType}`)\n    }\n\n    const nodeContent = renderComponent({\n      component: NodeHandler,\n      props: {\n        node: content,\n        parent,\n        renderElement: renderContent,\n        // Lazily compute the children to avoid unnecessary recursion\n        get children() {\n          // recursively render child content nodes\n          const children: TReturnType[] = []\n\n          if (content.content) {\n            content.content.forEach(child => {\n              children.push(\n                renderContent({\n                  content: child,\n                  parent: content,\n                }),\n              )\n            })\n          }\n\n          return children\n        },\n      },\n    })\n\n    // apply marks to the content\n    const markedContent = content.marks\n      ? content.marks.reduce((acc, mark) => {\n          const markType = typeof mark.type === 'string' ? mark.type : mark.type.name\n          const MarkHandler = markMapping[markType] ?? unhandledMark\n\n          if (!MarkHandler) {\n            throw new Error(`missing handler for mark type ${markType}`)\n          }\n\n          return renderComponent({\n            component: MarkHandler,\n            props: {\n              mark,\n              parent,\n              node: content,\n              children: acc,\n            },\n          })\n        }, nodeContent)\n      : nodeContent\n\n    return markedContent\n  }\n}\n"],"mappings":"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","names":["import_core","coreExtensions","import_react","_a","React","React"]}