{"version":3,"file":"StreamdownRender.mjs","names":[],"sources":["../../../src/Markdown/SyntaxMarkdown/StreamdownRender.tsx"],"sourcesContent":["'use client';\n\nimport { marked } from 'marked';\nimport {\n  memo,\n  Profiler,\n  type ProfilerOnRenderCallback,\n  useCallback,\n  useEffect,\n  useId,\n  useMemo,\n  useRef,\n} from 'react';\nimport Markdown, { type Options } from 'react-markdown';\nimport remend from 'remend';\nimport type { Pluggable, PluggableList } from 'unified';\n\nimport {\n  useMarkdownComponents,\n  useMarkdownContent,\n  useMarkdownRehypePlugins,\n  useMarkdownRemarkPlugins,\n} from '@/hooks/useMarkdown';\nimport { useMarkdownContext } from '@/Markdown/components/MarkdownProvider';\nimport { rehypeStreamAnimated } from '@/Markdown/plugins/rehypeStreamAnimated';\nimport { useStreamdownProfiler } from '@/Markdown/streamProfiler';\n\nimport { resolveBlockAnimationMeta } from './streamAnimationMeta';\nimport { styles } from './style';\nimport { useSmoothStreamContent } from './useSmoothStreamContent';\nimport { type BlockInfo, useStreamQueue } from './useStreamQueue';\n\nconst STREAM_FADE_DURATION = 280;\nconst REVEALED_STREAM_PLUGIN: Pluggable = [rehypeStreamAnimated, { revealed: true }];\n\nfunction countChars(text: string): number {\n  return [...text].length;\n}\n\nfunction getNow(): number {\n  return typeof performance === 'undefined' ? Date.now() : performance.now();\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n  typeof value === 'object' && value !== null;\n\nconst isDeepEqualValue = (a: unknown, b: unknown): boolean => {\n  if (a === b) return true;\n\n  if (Array.isArray(a) || Array.isArray(b)) {\n    if (!Array.isArray(a) || !Array.isArray(b)) return false;\n    if (a.length !== b.length) return false;\n    for (let i = 0; i < a.length; i++) {\n      if (!isDeepEqualValue(a[i], b[i])) return false;\n    }\n    return true;\n  }\n\n  if (!isRecord(a) || !isRecord(b)) return false;\n\n  const keysA = Object.keys(a);\n  const keysB = Object.keys(b);\n  if (keysA.length !== keysB.length) return false;\n\n  for (const key of keysA) {\n    if (!isDeepEqualValue(a[key], b[key])) return false;\n  }\n\n  return true;\n};\n\nconst isSamePlugin = (prevPlugin: Pluggable, nextPlugin: Pluggable): boolean => {\n  const prevTuple = Array.isArray(prevPlugin) ? prevPlugin : [prevPlugin];\n  const nextTuple = Array.isArray(nextPlugin) ? nextPlugin : [nextPlugin];\n\n  if (prevTuple.length !== nextTuple.length) return false;\n  if (prevTuple[0] !== nextTuple[0]) return false;\n\n  return isDeepEqualValue(prevTuple.slice(1), nextTuple.slice(1));\n};\n\nconst isSamePlugins = (\n  prevPlugins?: PluggableList | null,\n  nextPlugins?: PluggableList | null,\n): boolean => {\n  if (prevPlugins === nextPlugins) return true;\n  if (!prevPlugins || !nextPlugins) return !prevPlugins && !nextPlugins;\n  if (prevPlugins.length !== nextPlugins.length) return false;\n\n  for (let i = 0; i < prevPlugins.length; i++) {\n    if (!isSamePlugin(prevPlugins[i], nextPlugins[i])) return false;\n  }\n\n  return true;\n};\n\nconst useStablePlugins = (plugins: PluggableList): PluggableList => {\n  const stableRef = useRef<PluggableList>(plugins);\n\n  if (!isSamePlugins(stableRef.current, plugins)) {\n    stableRef.current = plugins;\n  }\n\n  return stableRef.current;\n};\n\nconst StreamdownBlock = memo<Options>(\n  ({ children, ...rest }) => {\n    return <Markdown {...rest}>{children}</Markdown>;\n  },\n  (prevProps, nextProps) =>\n    prevProps.children === nextProps.children &&\n    prevProps.components === nextProps.components &&\n    isSamePlugins(prevProps.rehypePlugins, nextProps.rehypePlugins) &&\n    isSamePlugins(prevProps.remarkPlugins, nextProps.remarkPlugins),\n);\n\nStreamdownBlock.displayName = 'StreamdownBlock';\n\nexport const StreamdownRender = memo<Options>(({ children, ...rest }) => {\n  const { streamSmoothingPreset = 'balanced' } = useMarkdownContext();\n  const profiler = useStreamdownProfiler();\n  const escapedContent = useMarkdownContent(children || '');\n  const components = useMarkdownComponents();\n  const baseRehypePlugins = useStablePlugins(useMarkdownRehypePlugins());\n  const remarkPlugins = useStablePlugins(useMarkdownRemarkPlugins());\n  const generatedId = useId();\n  const smoothedContent = useSmoothStreamContent(\n    typeof escapedContent === 'string' ? escapedContent : '',\n    { preset: streamSmoothingPreset },\n  );\n\n  const processedContentResult = useMemo(() => {\n    const start = profiler ? getNow() : 0;\n    const value = remend(smoothedContent);\n\n    return {\n      durationMs: profiler ? getNow() - start : 0,\n      value,\n    };\n  }, [profiler, smoothedContent]);\n  const processedContent = processedContentResult.value;\n\n  const blocksResult = useMemo(() => {\n    const start = profiler ? getNow() : 0;\n    const tokens = marked.lexer(processedContent);\n    let offset = 0;\n\n    const value = tokens.map((token) => {\n      const block = { content: token.raw, startOffset: offset };\n      offset += token.raw.length;\n      return block;\n    });\n\n    return {\n      durationMs: profiler ? getNow() - start : 0,\n      value,\n    };\n  }, [processedContent, profiler]);\n  const blocks: BlockInfo[] = blocksResult.value;\n\n  const { getBlockState, charDelay } = useStreamQueue(blocks);\n  const prevBlockCharCountRef = useRef<Map<number, number>>(new Map());\n  const blockCharDelayRef = useRef<Map<number, number>>(new Map());\n  const blockTimelineRef = useRef<Map<number, number>>(new Map());\n  const lastRenderTsRef = useRef<number | null>(null);\n\n  const renderTs = getNow();\n  const frameDt =\n    lastRenderTsRef.current === null\n      ? 0\n      : Math.max(0, Math.min(renderTs - lastRenderTsRef.current, 120));\n\n  const timelineResult = useMemo(() => {\n    const start = profiler ? getNow() : 0;\n    const next = new Map<number, number>();\n    const prevTimeline = blockTimelineRef.current;\n    const prevCharCounts = prevBlockCharCountRef.current;\n\n    for (const block of blocks) {\n      const blockCharCount = countChars(block.content);\n      const prevCharCount = prevCharCounts.get(block.startOffset) ?? 0;\n      const prevElapsed = prevTimeline.get(block.startOffset);\n      const latestCharStart = Math.max(0, (blockCharCount - 1) * charDelay);\n\n      if (prevElapsed === undefined || blockCharCount < prevCharCount) {\n        next.set(block.startOffset, latestCharStart);\n        continue;\n      }\n\n      const elapsedByTime = prevElapsed + frameDt;\n      // Avoid huge hidden backlog when stream updates in bursts.\n      const minElapsed = Math.max(0, latestCharStart - charDelay * 2);\n      next.set(block.startOffset, Math.max(elapsedByTime, minElapsed));\n    }\n\n    return {\n      durationMs: profiler ? getNow() - start : 0,\n      value: next,\n    };\n  }, [blocks, charDelay, frameDt, profiler]);\n  const timelineForRender = timelineResult.value;\n\n  useEffect(() => {\n    if (!profiler) return;\n\n    profiler.recordCalculation({\n      durationMs: processedContentResult.durationMs,\n      name: 'content-normalize',\n      textLength: processedContent.length,\n    });\n  }, [processedContent.length, processedContentResult.durationMs, profiler]);\n\n  useEffect(() => {\n    if (!profiler) return;\n\n    profiler.recordCalculation({\n      durationMs: blocksResult.durationMs,\n      itemCount: blocks.length,\n      name: 'block-lex',\n      textLength: processedContent.length,\n    });\n  }, [blocks.length, blocksResult.durationMs, processedContent.length, profiler]);\n\n  useEffect(() => {\n    if (!profiler) return;\n\n    profiler.recordCalculation({\n      durationMs: timelineResult.durationMs,\n      itemCount: blocks.length,\n      name: 'block-timeline',\n      textLength: processedContent.length,\n    });\n  }, [blocks.length, processedContent.length, profiler, timelineResult.durationMs]);\n\n  const blockAnimationMetaResult = useMemo(() => {\n    const nextBlockCharDelay = new Map<number, number>();\n    const blockAnimationMeta = new Map<number, ReturnType<typeof resolveBlockAnimationMeta>>();\n\n    for (const [index, block] of blocks.entries()) {\n      const state = getBlockState(index);\n      const timelineElapsedMs = timelineForRender.get(block.startOffset) ?? 0;\n      const animationMeta = resolveBlockAnimationMeta({\n        blockCharCount: countChars(block.content),\n        currentCharDelay: charDelay,\n        fadeDuration: STREAM_FADE_DURATION,\n        previousCharDelay: blockCharDelayRef.current.get(block.startOffset),\n        state,\n        timelineElapsedMs,\n      });\n\n      nextBlockCharDelay.set(block.startOffset, animationMeta.charDelay);\n      blockAnimationMeta.set(block.startOffset, animationMeta);\n    }\n\n    return {\n      blockAnimationMeta,\n      blockCharDelay: nextBlockCharDelay,\n    };\n  }, [blocks, charDelay, getBlockState, timelineForRender]);\n\n  useEffect(() => {\n    const nextCharCount = new Map<number, number>();\n    for (const block of blocks) {\n      nextCharCount.set(block.startOffset, countChars(block.content));\n    }\n    blockCharDelayRef.current = blockAnimationMetaResult.blockCharDelay;\n    prevBlockCharCountRef.current = nextCharCount;\n    blockTimelineRef.current = timelineForRender;\n    lastRenderTsRef.current = getNow();\n  }, [blockAnimationMetaResult.blockCharDelay, blocks, timelineForRender]);\n\n  const handleRootRender = useCallback<ProfilerOnRenderCallback>(\n    (_, phase, actualDuration, baseDuration) => {\n      profiler?.recordRootCommit({\n        actualDuration,\n        baseDuration,\n        blockCount: blocks.length,\n        phase,\n        textLength: processedContent.length,\n      });\n    },\n    [blocks.length, processedContent.length, profiler],\n  );\n\n  const handleBlockRender = useCallback<ProfilerOnRenderCallback>(\n    (id, phase, actualDuration, baseDuration) => {\n      if (!profiler) return;\n\n      const [, indexText, offsetText] = id.split(':');\n      const blockIndex = Number(indexText);\n\n      if (!Number.isFinite(blockIndex)) return;\n\n      const block = blocks[blockIndex];\n      if (!block) return;\n\n      profiler.recordBlockCommit({\n        actualDuration,\n        baseDuration,\n        blockChars: countChars(block.content),\n        blockIndex,\n        blockKey: offsetText ?? String(block.startOffset),\n        phase,\n        state: getBlockState(blockIndex),\n      });\n    },\n    [blocks, getBlockState, profiler],\n  );\n\n  const content = (\n    <div className={styles.animated}>\n      {blocks.map((block, index) => {\n        const state = getBlockState(index);\n        if (state === 'queued') return null;\n        const animationMeta = blockAnimationMetaResult.blockAnimationMeta.get(block.startOffset);\n        if (!animationMeta) return null;\n\n        const plugins: Pluggable[] = animationMeta.settled\n          ? [...baseRehypePlugins, REVEALED_STREAM_PLUGIN]\n          : [\n              ...baseRehypePlugins,\n              [\n                rehypeStreamAnimated,\n                {\n                  charDelay: animationMeta.charDelay,\n                  fadeDuration: STREAM_FADE_DURATION,\n                  timelineElapsedMs: animationMeta.timelineElapsedMs,\n                },\n              ],\n            ];\n\n        const key = `${generatedId}-${block.startOffset}`;\n        const blockNode = (\n          <StreamdownBlock\n            {...rest}\n            components={components}\n            rehypePlugins={plugins}\n            remarkPlugins={remarkPlugins}\n          >\n            {block.content}\n          </StreamdownBlock>\n        );\n\n        if (!profiler) {\n          return (\n            <StreamdownBlock\n              {...rest}\n              components={components}\n              key={key}\n              rehypePlugins={plugins}\n              remarkPlugins={remarkPlugins}\n            >\n              {block.content}\n            </StreamdownBlock>\n          );\n        }\n\n        return (\n          <Profiler\n            id={`streamdown-block:${index}:${block.startOffset}`}\n            key={key}\n            onRender={handleBlockRender}\n          >\n            {blockNode}\n          </Profiler>\n        );\n      })}\n    </div>\n  );\n\n  if (!profiler) return content;\n\n  return (\n    <Profiler id={'streamdown-root'} onRender={handleRootRender}>\n      {content}\n    </Profiler>\n  );\n});\n\nStreamdownRender.displayName = 'StreamdownRender';\n\nexport default StreamdownRender;\n"],"mappings":"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"}