{"version":3,"file":"takumi-renderer.cjs","sources":["../../../src/utils/takumi-renderer.js"],"sourcesContent":["/**\n * Takumi 渲染器单例与辅助工具\n *\n * 封装 @takumi-rs/core 与 @takumi-rs/helpers,提供:\n * - 全局共享的 Renderer 实例(复用字体/图片解码缓存)\n * - HTML / node tree 解析统一入口\n * - 字体注册缓存(幂等 + 失败可重试 + 并发安全)\n * - Emoji 渲染辅助(模块路径兼容 bundler / pnpm / npm hoisting)\n *\n * 修复记录:\n *  P0-1 字体加载失败不再永久污染缓存(写注册表改在 await 之后)\n *  P0-2 emoji 模块加载改用包名 import,不再硬拼 node_modules 路径\n *  P0-3 emoji 缓存绑到 renderer 实例(WeakMap),destroy() 后自动失效\n *  P1-4 字体注册并发竞态修复:inflight Promise 去重\n *  P1-5 emoji 并行预加载(Promise.all)\n *  P1-6 collectImageUrls 只收字符串 src,不再误把 Buffer 当 URL\n *  P2-7 renderHtmlFrame 透传 AbortSignal / images,加基础入参校验\n */\nimport { Renderer as TakumiRenderer } from '@takumi-rs/core';\nimport { fromHtml as takumiFromHtml } from '@takumi-rs/helpers/html';\nimport { pathToFileURL, fileURLToPath } from 'url';\nimport path from 'path';\n\n/* ============================================================================\n *  Emoji 模块加载\n *  - 优先按包名 import,兼容 bundler / pnpm / monorepo / npm hoisting 各种场景\n *  - 失败时静默降级(返回 null),调用方无需 try/catch\n * ========================================================================== */\nlet _extractEmojis = null;\n\n/**\n * @returns {Function|null} extractEmojis 函数;若模块不可用返回 null\n */\nasync function getExtractEmojis() {\n  if (_extractEmojis) return _extractEmojis;\n\n  // 优先级 1:子路径 export(包作者若在 package.json 中声明即可用)\n  const candidates = [\n    '@takumi-rs/helpers/emoji',\n    '@takumi-rs/helpers/dist/emoji.mjs',\n  ];\n  for (const spec of candidates) {\n    try {\n      const mod = await import(spec);\n      if (mod && typeof mod.extractEmojis === 'function') {\n        _extractEmojis = mod.extractEmojis;\n        return _extractEmojis;\n      }\n    } catch (_) {\n      // try next\n    }\n  }\n\n  // 优先级 2:相对 node_modules 路径解析\n  // 在 bundler / pnpm 下大概率失败,但 try/catch 兜底\n  try {\n    if (typeof import.meta.url === 'string' && import.meta.url.startsWith('file:')) {\n      const here = path.dirname(fileURLToPath(import.meta.url));\n      const emojiPath = path.join(\n        here,\n        '..', '..', 'node_modules', '@takumi-rs', 'helpers', 'dist', 'emoji.mjs'\n      );\n      const mod = await import(pathToFileURL(emojiPath).href);\n      if (mod && typeof mod.extractEmojis === 'function') {\n        _extractEmojis = mod.extractEmojis;\n        return _extractEmojis;\n      }\n    }\n  } catch (_) {\n    // 静默降级\n  }\n\n  return null;\n}\n\n/* ============================================================================\n *  Renderer 单例\n * ========================================================================== */\nlet _renderer = null;\n\n/**\n * 获取共享的 Takumi Renderer 实例\n * @returns {TakumiRenderer}\n */\nexport function getTakumiRenderer() {\n  if (!_renderer) {\n    _renderer = new TakumiRenderer();\n  }\n  return _renderer;\n}\n\n/**\n * 销毁共享实例(导出视频后调用,释放原生资源)\n * 字符串 key 的字体缓存必须清空 —— 旧 renderer 已死,新 renderer 不认识这些 key\n * WeakMap 绑定的缓存(emoji / Buffer 字体)随 renderer GC 自动失效,无需手动清\n */\nexport function destroyTakumiRenderer() {\n  _renderer = null;\n  _fontRegistry.clear();\n  _fontInflightByKey.clear();\n}\n\nlet _fontSeq = 0; // 仅用于生成唯一 key(label/debug 用,非去重键)\n\n/* ============================================================================\n *  字体注册:幂等 + 并发安全 + 失败可重试\n *  - 字符串 URL / 绝对路径:按 key 去重,inflight Promise 复用\n *  - Buffer 数据:按引用去重(WeakMap 绑到 renderer),同上语义\n * ========================================================================== */\n// key(string) → true:已成功加载的 URL / path\nconst _fontRegistry = new Map();\n// key(string) → Promise:正在加载中的 URL / path(防止同一 key 并发重入)\nconst _fontInflightByKey = new Map();\n// renderer → WeakMap<Buffer, true | Promise>:renderer 维度上的 Buffer 字体状态\n//   true 表示已加载,Promise 表示加载中,命中后允许并发复用\nconst _fontBufferState = new WeakMap();\n\n/**\n * 注册一组字体到 Takumi 渲染器(单个失败不阻塞其他)\n * @param {TakumiRenderer} renderer\n * @param {Array} fonts - 支持:\n *   - 字符串:URL,异步加载\n *   - { url: '...' }:异步加载\n *   - { path: '...' }:读盘后同步注册\n *   - { data: Buffer }:同步注册,按引用去重\n * @returns {Promise<void>}\n */\nexport async function registerFontsToTakumi(renderer, fonts) {\n  if (!Array.isArray(fonts) || fonts.length === 0) return;\n  await Promise.all(\n    fonts.map((f) =>\n      registerOneFont(renderer, f).catch((err) => {\n        // 单个字体失败仅打 warning,不阻塞整段渲染\n        // eslint-disable-next-line no-console\n        console.warn(\n          `[takumi-renderer] 字体注册失败 (${describeFont(f)}):`,\n          err?.message || err\n        );\n      })\n    )\n  );\n}\n\nfunction describeFont(f) {\n  if (typeof f === 'string') return `url:${f}`;\n  if (f && typeof f === 'object') {\n    if (f.url) return `url:${f.url}`;\n    if (f.path) return `path:${f.path}`;\n    if (f.data) return 'data:<Buffer>';\n  }\n  return 'unknown';\n}\n\nasync function registerOneFont(renderer, f) {\n  if (!renderer) throw new TypeError('registerOneFont: renderer is required');\n\n  // === string URL ===\n  if (typeof f === 'string') {\n    return runKeyOnce(renderer, `url:${f}`, () => renderer.loadFont(f));\n  }\n  if (!f || typeof f !== 'object') return;\n\n  // === { url } ===\n  if (f.url) {\n    return runKeyOnce(renderer, `url:${f.url}`, () => renderer.loadFont(f.url));\n  }\n\n  // === { path } ===\n  if (f.path) {\n    return runKeyOnce(renderer, `path:${f.path}`, async () => {\n      const fs = await import('fs/promises');\n      const data = await fs.readFile(f.path);\n      renderer.loadFontSync(data);\n    });\n  }\n\n  // === { data: Buffer } ===\n  // 按 Buffer 引用去重,且状态绑到 renderer —— destroy() 后自然失效,无内存泄漏\n  if (f.data) {\n    return runBufferOnce(renderer, f.data, () => renderer.loadFontSync(f.data));\n  }\n}\n\n/**\n * 按字符串 key(URL / 绝对路径)加载:幂等,失败可重试\n * - 已成功 → 立即返回\n * - 在飞 → 复用同一 Promise\n * - 加载失败 → 清掉状态,下次调用重新尝试\n */\nasync function runKeyOnce(renderer, key, loader) {\n  if (_fontRegistry.has(key)) return;\n  const existing = _fontInflightByKey.get(key);\n  if (existing) return existing;\n\n  const p = (async () => {\n    await loader();\n    _fontRegistry.set(key, true);\n  })().catch((err) => {\n    // 失败:清掉 inflight,以便后续可重试(不再写 _fontRegistry)\n    _fontInflightByKey.delete(key);\n    throw err;\n  });\n\n  _fontInflightByKey.set(key, p);\n  return p;\n}\n\n/**\n * 按 Buffer 引用加载(状态绑到 renderer,WeakMap 自动 GC)\n * - 值 true:已加载\n * - 值 Promise:加载中(复用)\n * - 失败:删除状态,下次可重试\n */\nasync function runBufferOnce(renderer, buffer, loader) {\n  if (!buffer || !(buffer instanceof Uint8Array)) {\n    throw new TypeError('runBufferOnce: buffer must be a Uint8Array');\n  }\n  let stateMap = _fontBufferState.get(renderer);\n  if (!stateMap) {\n    stateMap = new WeakMap();\n    _fontBufferState.set(renderer, stateMap);\n  }\n\n  const cur = stateMap.get(buffer);\n  if (cur === true) return;\n  if (cur instanceof Promise) {\n    await cur;\n    return;\n  }\n\n  const p = (async () => {\n    loader();\n    stateMap.set(buffer, true);\n  })().catch((err) => {\n    stateMap.delete(buffer); // 失败 → 允许重试\n    throw err;\n  });\n\n  stateMap.set(buffer, p);\n  await p;\n}\n\n/* ============================================================================\n *  Emoji 图片预加载\n *  - 缓存绑到 renderer(WeakMap),destroy() 后自动失效,无需手动清\n *  - 并发同 URL 复用同一 Promise\n *  - 失败 → 清状态,下次可重试\n *\n *  历史:\n *   1. 旧版 Takumi: renderer.loadImage(url) 一站式预加载\n *   2. 1.8.x: 重命名为 putPersistentImage({src,data}),需要先把 URL\n *      下载成 Buffer 再传 data 字段\n *  这里手动 fetch URL,再调 putPersistentImage。\n * ========================================================================== */\n// renderer → Map<url, true | Promise>\nconst _emojiState = new WeakMap();\n\n/**\n * 从 URL/相对路径/绝对路径读取图片字节\n * - http(s):// → node fetch\n * - 其他 → 当文件路径 fs.readFile\n */\nasync function fetchImageBytes(url) {\n  if (/^https?:\\/\\//i.test(url)) {\n    const res = await fetch(url);\n    if (!res.ok) {\n      throw new Error(`fetch ${url} failed: ${res.status} ${res.statusText}`);\n    }\n    const ab = await res.arrayBuffer();\n    return new Uint8Array(ab);\n  }\n  // 本地文件路径\n  const fs = await import('fs/promises');\n  return new Uint8Array(await fs.readFile(url));\n}\n\nasync function preloadEmojiImage(renderer, url) {\n  if (!url) return;\n  let stateMap = _emojiState.get(renderer);\n  if (!stateMap) {\n    stateMap = new Map();\n    _emojiState.set(renderer, stateMap);\n  }\n  if (stateMap.get(url) === true) return;\n  const inflight = stateMap.get(url);\n  if (inflight) {\n    await inflight;\n    return;\n  }\n  const p = (async () => {\n    if (typeof renderer.putPersistentImage === 'function') {\n      // 1.8.x:必须 {src,data} 一起传\n      const data = await fetchImageBytes(url);\n      await renderer.putPersistentImage({ src: url, data });\n    } else if (typeof renderer.loadImage === 'function') {\n      // 旧版本\n      await renderer.loadImage(url);\n    } else {\n      throw new Error('[takumi-renderer] renderer 不支持图片预加载 (无 putPersistentImage / loadImage)');\n    }\n    stateMap.set(url, true);\n  })().catch((err) => {\n    stateMap.delete(url); // 失败 → 允许下次重试\n    throw err;\n  });\n  stateMap.set(url, p);\n  await p;\n}\n\n/* ============================================================================\n *  Public helpers\n * ========================================================================== */\n\n/**\n * 解析 HTML 字符串为 Takumi node tree\n * @param {string} html\n * @returns {{ node: object, stylesheets: string[] }}\n */\nexport function parseHtml(html) {\n  if (typeof html !== 'string') {\n    throw new TypeError('parseHtml: html must be a string');\n  }\n  return takumiFromHtml(html);\n}\n\n/**\n * 包装 node tree(如果用户直接传入 node 树对象,直接返回)\n * @param {object} node\n * @returns {{ node: object, stylesheets: string[] }}\n */\nexport function wrapNode(node) {\n  if (!node || typeof node !== 'object') {\n    throw new TypeError('wrapNode: node must be an object');\n  }\n  return { node, stylesheets: [] };\n}\n\n/**\n * 递归收集节点树中所有 image 类型的 string src(用于预加载 emoji SVG 等)\n * 注意:Takumi 的 image.src 也可以是 Uint8Array/ArrayBuffer,这种已经通过\n *       Renderer.images 预注册,无需走 URL 拉取,跳过即可\n */\nfunction collectImageUrls(node, urls) {\n  if (!node) return;\n  if (Array.isArray(node)) {\n    for (const n of node) collectImageUrls(n, urls);\n    return;\n  }\n  if (node.type === 'image' && typeof node.src === 'string') {\n    urls.add(node.src);\n  }\n  if (node.children) {\n    collectImageUrls(node.children, urls);\n  }\n}\n\n/**\n * 统一的渲染入口:接受 html 或 node,返回 RGBA Buffer\n * @param {object} input\n * @param {string} [input.html]\n * @param {object} [input.node]\n * @param {string[]} [input.stylesheets]\n * @param {Array}  [input.fonts]\n * @param {number}  input.width  (required)\n * @param {number}  input.height (required)\n * @param {number} [input.timeMs=0]      - CSS keyframe 动画当前时间(毫秒)\n * @param {object} [input.keyframes]     - 结构化 keyframe 定义\n * @param {number} [input.devicePixelRatio=1]\n * @param {AbortSignal} [input.signal]   - 取消渲染\n * @param {object} [input.images]        - 预取图片 { src: Buffer }\n * @param {string|false} [input.emoji='twemoji'] - emoji 风格,false 禁用\n * @returns {Promise<Buffer>} width*height*4 RGBA bytes\n */\nexport async function renderHtmlFrame(input) {\n  if (!input || typeof input !== 'object') {\n    throw new TypeError('renderHtmlFrame: input must be an object');\n  }\n  const {\n    width, height,\n    html, node, stylesheets, fonts,\n    timeMs, keyframes, devicePixelRatio,\n    signal, images, emoji,\n  } = input;\n\n  if (!width || !height) {\n    throw new Error('renderHtmlFrame: width and height are required');\n  }\n  if (!html && !node) {\n    throw new Error('renderHtmlFrame: must provide either html or node');\n  }\n\n  // 1) 解析为 node tree\n  let parsed;\n  if (html) {\n    parsed = parseHtml(html);\n  } else {\n    parsed = wrapNode(node);\n  }\n\n  // 1.5) Emoji 处理(失败时静默降级,不影响主体渲染)\n  const renderer = getTakumiRenderer();\n  if (parsed.node && emoji !== false) {\n    const extractEmojis = await getExtractEmojis();\n    if (extractEmojis) {\n      const emojiType = typeof emoji === 'string' ? emoji : 'twemoji';\n      try {\n        const beforeNode = parsed.node;\n        parsed.node = extractEmojis(parsed.node, emojiType);\n        if (parsed.node !== beforeNode) {\n          // 收集所有 emoji SVG URL 并行预加载(修复 #5 串行问题)\n          const emojiUrls = new Set();\n          collectImageUrls(parsed.node, emojiUrls);\n          await Promise.all(\n            Array.from(emojiUrls, (url) => preloadEmojiImage(renderer, url))\n          );\n        }\n      } catch (_) {\n        // 静默跳过 emoji 处理\n      }\n    }\n  }\n\n  // 2) 注册用户字体(单个失败 warning,不阻塞)\n  if (fonts && fonts.length) {\n    await registerFontsToTakumi(renderer, fonts);\n  }\n\n  // 3) 渲染 raw RGBA\n  const allStylesheets = [\n    ...(parsed.stylesheets || []),\n    ...(stylesheets || []),\n  ];\n  const opts = {\n    width,\n    height,\n    format: 'raw',\n  };\n  if (allStylesheets.length) opts.stylesheets = allStylesheets;\n  if (timeMs !== undefined) opts.timeMs = timeMs;\n  if (keyframes) opts.keyframes = keyframes;\n  if (devicePixelRatio) opts.devicePixelRatio = devicePixelRatio;\n  if (images) opts.images = images;\n  if (signal) opts.signal = signal;\n\n  return await renderer.render(parsed.node, opts);\n}\n"],"names":["fileURLToPath","pathToFileURL","TakumiRenderer","html","takumiFromHtml"],"mappings":"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"}