{"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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"}