{"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 { 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 { useStableValue } from '@/hooks/useStableValue';\nimport { useMarkdownContext } from '@/Markdown/components/MarkdownProvider';\nimport {\n  rehypeStreamAnimated,\n  type StreamAnimatedRuntime,\n} from '@/Markdown/plugins/rehypeStreamAnimated';\nimport { useStreamdownProfiler } from '@/Markdown/streamProfiler';\nimport { type StreamAnimationGranularity } from '@/Markdown/type';\nimport { getNow } from '@/utils/getNow';\nimport { isDeepEqual } from '@/utils/isDeepEqual';\n\nimport { CachedMarkdown } from './CachedMarkdown';\nimport { type BlockAnimationMeta, resolveBlockAnimationMeta } from './streamAnimationMeta';\nimport { STREAM_FADE_DURATION, styles } from './style';\nimport { countChars, useSmoothStreamContent } from './useSmoothStreamContent';\nimport { type BlockInfo, type BlockState, useStreamQueue } from './useStreamQueue';\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 isDeepEqual(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 <CachedMarkdown {...rest}>{children}</CachedMarkdown>;\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\ninterface BlockRuntime extends StreamAnimatedRuntime {\n  charCount: number;\n  charDelay?: number;\n  rawLength: number;\n  settled: boolean;\n}\n\ninterface BlockPluginsCacheEntry {\n  base: PluggableList;\n  granularity: StreamAnimationGranularity;\n  value: PluggableList;\n}\n\ninterface UpdateBlockAnimationArgs {\n  blocks: BlockInfo[];\n  charDelay: number;\n  getBlockState: (index: number) => BlockState;\n  pluginsCache: Map<number, BlockPluginsCacheEntry>;\n  renderNow: number;\n  revealClock: { lastTs: number };\n  runtimes: Map<number, BlockRuntime>;\n}\n\nconst MIN_STREAM_CHAR_PACE_MS = 2;\nconst MAX_REVEAL_GAP_MS = 160;\n\n// Runs in the render phase: extends each visible block's birth timeline in\n// place and resolves its animation meta in one pass. Mutations are\n// idempotent for a given block content/length, so discarded or StrictMode\n// double renders re-derive the same state.\nconst updateBlockAnimation = ({\n  blocks,\n  charDelay,\n  getBlockState,\n  pluginsCache,\n  renderNow,\n  revealClock,\n  runtimes,\n}: UpdateBlockAnimationArgs): Map<number, BlockAnimationMeta> => {\n  const blockAnimationMeta = new Map<number, BlockAnimationMeta>();\n  const alive = new Set<number>();\n  let revealedNewChars = false;\n\n  for (const [index, block] of blocks.entries()) {\n    alive.add(block.startOffset);\n\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    const state = getBlockState(index);\n    if (state === 'queued') continue;\n\n    let runtime = runtimes.get(block.startOffset);\n    if (!runtime) {\n      runtime = { births: [], charCount: 0, rawLength: -1, settled: false, styles: [] };\n      runtimes.set(block.startOffset, runtime);\n    }\n\n    if (runtime.rawLength !== block.content.length) {\n      runtime.charCount = countChars(block.content);\n      runtime.rawLength = block.content.length;\n    }\n\n    const blockCharCount = runtime.charCount;\n    const births = runtime.births;\n\n    if (births.length > blockCharCount) {\n      // Block content shrunk (stream restart or upstream rewrite).\n      births.length = blockCharCount;\n      runtime.styles.length = blockCharCount;\n    }\n\n    if (births.length < blockCharCount) {\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      //\n      // The streaming tail paces its stagger from the observed reveal-commit\n      // gap instead of the queue's fixed charDelay: a commit's chars are\n      // spread to land exactly until the next commit arrives, so the flow\n      // stays per-char continuous no matter how far apart the throttled\n      // commits are.\n      const newChars = blockCharCount - births.length;\n      let pace = charDelay;\n      let cap = renderNow + STREAM_FADE_DURATION;\n      if (state === 'streaming') {\n        revealedNewChars = true;\n        const gapMs = Math.min(Math.max(renderNow - revealClock.lastTs, 16), MAX_REVEAL_GAP_MS);\n        pace = Math.min(charDelay, Math.max(gapMs / newChars, MIN_STREAM_CHAR_PACE_MS));\n        cap = renderNow + gapMs + STREAM_FADE_DURATION;\n      }\n      for (let i = births.length; i < blockCharCount; i++) {\n        const prevBirth = i > 0 ? births[i - 1] : renderNow - pace;\n        const chained = prevBirth + pace;\n        births.push(Math.min(cap, Math.max(chained, renderNow)));\n      }\n    }\n\n    let meta: BlockAnimationMeta;\n    if (runtime.settled) {\n      // Settled is monotone: a revealed block's births are frozen, so once\n      // its last fade completed it stays settled until the runtime is\n      // pruned by a stream restart.\n      meta = { charDelay: runtime.charDelay ?? charDelay, settled: true };\n    } else {\n      const lastBirthTs = births.length > 0 ? (births.at(-1) ?? renderNow) : renderNow;\n      meta = resolveBlockAnimationMeta({\n        currentCharDelay: charDelay,\n        fadeDuration: STREAM_FADE_DURATION,\n        lastElapsedMs: renderNow - lastBirthTs,\n        previousCharDelay: runtime.charDelay,\n        state,\n      });\n      runtime.settled = meta.settled;\n    }\n    runtime.charDelay = meta.charDelay;\n\n    blockAnimationMeta.set(block.startOffset, meta);\n  }\n\n  if (revealedNewChars) {\n    revealClock.lastTs = renderNow;\n  }\n\n  for (const key of runtimes.keys()) {\n    if (!alive.has(key)) {\n      runtimes.delete(key);\n      pluginsCache.delete(key);\n    }\n  }\n\n  return blockAnimationMeta;\n};\n\ninterface StreamdownBlocksProps {\n  content: string;\n  markdownOptions: Omit<Options, 'children'>;\n}\n\nconst StreamdownBlocks = memo<StreamdownBlocksProps>(\n  ({ content: smoothedContent, markdownOptions: rest }) => {\n    const { streamAnimationGranularity = 'char' } = useMarkdownContext();\n    const profiler = useStreamdownProfiler();\n    const components = useMarkdownComponents();\n    const baseRehypePlugins = useStablePlugins(useMarkdownRehypePlugins());\n    const remarkPlugins = useStablePlugins(useMarkdownRemarkPlugins());\n    const generatedId = useId();\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 blockRuntimesRef = useRef<Map<number, BlockRuntime>>(new Map());\n    const blockPluginsRef = useRef<Map<number, BlockPluginsCacheEntry>>(new Map());\n    const revealClockRef = useRef<{ lastTs: number }>({ lastTs: 0 });\n\n    const renderNow = getNow();\n\n    const animationStart = profiler ? getNow() : 0;\n    const blockAnimationMeta = updateBlockAnimation({\n      blocks,\n      charDelay,\n      getBlockState,\n      pluginsCache: blockPluginsRef.current,\n      renderNow,\n      revealClock: revealClockRef.current,\n      runtimes: blockRuntimesRef.current,\n    });\n    const blockAnimationDurationMs = profiler ? getNow() - animationStart : 0;\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: blockAnimationDurationMs,\n        itemCount: blocks.length,\n        name: 'block-births',\n        textLength: processedContent.length,\n      });\n    }, [blockAnimationDurationMs, blocks.length, processedContent.length, profiler]);\n\n    const resolveBlockPlugins = (startOffset: number, settled: boolean): PluggableList => {\n      if (settled) return baseRehypePlugins;\n\n      const cache = blockPluginsRef.current;\n      const entry = cache.get(startOffset);\n      if (\n        entry &&\n        entry.base === baseRehypePlugins &&\n        entry.granularity === streamAnimationGranularity\n      ) {\n        return entry.value;\n      }\n\n      const runtime = blockRuntimesRef.current.get(startOffset);\n      const value: PluggableList = [\n        ...baseRehypePlugins,\n        [\n          rehypeStreamAnimated,\n          {\n            fadeDuration: STREAM_FADE_DURATION,\n            granularity: streamAnimationGranularity,\n            runtime,\n          },\n        ],\n      ];\n      cache.set(startOffset, {\n        base: baseRehypePlugins,\n        granularity: streamAnimationGranularity,\n        value,\n      });\n      return value;\n    };\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 animationMeta = blockAnimationMeta.get(block.startOffset);\n          if (!animationMeta) return null;\n\n          const plugins = resolveBlockPlugins(block.startOffset, animationMeta.settled);\n          const key = `${generatedId}-${block.startOffset}`;\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              <StreamdownBlock\n                {...rest}\n                components={components}\n                rehypePlugins={plugins}\n                remarkPlugins={remarkPlugins}\n              >\n                {block.content}\n              </StreamdownBlock>\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);\n\nStreamdownBlocks.displayName = 'StreamdownBlocks';\n\n// The outer component absorbs the upstream per-chunk prop churn: every\n// streamed chunk re-renders it, but it only feeds the smoother and renders\n// a memoized child keyed on the smoother's output — so the expensive block\n// pipeline runs per reveal commit, not per chunk AND per commit.\nexport const StreamdownRender = memo<Options>(({ children, ...rest }) => {\n  const { streamSmoothingPreset = 'balanced' } = useMarkdownContext();\n  const escapedContent = useMarkdownContent(children || '');\n  const smoothedContent = useSmoothStreamContent(\n    typeof escapedContent === 'string' ? escapedContent : '',\n    { preset: streamSmoothingPreset },\n  );\n  const markdownOptions = useStableValue(rest);\n\n  return <StreamdownBlocks content={smoothedContent} markdownOptions={markdownOptions} />;\n});\n\nStreamdownRender.displayName = 'StreamdownRender';\n\nexport default StreamdownRender;\n"],"mappings":"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"}