mirror of
https://github.com/morluto/rea.git
synced 2026-10-12 02:19:24 +00:00
perf(mcp): reduce Windows startup module resolution (#1814)
perf(mcp): bundle internal modules to reduce Windows startup I/O
This commit is contained in:
Generated
+3
-20
@@ -64,6 +64,7 @@
|
||||
"lint-staged": "16.4.0",
|
||||
"oxfmt": "0.72.0",
|
||||
"oxlint": "1.87.0",
|
||||
"rolldown": "1.2.12",
|
||||
"turbo": "2.11.7",
|
||||
"typescript": "7.0.2",
|
||||
"typescript-termux": "npm:[email protected]",
|
||||
@@ -1128,7 +1129,6 @@
|
||||
"integrity": "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/oxc-project"
|
||||
}
|
||||
@@ -2117,7 +2117,6 @@
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2135,7 +2134,6 @@
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2153,7 +2151,6 @@
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2171,7 +2168,6 @@
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2189,7 +2185,6 @@
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2207,7 +2202,6 @@
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2228,7 +2222,6 @@
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2249,7 +2242,6 @@
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2270,7 +2262,6 @@
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2291,7 +2282,6 @@
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2312,7 +2302,6 @@
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2333,7 +2322,6 @@
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2351,7 +2339,6 @@
|
||||
"os": [
|
||||
"openharmony"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2369,7 +2356,6 @@
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2387,7 +2373,6 @@
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
@@ -2397,8 +2382,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
|
||||
"integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.64.1",
|
||||
@@ -6723,11 +6707,10 @@
|
||||
},
|
||||
"node_modules/rolldown": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.12.tgz",
|
||||
"resolved": "https://mirrors.cloud.tencent.com/npm/rolldown/-/rolldown-1.2.12.tgz",
|
||||
"integrity": "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@oxc-project/types": "=0.152.0",
|
||||
"@rolldown/pluginutils": "^1.0.0"
|
||||
|
||||
+6
-5
@@ -249,8 +249,8 @@
|
||||
"verify:evm:interface": "npm run build:cached && node scripts/verify-evm-interface.mjs",
|
||||
"verify:recorded:crash": "npm run build:cached && node scripts/verify-recorded-crash.mjs",
|
||||
"mcp-catalog:check:built": "node scripts/generate-mcp-tool-catalog.mjs --check",
|
||||
"compile": "node scripts/clean-build-output.mjs && tsc -p tsconfig.build.json",
|
||||
"compile:termux": "node scripts/clean-build-output.mjs && node --max-old-space-size=3072 node_modules/typescript-termux/lib/tsc.js -p tsconfig.build.json",
|
||||
"compile": "node scripts/clean-build-output.mjs && tsc -p tsconfig.build.json && node scripts/bundle-mcp-runtime.mjs",
|
||||
"compile:termux": "node scripts/clean-build-output.mjs && node --max-old-space-size=3072 node_modules/typescript-termux/lib/tsc.js -p tsconfig.build.json && node scripts/bundle-mcp-runtime.mjs",
|
||||
"artifacts:mcp-catalog": "node scripts/generate-mcp-tool-catalog.mjs",
|
||||
"artifacts:skills": "node scripts/generate-skill-metadata.mjs",
|
||||
"artifacts:product-catalog": "node scripts/generate-product-catalog.mjs",
|
||||
@@ -285,6 +285,7 @@
|
||||
"canonicalize": "3.0.0",
|
||||
"cross-spawn": "7.0.6",
|
||||
"diff": "9.0.0",
|
||||
"evmole": "0.9.3",
|
||||
"har-schema": "2.0.0",
|
||||
"ignore": "7.0.6",
|
||||
"incur": "0.6.1",
|
||||
@@ -301,9 +302,8 @@
|
||||
"stream-json": "3.7.0",
|
||||
"write-file-atomic": "7.0.0",
|
||||
"ws": "8.21.0",
|
||||
"zod": "4.4.3",
|
||||
"evmole": "0.9.3",
|
||||
"yaml": "2.9.0"
|
||||
"yaml": "2.9.0",
|
||||
"zod": "4.4.3"
|
||||
},
|
||||
"overrides": {
|
||||
"vitepress": {
|
||||
@@ -324,6 +324,7 @@
|
||||
"lint-staged": "16.4.0",
|
||||
"oxfmt": "0.72.0",
|
||||
"oxlint": "1.87.0",
|
||||
"rolldown": "1.2.12",
|
||||
"turbo": "2.11.7",
|
||||
"typescript": "7.0.2",
|
||||
"typescript-termux": "npm:[email protected]",
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export const bundleMcpRuntime: (root: string) => Promise<void>;
|
||||
@@ -0,0 +1,104 @@
|
||||
import { parse } from "@babel/parser";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
|
||||
/**
|
||||
* Reduce filesystem resolution during MCP startup. Keep dependencies external,
|
||||
* dynamic imports lazy, and the original compiled files for CLI/worker entrypoints.
|
||||
*/
|
||||
export const bundleMcpRuntime = async (root) => {
|
||||
const compiledRoot = join(root, "dist");
|
||||
const { rolldown, RUNTIME_MODULE_ID } = await import("rolldown");
|
||||
const { imports = {} } = JSON.parse(
|
||||
await readFile(join(root, "package.json"), "utf8"),
|
||||
);
|
||||
const bundle = await rolldown({
|
||||
input: { main: join(compiledRoot, "main.js") },
|
||||
platform: "node",
|
||||
treeshake: false,
|
||||
external: (source) => !source.startsWith(".") && !isAbsolute(source),
|
||||
plugins: [
|
||||
{
|
||||
name: "preserve-compiled-module-locations",
|
||||
transform(code, id) {
|
||||
if (id === RUNTIME_MODULE_ID) return null;
|
||||
if (!code.includes("import.meta")) return null;
|
||||
const sourcePath = relative(compiledRoot, id);
|
||||
if (
|
||||
isAbsolute(sourcePath) ||
|
||||
sourcePath === ".." ||
|
||||
sourcePath.startsWith(`..${sep}`)
|
||||
)
|
||||
throw new Error(`MCP bundle input is outside dist: ${id}`);
|
||||
// All chunks are directly under dist/mcp. Preserve the original
|
||||
// module URL, including URL escaping, for bridges and createRequire.
|
||||
const moduleUrl = `new URL(${JSON.stringify(`../${sourcePath.split(sep).map(encodeURIComponent).join("/")}`)}, import.meta.url).href`;
|
||||
const edits = [];
|
||||
const visit = (node) => {
|
||||
if (node === null || typeof node !== "object") return;
|
||||
const isMeta = (value) =>
|
||||
value?.type === "MetaProperty" &&
|
||||
value.meta.name === "import" &&
|
||||
value.property.name === "meta";
|
||||
if (
|
||||
node.type === "CallExpression" &&
|
||||
node.callee.type === "MemberExpression" &&
|
||||
!node.callee.computed &&
|
||||
isMeta(node.callee.object) &&
|
||||
node.callee.property.name === "resolve" &&
|
||||
node.arguments.length === 1 &&
|
||||
node.arguments[0].type === "StringLiteral" &&
|
||||
Object.hasOwn(imports, node.arguments[0].value)
|
||||
)
|
||||
// Package imports resolve in the same package scope after bundling.
|
||||
return;
|
||||
if (
|
||||
node.type === "MemberExpression" &&
|
||||
!node.computed &&
|
||||
isMeta(node.object) &&
|
||||
node.property.name === "url"
|
||||
) {
|
||||
edits.push({ start: node.start, end: node.end });
|
||||
return;
|
||||
}
|
||||
if (isMeta(node))
|
||||
throw new Error(
|
||||
`Unsupported import.meta use in MCP bundle: ${id}`,
|
||||
);
|
||||
for (const value of Object.values(node)) {
|
||||
if (Array.isArray(value)) value.forEach(visit);
|
||||
else visit(value);
|
||||
}
|
||||
};
|
||||
visit(parse(code, { sourceType: "module" }).program);
|
||||
for (const { start, end } of edits.sort((a, b) => b.start - a.start))
|
||||
code = code.slice(0, start) + moduleUrl + code.slice(end);
|
||||
return { code, map: null };
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
try {
|
||||
await bundle.write({
|
||||
dir: join(compiledRoot, "mcp"),
|
||||
format: "esm",
|
||||
entryFileNames: "[name].js",
|
||||
chunkFileNames: "[name]-[hash].js",
|
||||
codeSplitting: true,
|
||||
strictExecutionOrder: true,
|
||||
minify: false,
|
||||
sourcemap: false,
|
||||
});
|
||||
} finally {
|
||||
await bundle.close();
|
||||
}
|
||||
};
|
||||
|
||||
if (
|
||||
process.argv[1] !== undefined &&
|
||||
pathToFileURL(resolve(process.argv[1])).href === import.meta.url
|
||||
)
|
||||
await bundleMcpRuntime(
|
||||
resolve(dirname(fileURLToPath(import.meta.url)), ".."),
|
||||
);
|
||||
@@ -46,6 +46,7 @@ if (await pathExists(join(root, "src"))) {
|
||||
} else {
|
||||
for (const path of [
|
||||
"dist/main.js",
|
||||
"dist/mcp/main.js",
|
||||
"dist/mcpDoctor.js",
|
||||
"dist/cli.js",
|
||||
"dist/cliOutput.js",
|
||||
|
||||
+4
-4
@@ -5,7 +5,7 @@ import { dirname, join, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
// Route production MCP before importing Incur. Incur owns registration helpers
|
||||
// such as `mcp add`, while only dist/main.js may serve the stdio tool catalog.
|
||||
// such as `mcp add`, while the MCP runtime serves the stdio tool catalog.
|
||||
const args = process.argv.slice(2);
|
||||
const { default: packageJson } = await import("../package.json", {
|
||||
with: { type: "json" },
|
||||
@@ -31,9 +31,9 @@ if (
|
||||
}
|
||||
|
||||
const runtimeFiles = isMcpMode
|
||||
? ["dist/main.js"]
|
||||
? ["dist/mcp/main.js"]
|
||||
: isMcpDoctorMode
|
||||
? ["dist/main.js", "dist/mcpDoctor.js"]
|
||||
? ["dist/mcp/main.js", "dist/mcpDoctor.js"]
|
||||
: ["dist/cli.js", "dist/cliOutput.js", "dist/cli/streamedJsonOutput.js"];
|
||||
|
||||
if (!(await compiledRuntimeExists(runtimeFiles))) {
|
||||
@@ -42,7 +42,7 @@ if (!(await compiledRuntimeExists(runtimeFiles))) {
|
||||
);
|
||||
process.exitCode = 1;
|
||||
} else if (isMcpMode) {
|
||||
const { runEntrypoint } = await import("../dist/main.js");
|
||||
const { runEntrypoint } = await import("../dist/mcp/main.js");
|
||||
await runEntrypoint();
|
||||
} else if (isMcpDoctorMode) {
|
||||
const { runProductionMcpDoctorCli } = await import("../dist/mcpDoctor.js");
|
||||
|
||||
@@ -12,6 +12,7 @@ describe("executable dispatcher", () => {
|
||||
const scripts = await workspace.mkdir("scripts");
|
||||
await workspace.mkdir("dist");
|
||||
await workspace.mkdir("dist/cli");
|
||||
await workspace.mkdir("dist/mcp");
|
||||
await Promise.all([
|
||||
copyFile("scripts/rea.mjs", join(scripts, "rea.mjs")),
|
||||
workspace.write(
|
||||
@@ -19,7 +20,7 @@ describe("executable dispatcher", () => {
|
||||
JSON.stringify({ type: "module", version: "1.0.0" }),
|
||||
),
|
||||
workspace.write(
|
||||
"dist/main.js",
|
||||
"dist/mcp/main.js",
|
||||
'export const runEntrypoint = () => process.stdout.write(JSON.stringify({ adapter: "mcp" }));\n',
|
||||
),
|
||||
workspace.write(
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
import { readFile, readdir } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
|
||||
import { describe, expect } from "vitest";
|
||||
|
||||
import { bundleMcpRuntime } from "../../../scripts/bundle-mcp-runtime.mjs";
|
||||
import { workspaceCliTest } from "../../support/cli/workspaceCliFixture.js";
|
||||
|
||||
describe("MCP runtime bundle", () => {
|
||||
workspaceCliTest(
|
||||
"preserves module locations, lazy side effects, package resolution and worker entrypoints",
|
||||
async ({ processes, workspace }) => {
|
||||
await workspace.mkdir("dist/provider");
|
||||
await workspace.mkdir("dist/composition");
|
||||
await workspace.mkdir("bridge");
|
||||
await workspace.mkdir("node_modules/external-probe");
|
||||
const files = {
|
||||
"package.json": JSON.stringify({
|
||||
type: "module",
|
||||
imports: {
|
||||
"#javascript-analysis-worker":
|
||||
"./dist/composition/javascriptAnalysisWorkerProcess.js",
|
||||
},
|
||||
}),
|
||||
"bridge/resource.txt": "bridge resource\n",
|
||||
"node_modules/external-probe/package.json": JSON.stringify({
|
||||
name: "external-probe",
|
||||
main: "index.cjs",
|
||||
}),
|
||||
"node_modules/external-probe/index.cjs": 'module.exports = "external";',
|
||||
"dist/provider/probe λ.js": `
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { createRequire } from 'node:module';
|
||||
globalThis.effects ??= [];
|
||||
globalThis.effects.push('provider');
|
||||
export const facts = {
|
||||
url: import.meta.url,
|
||||
resource: readFileSync(new URL('../../bridge/resource.txt', import.meta.url), 'utf8'),
|
||||
external: createRequire(import.meta.url)('external-probe'),
|
||||
worker: import.meta.resolve('#javascript-analysis-worker')
|
||||
};`,
|
||||
"dist/lazy.js": `
|
||||
globalThis.effects.push('lazy');
|
||||
export const lazyUrl = import.meta.url;`,
|
||||
"dist/composition/javascriptAnalysisWorkerProcess.js":
|
||||
'process.stdout.write("worker-entry");',
|
||||
"dist/main.js": `
|
||||
import { facts } from './provider/probe λ.js';
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
globalThis.effects.push('main');
|
||||
export const run = async () => {
|
||||
const beforeLazy = [...globalThis.effects];
|
||||
const { lazyUrl } = await import('./lazy.js');
|
||||
return {
|
||||
...facts, beforeLazy, afterLazy: globalThis.effects, lazyUrl,
|
||||
workerOutput: execFileSync(process.execPath, [fileURLToPath(facts.worker)], { encoding: 'utf8' })
|
||||
};
|
||||
};`,
|
||||
};
|
||||
for (const [path, contents] of Object.entries(files))
|
||||
await workspace.write(path, contents);
|
||||
const invoke = async (entry: string) => {
|
||||
const moduleUrl = pathToFileURL(join(workspace.root, entry)).href;
|
||||
const result = await processes.run(
|
||||
process.execPath,
|
||||
[
|
||||
"--input-type=module",
|
||||
"--eval",
|
||||
`const { run } = await import(${JSON.stringify(moduleUrl)}); process.stdout.write(JSON.stringify(await run()));`,
|
||||
],
|
||||
{ cwd: workspace.root },
|
||||
);
|
||||
expect(result.exitCode).toBe(0);
|
||||
return JSON.parse(result.stdout) as unknown;
|
||||
};
|
||||
const original = await invoke("dist/main.js");
|
||||
await bundleMcpRuntime(workspace.root);
|
||||
const bundled = await invoke("dist/mcp/main.js");
|
||||
expect(bundled).toEqual(original);
|
||||
expect(bundled).toMatchObject({
|
||||
resource: "bridge resource\n",
|
||||
external: "external",
|
||||
beforeLazy: ["provider", "main"],
|
||||
afterLazy: ["provider", "main", "lazy"],
|
||||
workerOutput: "worker-entry",
|
||||
});
|
||||
for (const [path, contents] of Object.entries(files))
|
||||
expect(await readFile(join(workspace.root, path), "utf8")).toBe(
|
||||
contents,
|
||||
);
|
||||
expect(
|
||||
(await readdir(join(workspace.root, "dist/mcp"))).length,
|
||||
).toBeGreaterThan(1);
|
||||
},
|
||||
);
|
||||
|
||||
workspaceCliTest(
|
||||
"rejects module-relative resolution and unknown import metadata during the build",
|
||||
async ({ workspace }) => {
|
||||
await workspace.mkdir("dist");
|
||||
await workspace.write("package.json", '{"type":"module"}');
|
||||
for (const expression of [
|
||||
"import.meta.resolve('./worker.js')",
|
||||
"import.meta.env",
|
||||
]) {
|
||||
await workspace.write(
|
||||
"dist/main.js",
|
||||
`export const value = ${expression};`,
|
||||
);
|
||||
await expect(bundleMcpRuntime(workspace.root)).rejects.toThrow(
|
||||
"Unsupported import.meta use in MCP bundle",
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -10,6 +10,7 @@
|
||||
"package-lock.json",
|
||||
"scripts/check-dependency-install.mjs",
|
||||
"scripts/clean-build-output.mjs",
|
||||
"scripts/bundle-mcp-runtime.mjs",
|
||||
"scripts/generate-package-metadata.mjs",
|
||||
"src/**/*.ts",
|
||||
"!src/**/*.test.ts",
|
||||
|
||||
Reference in New Issue
Block a user