{"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 blockCharDelayRef = useRef<Map<number, number>>(new Map());\n  const blockBirthsRef = useRef<Map<number, number[]>>(new Map());\n\n  const renderNow = getNow();\n\n  const birthsResult = useMemo(() => {\n    const start = profiler ? getNow() : 0;\n    const nextBirths = new Map<number, number[]>();\n    const prevBirths = blockBirthsRef.current;\n\n    for (const [index, block] of blocks.entries()) {\n      const state = getBlockState(index);\n      // Queued blocks are not rendered. Defer birth assignment so that\n      // when the block later transitions to animating/streaming, its\n      // chars start fading from that moment instead of having already\n      // \"aged out\" of the fade window.\n      if (state === 'queued') continue;\n\n      const blockCharCount = countChars(block.content);\n      const prev = prevBirths.get(block.startOffset);\n      let arr: number[];\n\n      if (prev && prev.length === blockCharCount) {\n        arr = prev;\n      } else if (prev && prev.length > blockCharCount) {\n        // Block content shrunk (stream restart or upstream rewrite).\n        arr = prev.slice(0, blockCharCount);\n      } else {\n        arr = prev ? prev.slice() : [];\n        const startIdx = arr.length;\n        // Chain each new char monotonically after the previous one so fades\n        // never race out of order. Cap how far the fade queue can run ahead\n        // of renderNow to prevent stream-faster-than-fade producing seconds\n        // of invisible backlog at the tail.\n        const cap = renderNow + STREAM_FADE_DURATION;\n        for (let i = startIdx; i < blockCharCount; i++) {\n          const prevBirth = i > 0 ? (arr[i - 1] as number) : renderNow - charDelay;\n          const chained = prevBirth + charDelay;\n          arr.push(Math.min(cap, Math.max(chained, renderNow)));\n        }\n      }\n\n      nextBirths.set(block.startOffset, arr);\n    }\n\n    return {\n      durationMs: profiler ? getNow() - start : 0,\n      value: nextBirths,\n    };\n  }, [blocks, charDelay, getBlockState, profiler, renderNow]);\n  const birthsForRender = birthsResult.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: birthsResult.durationMs,\n      itemCount: blocks.length,\n      name: 'block-births',\n      textLength: processedContent.length,\n    });\n  }, [birthsResult.durationMs, blocks.length, processedContent.length, profiler]);\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 births = birthsForRender.get(block.startOffset);\n      const lastBirthTs = births && births.length > 0 ? (births.at(-1) ?? renderNow) : renderNow;\n      const lastElapsedMs = renderNow - lastBirthTs;\n      const animationMeta = resolveBlockAnimationMeta({\n        currentCharDelay: charDelay,\n        fadeDuration: STREAM_FADE_DURATION,\n        lastElapsedMs,\n        previousCharDelay: blockCharDelayRef.current.get(block.startOffset),\n        state,\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  }, [birthsForRender, blocks, charDelay, getBlockState, renderNow]);\n\n  useEffect(() => {\n    blockCharDelayRef.current = blockAnimationMetaResult.blockCharDelay;\n    blockBirthsRef.current = birthsForRender;\n  }, [birthsForRender, blockAnimationMetaResult.blockCharDelay]);\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 births = birthsForRender.get(block.startOffset);\n        const plugins: Pluggable[] = animationMeta.settled\n          ? [...baseRehypePlugins, REVEALED_STREAM_PLUGIN]\n          : [\n              ...baseRehypePlugins,\n              [\n                rehypeStreamAnimated,\n                {\n                  births,\n                  fadeDuration: STREAM_FADE_DURATION,\n                  nowMs: renderNow,\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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"}