veryfront 0.1.738 → 0.1.742
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/esm/cli/templates/manifest.js +3 -3
- package/esm/deno.js +1 -1
- package/esm/src/agent/ag-ui/sse-parser.d.ts.map +1 -1
- package/esm/src/agent/ag-ui/sse-parser.js +20 -12
- package/esm/src/agent/hosted/child-tool-input.js +1 -1
- package/esm/src/agent/react/use-chat/streaming/handler.d.ts.map +1 -1
- package/esm/src/agent/react/use-chat/streaming/handler.js +53 -39
- package/esm/src/fs/index.d.ts +1 -1
- package/esm/src/fs/index.d.ts.map +1 -1
- package/esm/src/fs/index.js +1 -1
- package/esm/src/mcp/http-transport.js +1 -1
- package/esm/src/mcp/server.d.ts.map +1 -1
- package/esm/src/mcp/server.js +1 -4
- package/esm/src/mcp/session.d.ts +23 -0
- package/esm/src/mcp/session.d.ts.map +1 -1
- package/esm/src/mcp/session.js +46 -3
- package/esm/src/modules/manifest/route-module-manifest.d.ts.map +1 -1
- package/esm/src/modules/manifest/route-module-manifest.js +12 -4
- package/esm/src/modules/react-loader/ssr-module-loader/cross-project-import-loader.d.ts.map +1 -1
- package/esm/src/modules/react-loader/ssr-module-loader/cross-project-import-loader.js +2 -1
- package/esm/src/modules/server/cross-project-source-limit.d.ts +7 -0
- package/esm/src/modules/server/cross-project-source-limit.d.ts.map +1 -0
- package/esm/src/modules/server/cross-project-source-limit.js +46 -0
- package/esm/src/modules/server/module-batch-handler.d.ts.map +1 -1
- package/esm/src/modules/server/module-batch-handler.js +3 -4
- package/esm/src/modules/server/module-server.d.ts.map +1 -1
- package/esm/src/modules/server/module-server.js +11 -1
- package/esm/src/oauth/handlers/init-handler.js +6 -6
- package/esm/src/oauth/providers/base.d.ts +3 -0
- package/esm/src/oauth/providers/base.d.ts.map +1 -1
- package/esm/src/oauth/providers/base.js +24 -2
- package/esm/src/platform/compat/fs.d.ts +6 -0
- package/esm/src/platform/compat/fs.d.ts.map +1 -1
- package/esm/src/platform/compat/fs.js +12 -0
- package/esm/src/provider/runtime-loader/tool-input-status.d.ts.map +1 -1
- package/esm/src/provider/runtime-loader/tool-input-status.js +16 -8
- package/esm/src/rendering/orchestrator/module-loader/dependency-resolver.d.ts +2 -0
- package/esm/src/rendering/orchestrator/module-loader/dependency-resolver.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/module-loader/dependency-resolver.js +23 -10
- package/esm/src/rendering/renderer-concurrency.d.ts.map +1 -1
- package/esm/src/rendering/renderer-concurrency.js +9 -2
- package/esm/src/security/sandbox/worker-permissions.d.ts +10 -7
- package/esm/src/security/sandbox/worker-permissions.d.ts.map +1 -1
- package/esm/src/security/sandbox/worker-permissions.js +32 -12
- package/esm/src/security/utils/constant-time.d.ts.map +1 -1
- package/esm/src/security/utils/constant-time.js +4 -1
- package/esm/src/server/services/rendering/ssr.service.d.ts.map +1 -1
- package/esm/src/server/services/rendering/ssr.service.js +6 -3
- package/esm/src/transforms/mdx/esm-module-loader/loader-helpers.d.ts +4 -0
- package/esm/src/transforms/mdx/esm-module-loader/loader-helpers.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/loader-helpers.js +22 -18
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/http-fetcher.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/http-fetcher.js +27 -8
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/import-rewriter.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/import-rewriter.js +24 -14
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.d.ts +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.js +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/nested-imports.d.ts +4 -0
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/nested-imports.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/nested-imports.js +45 -37
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/path-cache-lookup.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/path-cache-lookup.js +6 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.d.ts +5 -0
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.js +27 -2
- package/esm/src/transforms/mdx/esm-module-loader/types.d.ts +2 -0
- package/esm/src/transforms/mdx/esm-module-loader/types.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/utils/source-spans.d.ts +23 -0
- package/esm/src/transforms/mdx/esm-module-loader/utils/source-spans.d.ts.map +1 -0
- package/esm/src/transforms/mdx/esm-module-loader/utils/source-spans.js +188 -0
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/esm/src/workflow/executor/dag/index.d.ts.map +1 -1
- package/esm/src/workflow/executor/dag/index.js +9 -8
- package/esm/src/workflow/worker/workflow-worker.d.ts.map +1 -1
- package/esm/src/workflow/worker/workflow-worker.js +9 -1
- package/package.json +1 -1
|
@@ -39,9 +39,9 @@ export default {
|
|
|
39
39
|
"app/page.tsx": "'use client'\n\nimport { Chat, useChat } from 'veryfront/chat'\n\nexport default function CodeAgent(): JSX.Element {\n const chat = useChat({ api: '/api/ag-ui' })\n\n return (\n <Chat\n {...chat}\n className=\"flex-1 min-h-0\"\n placeholder=\"Describe what you want to build or fix...\"\n />\n )\n}\n",
|
|
40
40
|
"globals.css": "@import \"tailwindcss\";\n",
|
|
41
41
|
"README.md": "# Coding Agent\n\nAn AI assistant that can read, understand, and modify project files.\n\n## What's included\n\n- Coder agent with file system tools\n- Read, list, and edit files through conversation\n- Safe search/replace editing pattern\n\n## Structure\n\n```\nagents/coder.ts Agent with coding instructions\ntools/\n read-file.ts Read file contents\n list-files.ts List directory contents\n edit-file.ts Search and replace in files\napp/\n api/ag-ui/route.ts AG-UI endpoint\n page.tsx Chat interface\n```\n\nThis starter is not production-ready.\n",
|
|
42
|
-
"tools/edit-file.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { readTextFile,
|
|
43
|
-
"tools/list-files.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { readDir,
|
|
44
|
-
"tools/read-file.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { readTextFile,
|
|
42
|
+
"tools/edit-file.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { cwd, readTextFile, realPath, resolve, writeTextFile } from \"veryfront/fs\";\n\n/** True when `target` is the same as, or nested under, `root` (both canonical). */\nfunction isWithin(root: string, target: string): boolean {\n const r = root.replace(/\\\\/g, \"/\");\n const t = target.replace(/\\\\/g, \"/\");\n return t === r || t.startsWith(`${r}/`);\n}\n\nexport default tool({\n id: \"edit-file\",\n description: \"Edit a file by replacing a specific string with new content\",\n inputSchema: defineSchema((v) => v.object({\n path: v.string().describe(\"File path relative to the project root\"),\n search: v.string().describe(\"Exact string to find in the file\"),\n replace: v.string().describe(\"String to replace it with\"),\n }))(),\n execute: async ({ path, search, replace }) => {\n let projectDir: string;\n let absolute: string;\n try {\n // Canonicalize both sides so a symlink that points outside the project\n // is resolved to its real target before the containment check.\n projectDir = await realPath(cwd());\n absolute = await realPath(resolve(projectDir, path));\n } catch {\n return { error: `File not found: ${path}` };\n }\n if (!isWithin(projectDir, absolute)) {\n return { error: `Path escapes project directory: ${path}` };\n }\n\n const content = await readTextFile(absolute);\n if (!content.includes(search)) {\n return { error: \"Search string not found in file\" };\n }\n\n const updated = content.replace(search, replace);\n await writeTextFile(absolute, updated);\n return { path, success: true };\n },\n});\n",
|
|
43
|
+
"tools/list-files.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { cwd, readDir, realPath, resolve } from \"veryfront/fs\";\n\n/** True when `target` is the same as, or nested under, `root` (both canonical). */\nfunction isWithin(root: string, target: string): boolean {\n const r = root.replace(/\\\\/g, \"/\");\n const t = target.replace(/\\\\/g, \"/\");\n return t === r || t.startsWith(`${r}/`);\n}\n\nexport default tool({\n id: \"list-files\",\n description: \"List files in a project directory\",\n inputSchema: defineSchema((v) => v.object({\n directory: v\n .string()\n .default(\".\")\n .describe(\"Directory path relative to project root\"),\n extensions: v\n .array(v.string())\n .optional()\n .describe(\"Filter by file extensions (e.g. ['.ts', '.tsx'])\"),\n }))(),\n execute: async ({ directory, extensions }) => {\n let projectDir: string;\n let absolute: string;\n try {\n // Canonicalize both sides so a symlink that points outside the project\n // is resolved to its real target before the containment check.\n projectDir = await realPath(cwd());\n absolute = await realPath(resolve(projectDir, directory));\n } catch {\n return { error: `Directory not found: ${directory}` };\n }\n if (!isWithin(projectDir, absolute)) {\n return { error: `Path escapes project directory: ${directory}` };\n }\n\n const entries = await readDir(absolute);\n\n let files = entries\n .filter((e) => e.isFile)\n .map((e) => e.name);\n\n if (extensions?.length) {\n files = files.filter((f) =>\n extensions.some((ext) => f.endsWith(ext))\n );\n }\n\n return { directory, files, count: files.length };\n },\n});\n",
|
|
44
|
+
"tools/read-file.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { cwd, readTextFile, realPath, resolve } from \"veryfront/fs\";\n\n/** True when `target` is the same as, or nested under, `root` (both canonical). */\nfunction isWithin(root: string, target: string): boolean {\n const r = root.replace(/\\\\/g, \"/\");\n const t = target.replace(/\\\\/g, \"/\");\n return t === r || t.startsWith(`${r}/`);\n}\n\nexport default tool({\n id: \"read-file\",\n description: \"Read the contents of a file in the project\",\n inputSchema: defineSchema((v) => v.object({\n path: v.string().describe(\"File path relative to the project root\"),\n }))(),\n execute: async ({ path }) => {\n let projectDir: string;\n let absolute: string;\n try {\n // Canonicalize both sides so a symlink that points outside the project\n // is resolved to its real target before the containment check.\n projectDir = await realPath(cwd());\n absolute = await realPath(resolve(projectDir, path));\n } catch {\n return { error: `File not found: ${path}` };\n }\n if (!isWithin(projectDir, absolute)) {\n return { error: `Path escapes project directory: ${path}` };\n }\n const content = await readTextFile(absolute);\n return { path, content };\n },\n});\n",
|
|
45
45
|
"tsconfig.json": "{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"jsx\": \"react-jsx\",\n \"skipLibCheck\": true,\n \"esModuleInterop\": true,\n \"paths\": {\n \"@/*\": [\"./*\"]\n }\n },\n \"include\": [\"**/*.ts\", \"**/*.tsx\"],\n \"exclude\": [\"node_modules\"]\n}\n"
|
|
46
46
|
}
|
|
47
47
|
},
|
package/esm/deno.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse-parser.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/ag-ui/sse-parser.ts"],"names":[],"mappings":"AAGA,kFAAkF;AAClF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;CAmBpB,CAAC;AAEX,iDAAiD;AACjD,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAE1F,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,qEAAqE;AACrE,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,4CAA4C;AAC5C,MAAM,WAAW,2BAA2B;IAC1C,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,uBAAuB,KAAK,IAAI,CAAC;IACzD,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,sEAAsE;AACtE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE5D;AAED,kEAAkE;AAClE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGjG;AAED,+DAA+D;AAC/D,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACtC,SAAS,EAAE,MAAM,GAChB,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAEhC;AAED,0EAA0E;AAC1E,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAEvE;AAoLD,yGAAyG;AACzG,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"sse-parser.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/ag-ui/sse-parser.ts"],"names":[],"mappings":"AAGA,kFAAkF;AAClF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;CAmBpB,CAAC;AAEX,iDAAiD;AACjD,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAE1F,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,qEAAqE;AACrE,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,4CAA4C;AAC5C,MAAM,WAAW,2BAA2B;IAC1C,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,uBAAuB,KAAK,IAAI,CAAC;IACzD,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,sEAAsE;AACtE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE5D;AAED,kEAAkE;AAClE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGjG;AAED,+DAA+D;AAC/D,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACtC,SAAS,EAAE,MAAM,GAChB,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAEhC;AAED,0EAA0E;AAC1E,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAEvE;AAoLD,yGAAyG;AACzG,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,gBAAgB,CAAC,CAoD3B"}
|
|
@@ -197,20 +197,28 @@ export async function parseAgUiSseResponse(response, options = {}) {
|
|
|
197
197
|
else {
|
|
198
198
|
const reader = response.body.getReader();
|
|
199
199
|
let buffer = "";
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
200
|
+
// try/finally so an error/abort mid-read still releases the reader lock;
|
|
201
|
+
// otherwise the underlying ReadableStream stays locked and the response
|
|
202
|
+
// body leaks.
|
|
203
|
+
try {
|
|
204
|
+
while (true) {
|
|
205
|
+
const result = await reader.read();
|
|
206
|
+
if (result.done) {
|
|
207
|
+
const tail = decoder.decode();
|
|
208
|
+
if (tail.length > 0) {
|
|
209
|
+
rawChunks.push(tail);
|
|
210
|
+
buffer += tail;
|
|
211
|
+
}
|
|
212
|
+
break;
|
|
207
213
|
}
|
|
208
|
-
|
|
214
|
+
const decoded = decoder.decode(result.value, { stream: true });
|
|
215
|
+
rawChunks.push(decoded);
|
|
216
|
+
buffer += decoded;
|
|
217
|
+
buffer = consumeSseBuffer(run, buffer, options, state);
|
|
209
218
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
buffer = consumeSseBuffer(run, buffer, options, state);
|
|
219
|
+
}
|
|
220
|
+
finally {
|
|
221
|
+
reader.releaseLock();
|
|
214
222
|
}
|
|
215
223
|
}
|
|
216
224
|
if (options.onProgress) {
|
|
@@ -5,7 +5,7 @@ export const DEFAULT_HOSTED_CHILD_AGENT_ID = "invoke-agent-child";
|
|
|
5
5
|
export const getHostedChildForkToolInputSchema = defineSchema((v) => v.object({
|
|
6
6
|
description: v.string().describe("3-5 word task summary"),
|
|
7
7
|
prompt: v.string().describe("Detailed instructions for the task"),
|
|
8
|
-
context: v.record(v.string(), getJsonValueSchema()).describe("
|
|
8
|
+
context: v.record(v.string(), getJsonValueSchema()).default({}).describe("Structured data payload for the child task. Use this for critical facts, records, ids, decisions, and values the child must act on. Defaults to {} when the delegation has no record or evidence payload."),
|
|
9
9
|
project_id: v.string().optional().describe("Override project context. Use after studio_open_project."),
|
|
10
10
|
tools: v.array(v.string()).optional().describe("Tool subset for this fork. Omit = inherit all parent tools."),
|
|
11
11
|
model: v.string().optional().describe('Model override (e.g. "sonnet" for cheaper work).'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../../../src/src/agent/react/use-chat/streaming/handler.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAKV,kBAAkB,EAEnB,MAAM,YAAY,CAAC;AA8BpB,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,cAAc,EACpB,SAAS,EAAE,kBAAkB,GAC5B,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../../../src/src/agent/react/use-chat/streaming/handler.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAKV,kBAAkB,EAEnB,MAAM,YAAY,CAAC;AA8BpB,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,cAAc,EACpB,SAAS,EAAE,kBAAkB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAyDf;AAED,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,cAAc,EACpB,SAAS,EAAE,kBAAkB,GAC5B,OAAO,CAAC,IAAI,CAAC,CA4Cf"}
|
|
@@ -21,41 +21,48 @@ export async function handleStreamingResponse(body, callbacks) {
|
|
|
21
21
|
const state = createStreamingState();
|
|
22
22
|
const getBuildParts = () => buildCurrentParts(state.textBlocks, state.reasoningBlocks, state.toolCalls, state.steps, state.dataParts);
|
|
23
23
|
let buffer = "";
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
const raw = JSON.parse(data);
|
|
37
|
-
if (!raw || typeof raw !== "object")
|
|
24
|
+
// try/finally so a read error or a throwing event handler still releases
|
|
25
|
+
// the reader lock, otherwise the stream stays locked and leaks.
|
|
26
|
+
try {
|
|
27
|
+
while (true) {
|
|
28
|
+
const { done, value } = await reader.read();
|
|
29
|
+
if (done)
|
|
30
|
+
break;
|
|
31
|
+
buffer += decoder.decode(value, { stream: true });
|
|
32
|
+
const lines = buffer.split("\n");
|
|
33
|
+
buffer = lines.pop() ?? ""; // last element may be incomplete
|
|
34
|
+
for (const line of lines) {
|
|
35
|
+
if (!line.startsWith("data: ") || !line.trim())
|
|
38
36
|
continue;
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
const data = line.slice(6);
|
|
38
|
+
try {
|
|
39
|
+
const raw = JSON.parse(data);
|
|
40
|
+
if (!raw || typeof raw !== "object")
|
|
41
|
+
continue;
|
|
42
|
+
const parsed = raw;
|
|
43
|
+
processStreamEvent(parsed, state, callbacks, getBuildParts);
|
|
44
|
+
}
|
|
45
|
+
catch (_) {
|
|
46
|
+
/* expected: skip malformed JSON in SSE stream */
|
|
47
|
+
}
|
|
44
48
|
}
|
|
45
49
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
// Process any remaining buffered data
|
|
51
|
+
if (buffer.startsWith("data: ") && buffer.trim()) {
|
|
52
|
+
try {
|
|
53
|
+
const raw = JSON.parse(buffer.slice(6));
|
|
54
|
+
if (raw && typeof raw === "object") {
|
|
55
|
+
const parsed = raw;
|
|
56
|
+
processStreamEvent(parsed, state, callbacks, getBuildParts);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Skip invalid JSON
|
|
54
61
|
}
|
|
55
62
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
reader.releaseLock();
|
|
59
66
|
}
|
|
60
67
|
}
|
|
61
68
|
export async function handleAgUiStreamingResponse(body, callbacks) {
|
|
@@ -69,18 +76,25 @@ export async function handleAgUiStreamingResponse(body, callbacks) {
|
|
|
69
76
|
processChatStreamEvent(event, state, callbacks, getBuildParts);
|
|
70
77
|
}
|
|
71
78
|
};
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
// try/finally so a read error or a throwing event handler still releases
|
|
80
|
+
// the reader lock, otherwise the stream stays locked and leaks.
|
|
81
|
+
try {
|
|
82
|
+
while (true) {
|
|
83
|
+
const { done, value } = await reader.read();
|
|
84
|
+
if (done)
|
|
85
|
+
break;
|
|
86
|
+
const decoded = decodeAgUiSseChunk(decoderState, decoder.decode(value, { stream: true }));
|
|
87
|
+
for (const event of decoded.events) {
|
|
88
|
+
processDecodedEvents(event.chatEvents);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const flushed = flushAgUiSseChunk(decoderState);
|
|
92
|
+
for (const event of flushed.events) {
|
|
78
93
|
processDecodedEvents(event.chatEvents);
|
|
79
94
|
}
|
|
80
95
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
processDecodedEvents(event.chatEvents);
|
|
96
|
+
finally {
|
|
97
|
+
reader.releaseLock();
|
|
84
98
|
}
|
|
85
99
|
}
|
|
86
100
|
function processStreamEvent(parsed, state, callbacks, getBuildParts) {
|
package/esm/src/fs/index.d.ts
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* ```
|
|
29
29
|
*/
|
|
30
30
|
import "../../_dnt.polyfills.js";
|
|
31
|
-
export { createFileSystem, exists, type FileSystem, mkdir, readDir, readTextFile, remove, writeTextFile, } from "../platform/compat/fs.js";
|
|
31
|
+
export { createFileSystem, exists, type FileSystem, mkdir, readDir, readTextFile, realPath, remove, writeTextFile, } from "../platform/compat/fs.js";
|
|
32
32
|
export { basename, dirname, extname, join, resolve, } from "../platform/compat/path/index.js";
|
|
33
33
|
export { cwd } from "../platform/compat/process.js";
|
|
34
34
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/fs/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,yBAAyB,CAAC;AAGjC,OAAO,EACL,gBAAgB,EAChB,MAAM,EACN,KAAK,UAAU,EACf,KAAK,EACL,OAAO,EACP,YAAY,EACZ,MAAM,EACN,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,QAAQ,EACR,OAAO,EACP,OAAO,EACP,IAAI,EACJ,OAAO,GACR,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/fs/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,yBAAyB,CAAC;AAGjC,OAAO,EACL,gBAAgB,EAChB,MAAM,EACN,KAAK,UAAU,EACf,KAAK,EACL,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,QAAQ,EACR,OAAO,EACP,OAAO,EACP,IAAI,EACJ,OAAO,GACR,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAC"}
|
package/esm/src/fs/index.js
CHANGED
|
@@ -28,6 +28,6 @@
|
|
|
28
28
|
* ```
|
|
29
29
|
*/
|
|
30
30
|
import "../../_dnt.polyfills.js";
|
|
31
|
-
export { createFileSystem, exists, mkdir, readDir, readTextFile, remove, writeTextFile, } from "../platform/compat/fs.js";
|
|
31
|
+
export { createFileSystem, exists, mkdir, readDir, readTextFile, realPath, remove, writeTextFile, } from "../platform/compat/fs.js";
|
|
32
32
|
export { basename, dirname, extname, join, resolve, } from "../platform/compat/path/index.js";
|
|
33
33
|
export { cwd } from "../platform/compat/process.js";
|
|
@@ -76,7 +76,7 @@ export function createMCPHTTPHandler(dependencies) {
|
|
|
76
76
|
return createJSONResponse(rpcResponse, { headers: responseHeaders });
|
|
77
77
|
}
|
|
78
78
|
let sessionId;
|
|
79
|
-
if (sessionManager.
|
|
79
|
+
if (sessionManager.requiresSessionHeader()) {
|
|
80
80
|
sessionId = request.headers.get("MCP-Session-Id") ?? undefined;
|
|
81
81
|
if (!sessionId) {
|
|
82
82
|
return createJSONRPCErrorResponse(400, -32600, "Missing MCP-Session-Id header");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/src/mcp/server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAI7D,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,YAAY,CAAC;AAIjE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAUzE,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE,CAAC;AA2CzD,UAAU,cAAc;IACtB,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;CACH;AAWD,gDAAgD;AAChD,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,GAAG,SAAS,CAAC,CAAC;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,2BAA2B;AAC3B,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAC,UAAU,CASd;IACX,OAAO,CAAC,QAAQ,CAAkD;IAClE,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,iBAAiB,CAAC,CAA0B;IACpD,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,YAAY,CAAqC;IACzD,OAAO,CAAC,8BAA8B,CAAsC;IAC5E,OAAO,CAAC,kBAAkB,CAA+B;IACzD,OAAO,CAAC,mBAAmB,CAA8C;IAEzE,2EAA2E;IAC3E,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE;QAAE,OAAO,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;gBAElF,MAAM,EAAE,eAAe;IAWnC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAyCjC,kBAAkB,IAAI,IAAI;IAI1B,sBAAsB,IAAI,IAAI;IAI9B,oBAAoB,IAAI,IAAI;IAI5B;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI;IAK3D,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO;IAY5E,aAAa,CACX,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,oBAAoB,EAC9B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,CAAC;IAyB3B,OAAO,CAAC,QAAQ;IAkDhB,OAAO,CAAC,UAAU;YAgCJ,SAAS;IAgCvB,OAAO,CAAC,QAAQ;IA0IhB,OAAO,CAAC,qBAAqB;IAuB7B,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,YAAY;IA6CpB,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,SAAS;IAuCjB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,WAAW;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/src/mcp/server.ts"],"names":[],"mappings":"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"}
|
package/esm/src/mcp/server.js
CHANGED
|
@@ -493,10 +493,7 @@ export class MCPServer {
|
|
|
493
493
|
const p = toParamsRecord(params);
|
|
494
494
|
const level = p.level;
|
|
495
495
|
if (!MCPServer.LOG_LEVELS.includes(level)) {
|
|
496
|
-
return Promise.reject({
|
|
497
|
-
code: -32602,
|
|
498
|
-
message: `Invalid log level: ${level}. Valid levels: ${MCPServer.LOG_LEVELS.join(", ")}`,
|
|
499
|
-
});
|
|
496
|
+
return Promise.reject(new JsonRpcError(-32602, `Invalid log level: ${level}. Valid levels: ${MCPServer.LOG_LEVELS.join(", ")}`));
|
|
500
497
|
}
|
|
501
498
|
this.logLevel = level;
|
|
502
499
|
return Promise.resolve({});
|
package/esm/src/mcp/session.d.ts
CHANGED
|
@@ -1,9 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages MCP sessions for the Streamable HTTP transport.
|
|
3
|
+
* Sessions are created during initialization and validated on subsequent requests.
|
|
4
|
+
*
|
|
5
|
+
* Sessions expire after a period of inactivity so that clients which disconnect
|
|
6
|
+
* uncleanly (closed tab, crash, dropped network) don't leak entries forever.
|
|
7
|
+
* Expiry is lazy: stale entries are pruned on access, so no background timer is
|
|
8
|
+
* required.
|
|
9
|
+
*/
|
|
10
|
+
export interface SessionManagerOptions {
|
|
11
|
+
/** Inactivity TTL in ms (default 30 minutes). */
|
|
12
|
+
ttlMs?: number;
|
|
13
|
+
/** Clock, injectable for tests. Defaults to Date.now. */
|
|
14
|
+
now?: () => number;
|
|
15
|
+
}
|
|
1
16
|
export declare class SessionManager {
|
|
17
|
+
/** id -> last-seen timestamp (ms). */
|
|
2
18
|
private sessions;
|
|
19
|
+
private readonly ttlMs;
|
|
20
|
+
private readonly now;
|
|
21
|
+
private sessionHeaderRequired;
|
|
22
|
+
constructor(options?: SessionManagerOptions);
|
|
3
23
|
create(): string;
|
|
4
24
|
isValid(id: string): boolean;
|
|
5
25
|
terminate(id: string): void;
|
|
6
26
|
get size(): number;
|
|
7
27
|
clear(): void;
|
|
28
|
+
requiresSessionHeader(): boolean;
|
|
29
|
+
private isExpired;
|
|
30
|
+
private pruneExpired;
|
|
8
31
|
}
|
|
9
32
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/src/mcp/session.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/src/mcp/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,MAAM,WAAW,qBAAqB;IACpC,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,qBAAa,cAAc;IACzB,sCAAsC;IACtC,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,qBAAqB,CAAS;gBAE1B,OAAO,GAAE,qBAA0B;IAK/C,MAAM,IAAI,MAAM;IAQhB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAY5B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAK3B,IAAI,IAAI,IAAI,MAAM,CAGjB;IAED,KAAK,IAAI,IAAI;IAKb,qBAAqB,IAAI,OAAO;IAIhC,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,YAAY;CAMrB"}
|
package/esm/src/mcp/session.js
CHANGED
|
@@ -1,25 +1,68 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Manages MCP sessions for the Streamable HTTP transport.
|
|
3
3
|
* Sessions are created during initialization and validated on subsequent requests.
|
|
4
|
+
*
|
|
5
|
+
* Sessions expire after a period of inactivity so that clients which disconnect
|
|
6
|
+
* uncleanly (closed tab, crash, dropped network) don't leak entries forever.
|
|
7
|
+
* Expiry is lazy: stale entries are pruned on access, so no background timer is
|
|
8
|
+
* required.
|
|
4
9
|
*/
|
|
10
|
+
/** Default inactivity window before a session is considered expired (30 min). */
|
|
5
11
|
import * as dntShim from "../../_dnt.shims.js";
|
|
12
|
+
const DEFAULT_SESSION_TTL_MS = 30 * 60_000;
|
|
6
13
|
export class SessionManager {
|
|
7
|
-
|
|
14
|
+
/** id -> last-seen timestamp (ms). */
|
|
15
|
+
sessions = new Map();
|
|
16
|
+
ttlMs;
|
|
17
|
+
now;
|
|
18
|
+
sessionHeaderRequired = false;
|
|
19
|
+
constructor(options = {}) {
|
|
20
|
+
this.ttlMs = options.ttlMs ?? DEFAULT_SESSION_TTL_MS;
|
|
21
|
+
this.now = options.now ?? Date.now;
|
|
22
|
+
}
|
|
8
23
|
create() {
|
|
24
|
+
this.pruneExpired();
|
|
9
25
|
const id = dntShim.crypto.randomUUID();
|
|
10
|
-
this.sessions.
|
|
26
|
+
this.sessions.set(id, this.now());
|
|
27
|
+
this.sessionHeaderRequired = true;
|
|
11
28
|
return id;
|
|
12
29
|
}
|
|
13
30
|
isValid(id) {
|
|
14
|
-
|
|
31
|
+
const lastSeen = this.sessions.get(id);
|
|
32
|
+
if (lastSeen === undefined)
|
|
33
|
+
return false;
|
|
34
|
+
if (this.isExpired(lastSeen)) {
|
|
35
|
+
this.sessions.delete(id);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
// Touch: activity refreshes the inactivity window.
|
|
39
|
+
this.sessions.set(id, this.now());
|
|
40
|
+
return true;
|
|
15
41
|
}
|
|
16
42
|
terminate(id) {
|
|
17
43
|
this.sessions.delete(id);
|
|
44
|
+
if (this.sessions.size === 0)
|
|
45
|
+
this.sessionHeaderRequired = false;
|
|
18
46
|
}
|
|
19
47
|
get size() {
|
|
48
|
+
this.pruneExpired();
|
|
20
49
|
return this.sessions.size;
|
|
21
50
|
}
|
|
22
51
|
clear() {
|
|
23
52
|
this.sessions.clear();
|
|
53
|
+
this.sessionHeaderRequired = false;
|
|
54
|
+
}
|
|
55
|
+
requiresSessionHeader() {
|
|
56
|
+
return this.sessionHeaderRequired;
|
|
57
|
+
}
|
|
58
|
+
isExpired(lastSeen) {
|
|
59
|
+
return this.now() - lastSeen > this.ttlMs;
|
|
60
|
+
}
|
|
61
|
+
pruneExpired() {
|
|
62
|
+
const cutoff = this.now() - this.ttlMs;
|
|
63
|
+
for (const [id, lastSeen] of this.sessions) {
|
|
64
|
+
if (lastSeen < cutoff)
|
|
65
|
+
this.sessions.delete(id);
|
|
66
|
+
}
|
|
24
67
|
}
|
|
25
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-module-manifest.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/manifest/route-module-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"route-module-manifest.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/manifest/route-module-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAYH,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAyBD,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE7D;AAED,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,UAAQ,GAChB,IAAI,CAEN;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,KAAK,EAAE,MAAM,EACb,eAAe,GAAE,MAAM,EAAO,GAC7B,IAAI,CAwCN;AAED,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,KAAK,EAAE,MAAM,GACZ,aAAa,GAAG,IAAI,CAYtB;AAED,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,KAAK,EAAE,MAAM,GACZ,MAAM,EAAE,CAOV;AAED,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,KAAK,EAAE,MAAM,GACZ,MAAM,EAAE,CAQV;AAED,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,GAChB,IAAI,CA2BN;AAED,wBAAgB,sCAAsC,CACpD,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,KAAK,EAAE,MAAM,EACb,QAAQ,SAAK,GACZ,MAAM,EAAE,CAQV;AAED,wBAAgB,gBAAgB,IAAI;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5E,CAcA;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAU/D;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAIxC"}
|
|
@@ -10,9 +10,16 @@
|
|
|
10
10
|
* @module module-system/manifest/route-module-manifest
|
|
11
11
|
*/
|
|
12
12
|
import { serverLogger } from "../../utils/index.js";
|
|
13
|
+
import { LRUCache } from "../../utils/lru-wrapper.js";
|
|
13
14
|
const logger = serverLogger.component("route-module-manifest");
|
|
14
|
-
|
|
15
|
-
const
|
|
15
|
+
/** Bound on tracked routes; manifests are a regenerable preload optimization. */
|
|
16
|
+
const MAX_TRACKED_ROUTES = 2_000;
|
|
17
|
+
/** Bound on in-flight collections; abandoned ones (render errors) get evicted. */
|
|
18
|
+
const MAX_PENDING_COLLECTIONS = 2_000;
|
|
19
|
+
const manifestStore = new LRUCache({ maxEntries: MAX_TRACKED_ROUTES });
|
|
20
|
+
const pendingCollections = new LRUCache({
|
|
21
|
+
maxEntries: MAX_PENDING_COLLECTIONS,
|
|
22
|
+
});
|
|
16
23
|
function buildKey(projectSlug, route) {
|
|
17
24
|
return `${projectSlug ?? "default"}:${route || "index"}`;
|
|
18
25
|
}
|
|
@@ -132,7 +139,7 @@ export function generateModulePreloadHintsFromManifest(projectSlug, route, maxHi
|
|
|
132
139
|
export function getManifestStats() {
|
|
133
140
|
const routes = [];
|
|
134
141
|
let totalModules = 0;
|
|
135
|
-
for (const [key, manifest] of manifestStore) {
|
|
142
|
+
for (const [key, manifest] of manifestStore.entries()) {
|
|
136
143
|
routes.push({
|
|
137
144
|
route: key,
|
|
138
145
|
moduleCount: manifest.moduleCount,
|
|
@@ -144,7 +151,8 @@ export function getManifestStats() {
|
|
|
144
151
|
}
|
|
145
152
|
export function clearProjectManifests(projectSlug) {
|
|
146
153
|
const prefix = `${projectSlug}:`;
|
|
147
|
-
|
|
154
|
+
// Snapshot keys before deleting to avoid mutating during iteration.
|
|
155
|
+
for (const key of [...manifestStore.keys()]) {
|
|
148
156
|
if (!key.startsWith(prefix))
|
|
149
157
|
continue;
|
|
150
158
|
manifestStore.delete(key);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cross-project-import-loader.d.ts","sourceRoot":"","sources":["../../../../../src/src/modules/react-loader/ssr-module-loader/cross-project-import-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAInF,OAAO,EAAE,cAAc,IAAI,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cross-project-import-loader.d.ts","sourceRoot":"","sources":["../../../../../src/src/modules/react-loader/ssr-module-loader/cross-project-import-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAInF,OAAO,EAAE,cAAc,IAAI,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGzD,UAAU,uBAAuB;IAC/B,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrE,KAAK,IAAI,UAAU,CAAC;CACrB;AAED,UAAU,sCAAsC;IAC9C,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,OAAO,EAAE,IAAI,CACX,sBAAsB,EACtB,WAAW,GAAG,YAAY,GAAG,KAAK,GAAG,YAAY,GAAG,cAAc,GAAG,SAAS,CAC/E,CAAC;IACF,KAAK,EAAE,uBAAuB,CAAC;IAC/B,qBAAqB,EAAE,CAAC,CAAC,EACvB,iBAAiB,EAAE,MAAM,EACzB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KACxB,OAAO,CAAC,CAAC,CAAC,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,cAAc,CAAC;IAC3C,iBAAiB,CAAC,EAAE,OAAO,aAAa,CAAC;IACzC,UAAU,CAAC,EAAE,IAAI,CAAC,OAAO,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC;IACpD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAOD,wBAAsB,+BAA+B,CACnD,WAAW,EAAE,sCAAsC,GAClD,OAAO,CAAC,MAAM,CAAC,CA0GjB"}
|
|
@@ -7,6 +7,7 @@ import { HTTP_FETCH_TIMEOUT_MS } from "../../../utils/constants/http.js";
|
|
|
7
7
|
import { writeCacheFile } from "../../../utils/cache-file-ops.js";
|
|
8
8
|
import { rendererLogger as logger } from "../../../utils/index.js";
|
|
9
9
|
import { globalCrossProjectCache } from "./cache/index.js";
|
|
10
|
+
import { readLimitedCrossProjectSource } from "../../server/cross-project-source-limit.js";
|
|
10
11
|
function getRegistryBaseUrl(apiBaseUrl) {
|
|
11
12
|
const resolvedApiBaseUrl = apiBaseUrl || getApiBaseUrlEnv();
|
|
12
13
|
return resolvedApiBaseUrl.replace(/\/api\/?$/, "");
|
|
@@ -40,7 +41,7 @@ export async function transformCrossProjectImportFlow(flowOptions) {
|
|
|
40
41
|
detail: `Failed to fetch ${registryUrl}: ${response.status} ${response.statusText}`,
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
|
-
const sourceCode = await response
|
|
44
|
+
const sourceCode = await readLimitedCrossProjectSource(response, registryUrl);
|
|
44
45
|
const contentHash = await cache.hashContentAsync(sourceCode);
|
|
45
46
|
const ext = path.match(/\.(tsx?|jsx?|mdx)$/)?.[0] ?? ".tsx";
|
|
46
47
|
const syntheticFilePath = `cross-project/${projectRef}/@/${path}`;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Max size of a fetched cross-project module source, to bound memory use. */
|
|
2
|
+
export declare const MAX_CROSS_PROJECT_SOURCE_BYTES: number;
|
|
3
|
+
export declare class CrossProjectSourceTooLargeError extends Error {
|
|
4
|
+
constructor(registryUrl: string, maxBytes?: number);
|
|
5
|
+
}
|
|
6
|
+
export declare function readLimitedCrossProjectSource(response: Response, registryUrl: string, maxBytes?: number): Promise<string>;
|
|
7
|
+
//# sourceMappingURL=cross-project-source-limit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-project-source-limit.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/cross-project-source-limit.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,eAAO,MAAM,8BAA8B,QAAkB,CAAC;AAE9D,qBAAa,+BAAgC,SAAQ,KAAK;gBAC5C,WAAW,EAAE,MAAM,EAAE,QAAQ,SAAiC;CAI3E;AAED,wBAAsB,6BAA6B,CACjD,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,SAAiC,GACxC,OAAO,CAAC,MAAM,CAAC,CAwCjB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Max size of a fetched cross-project module source, to bound memory use. */
|
|
2
|
+
export const MAX_CROSS_PROJECT_SOURCE_BYTES = 5 * 1024 * 1024; // 5MB
|
|
3
|
+
export class CrossProjectSourceTooLargeError extends Error {
|
|
4
|
+
constructor(registryUrl, maxBytes = MAX_CROSS_PROJECT_SOURCE_BYTES) {
|
|
5
|
+
super(`Cross-project source exceeds size limit: ${registryUrl} (${maxBytes} bytes)`);
|
|
6
|
+
this.name = "CrossProjectSourceTooLargeError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export async function readLimitedCrossProjectSource(response, registryUrl, maxBytes = MAX_CROSS_PROJECT_SOURCE_BYTES) {
|
|
10
|
+
const declaredLength = Number(response.headers.get("content-length") ?? "");
|
|
11
|
+
if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
|
|
12
|
+
await response.body?.cancel();
|
|
13
|
+
throw new CrossProjectSourceTooLargeError(registryUrl, maxBytes);
|
|
14
|
+
}
|
|
15
|
+
if (!response.body) {
|
|
16
|
+
const text = await response.text();
|
|
17
|
+
if (new TextEncoder().encode(text).byteLength > maxBytes) {
|
|
18
|
+
throw new CrossProjectSourceTooLargeError(registryUrl, maxBytes);
|
|
19
|
+
}
|
|
20
|
+
return text;
|
|
21
|
+
}
|
|
22
|
+
const reader = response.body.getReader();
|
|
23
|
+
const decoder = new TextDecoder();
|
|
24
|
+
const chunks = [];
|
|
25
|
+
let totalBytes = 0;
|
|
26
|
+
try {
|
|
27
|
+
while (true) {
|
|
28
|
+
const { done, value } = await reader.read();
|
|
29
|
+
if (done)
|
|
30
|
+
break;
|
|
31
|
+
totalBytes += value.byteLength;
|
|
32
|
+
if (totalBytes > maxBytes) {
|
|
33
|
+
await reader.cancel();
|
|
34
|
+
throw new CrossProjectSourceTooLargeError(registryUrl, maxBytes);
|
|
35
|
+
}
|
|
36
|
+
chunks.push(decoder.decode(value, { stream: true }));
|
|
37
|
+
}
|
|
38
|
+
const tail = decoder.decode();
|
|
39
|
+
if (tail.length > 0)
|
|
40
|
+
chunks.push(tail);
|
|
41
|
+
return chunks.join("");
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
reader.releaseLock();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-batch-handler.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/module-batch-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAqDtE,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CA2K/F;
|
|
1
|
+
{"version":3,"file":"module-batch-handler.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/module-batch-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAqDtE,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CA2K/F;AA2JD;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAY1D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAKrE"}
|
|
@@ -298,10 +298,9 @@ function generateBatchBundle(successes, failures) {
|
|
|
298
298
|
* Converts ES module syntax to work within the bundle wrapper
|
|
299
299
|
*/
|
|
300
300
|
function transformExportsForBundle(code) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
.join("\n");
|
|
301
|
+
// Indent every line by two spaces. A single regex avoids allocating an
|
|
302
|
+
// intermediate array of lines per module on the batch hot path.
|
|
303
|
+
return code.replace(/^/gm, " ");
|
|
305
304
|
}
|
|
306
305
|
/**
|
|
307
306
|
* Clear the transform cache (on deployment or memory pressure)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-server.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/module-server.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAG5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"module-server.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/module-server.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAG5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAuBtE;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsDrD,CAAC;AAQF,MAAM,WAAW,mBAAmB;IAClC,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,uBAAuB;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CA0TzF;AA+PD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAGrD"}
|
|
@@ -15,6 +15,7 @@ import { applySSRImportRewrites } from "./ssr-import-rewriter.js";
|
|
|
15
15
|
import { addHMRTimestamps } from "../../transforms/esm/import-rewriter.js";
|
|
16
16
|
import { FRAMEWORK_ROOT, resolveFrameworkSourcePath, } from "../../platform/compat/framework-source-resolver.js";
|
|
17
17
|
import { getReactUrls, REACT_DEFAULT_VERSION } from "../../utils/constants/cdn.js";
|
|
18
|
+
import { readLimitedCrossProjectSource } from "./cross-project-source-limit.js";
|
|
18
19
|
const logger = serverLogger.component("module-server");
|
|
19
20
|
/**
|
|
20
21
|
* Embedded polyfills for compiled Deno binaries.
|
|
@@ -600,5 +601,14 @@ async function fetchCrossProjectSource(projectRef, filePath) {
|
|
|
600
601
|
});
|
|
601
602
|
return null;
|
|
602
603
|
}
|
|
603
|
-
|
|
604
|
+
try {
|
|
605
|
+
return await readLimitedCrossProjectSource(response, registryUrl);
|
|
606
|
+
}
|
|
607
|
+
catch (error) {
|
|
608
|
+
logger.warn("Cross-project source too large", {
|
|
609
|
+
registryUrl,
|
|
610
|
+
error: error instanceof Error ? error.message : String(error),
|
|
611
|
+
});
|
|
612
|
+
return null;
|
|
613
|
+
}
|
|
604
614
|
}
|