@agent-native/core 0.79.10 → 0.79.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/core/CHANGELOG.md +12 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/deploy/build.ts +343 -27
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +2 -2
- package/dist/deploy/build.d.ts +27 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +245 -26
- package/dist/deploy/build.js.map +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +1 -1
package/dist/deploy/build.js
CHANGED
|
@@ -46,6 +46,24 @@ export const NITRO_RUNTIME_IGNORE_PATTERNS = [
|
|
|
46
46
|
"**/*.test.mjs",
|
|
47
47
|
"**/*.test.cjs",
|
|
48
48
|
];
|
|
49
|
+
export const CLOUDFLARE_WORKER_ESBUILD_EXTERNALS = [
|
|
50
|
+
"mermaid",
|
|
51
|
+
"@excalidraw/excalidraw",
|
|
52
|
+
"@excalidraw/mermaid-to-excalidraw",
|
|
53
|
+
"pdf-parse",
|
|
54
|
+
"pdfjs-dist",
|
|
55
|
+
"@google/genai",
|
|
56
|
+
"chartjs-node-canvas",
|
|
57
|
+
"@napi-rs/canvas",
|
|
58
|
+
"@anthropic-ai/tokenizer",
|
|
59
|
+
"@resvg/resvg-js",
|
|
60
|
+
"playwright",
|
|
61
|
+
"playwright-core",
|
|
62
|
+
"chromium-bidi",
|
|
63
|
+
"chromium-bidi/*",
|
|
64
|
+
"@sparticuz/chromium-min",
|
|
65
|
+
"fsevents",
|
|
66
|
+
];
|
|
49
67
|
function normalizeConfiguredAppBasePath() {
|
|
50
68
|
return normalizeAppBasePath(process.env.VITE_APP_BASE_PATH || process.env.APP_BASE_PATH);
|
|
51
69
|
}
|
|
@@ -115,7 +133,8 @@ export function addImmutableAssetRouteRulesForClientBuild(routeRules, clientDir,
|
|
|
115
133
|
* `@agent-native/core/server`. This is the middle layer of the three-layer
|
|
116
134
|
* inheritance model: app local > workspace core > framework default.
|
|
117
135
|
*/
|
|
118
|
-
export function generateWorkerEntry(routes, pluginPaths, defaultPluginStems = [], actions = [], workspaceCore = null, immutableAssetPaths = [], builtAppBasePath = normalizeConfiguredAppBasePath()) {
|
|
136
|
+
export function generateWorkerEntry(routes, pluginPaths, defaultPluginStems = [], actions = [], workspaceCore = null, immutableAssetPaths = [], builtAppBasePath = normalizeConfiguredAppBasePath(), options = {}) {
|
|
137
|
+
const includeReactRouterSsr = options.includeReactRouterSsr ?? true;
|
|
119
138
|
const routeImports = [];
|
|
120
139
|
const routeRegistrations = [];
|
|
121
140
|
for (let i = 0; i < routes.length; i++) {
|
|
@@ -212,8 +231,8 @@ export function generateWorkerEntry(routes, pluginPaths, defaultPluginStems = []
|
|
|
212
231
|
return `
|
|
213
232
|
// Auto-generated worker entry point for ${preset}
|
|
214
233
|
import { H3, defineEventHandler, readBody, toResponse } from "h3";
|
|
215
|
-
import { createRequestHandler } from "react-router";
|
|
216
|
-
import * as serverBuild from "./server-build.js";
|
|
234
|
+
${includeReactRouterSsr ? 'import { createRequestHandler } from "react-router";' : ""}
|
|
235
|
+
${includeReactRouterSsr ? 'import * as serverBuild from "./server-build.js";' : ""}
|
|
217
236
|
|
|
218
237
|
function normalizeAppBasePath(value) {
|
|
219
238
|
if (!value || value === "/") return "";
|
|
@@ -529,6 +548,52 @@ function requestWithPathname(request, pathname) {
|
|
|
529
548
|
return new Request(url, request);
|
|
530
549
|
}
|
|
531
550
|
|
|
551
|
+
function isStaticAppShellRequest(request) {
|
|
552
|
+
if (request.method !== "GET" && request.method !== "HEAD") return false;
|
|
553
|
+
const p = stripAppBasePath(new URL(request.url).pathname);
|
|
554
|
+
if (
|
|
555
|
+
p.startsWith("/.well-known/") ||
|
|
556
|
+
p.startsWith("/_agent-native/") ||
|
|
557
|
+
isApiPath(p) ||
|
|
558
|
+
p === "/favicon.ico" ||
|
|
559
|
+
p === "/favicon.png" ||
|
|
560
|
+
/\\.\\w+$/.test(p)
|
|
561
|
+
) {
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
return true;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
async function fetchStaticAppShell(request, env) {
|
|
568
|
+
if (!env?.ASSETS || !isStaticAppShellRequest(request)) return null;
|
|
569
|
+
const basePath = getAppBasePath();
|
|
570
|
+
const p = stripAppBasePath(new URL(request.url).pathname);
|
|
571
|
+
const shellRequest = requestWithPathname(
|
|
572
|
+
requestWithMethod(request, "GET"),
|
|
573
|
+
"/index.html",
|
|
574
|
+
);
|
|
575
|
+
let response;
|
|
576
|
+
try {
|
|
577
|
+
response = await env.ASSETS.fetch(shellRequest);
|
|
578
|
+
} catch {
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
if (response.status === 404) return null;
|
|
582
|
+
if (request.method === "HEAD") {
|
|
583
|
+
return rewriteMountedResponse(
|
|
584
|
+
new Response(null, {
|
|
585
|
+
status: response.status,
|
|
586
|
+
statusText: response.statusText,
|
|
587
|
+
headers: response.headers,
|
|
588
|
+
}),
|
|
589
|
+
basePath,
|
|
590
|
+
p,
|
|
591
|
+
request,
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
return rewriteMountedResponse(response, basePath, p, request);
|
|
595
|
+
}
|
|
596
|
+
|
|
532
597
|
// API route handlers
|
|
533
598
|
${routeImports.join("\n")}
|
|
534
599
|
|
|
@@ -584,7 +649,8 @@ ${routeRegistrations.join("\n")}
|
|
|
584
649
|
// Register action routes (/_agent-native/actions/*)
|
|
585
650
|
${actionRegistrations.join("\n")}
|
|
586
651
|
|
|
587
|
-
|
|
652
|
+
${includeReactRouterSsr
|
|
653
|
+
? ` // SSR catch-all for React Router
|
|
588
654
|
const rrHandler = createRequestHandler(() => serverBuild);
|
|
589
655
|
app.all("/**", defineEventHandler(async (event) => {
|
|
590
656
|
const basePath = getAppBasePath();
|
|
@@ -615,7 +681,8 @@ ${actionRegistrations.join("\n")}
|
|
|
615
681
|
);
|
|
616
682
|
}
|
|
617
683
|
return rewriteMountedResponse(await rrHandler(request), basePath, p, request);
|
|
618
|
-
}))
|
|
684
|
+
}));`
|
|
685
|
+
: ""}
|
|
619
686
|
|
|
620
687
|
_handler = app.fetch.bind(app);
|
|
621
688
|
return _handler;
|
|
@@ -654,11 +721,166 @@ export default {
|
|
|
654
721
|
}
|
|
655
722
|
|
|
656
723
|
const handler = await getHandler();
|
|
657
|
-
|
|
724
|
+
const response = await handler(requestWithMountedApiPrefixStripped(request));
|
|
725
|
+
${includeReactRouterSsr
|
|
726
|
+
? " return response;"
|
|
727
|
+
: ` if (response.status === 404) {
|
|
728
|
+
const shellResponse = await fetchStaticAppShell(request, env);
|
|
729
|
+
if (shellResponse) return shellResponse;
|
|
730
|
+
}
|
|
731
|
+
return response;`}
|
|
658
732
|
}
|
|
659
733
|
};
|
|
660
734
|
`;
|
|
661
735
|
}
|
|
736
|
+
function escapeHtmlAttribute(value) {
|
|
737
|
+
return value
|
|
738
|
+
.replaceAll("&", "&")
|
|
739
|
+
.replaceAll('"', """)
|
|
740
|
+
.replaceAll("<", "<")
|
|
741
|
+
.replaceAll(">", ">");
|
|
742
|
+
}
|
|
743
|
+
function findReactRouterManifest(distDir) {
|
|
744
|
+
const assetsDir = path.join(distDir, "assets");
|
|
745
|
+
const manifestFile = fs
|
|
746
|
+
.readdirSync(assetsDir)
|
|
747
|
+
.find((file) => /^manifest-[\w-]+\.js$/.test(file));
|
|
748
|
+
if (!manifestFile) {
|
|
749
|
+
throw new Error(`React Router client manifest not found in ${assetsDir}`);
|
|
750
|
+
}
|
|
751
|
+
const source = fs.readFileSync(path.join(assetsDir, manifestFile), "utf8");
|
|
752
|
+
const match = source.match(/^window\.__reactRouterManifest=(.*);?\s*$/);
|
|
753
|
+
if (!match) {
|
|
754
|
+
throw new Error(`Could not parse React Router manifest ${manifestFile}`);
|
|
755
|
+
}
|
|
756
|
+
return JSON.parse(match[1].replace(/;$/, ""));
|
|
757
|
+
}
|
|
758
|
+
function collectModulePreloads(manifest, route) {
|
|
759
|
+
const paths = new Set();
|
|
760
|
+
const add = (value) => {
|
|
761
|
+
if (value)
|
|
762
|
+
paths.add(value);
|
|
763
|
+
};
|
|
764
|
+
add(manifest.url);
|
|
765
|
+
add(manifest.entry.module);
|
|
766
|
+
manifest.entry.imports?.forEach(add);
|
|
767
|
+
add(route.module);
|
|
768
|
+
route.imports?.forEach(add);
|
|
769
|
+
add(route.clientActionModule);
|
|
770
|
+
add(route.clientLoaderModule);
|
|
771
|
+
add(route.clientMiddlewareModule);
|
|
772
|
+
add(route.hydrateFallbackModule);
|
|
773
|
+
return [...paths];
|
|
774
|
+
}
|
|
775
|
+
function collectStylesheetLinks(manifest, route) {
|
|
776
|
+
return [...new Set([...(manifest.entry.css ?? []), ...(route.css ?? [])])];
|
|
777
|
+
}
|
|
778
|
+
function generateRouteModuleImportScript(manifest, route) {
|
|
779
|
+
const modules = [
|
|
780
|
+
["route0", route.module],
|
|
781
|
+
["route0_clientAction", route.clientActionModule],
|
|
782
|
+
["route0_clientLoader", route.clientLoaderModule],
|
|
783
|
+
["route0_clientMiddleware", route.clientMiddlewareModule],
|
|
784
|
+
["route0_hydrateFallback", route.hydrateFallbackModule],
|
|
785
|
+
];
|
|
786
|
+
const imports = modules
|
|
787
|
+
.filter(([, modulePath]) => modulePath)
|
|
788
|
+
.map(([name, modulePath]) => `import * as ${name} from ${JSON.stringify(modulePath)};`);
|
|
789
|
+
const parts = modules
|
|
790
|
+
.filter(([, modulePath]) => modulePath)
|
|
791
|
+
.map(([name]) => `...${name}`);
|
|
792
|
+
return [
|
|
793
|
+
`import ${JSON.stringify(manifest.url)};`,
|
|
794
|
+
...imports,
|
|
795
|
+
`window.__reactRouterRouteModules = {${JSON.stringify(route.id)}:{${parts.join(",")}}};`,
|
|
796
|
+
`import(${JSON.stringify(manifest.entry.module)});`,
|
|
797
|
+
].join("\n");
|
|
798
|
+
}
|
|
799
|
+
const EMPTY_REACT_ROUTER_TURBO_STREAM = '[{"_1":2,"_3":-5,"_4":-5},"loaderData",{},"actionData","errors"]\n';
|
|
800
|
+
// Manifest fallbacks cannot execute server loaders, so root loaders get the
|
|
801
|
+
// framework's default locale shape to keep hydration from reading undefined.
|
|
802
|
+
const DEFAULT_ROOT_LOADER_REACT_ROUTER_TURBO_STREAM = '[{"_1":2,"_3":-5,"_4":-5},"loaderData",{"_5":6},"actionData","errors","root",{"_7":8,"_9":10,"_11":12,"_13":14},"locale","en-US","preference",{"_7":15},"dir","ltr","messages",{},"system"]\n';
|
|
803
|
+
export function generateCloudflarePagesStaticShellFromManifest(manifest, basePath = normalizeConfiguredAppBasePath()) {
|
|
804
|
+
const rootRoute = manifest.routes.root;
|
|
805
|
+
if (!rootRoute) {
|
|
806
|
+
throw new Error("React Router manifest is missing the root route");
|
|
807
|
+
}
|
|
808
|
+
const modulePreloads = collectModulePreloads(manifest, rootRoute)
|
|
809
|
+
.map((href) => `<link rel="modulepreload" href="${escapeHtmlAttribute(href)}"/>`)
|
|
810
|
+
.join("");
|
|
811
|
+
const stylesheets = collectStylesheetLinks(manifest, rootRoute)
|
|
812
|
+
.map((href) => `<link rel="stylesheet" href="${escapeHtmlAttribute(href)}"/>`)
|
|
813
|
+
.join("");
|
|
814
|
+
const routeModuleScript = generateRouteModuleImportScript(manifest, rootRoute);
|
|
815
|
+
const context = {
|
|
816
|
+
basename: basePath || "/",
|
|
817
|
+
future: { unstable_optimizeDeps: false },
|
|
818
|
+
routeDiscovery: { mode: "initial" },
|
|
819
|
+
ssr: true,
|
|
820
|
+
isSpaMode: true,
|
|
821
|
+
};
|
|
822
|
+
const encodedInitialState = rootRoute.hasLoader
|
|
823
|
+
? DEFAULT_ROOT_LOADER_REACT_ROUTER_TURBO_STREAM
|
|
824
|
+
: EMPTY_REACT_ROUTER_TURBO_STREAM;
|
|
825
|
+
return `<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/><link rel="manifest" href="/manifest.json"/><link rel="icon" type="image/svg+xml" href="/favicon.svg"/>${modulePreloads}${stylesheets}</head><body><div style="display:flex;align-items:center;justify-content:center;height:100vh;width:100%"><svg role="status" aria-label="Loading" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="animation:an-spin 1s linear infinite;opacity:0.7"><path d="M21 12a9 9 0 1 1-6.219-8.56"></path></svg><style>@keyframes an-spin { to { transform: rotate(360deg) } } @media (prefers-color-scheme: dark) { html { background: #09090b; color: #fafafa } }</style></div><script>window.__reactRouterContext = ${JSON.stringify(context)};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());</script><script type="module" async="">${routeModuleScript}</script><!--$--><script>window.__reactRouterContext.streamController.enqueue(${JSON.stringify(encodedInitialState)});</script><!--$--><script>window.__reactRouterContext.streamController.close();</script><!--/$--><!--/$--></body></html>`;
|
|
826
|
+
}
|
|
827
|
+
function writeCloudflarePagesStaticShell({ serverDir, distDir, tmpDir, }) {
|
|
828
|
+
const serverEntry = path.join(serverDir, "index.js");
|
|
829
|
+
if (!fs.existsSync(serverEntry)) {
|
|
830
|
+
throw new Error(`React Router server build not found at ${serverEntry}`);
|
|
831
|
+
}
|
|
832
|
+
const outFile = path.join(distDir, "index.html");
|
|
833
|
+
const renderScript = path.join(tmpDir, "render-cloudflare-static-shell.mjs");
|
|
834
|
+
const basePath = normalizeConfiguredAppBasePath();
|
|
835
|
+
fs.writeFileSync(renderScript, `
|
|
836
|
+
import fs from "node:fs";
|
|
837
|
+
import { createRequire } from "node:module";
|
|
838
|
+
import { pathToFileURL } from "node:url";
|
|
839
|
+
|
|
840
|
+
const cwd = ${JSON.stringify(cwd)};
|
|
841
|
+
const serverEntry = ${JSON.stringify(serverEntry)};
|
|
842
|
+
const outFile = ${JSON.stringify(outFile)};
|
|
843
|
+
const basePath = ${JSON.stringify(basePath)};
|
|
844
|
+
|
|
845
|
+
const requireFromApp = createRequire(cwd + "/package.json");
|
|
846
|
+
const reactRouterEntry = requireFromApp.resolve("react-router");
|
|
847
|
+
const { createRequestHandler } = await import(pathToFileURL(reactRouterEntry).href);
|
|
848
|
+
const serverBuild = await import(pathToFileURL(serverEntry).href);
|
|
849
|
+
const handler = createRequestHandler(serverBuild, "production");
|
|
850
|
+
const pathname = basePath ? basePath + "/" : "/";
|
|
851
|
+
const response = await handler(
|
|
852
|
+
new Request(new URL(pathname, "https://agent-native.local"), {
|
|
853
|
+
headers: { "X-React-Router-SPA-Mode": "yes" },
|
|
854
|
+
}),
|
|
855
|
+
);
|
|
856
|
+
const html = await response.text();
|
|
857
|
+
|
|
858
|
+
if (!html || !html.includes("__reactRouterContext") || !html.includes("entry.client")) {
|
|
859
|
+
throw new Error("React Router did not render a usable Cloudflare Pages static shell");
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
fs.writeFileSync(outFile, html);
|
|
863
|
+
process.exit(0);
|
|
864
|
+
`);
|
|
865
|
+
try {
|
|
866
|
+
execFileSync(process.execPath, [renderScript], {
|
|
867
|
+
cwd,
|
|
868
|
+
env: {
|
|
869
|
+
...process.env,
|
|
870
|
+
NODE_ENV: process.env.NODE_ENV || "production",
|
|
871
|
+
IS_RR_BUILD_REQUEST: "yes",
|
|
872
|
+
},
|
|
873
|
+
stdio: "inherit",
|
|
874
|
+
});
|
|
875
|
+
console.log("[deploy] Wrote Cloudflare Pages static app shell.");
|
|
876
|
+
}
|
|
877
|
+
catch (error) {
|
|
878
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
879
|
+
console.warn(`[deploy] React Router static shell render failed; using manifest fallback. ${message}`);
|
|
880
|
+
fs.writeFileSync(outFile, generateCloudflarePagesStaticShellFromManifest(findReactRouterManifest(distDir), basePath));
|
|
881
|
+
console.log("[deploy] Wrote Cloudflare Pages static app shell fallback.");
|
|
882
|
+
}
|
|
883
|
+
}
|
|
662
884
|
/**
|
|
663
885
|
* Build for Cloudflare Pages.
|
|
664
886
|
* Output structure:
|
|
@@ -684,6 +906,9 @@ async function buildCloudflarePages() {
|
|
|
684
906
|
fs.mkdirSync(distDir, { recursive: true });
|
|
685
907
|
// Copy client assets to dist/
|
|
686
908
|
copyDir(clientDir, distDir);
|
|
909
|
+
const tmpDir = path.join(cwd, ".deploy-tmp");
|
|
910
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
911
|
+
writeCloudflarePagesStaticShell({ serverDir, distDir, tmpDir });
|
|
687
912
|
// Exclude _worker.js from being served as a public asset
|
|
688
913
|
fs.writeFileSync(path.join(distDir, ".assetsignore"), "_worker.js\n");
|
|
689
914
|
// Write a package.json inside _worker.js/ to tell wrangler this is a
|
|
@@ -700,30 +925,35 @@ async function buildCloudflarePages() {
|
|
|
700
925
|
const actions = await discoverActionFiles(cwd);
|
|
701
926
|
const missingDefaults = await getMissingDefaultPlugins(cwd);
|
|
702
927
|
const workspaceCore = await getWorkspaceCoreExports(cwd);
|
|
928
|
+
const includeReactRouterSsr = false;
|
|
703
929
|
const workspaceSlotCount = workspaceCore
|
|
704
930
|
? Object.keys(workspaceCore.plugins).length
|
|
705
931
|
: 0;
|
|
706
932
|
console.log(`[deploy] ${routes.length} API routes, ${actions.length} actions, ${plugins.length} plugins (${plugins.filter((p) => isNodeOnlyPlugin(p)).length} skipped as Node-only), ${missingDefaults.length} auto-mounted defaults${workspaceCore ? `, workspace-core ${workspaceCore.packageName} (${workspaceSlotCount} plugin slots)` : ""}`);
|
|
707
933
|
// Generate the worker entry
|
|
708
934
|
const immutableAssetPaths = collectImmutableAssetPaths(clientDir);
|
|
709
|
-
const entrySource = generateWorkerEntry(routes, plugins, missingDefaults, actions, workspaceCore, immutableAssetPaths);
|
|
935
|
+
const entrySource = generateWorkerEntry(routes, plugins, missingDefaults, actions, workspaceCore, immutableAssetPaths, normalizeConfiguredAppBasePath(), { includeReactRouterSsr });
|
|
710
936
|
// Create _worker.js output directory
|
|
711
937
|
const workerOutDir = path.join(distDir, "_worker.js");
|
|
712
938
|
fs.mkdirSync(workerOutDir, { recursive: true });
|
|
713
939
|
// Write the worker entry
|
|
714
940
|
const entryFile = path.join(workerOutDir, "index.js");
|
|
715
|
-
// Rewrite the server-build import to point at the copied files
|
|
716
|
-
|
|
941
|
+
// Rewrite the server-build import to point at the copied files when this
|
|
942
|
+
// worker intentionally includes React Router SSR.
|
|
943
|
+
const adjustedEntry = includeReactRouterSsr
|
|
944
|
+
? entrySource.replace(`import * as serverBuild from "./server-build.js";`, `import * as serverBuild from "./server/index.js";`)
|
|
945
|
+
: entrySource;
|
|
717
946
|
// Write a temp file for esbuild to bundle everything into a single worker entry.
|
|
718
|
-
//
|
|
719
|
-
|
|
720
|
-
|
|
947
|
+
// When React Router SSR is enabled, the server build is copied to tmp so
|
|
948
|
+
// esbuild can resolve it. Cloudflare Pages currently uses a static app shell
|
|
949
|
+
// instead so the worker stays under the platform bundle size limit.
|
|
721
950
|
// Name the entry "index.js" so esbuild outputs index.js in the outdir,
|
|
722
951
|
// matching the _worker.js/index.js entry point that Cloudflare Pages expects.
|
|
723
952
|
const tmpEntry = path.join(tmpDir, "index.js");
|
|
724
953
|
fs.writeFileSync(tmpEntry, adjustedEntry);
|
|
725
|
-
|
|
726
|
-
|
|
954
|
+
if (includeReactRouterSsr) {
|
|
955
|
+
copyDir(serverDir, path.join(tmpDir, "server"));
|
|
956
|
+
}
|
|
727
957
|
// Create a require shim so CJS require("fs") calls resolve via ESM imports.
|
|
728
958
|
// This is injected via esbuild --inject to replace its broken __require shim.
|
|
729
959
|
fs.writeFileSync(path.join(tmpDir, "_require-shim.js"), generateRequireShim());
|
|
@@ -784,18 +1014,7 @@ async function buildCloudflarePages() {
|
|
|
784
1014
|
// files. Both import sites degrade gracefully when the runtime import
|
|
785
1015
|
// fails: context-xray token counts fall back to char/4 estimates and the
|
|
786
1016
|
// OG image route falls back to SVG.
|
|
787
|
-
const heavyClientExternals =
|
|
788
|
-
"mermaid",
|
|
789
|
-
"@excalidraw/excalidraw",
|
|
790
|
-
"@excalidraw/mermaid-to-excalidraw",
|
|
791
|
-
"pdf-parse",
|
|
792
|
-
"pdfjs-dist",
|
|
793
|
-
"@google/genai",
|
|
794
|
-
"chartjs-node-canvas",
|
|
795
|
-
"@napi-rs/canvas",
|
|
796
|
-
"@anthropic-ai/tokenizer",
|
|
797
|
-
"@resvg/resvg-js",
|
|
798
|
-
].map((p) => `--external:${p}`);
|
|
1017
|
+
const heavyClientExternals = CLOUDFLARE_WORKER_ESBUILD_EXTERNALS.map((p) => `--external:${p}`);
|
|
799
1018
|
execFileSync(esbuildBin, [
|
|
800
1019
|
tmpEntry,
|
|
801
1020
|
"--bundle",
|