<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Astro-Theme-Live_Flow - astro-in-cloudflare</title><description>Power by Github Discussions &amp; Astro</description><link>https://live-flow.iiv.workers.dev/</link><language>zh-cn</language><item><title>如何在Astro v6上实现 动态的 OpenGraph 社交图片生成？运行在边缘计算 使用wasm！支持Cloudflare workers</title><link>https://live-flow.iiv.workers.dev/astro-in-cloudflare/p/5</link><guid isPermaLink="true">https://live-flow.iiv.workers.dev/astro-in-cloudflare/p/5</guid><pubDate>Sat, 28 Mar 2026 09:37:44 GMT</pubDate><content:encoded>&lt;h4 dir=&quot;auto&quot;&gt;代码&lt;/h4&gt;
&lt;details&gt;&lt;summary&gt;Details&lt;/summary&gt;
&lt;p dir=&quot;auto&quot;&gt;
&lt;/p&gt;&lt;div class=&quot;highlight highlight-source-ts notranslate position-relative overflow-auto&quot; dir=&quot;auto&quot; data-snippet-clipboard-copy-content=&quot;import type { APIRoute } from &amp;quot;astro&amp;quot;;
// @ts-ignore
import { env } from &amp;quot;cloudflare:workers&amp;quot;;
import { getLiveEntry } from &amp;quot;astro:content&amp;quot;;
import { formatDate } from &amp;quot;@/lib/utils&amp;quot;;

import satori, { init } from &amp;quot;satori/standalone&amp;quot;;
import { initWasm, Resvg } from &amp;quot;@resvg/resvg-wasm&amp;quot;;

// @ts-ignore
import yogaWasm from &amp;quot;satori/yoga.wasm?module&amp;quot;;
// @ts-ignore
import resvgWasm from &amp;quot;@resvg/resvg-wasm/index_bg.wasm?module&amp;quot;;

// --- 1. 在函数外部定义全局锁和缓存 ---
let wasmInitPromise: Promise&amp;lt;void&amp;gt; | null = null;
let fontCache: ArrayBuffer | null = null;

// 封装一个纯粹的初始化函数
async function initializeWasm(yogaWasm: any, resvgWasm: any) {
  // 如果已经有 Promise 在运行或已完成，直接返回它
  if (wasmInitPromise) return wasmInitPromise;

  wasmInitPromise = (async () =&amp;gt; {
    try {
      await Promise.all([init(yogaWasm), initWasm(resvgWasm)]);
      console.log(&amp;quot;WASM Initialized successfully&amp;quot;);
    } catch (e: any) {
      // 如果报错内容包含 &amp;quot;already initialized&amp;quot;，说明其实已经好了，忽略它
      if (
        e.message?.includes(&amp;quot;already initialized&amp;quot;) ||
        e.message?.includes(&amp;quot;used only once&amp;quot;)
      ) {
        return;
      }
      // 如果是其他致命错误，清空锁以便下次重试
      wasmInitPromise = null;
      throw e;
    }
  })();

  return wasmInitPromise;
}

export const GET: APIRoute = async ({ params, request }) =&amp;gt; {
  const { entry } = await getLiveEntry(&amp;quot;data&amp;quot;, params.id as string);
  if (!entry) return new Response(&amp;quot;Not Found&amp;quot;, { status: 404 });
  try {
    // --- 2. 这里的调用现在是“线程安全”的 ---
    await initializeWasm(yogaWasm, resvgWasm);

    // 字体持久化逻辑保持不变
    if (!fontCache) {
      const fontRes = await env.ASSETS.fetch(
        new URL(&amp;quot;/fonts/MiSans-Regular.ttf&amp;quot;, request.url),
      );
      fontCache = await fontRes.arrayBuffer();
    }

    // 3. Satori 渲染 SVG
    const svg = await satori(
      {
        type: &amp;quot;div&amp;quot;,
        props: {
          style: {
            height: &amp;quot;100%&amp;quot;,
            width: &amp;quot;100%&amp;quot;,
            display: &amp;quot;flex&amp;quot;,
            flexDirection: &amp;quot;column&amp;quot;,
            backgroundColor: &amp;quot;#000&amp;quot;,
            color: &amp;quot;#fff&amp;quot;,
            fontFamily: &amp;quot;MiSans&amp;quot;,
            border: &amp;quot;1px solid #222&amp;quot;,
          },
          children: [
            // ... 你的 UI 结构保持不变
            {
              type: &amp;quot;div&amp;quot;,
              props: {
                style: {
                  display: &amp;quot;flex&amp;quot;,
                  padding: &amp;quot;30px 40px&amp;quot;,
                  borderBottom: &amp;quot;1px solid #222&amp;quot;,
                  alignItems: &amp;quot;center&amp;quot;,
                },
                children: [
                  {
                    type: &amp;quot;div&amp;quot;,
                    props: {
                      style: {
                        border: &amp;quot;1px solid #444&amp;quot;,
                        borderRadius: &amp;quot;8px&amp;quot;,
                        padding: &amp;quot;4px 12px&amp;quot;,
                        color: &amp;quot;#888&amp;quot;,
                        fontSize: &amp;quot;24px&amp;quot;,
                      },
                      children: &amp;quot;#&amp;quot; + entry.id,
                    },
                  },
                ],
              },
            },
            {
              type: &amp;quot;div&amp;quot;,
              props: {
                style: {
                  display: &amp;quot;flex&amp;quot;,
                  flex: 1,
                  padding: &amp;quot;0 40px&amp;quot;,
                  alignItems: &amp;quot;center&amp;quot;,
                  justifyContent: &amp;quot;center&amp;quot;,
                },
                children: {
                  type: &amp;quot;h1&amp;quot;,
                  props: {
                    style: {
                      fontSize: &amp;quot;85px&amp;quot;,
                      fontWeight: &amp;quot;300&amp;quot;,
                      textAlign: &amp;quot;center&amp;quot;,
                      lineHeight: &amp;quot;1.3&amp;quot;,
                    },
                    children: entry.data.title,
                  },
                },
              },
            },
            {
              type: &amp;quot;div&amp;quot;,
              props: {
                style: {
                  display: &amp;quot;flex&amp;quot;,
                  justifyContent: &amp;quot;space-between&amp;quot;,
                  padding: &amp;quot;30px 40px&amp;quot;,
                  borderTop: &amp;quot;1px solid #222&amp;quot;,
                  color: &amp;quot;#666&amp;quot;,
                },
                children: [
                  {
                    type: &amp;quot;span&amp;quot;,
                    props: { children: formatDate(entry.data.createdAt) },
                  },
                  {
                    type: &amp;quot;span&amp;quot;,
                    props: { children: entry.data.category.name },
                  },
                ],
              },
            },
          ],
        },
      },
      {
        width: 1200,
        height: 630,
        fonts: [
          {
            name: &amp;quot;MiSans&amp;quot;,
            data: fontCache,
            weight: 400,
            style: &amp;quot;normal&amp;quot;,
          },
        ],
      },
    );

    // 4. Resvg 渲染 PNG
    const resvg = new Resvg(svg, {
      fitTo: { mode: &amp;quot;width&amp;quot;, value: 1200 },
    });
    const pngData = resvg.render();
    const pngBuffer = pngData.asPng();

    return new Response(new Uint8Array(pngBuffer) as any, {
      headers: {
        &amp;quot;Content-Type&amp;quot;: &amp;quot;image/png&amp;quot;,
        &amp;quot;Cache-Control&amp;quot;: &amp;quot;public, max-age=31536000, immutable&amp;quot;,
      },
    });
  } catch (e: any) {
    console.error(&amp;quot;OG Error:&amp;quot;, e.message);
    return new Response(`Error generating image: ${e.message}`, {
      status: 500,
    });
  }
};
&quot;&gt;&lt;pre class=&quot;notranslate&quot;&gt;&lt;span class=&quot;pl-k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;APIRoute&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;pl-s&quot;&gt;&quot;astro&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;pl-c&quot;&gt;// &lt;span class=&quot;pl-k&quot;&gt;@ts&lt;/span&gt;-ignore&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;env&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;pl-s&quot;&gt;&quot;cloudflare:workers&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;getLiveEntry&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;pl-s&quot;&gt;&quot;astro:content&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;formatDate&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;pl-s&quot;&gt;&quot;@/lib/utils&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;pl-k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;satori&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;init&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;pl-s&quot;&gt;&quot;satori/standalone&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;initWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Resvg&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;pl-s&quot;&gt;&quot;@resvg/resvg-wasm&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;pl-c&quot;&gt;// &lt;span class=&quot;pl-k&quot;&gt;@ts&lt;/span&gt;-ignore&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;yogaWasm&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;pl-s&quot;&gt;&quot;satori/yoga.wasm?module&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;pl-c&quot;&gt;// &lt;span class=&quot;pl-k&quot;&gt;@ts&lt;/span&gt;-ignore&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;resvgWasm&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;pl-s&quot;&gt;&quot;@resvg/resvg-wasm/index_bg.wasm?module&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;pl-c&quot;&gt;// --- 1. 在函数外部定义全局锁和缓存 ---&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;wasmInitPromise&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;pl-smi&quot;&gt;&lt;span class=&quot;pl-k&quot;&gt;void&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;fontCache&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;ArrayBuffer&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;pl-c&quot;&gt;// 封装一个纯粹的初始化函数&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;pl-en&quot;&gt;initializeWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;yogaWasm&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;resvgWasm&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;pl-c&quot;&gt;// 如果已经有 Promise 在运行或已完成，直接返回它&lt;/span&gt;
  &lt;span class=&quot;pl-k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;wasmInitPromise&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;wasmInitPromise&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;pl-s1&quot;&gt;wasmInitPromise&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;pl-k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;yogaWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-en&quot;&gt;initWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;resvgWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;pl-smi&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;WASM Initialized successfully&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;pl-c&quot;&gt;// 如果报错内容包含 &quot;already initialized&quot;，说明其实已经好了，忽略它&lt;/span&gt;
      &lt;span class=&quot;pl-k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;already initialized&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;||&lt;/span&gt;
        &lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;used only once&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;pl-k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;pl-c&quot;&gt;// 如果是其他致命错误，清空锁以便下次重试&lt;/span&gt;
      &lt;span class=&quot;pl-s1&quot;&gt;wasmInitPromise&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;pl-k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;pl-k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;wasmInitPromise&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;pl-k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;GET&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;APIRoute&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; request &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; entry &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;pl-en&quot;&gt;getLiveEntry&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;pl-smi&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;pl-k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;Not Found&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;status&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;404&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;pl-k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;pl-c&quot;&gt;// --- 2. 这里的调用现在是“线程安全”的 ---&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;pl-en&quot;&gt;initializeWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;yogaWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;resvgWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;pl-c&quot;&gt;// 字体持久化逻辑保持不变&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;fontCache&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;fontRes&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;ASSETS&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;pl-k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;/fonts/MiSans-Regular.ttf&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;pl-s1&quot;&gt;fontCache&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;fontRes&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;arrayBuffer&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;pl-c&quot;&gt;// 3. Satori 渲染 SVG&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;svg&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;pl-en&quot;&gt;satori&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;height&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;100%&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;width&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;100%&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;display&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;flex&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;flexDirection&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;column&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;backgroundColor&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;#000&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;color&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;fontFamily&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;MiSans&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;border&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;1px solid #222&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;pl-c&quot;&gt;// ... 你的 UI 结构保持不变&lt;/span&gt;
            &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;display&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;flex&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;padding&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;30px 40px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;borderBottom&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;1px solid #222&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;alignItems&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;center&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;[&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                      &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;pl-c1&quot;&gt;border&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;1px solid #444&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;pl-c1&quot;&gt;borderRadius&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;8px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;pl-c1&quot;&gt;padding&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;4px 12px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;pl-c1&quot;&gt;color&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;#888&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;pl-c1&quot;&gt;fontSize&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;24px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;#&quot;&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-kos&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;display&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;flex&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;flex&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;padding&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;0 40px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;alignItems&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;center&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;justifyContent&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;center&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;h1&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                      &lt;span class=&quot;pl-c1&quot;&gt;fontSize&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;85px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;pl-c1&quot;&gt;fontWeight&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;300&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;pl-c1&quot;&gt;textAlign&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;center&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;pl-c1&quot;&gt;lineHeight&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;1.3&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-s1&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;display&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;flex&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;justifyContent&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;space-between&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;padding&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;30px 40px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;borderTop&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;1px solid #222&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;color&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;#666&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;[&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;span&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-en&quot;&gt;formatDate&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;createdAt&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;span&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-s1&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-kos&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;pl-kos&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;pl-c1&quot;&gt;width&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;1200&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;pl-c1&quot;&gt;height&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;630&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;pl-c1&quot;&gt;fonts&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;name&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;MiSans&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;data&lt;/span&gt;: &lt;span class=&quot;pl-s1&quot;&gt;fontCache&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;weight&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;normal&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;pl-kos&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;pl-c&quot;&gt;// 4. Resvg 渲染 PNG&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;resvg&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Resvg&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;svg&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;pl-c1&quot;&gt;fitTo&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;mode&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;value&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;1200&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;pngData&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;resvg&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;pngBuffer&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;pngData&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;asPng&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;pl-k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Uint8Array&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;pngBuffer&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;pl-smi&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;pl-c1&quot;&gt;headers&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;pl-s&quot;&gt;&quot;Content-Type&quot;&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;image/png&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;pl-s&quot;&gt;&quot;Cache-Control&quot;&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;public, max-age=31536000, immutable&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;pl-smi&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;OG Error:&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;`Error generating image: &lt;span class=&quot;pl-s1&quot;&gt;&lt;span class=&quot;pl-kos&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;/span&gt;`&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;pl-c1&quot;&gt;status&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p dir=&quot;auto&quot;&gt;&lt;/p&gt;
&lt;/details&gt; 
&lt;p dir=&quot;auto&quot;&gt;如果你网站部署在提供边缘计算的服务商上，这个方案很合适。无需编译时生成图片耗费时间。&lt;/p&gt;
&lt;h2 dir=&quot;auto&quot;&gt;需要&lt;/h2&gt;
&lt;ul dir=&quot;auto&quot;&gt;
&lt;li&gt;@resvg/resvg-wasm&lt;/li&gt;
&lt;li&gt;satori&lt;/li&gt;
&lt;/ul&gt;
&lt;p dir=&quot;auto&quot;&gt;这两个包被打包进workers大小在2.5mb，压缩后 1.4mb 如果你还有其他模块。可能会超过免费额度&lt;/p&gt;
&lt;div class=&quot;snippet-clipboard-content notranslate position-relative overflow-auto&quot; data-snippet-clipboard-copy-content=&quot; _astro/index_bg.Blvrv-U2.wasm                             │ compiled-wasm │ 2420.51 KiB 
_astro/yoga.sbSbVeWy.wasm                                 │ compiled-wasm │ 70.05 KiB 

Total Upload: 4498.55 KiB / gzip: 1433.02 KiB&quot;&gt;&lt;pre class=&quot;notranslate&quot;&gt;&lt;code class=&quot;notranslate&quot;&gt; _astro/index_bg.Blvrv-U2.wasm                             │ compiled-wasm │ 2420.51 KiB 
_astro/yoga.sbSbVeWy.wasm                                 │ compiled-wasm │ 70.05 KiB 

Total Upload: 4498.55 KiB / gzip: 1433.02 KiB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 dir=&quot;auto&quot;&gt;[id].ts&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;我创建了 &lt;code class=&quot;notranslate&quot;&gt;src\pages\og\[id].png.ts&lt;/code&gt; 文件，访问&lt;code class=&quot;notranslate&quot;&gt;/og/1.png&lt;/code&gt;就可以获取图片&lt;/p&gt;
&lt;h2 dir=&quot;auto&quot;&gt;原理&lt;/h2&gt;
&lt;h3 dir=&quot;auto&quot;&gt;satori&lt;/h3&gt;
&lt;p dir=&quot;auto&quot;&gt;使用字体和实现布局创建svg数据&lt;/p&gt;
&lt;h3 dir=&quot;auto&quot;&gt;resvg&lt;/h3&gt;
&lt;p dir=&quot;auto&quot;&gt;将svg数据画成PNG图片&lt;/p&gt;
&lt;h2 dir=&quot;auto&quot;&gt;实现与限制&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;Cloudflare workers不允许实时编译生成wasm。一切都要预载&lt;/p&gt;
&lt;h3 dir=&quot;auto&quot;&gt;satori&lt;/h3&gt;
&lt;p dir=&quot;auto&quot;&gt;导入 satori 标准版无yoga&lt;/p&gt;
&lt;div class=&quot;highlight highlight-source-ts notranslate position-relative overflow-auto&quot; dir=&quot;auto&quot; data-snippet-clipboard-copy-content=&quot;import satori, { init } from &amp;quot;satori/standalone&amp;quot;;&quot;&gt;&lt;pre class=&quot;notranslate&quot;&gt;&lt;span class=&quot;pl-k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;satori&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;init&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;pl-s&quot;&gt;&quot;satori/standalone&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p dir=&quot;auto&quot;&gt;导入Yoga wasm&lt;/p&gt;
&lt;div class=&quot;highlight highlight-source-ts notranslate position-relative overflow-auto&quot; dir=&quot;auto&quot; data-snippet-clipboard-copy-content=&quot;// @ts-ignore
import yogaWasm from &amp;quot;satori/yoga.wasm?module&amp;quot;;&quot;&gt;&lt;pre class=&quot;notranslate&quot;&gt;&lt;span class=&quot;pl-c&quot;&gt;// &lt;span class=&quot;pl-k&quot;&gt;@ts&lt;/span&gt;-ignore&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;yogaWasm&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;pl-s&quot;&gt;&quot;satori/yoga.wasm?module&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 dir=&quot;auto&quot;&gt;Resvg&lt;/h3&gt;
&lt;div class=&quot;highlight highlight-source-ts notranslate position-relative overflow-auto&quot; dir=&quot;auto&quot; data-snippet-clipboard-copy-content=&quot;import { initWasm, Resvg } from &amp;quot;@resvg/resvg-wasm&amp;quot;;

// @ts-ignore
import resvgWasm from &amp;quot;@resvg/resvg-wasm/index_bg.wasm?module&amp;quot;;&quot;&gt;&lt;pre class=&quot;notranslate&quot;&gt;&lt;span class=&quot;pl-k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;initWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Resvg&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;pl-s&quot;&gt;&quot;@resvg/resvg-wasm&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;pl-c&quot;&gt;// &lt;span class=&quot;pl-k&quot;&gt;@ts&lt;/span&gt;-ignore&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;resvgWasm&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;pl-s&quot;&gt;&quot;@resvg/resvg-wasm/index_bg.wasm?module&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 dir=&quot;auto&quot;&gt;初始化&lt;/h3&gt;
&lt;div class=&quot;highlight highlight-source-ts notranslate position-relative overflow-auto&quot; dir=&quot;auto&quot; data-snippet-clipboard-copy-content=&quot;// --- 1. 在函数外部定义全局锁和缓存 ---
let wasmInitPromise: Promise&amp;lt;void&amp;gt; | null = null;
let fontCache: ArrayBuffer | null = null;

// 封装一个纯粹的初始化函数
async function initializeWasm(yogaWasm: any, resvgWasm: any) {
  // 如果已经有 Promise 在运行或已完成，直接返回它
  if (wasmInitPromise) return wasmInitPromise;

  wasmInitPromise = (async () =&amp;gt; {
    try {
      await Promise.all([init(yogaWasm), initWasm(resvgWasm)]);
      console.log(&amp;quot;WASM Initialized successfully&amp;quot;);
    } catch (e: any) {
      // 如果报错内容包含 &amp;quot;already initialized&amp;quot;，说明其实已经好了，忽略它
      if (
        e.message?.includes(&amp;quot;already initialized&amp;quot;) ||
        e.message?.includes(&amp;quot;used only once&amp;quot;)
      ) {
        return;
      }
      // 如果是其他致命错误，清空锁以便下次重试
      wasmInitPromise = null;
      throw e;
    }
  })();

  return wasmInitPromise;
}&quot;&gt;&lt;pre class=&quot;notranslate&quot;&gt;&lt;span class=&quot;pl-c&quot;&gt;// --- 1. 在函数外部定义全局锁和缓存 ---&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;wasmInitPromise&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;pl-smi&quot;&gt;&lt;span class=&quot;pl-k&quot;&gt;void&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;fontCache&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;ArrayBuffer&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;pl-c&quot;&gt;// 封装一个纯粹的初始化函数&lt;/span&gt;
&lt;span class=&quot;pl-k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;pl-en&quot;&gt;initializeWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;yogaWasm&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;resvgWasm&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;pl-c&quot;&gt;// 如果已经有 Promise 在运行或已完成，直接返回它&lt;/span&gt;
  &lt;span class=&quot;pl-k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;wasmInitPromise&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;wasmInitPromise&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;pl-s1&quot;&gt;wasmInitPromise&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;pl-k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;yogaWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-en&quot;&gt;initWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;resvgWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;pl-smi&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;WASM Initialized successfully&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;pl-c&quot;&gt;// 如果报错内容包含 &quot;already initialized&quot;，说明其实已经好了，忽略它&lt;/span&gt;
      &lt;span class=&quot;pl-k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;already initialized&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;||&lt;/span&gt;
        &lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;used only once&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;pl-k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;pl-c&quot;&gt;// 如果是其他致命错误，清空锁以便下次重试&lt;/span&gt;
      &lt;span class=&quot;pl-s1&quot;&gt;wasmInitPromise&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;pl-k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;pl-k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;wasmInitPromise&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 dir=&quot;auto&quot;&gt;字体&lt;/h3&gt;
&lt;p dir=&quot;auto&quot;&gt;放在了public，并使用Workers assets方式读取&lt;br&gt;
&lt;code class=&quot;notranslate&quot;&gt;public\fonts\MiSans-Regular.ttf&lt;/code&gt;&lt;/p&gt;
&lt;h2 dir=&quot;auto&quot;&gt;API代码&lt;/h2&gt;
&lt;p dir=&quot;auto&quot;&gt;使用astro api 获取GET ID后&lt;/p&gt;
&lt;div class=&quot;highlight highlight-source-ts notranslate position-relative overflow-auto&quot; dir=&quot;auto&quot; data-snippet-clipboard-copy-content=&quot;export const GET: APIRoute = async ({ params, request }) =&amp;gt; {
  const { entry } = await getLiveEntry(&amp;quot;data&amp;quot;, params.id as string);
  if (!entry) return new Response(&amp;quot;Not Found&amp;quot;, { status: 404 });
  try {
    // --- 2. 这里的调用现在是“线程安全”的 ---
    await initializeWasm(yogaWasm, resvgWasm);

    // 字体持久化逻辑保持不变
    if (!fontCache) {
      const fontRes = await env.ASSETS.fetch(
        new URL(&amp;quot;/fonts/MiSans-Regular.ttf&amp;quot;, request.url),
      );
      fontCache = await fontRes.arrayBuffer();
    }

    // 3. Satori 渲染 SVG
    const svg = await satori(
      {
        type: &amp;quot;div&amp;quot;,
        props: {
          style: {
            height: &amp;quot;100%&amp;quot;,
            width: &amp;quot;100%&amp;quot;,
            display: &amp;quot;flex&amp;quot;,
            flexDirection: &amp;quot;column&amp;quot;,
            backgroundColor: &amp;quot;#000&amp;quot;,
            color: &amp;quot;#fff&amp;quot;,
            fontFamily: &amp;quot;MiSans&amp;quot;,
            border: &amp;quot;1px solid #222&amp;quot;,
          },
          children: [
            // ... 你的 UI 结构保持不变
            {
              type: &amp;quot;div&amp;quot;,
              props: {
                style: {
                  display: &amp;quot;flex&amp;quot;,
                  padding: &amp;quot;30px 40px&amp;quot;,
                  borderBottom: &amp;quot;1px solid #222&amp;quot;,
                  alignItems: &amp;quot;center&amp;quot;,
                },
                children: [
                  {
                    type: &amp;quot;div&amp;quot;,
                    props: {
                      style: {
                        border: &amp;quot;1px solid #444&amp;quot;,
                        borderRadius: &amp;quot;8px&amp;quot;,
                        padding: &amp;quot;4px 12px&amp;quot;,
                        color: &amp;quot;#888&amp;quot;,
                        fontSize: &amp;quot;24px&amp;quot;,
                      },
                      children: &amp;quot;#&amp;quot; + entry.id,
                    },
                  },
                ],
              },
            },
            {
              type: &amp;quot;div&amp;quot;,
              props: {
                style: {
                  display: &amp;quot;flex&amp;quot;,
                  flex: 1,
                  padding: &amp;quot;0 40px&amp;quot;,
                  alignItems: &amp;quot;center&amp;quot;,
                  justifyContent: &amp;quot;center&amp;quot;,
                },
                children: {
                  type: &amp;quot;h1&amp;quot;,
                  props: {
                    style: {
                      fontSize: &amp;quot;85px&amp;quot;,
                      fontWeight: &amp;quot;300&amp;quot;,
                      textAlign: &amp;quot;center&amp;quot;,
                      lineHeight: &amp;quot;1.3&amp;quot;,
                    },
                    children: entry.data.title,
                  },
                },
              },
            },
            {
              type: &amp;quot;div&amp;quot;,
              props: {
                style: {
                  display: &amp;quot;flex&amp;quot;,
                  justifyContent: &amp;quot;space-between&amp;quot;,
                  padding: &amp;quot;30px 40px&amp;quot;,
                  borderTop: &amp;quot;1px solid #222&amp;quot;,
                  color: &amp;quot;#666&amp;quot;,
                },
                children: [
                  {
                    type: &amp;quot;span&amp;quot;,
                    props: { children: formatDate(entry.data.createdAt) },
                  },
                  {
                    type: &amp;quot;span&amp;quot;,
                    props: { children: entry.data.category.name },
                  },
                ],
              },
            },
          ],
        },
      },
      {
        width: 1200,
        height: 630,
        fonts: [
          {
            name: &amp;quot;MiSans&amp;quot;,
            data: fontCache,
            weight: 400,
            style: &amp;quot;normal&amp;quot;,
          },
        ],
      },
    );

    // 4. Resvg 渲染 PNG
    const resvg = new Resvg(svg, {
      fitTo: { mode: &amp;quot;width&amp;quot;, value: 1200 },
    });
    const pngData = resvg.render();
    const pngBuffer = pngData.asPng();

    return new Response(new Uint8Array(pngBuffer) as any, {
      headers: {
        &amp;quot;Content-Type&amp;quot;: &amp;quot;image/png&amp;quot;,
        &amp;quot;Cache-Control&amp;quot;: &amp;quot;public, max-age=31536000, immutable&amp;quot;,
      },
    });
  } catch (e: any) {
    console.error(&amp;quot;OG Error:&amp;quot;, e.message);
    return new Response(`Error generating image: ${e.message}`, {
      status: 500,
    });
  }
};
&quot;&gt;&lt;pre class=&quot;notranslate&quot;&gt;&lt;span class=&quot;pl-k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;GET&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;APIRoute&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; request &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; entry &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;pl-en&quot;&gt;getLiveEntry&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;pl-smi&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;pl-k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;Not Found&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;status&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;404&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;pl-k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;pl-c&quot;&gt;// --- 2. 这里的调用现在是“线程安全”的 ---&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;pl-en&quot;&gt;initializeWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;yogaWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;resvgWasm&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;pl-c&quot;&gt;// 字体持久化逻辑保持不变&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;fontCache&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;fontRes&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;ASSETS&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;pl-k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;/fonts/MiSans-Regular.ttf&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;pl-s1&quot;&gt;fontCache&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;fontRes&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;arrayBuffer&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;pl-c&quot;&gt;// 3. Satori 渲染 SVG&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;svg&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;pl-en&quot;&gt;satori&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;height&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;100%&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;width&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;100%&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;display&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;flex&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;flexDirection&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;column&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;backgroundColor&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;#000&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;color&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;fontFamily&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;MiSans&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;border&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;1px solid #222&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;pl-c&quot;&gt;// ... 你的 UI 结构保持不变&lt;/span&gt;
            &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;display&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;flex&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;padding&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;30px 40px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;borderBottom&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;1px solid #222&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;alignItems&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;center&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;[&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                      &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;pl-c1&quot;&gt;border&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;1px solid #444&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;pl-c1&quot;&gt;borderRadius&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;8px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;pl-c1&quot;&gt;padding&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;4px 12px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;pl-c1&quot;&gt;color&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;#888&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;pl-c1&quot;&gt;fontSize&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;24px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;#&quot;&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-kos&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;display&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;flex&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;flex&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;padding&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;0 40px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;alignItems&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;center&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;justifyContent&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;center&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;h1&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                      &lt;span class=&quot;pl-c1&quot;&gt;fontSize&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;85px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;pl-c1&quot;&gt;fontWeight&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;300&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;pl-c1&quot;&gt;textAlign&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;center&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;pl-c1&quot;&gt;lineHeight&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;1.3&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-s1&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;display&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;flex&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;justifyContent&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;space-between&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;padding&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;30px 40px&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;borderTop&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;1px solid #222&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-c1&quot;&gt;color&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;#666&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;[&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;span&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-en&quot;&gt;formatDate&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;createdAt&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;span&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;pl-c1&quot;&gt;props&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;children&lt;/span&gt;: &lt;span class=&quot;pl-s1&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;pl-kos&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;pl-kos&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;pl-c1&quot;&gt;width&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;1200&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;pl-c1&quot;&gt;height&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;630&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;pl-c1&quot;&gt;fonts&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;name&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;MiSans&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;data&lt;/span&gt;: &lt;span class=&quot;pl-s1&quot;&gt;fontCache&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;weight&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;pl-c1&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;normal&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;pl-kos&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;pl-c&quot;&gt;// 4. Resvg 渲染 PNG&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;resvg&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Resvg&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;svg&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;pl-c1&quot;&gt;fitTo&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;mode&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;value&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;1200&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;pngData&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;resvg&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;pngBuffer&lt;/span&gt; &lt;span class=&quot;pl-c1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;pngData&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;asPng&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;pl-k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Uint8Array&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;pngBuffer&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;pl-smi&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;pl-c1&quot;&gt;headers&lt;/span&gt;: &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;pl-s&quot;&gt;&quot;Content-Type&quot;&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;image/png&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;pl-s&quot;&gt;&quot;Cache-Control&quot;&lt;/span&gt;: &lt;span class=&quot;pl-s&quot;&gt;&quot;public, max-age=31536000, immutable&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;: &lt;span class=&quot;pl-smi&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;pl-smi&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-en&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;&quot;OG Error:&quot;&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;pl-k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;pl-k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;pl-v&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;pl-s&quot;&gt;`Error generating image: &lt;span class=&quot;pl-s1&quot;&gt;&lt;span class=&quot;pl-kos&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;pl-s1&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;pl-c1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;/span&gt;`&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;pl-kos&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;pl-c1&quot;&gt;status&lt;/span&gt;: &lt;span class=&quot;pl-c1&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;pl-kos&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;pl-kos&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item></channel></rss>