veryfront 0.1.739 → 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/deno.js +1 -1
- package/esm/src/agent/hosted/child-tool-input.js +1 -1
- package/esm/src/mcp/http-transport.js +1 -1
- 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/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/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 -18
- 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/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/worker/workflow-worker.d.ts.map +1 -1
- package/esm/src/workflow/worker/workflow-worker.js +9 -1
- package/package.json +1 -1
|
@@ -6,11 +6,10 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module security/sandbox/worker-permissions
|
|
8
8
|
*/
|
|
9
|
-
/**
|
|
10
|
-
* Deno Worker permission object.
|
|
11
|
-
* See: https://docs.deno.com/runtime/fundamentals/permissions/
|
|
12
|
-
*/
|
|
13
9
|
import * as dntShim from "../../../_dnt.shims.js";
|
|
10
|
+
import { getFrameworkRootFromMeta } from "../../platform/compat/vfs-paths.js";
|
|
11
|
+
import { getHostEnv } from "../../platform/compat/process.js";
|
|
12
|
+
import { getCacheBaseDir, getHttpBundleCacheDir, getMdxEsmCacheDir, } from "../../utils/cache-dir.js";
|
|
14
13
|
// Cache compiled binary check — Deno.execPath() is a syscall that never changes at runtime
|
|
15
14
|
const _isCompiledBinary = (() => {
|
|
16
15
|
try {
|
|
@@ -24,6 +23,27 @@ const _isCompiledBinary = (() => {
|
|
|
24
23
|
return false;
|
|
25
24
|
}
|
|
26
25
|
})();
|
|
26
|
+
function normalizeReadPaths(paths) {
|
|
27
|
+
const unique = new Set();
|
|
28
|
+
for (const path of paths) {
|
|
29
|
+
if (!path)
|
|
30
|
+
continue;
|
|
31
|
+
const trimmed = path.trim();
|
|
32
|
+
if (!trimmed)
|
|
33
|
+
continue;
|
|
34
|
+
unique.add(trimmed);
|
|
35
|
+
}
|
|
36
|
+
return [...unique];
|
|
37
|
+
}
|
|
38
|
+
function getDefaultCompiledReadPaths() {
|
|
39
|
+
return normalizeReadPaths([
|
|
40
|
+
getFrameworkRootFromMeta(globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).url),
|
|
41
|
+
getCacheBaseDir(),
|
|
42
|
+
getMdxEsmCacheDir(),
|
|
43
|
+
getHttpBundleCacheDir(),
|
|
44
|
+
getHostEnv("DENO_DIR"),
|
|
45
|
+
]);
|
|
46
|
+
}
|
|
27
47
|
/**
|
|
28
48
|
* Build scoped permissions for a project worker.
|
|
29
49
|
*
|
|
@@ -35,20 +55,14 @@ const _isCompiledBinary = (() => {
|
|
|
35
55
|
* - ffi: denied (no native code from user code)
|
|
36
56
|
* - sys: denied (no system info access from user code)
|
|
37
57
|
*/
|
|
38
|
-
export function buildWorkerPermissions(readPaths) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// SECURITY (residual, tracked in #2245): with read:true a user route
|
|
45
|
-
// handler can call Deno.readTextFile directly to read any host file,
|
|
46
|
-
// bypassing the project-scoped ctx.fs adapter. Narrowing this to a
|
|
47
|
-
// binary-validated allow-list (or removing direct Deno fs from user module
|
|
48
|
-
// scope) is blocking work for the next security batch.
|
|
49
|
-
if (_isCompiledBinary) {
|
|
58
|
+
export function buildWorkerPermissions(readPaths, options = {}) {
|
|
59
|
+
const isCompiledBinary = options.isCompiledBinary ?? _isCompiledBinary;
|
|
60
|
+
const normalizedReadPaths = normalizeReadPaths(readPaths);
|
|
61
|
+
if (isCompiledBinary) {
|
|
62
|
+
const compiledReadPaths = options.compiledReadPaths ?? getDefaultCompiledReadPaths();
|
|
63
|
+
const scopedReadPaths = normalizeReadPaths([...normalizedReadPaths, ...compiledReadPaths]);
|
|
50
64
|
return {
|
|
51
|
-
read:
|
|
65
|
+
read: scopedReadPaths.length > 0 ? scopedReadPaths : false,
|
|
52
66
|
write: false,
|
|
53
67
|
net: true,
|
|
54
68
|
env: true,
|
|
@@ -58,7 +72,7 @@ export function buildWorkerPermissions(readPaths) {
|
|
|
58
72
|
};
|
|
59
73
|
}
|
|
60
74
|
return {
|
|
61
|
-
read:
|
|
75
|
+
read: normalizedReadPaths.length > 0 ? normalizedReadPaths : false,
|
|
62
76
|
write: false,
|
|
63
77
|
net: true,
|
|
64
78
|
env: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr.service.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/services/rendering/ssr.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"ssr.service.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/services/rendering/ssr.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,kCAAkC,CAAC;AAuB1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAItE;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC5D;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,mBAAmB,IAAI,YAAY,CAAC;IACpC,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACrF,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAC;CAC3D;AAUD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACpC,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,UAAU,GAAG,OAAO,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,cAAc,GAAG,SAAS,CAAC;IACjF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAqBD,qBAAa,UAAW,YAAW,cAAc;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAA0B;IACrD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;gBAExC,OAAO,CAAC,EAAE;QACpB,SAAS,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;QACpC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACrC;IAKD,mBAAmB,IAAI,YAAY;IAW7B,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAI1D,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IA+G1F,OAAO,CAAC,iBAAiB;IAyHzB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;CAS1D"}
|
|
@@ -4,7 +4,7 @@ import { serverLogger, timeAsync } from "../../../utils/index.js";
|
|
|
4
4
|
import { computeSSRETag } from "../../handlers/request/ssr/etag-handler.js";
|
|
5
5
|
import { VeryfrontError } from "../../../errors/index.js";
|
|
6
6
|
import { getColorSchemeFromRequest } from "../../../security/http/client-hints.js";
|
|
7
|
-
import { endRenderSession, hasRenderSession, startRenderSession, } from "../../../transforms/mdx/esm-module-loader/module-fetcher/index.js";
|
|
7
|
+
import { endRenderSession, hasRenderSession, runInRenderSession, startRenderSession, } from "../../../transforms/mdx/esm-module-loader/module-fetcher/index.js";
|
|
8
8
|
import { getErrorCollector } from "../../../observability/error-collector.js";
|
|
9
9
|
import { profilePhase } from "../../../observability/request-profiler.js";
|
|
10
10
|
import { ErrorOverlay, parseErrorLocation } from "../../dev-server/error-overlay/index.js";
|
|
@@ -68,7 +68,10 @@ export class SSRService {
|
|
|
68
68
|
slug,
|
|
69
69
|
});
|
|
70
70
|
const renderStartTime = performance.now();
|
|
71
|
-
|
|
71
|
+
// Bind the render session to this async context so modules fetched
|
|
72
|
+
// during the render are attributed to THIS render, not whichever
|
|
73
|
+
// concurrent session started first.
|
|
74
|
+
const result = await runInRenderSession(renderSessionId, () => profilePhase("ssr.render_page", () => timeAsync("render-page", () => renderer.renderPage(slug, {
|
|
72
75
|
delivery: "stream",
|
|
73
76
|
request,
|
|
74
77
|
url,
|
|
@@ -84,7 +87,7 @@ export class SSRService {
|
|
|
84
87
|
noHmr,
|
|
85
88
|
forceProductionScripts: options.forceProductionScripts,
|
|
86
89
|
renderSessionId,
|
|
87
|
-
})));
|
|
90
|
+
}))));
|
|
88
91
|
logger.debug("renderPage DONE", {
|
|
89
92
|
projectSlug: ctx.projectSlug,
|
|
90
93
|
slug,
|
|
@@ -25,6 +25,8 @@ export declare function initializeCacheDir(context: ESMLoaderContext): Promise<s
|
|
|
25
25
|
export declare function findVfModuleImports(code: string): Array<{
|
|
26
26
|
original: string;
|
|
27
27
|
path: string;
|
|
28
|
+
start: number;
|
|
29
|
+
end: number;
|
|
28
30
|
}>;
|
|
29
31
|
/**
|
|
30
32
|
* Process /_vf_modules/ imports and replace them with file:// paths.
|
|
@@ -32,5 +34,7 @@ export declare function findVfModuleImports(code: string): Array<{
|
|
|
32
34
|
export declare function processVfModuleImports(code: string, imports: Array<{
|
|
33
35
|
original: string;
|
|
34
36
|
path: string;
|
|
37
|
+
start: number;
|
|
38
|
+
end: number;
|
|
35
39
|
}>, context: ESMLoaderContext, projectDir: string, strictMissingModules: boolean): Promise<string>;
|
|
36
40
|
//# sourceMappingURL=loader-helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader-helpers.d.ts","sourceRoot":"","sources":["../../../../../src/src/transforms/mdx/esm-module-loader/loader-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"loader-helpers.d.ts","sourceRoot":"","sources":["../../../../../src/src/transforms/mdx/esm-module-loader/loader-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmBH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;GAGG;AACH,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAapF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAWnE;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgCnF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,GACX,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAKvE;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,EAC9E,OAAO,EAAE,gBAAgB,EACzB,UAAU,EAAE,MAAM,EAClB,oBAAoB,EAAE,OAAO,GAC5B,OAAO,CAAC,MAAM,CAAC,CAoHjB"}
|
|
@@ -17,6 +17,7 @@ import { exists as fsExists } from "../../../platform/compat/fs.js";
|
|
|
17
17
|
import { LOG_PREFIX_MDX_LOADER } from "./constants.js";
|
|
18
18
|
import { getLocalFs } from "./cache/index.js";
|
|
19
19
|
import { createStubModule } from "./utils/stub-module.js";
|
|
20
|
+
import { findStaticImportFromSpans, replaceSourceSpans, } from "./utils/source-spans.js";
|
|
20
21
|
import { createModuleFetcherContext, fetchAndCacheModule } from "./module-fetcher/index.js";
|
|
21
22
|
import { buildMissingModuleError } from "./missing-module.js";
|
|
22
23
|
/**
|
|
@@ -89,15 +90,7 @@ export async function initializeCacheDir(context) {
|
|
|
89
90
|
* Find /_vf_modules/ imports in code.
|
|
90
91
|
*/
|
|
91
92
|
export function findVfModuleImports(code) {
|
|
92
|
-
|
|
93
|
-
const pattern = /from\s*["'](\/?)(_vf_modules\/[^"']+)["']/g;
|
|
94
|
-
let match;
|
|
95
|
-
while ((match = pattern.exec(code)) !== null) {
|
|
96
|
-
const [original, , path] = match;
|
|
97
|
-
if (path)
|
|
98
|
-
imports.push({ original, path });
|
|
99
|
-
}
|
|
100
|
-
return imports;
|
|
93
|
+
return findStaticImportFromSpans(code, (specifier) => specifier.match(/^\/?(_vf_modules\/[^?]+)(?:\?.*)?$/)?.[1]);
|
|
101
94
|
}
|
|
102
95
|
/**
|
|
103
96
|
* Process /_vf_modules/ imports and replace them with file:// paths.
|
|
@@ -136,7 +129,7 @@ export async function processVfModuleImports(code, imports, context, projectDir,
|
|
|
136
129
|
strictMissingModules,
|
|
137
130
|
});
|
|
138
131
|
const fetchStart = performance.now();
|
|
139
|
-
const results = await Promise.all(imports.map(async ({ original, path }, index) => {
|
|
132
|
+
const results = await Promise.all(imports.map(async ({ original, path, start, end }, index) => {
|
|
140
133
|
return await withSpan(SpanNames.MDX_FETCH_MODULE, async () => {
|
|
141
134
|
const moduleStart = performance.now();
|
|
142
135
|
logger.debug(`${LOG_PREFIX_MDX_LOADER} Fetching module START`, {
|
|
@@ -151,7 +144,7 @@ export async function processVfModuleImports(code, imports, context, projectDir,
|
|
|
151
144
|
path,
|
|
152
145
|
durationMs: (performance.now() - moduleStart).toFixed(1),
|
|
153
146
|
});
|
|
154
|
-
return { original, filePath, path };
|
|
147
|
+
return { original, start, end, filePath, path };
|
|
155
148
|
}, {
|
|
156
149
|
"mdx.module_path": path,
|
|
157
150
|
"mdx.module_index": index,
|
|
@@ -163,10 +156,15 @@ export async function processVfModuleImports(code, imports, context, projectDir,
|
|
|
163
156
|
moduleCount: imports.length,
|
|
164
157
|
durationMs: (performance.now() - fetchStart).toFixed(1),
|
|
165
158
|
});
|
|
166
|
-
|
|
167
|
-
for (const { original, filePath, path } of results) {
|
|
159
|
+
const replacements = [];
|
|
160
|
+
for (const { original, start, end, filePath, path } of results) {
|
|
168
161
|
if (filePath) {
|
|
169
|
-
|
|
162
|
+
replacements.push({
|
|
163
|
+
start,
|
|
164
|
+
end,
|
|
165
|
+
expected: original,
|
|
166
|
+
replacement: `from "file://${filePath}"`,
|
|
167
|
+
});
|
|
170
168
|
continue;
|
|
171
169
|
}
|
|
172
170
|
if (strictMissingModules) {
|
|
@@ -178,9 +176,15 @@ export async function processVfModuleImports(code, imports, context, projectDir,
|
|
|
178
176
|
projectSlug,
|
|
179
177
|
});
|
|
180
178
|
}
|
|
181
|
-
const stubPath = await createStubModule(path,
|
|
182
|
-
if (stubPath)
|
|
183
|
-
|
|
179
|
+
const stubPath = await createStubModule(path, code, original, context.esmCacheDir);
|
|
180
|
+
if (stubPath) {
|
|
181
|
+
replacements.push({
|
|
182
|
+
start,
|
|
183
|
+
end,
|
|
184
|
+
expected: original,
|
|
185
|
+
replacement: `from "file://${stubPath}"`,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
184
188
|
}
|
|
185
|
-
return
|
|
189
|
+
return replaceSourceSpans(code, replacements);
|
|
186
190
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-fetcher.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/mdx/esm-module-loader/module-fetcher/http-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAGjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"http-fetcher.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/mdx/esm-module-loader/module-fetcher/http-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAGjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAM5E;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,cAAc,EACvB,qBAAqB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,EAChF,GAAG,EAAE,MAAM,EACX,WAAW,CAAC,EAAE,MAAM,EACpB,cAAc,CAAC,EAAE,OAAO,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuExB"}
|
|
@@ -11,6 +11,7 @@ import { SpanNames } from "../../../../observability/tracing/span-names.js";
|
|
|
11
11
|
import { LOG_PREFIX_MDX_LOADER } from "../constants.js";
|
|
12
12
|
import { rewriteVeryfrontImports } from "./import-rewriter.js";
|
|
13
13
|
import { findNestedImports } from "./nested-imports.js";
|
|
14
|
+
import { replaceSourceSpans } from "../utils/source-spans.js";
|
|
14
15
|
/**
|
|
15
16
|
* Fetch module via HTTP as a fallback (local development only).
|
|
16
17
|
*
|
|
@@ -38,20 +39,38 @@ export async function fetchModuleViaHTTP(normalizedPath, adapter, fetchAndCacheM
|
|
|
38
39
|
log.warn(`${LOG_PREFIX_MDX_LOADER} HTTP fetch also failed: ${moduleUrl} (${response.status})`);
|
|
39
40
|
return null;
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
+
const moduleCode = rewriteVeryfrontImports(await response.text());
|
|
42
43
|
const { vfModules, relative } = findNestedImports(moduleCode);
|
|
43
44
|
const allImports = [
|
|
44
|
-
...vfModules.map(({ original, path }) => ({
|
|
45
|
-
|
|
45
|
+
...vfModules.map(({ original, path, start, end }) => ({
|
|
46
|
+
original,
|
|
47
|
+
path,
|
|
48
|
+
start,
|
|
49
|
+
end,
|
|
50
|
+
key: "nestedPath",
|
|
51
|
+
})),
|
|
52
|
+
...relative.map(({ original, path, start, end }) => ({
|
|
53
|
+
original,
|
|
54
|
+
path,
|
|
55
|
+
start,
|
|
56
|
+
end,
|
|
57
|
+
key: "relativePath",
|
|
58
|
+
})),
|
|
46
59
|
];
|
|
47
|
-
const results = await Promise.all(allImports.map(async ({ original, path, key }) => {
|
|
60
|
+
const results = await Promise.all(allImports.map(async ({ original, path, start, end, key }) => {
|
|
48
61
|
const nestedFilePath = await fetchAndCacheModuleFn(path, normalizedPath);
|
|
49
|
-
return { original, nestedFilePath, [key]: path };
|
|
62
|
+
return { original, start, end, nestedFilePath, [key]: path };
|
|
50
63
|
}));
|
|
51
|
-
|
|
64
|
+
const replacements = [];
|
|
65
|
+
for (const { original, start, end, nestedFilePath } of results) {
|
|
52
66
|
if (nestedFilePath) {
|
|
53
|
-
|
|
67
|
+
replacements.push({
|
|
68
|
+
start,
|
|
69
|
+
end,
|
|
70
|
+
expected: original,
|
|
71
|
+
replacement: `from "file://${nestedFilePath}"`,
|
|
72
|
+
});
|
|
54
73
|
}
|
|
55
74
|
}
|
|
56
|
-
return moduleCode;
|
|
75
|
+
return replaceSourceSpans(moduleCode, replacements);
|
|
57
76
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-rewriter.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/mdx/esm-module-loader/module-fetcher/import-rewriter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"import-rewriter.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/mdx/esm-module-loader/module-fetcher/import-rewriter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgB5D;AAwCD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA0D7F"}
|
|
@@ -7,17 +7,24 @@ import { dirname, join, resolve } from "../../../../platform/compat/path/index.j
|
|
|
7
7
|
import { FRAMEWORK_ROOT } from "../constants.js";
|
|
8
8
|
import { resolveVeryfrontModuleUrl } from "../../../veryfront-module-urls.js";
|
|
9
9
|
import { getLocalFs } from "../cache/index.js";
|
|
10
|
+
import { findStaticImportFromSpans, findStaticSideEffectImportSpans, replaceSourceSpans, } from "../utils/source-spans.js";
|
|
10
11
|
/**
|
|
11
12
|
* Rewrite veryfront/* imports to /_vf_modules/_veryfront/ paths for MDX module loading.
|
|
12
13
|
* Uses deno.json exports/imports as the source of truth and appends ?ssr=true.
|
|
13
14
|
*/
|
|
14
15
|
export function rewriteVeryfrontImports(code) {
|
|
15
|
-
|
|
16
|
-
const mapped = resolveVeryfrontModuleUrl(
|
|
16
|
+
const replacements = findStaticImportFromSpans(code, (specifier) => specifier.startsWith("veryfront/") ? specifier : null).flatMap(({ original, path, start, end }) => {
|
|
17
|
+
const mapped = resolveVeryfrontModuleUrl(path);
|
|
17
18
|
if (!mapped)
|
|
18
|
-
return
|
|
19
|
-
return
|
|
19
|
+
return [];
|
|
20
|
+
return [{
|
|
21
|
+
start,
|
|
22
|
+
end,
|
|
23
|
+
expected: original,
|
|
24
|
+
replacement: `from "${mapped}?ssr=true"`,
|
|
25
|
+
}];
|
|
20
26
|
});
|
|
27
|
+
return replaceSourceSpans(code, replacements);
|
|
21
28
|
}
|
|
22
29
|
/**
|
|
23
30
|
* Rewrite relative imports in framework files to absolute file:// paths.
|
|
@@ -72,27 +79,30 @@ export async function rewriteDntImports(code, sourceFilePath) {
|
|
|
72
79
|
let rewritten = code;
|
|
73
80
|
const patterns = [
|
|
74
81
|
{
|
|
75
|
-
|
|
82
|
+
findMatches: (source) => findStaticImportFromSpans(source, (specifier) => specifier.match(/^(\.\.?\/[^?]+)(?:\?.*)?$/)?.[1]),
|
|
76
83
|
buildReplacement: (path) => `from "file://${path}"`,
|
|
77
84
|
},
|
|
78
85
|
{
|
|
79
|
-
|
|
86
|
+
findMatches: (source) => findStaticSideEffectImportSpans(source, (specifier) => specifier.match(/^(\.\.?\/[^?]+)(?:\?.*)?$/)?.[1]),
|
|
80
87
|
buildReplacement: (path) => `import "file://${path}"`,
|
|
81
88
|
},
|
|
82
89
|
];
|
|
83
|
-
for (const {
|
|
84
|
-
const matches =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const relativePath = match[1];
|
|
88
|
-
if (!relativePath)
|
|
89
|
-
continue;
|
|
90
|
+
for (const { findMatches, buildReplacement } of patterns) {
|
|
91
|
+
const matches = findMatches(rewritten);
|
|
92
|
+
const replacements = [];
|
|
93
|
+
for (const { original, path: relativePath, start, end } of matches) {
|
|
90
94
|
const absolutePath = resolve(sourceDir, relativePath);
|
|
91
95
|
const resolvedPath = needsFrameworkSourceFallback
|
|
92
96
|
? await findExistingFrameworkRelativeTarget(absolutePath) ?? absolutePath
|
|
93
97
|
: absolutePath;
|
|
94
|
-
|
|
98
|
+
replacements.push({
|
|
99
|
+
start,
|
|
100
|
+
end,
|
|
101
|
+
expected: original,
|
|
102
|
+
replacement: buildReplacement(resolvedPath),
|
|
103
|
+
});
|
|
95
104
|
}
|
|
105
|
+
rewritten = replaceSourceSpans(rewritten, replacements);
|
|
96
106
|
}
|
|
97
107
|
return rewritten;
|
|
98
108
|
}
|
|
@@ -15,7 +15,7 @@ import type { Logger } from "../../../../utils/logger/logger.js";
|
|
|
15
15
|
import type { RuntimeAdapter } from "../../../../platform/adapters/base.js";
|
|
16
16
|
import type { ModuleFetcherContext } from "../types.js";
|
|
17
17
|
export { rewriteDntImports } from "./import-rewriter.js";
|
|
18
|
-
export { endRenderSession, hasRenderSession, startRenderSession } from "./render-sessions.js";
|
|
18
|
+
export { endRenderSession, hasRenderSession, runInRenderSession, startRenderSession, } from "./render-sessions.js";
|
|
19
19
|
/**
|
|
20
20
|
* Error thrown when transform tree exceeds the timeout.
|
|
21
21
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/mdx/esm-module-loader/module-fetcher/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAG5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAcxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/mdx/esm-module-loader/module-fetcher/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAG5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAcxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAS9B;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAOtD;AAED;;GAEG;AACH,qBAAa,6BAA8B,SAAQ,KAAK;gBAC1C,SAAS,EAAE,MAAM;CAI9B;AAcD;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,oBAAoB,EAC7B,gBAAgB,CAAC,EAAE,MAAM,EACzB,OAAO,GAAE,GAAG,CAAC,MAAM,CAAa,GAC/B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwFxB;AA6KD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IACR,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,GACA,oBAAoB,CAUtB"}
|
|
@@ -27,7 +27,7 @@ import { readValidCachedModulePath } from "./path-cache-lookup.js";
|
|
|
27
27
|
import { transformResolvedModuleSource } from "./source-transform.js";
|
|
28
28
|
// Re-export extracted modules for backward compatibility
|
|
29
29
|
export { rewriteDntImports } from "./import-rewriter.js";
|
|
30
|
-
export { endRenderSession, hasRenderSession, startRenderSession } from "./render-sessions.js";
|
|
30
|
+
export { endRenderSession, hasRenderSession, runInRenderSession, startRenderSession, } from "./render-sessions.js";
|
|
31
31
|
/**
|
|
32
32
|
* Maximum time allowed for the entire transform tree (recursive module resolution).
|
|
33
33
|
* If the cumulative time exceeds this, we fail fast instead of hanging indefinitely.
|
|
@@ -13,10 +13,14 @@ export declare function findNestedImports(moduleCode: string): {
|
|
|
13
13
|
vfModules: Array<{
|
|
14
14
|
original: string;
|
|
15
15
|
path: string;
|
|
16
|
+
start: number;
|
|
17
|
+
end: number;
|
|
16
18
|
}>;
|
|
17
19
|
relative: Array<{
|
|
18
20
|
original: string;
|
|
19
21
|
path: string;
|
|
22
|
+
start: number;
|
|
23
|
+
end: number;
|
|
20
24
|
}>;
|
|
21
25
|
};
|
|
22
26
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nested-imports.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/mdx/esm-module-loader/module-fetcher/nested-imports.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"nested-imports.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/mdx/esm-module-loader/module-fetcher/nested-imports.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAQtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAEjE;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,GACjB;IACD,SAAS,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjF,QAAQ,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjF,CAkCA;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAO3F;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,kBAAkB,EAAE,EAC7B,WAAW,EAAE,MAAM,EACnB,oBAAoB,EAAE,OAAO,EAC7B,gBAAgB,CAAC,EAAE,MAAM,EACzB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAqCjB;AAED,MAAM,WAAW,+BAA+B;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC/E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,+BAA+B,GACrC,OAAO,CAAC,MAAM,CAAC,CAuDjB"}
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module transforms/mdx/esm-module-loader/module-fetcher/nested-imports
|
|
5
5
|
*/
|
|
6
|
-
import { LOG_PREFIX_MDX_LOADER,
|
|
6
|
+
import { LOG_PREFIX_MDX_LOADER, UNRESOLVED_VF_MODULES_PATTERN } from "../constants.js";
|
|
7
7
|
import { createStubModule } from "../utils/stub-module.js";
|
|
8
|
+
import { findStaticImportFromSpans, replaceSourceSpans, } from "../utils/source-spans.js";
|
|
8
9
|
import { buildMissingModuleError } from "../missing-module.js";
|
|
9
10
|
/**
|
|
10
11
|
* Find nested module imports in code.
|
|
@@ -13,20 +14,22 @@ import { buildMissingModuleError } from "../missing-module.js";
|
|
|
13
14
|
export function findNestedImports(moduleCode) {
|
|
14
15
|
const vfModules = [];
|
|
15
16
|
const relative = [];
|
|
16
|
-
const
|
|
17
|
-
let match;
|
|
18
|
-
while ((match = vfPattern.exec(moduleCode)) !== null) {
|
|
19
|
-
const rawPath = match[1];
|
|
17
|
+
for (const { original, path: rawPath, start, end } of findStaticImportFromSpans(moduleCode, (specifier) => specifier.match(/^((?:file:\/\/)?\/?\/?_vf_modules\/[^?]+)(?:\?.*)?$/)?.[1])) {
|
|
20
18
|
// Strip file:// prefix and leading slashes to get clean _vf_modules/... path
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
vfModules.push({
|
|
20
|
+
original,
|
|
21
|
+
path: rawPath.replace(/^(?:file:\/\/)?\/+/, ""),
|
|
22
|
+
start,
|
|
23
|
+
end,
|
|
24
|
+
});
|
|
24
25
|
}
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
for (const { original, path, start, end } of findStaticImportFromSpans(moduleCode, (specifier) => specifier.match(/^(\.\.?\/[^?]+)(?:\?.*)?$/)?.[1])) {
|
|
27
|
+
relative.push({
|
|
28
|
+
original,
|
|
29
|
+
path,
|
|
30
|
+
start,
|
|
31
|
+
end,
|
|
32
|
+
});
|
|
30
33
|
}
|
|
31
34
|
return { vfModules, relative };
|
|
32
35
|
}
|
|
@@ -45,10 +48,15 @@ export function hasUnresolvedImports(moduleCode) {
|
|
|
45
48
|
* Process nested imports by replacing them with file:// paths or stub modules.
|
|
46
49
|
*/
|
|
47
50
|
export async function processNestedImports(moduleCode, results, esmCacheDir, strictMissingModules, parentModulePath, projectSlug) {
|
|
48
|
-
|
|
49
|
-
for (const { original, nestedFilePath, nestedPath, relativePath } of results) {
|
|
51
|
+
const replacements = [];
|
|
52
|
+
for (const { original, start, end, nestedFilePath, nestedPath, relativePath } of results) {
|
|
50
53
|
if (nestedFilePath) {
|
|
51
|
-
|
|
54
|
+
replacements.push({
|
|
55
|
+
start,
|
|
56
|
+
end,
|
|
57
|
+
expected: original,
|
|
58
|
+
replacement: `from "file://${nestedFilePath}"`,
|
|
59
|
+
});
|
|
52
60
|
continue;
|
|
53
61
|
}
|
|
54
62
|
const modulePath = nestedPath || relativePath || "";
|
|
@@ -61,17 +69,23 @@ export async function processNestedImports(moduleCode, results, esmCacheDir, str
|
|
|
61
69
|
projectSlug,
|
|
62
70
|
});
|
|
63
71
|
}
|
|
64
|
-
const stubPath = await createStubModule(modulePath,
|
|
65
|
-
if (stubPath)
|
|
66
|
-
|
|
72
|
+
const stubPath = await createStubModule(modulePath, moduleCode, original, esmCacheDir);
|
|
73
|
+
if (stubPath) {
|
|
74
|
+
replacements.push({
|
|
75
|
+
start,
|
|
76
|
+
end,
|
|
77
|
+
expected: original,
|
|
78
|
+
replacement: `from "file://${stubPath}"`,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
67
81
|
}
|
|
68
|
-
return
|
|
82
|
+
return replaceSourceSpans(moduleCode, replacements);
|
|
69
83
|
}
|
|
70
84
|
/**
|
|
71
85
|
* Resolve nested /_vf_modules and relative imports into local file:// cache paths.
|
|
72
86
|
*/
|
|
73
87
|
export async function resolveNestedModuleImports(input) {
|
|
74
|
-
|
|
88
|
+
const moduleCode = input.moduleCode;
|
|
75
89
|
const { vfModules, relative } = findNestedImports(moduleCode);
|
|
76
90
|
input.log?.debug(`${LOG_PREFIX_MDX_LOADER} [fetchAndCacheModule] found nested imports`, {
|
|
77
91
|
projectSlug: input.projectSlug,
|
|
@@ -87,32 +101,26 @@ export async function resolveNestedModuleImports(input) {
|
|
|
87
101
|
count: vfModules.length,
|
|
88
102
|
});
|
|
89
103
|
const vfStart = performance.now();
|
|
90
|
-
const
|
|
104
|
+
const allImports = [
|
|
105
|
+
...vfModules.map((module) => ({ ...module, key: "nestedPath" })),
|
|
106
|
+
...relative.map((module) => ({ ...module, key: "relativePath" })),
|
|
107
|
+
];
|
|
108
|
+
const nestedResults = await Promise.all(allImports.map(async ({ original, path, start, end, key }) => ({
|
|
91
109
|
original,
|
|
110
|
+
start,
|
|
111
|
+
end,
|
|
92
112
|
nestedFilePath: await input.fetchAndCacheModule(path, input.normalizedPath),
|
|
93
|
-
|
|
113
|
+
[key]: path,
|
|
94
114
|
})));
|
|
95
115
|
input.log?.debug(`${LOG_PREFIX_MDX_LOADER} [fetchAndCacheModule] processing vfModules DONE`, {
|
|
96
116
|
projectSlug: input.projectSlug,
|
|
97
117
|
normalizedPath: input.normalizedPath,
|
|
98
118
|
vfMs: (performance.now() - vfStart).toFixed(1),
|
|
99
119
|
});
|
|
100
|
-
|
|
101
|
-
input.log?.debug(`${LOG_PREFIX_MDX_LOADER} [fetchAndCacheModule] processing relative imports START`, {
|
|
120
|
+
input.log?.debug(`${LOG_PREFIX_MDX_LOADER} [fetchAndCacheModule] processing relative imports`, {
|
|
102
121
|
projectSlug: input.projectSlug,
|
|
103
122
|
normalizedPath: input.normalizedPath,
|
|
104
123
|
count: relative.length,
|
|
105
124
|
});
|
|
106
|
-
|
|
107
|
-
const relativeResults = await Promise.all(relative.map(async ({ original, path }) => ({
|
|
108
|
-
original,
|
|
109
|
-
nestedFilePath: await input.fetchAndCacheModule(path, input.normalizedPath),
|
|
110
|
-
relativePath: path,
|
|
111
|
-
})));
|
|
112
|
-
input.log?.debug(`${LOG_PREFIX_MDX_LOADER} [fetchAndCacheModule] processing relative imports DONE`, {
|
|
113
|
-
projectSlug: input.projectSlug,
|
|
114
|
-
normalizedPath: input.normalizedPath,
|
|
115
|
-
relMs: (performance.now() - relStart).toFixed(1),
|
|
116
|
-
});
|
|
117
|
-
return await processNestedImports(moduleCode, relativeResults, input.esmCacheDir, input.strictMissingModules, input.normalizedPath, input.projectSlug);
|
|
125
|
+
return await processNestedImports(moduleCode, nestedResults, input.esmCacheDir, input.strictMissingModules, input.normalizedPath, input.projectSlug);
|
|
118
126
|
}
|
|
@@ -5,6 +5,11 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module transforms/mdx/esm-module-loader/module-fetcher/render-sessions
|
|
7
7
|
*/
|
|
8
|
+
/**
|
|
9
|
+
* Run `fn` with `sessionId` bound as the active render session for all async
|
|
10
|
+
* work it spawns. Modules fetched inside are attributed to this session.
|
|
11
|
+
*/
|
|
12
|
+
export declare function runInRenderSession<T>(sessionId: string, fn: () => T): T;
|
|
8
13
|
/**
|
|
9
14
|
* Start a render session to track module loading.
|
|
10
15
|
* Call this before rendering a page.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-sessions.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"render-sessions.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA6BH;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEvE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAOhG;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAiCxD;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE3D;AAuBD,wBAAgB,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAQlE"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module transforms/mdx/esm-module-loader/module-fetcher/render-sessions
|
|
7
7
|
*/
|
|
8
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
9
|
import { rendererLogger as globalLogger } from "../../../../utils/index.js";
|
|
9
10
|
import { LOG_PREFIX_MDX_LOADER } from "../constants.js";
|
|
10
11
|
import { recordSSRModules } from "../../../../modules/manifest/route-module-manifest.js";
|
|
@@ -13,6 +14,19 @@ import { recordSSRModules } from "../../../../modules/manifest/route-module-mani
|
|
|
13
14
|
* Key: renderSessionId, Value: RenderSession
|
|
14
15
|
*/
|
|
15
16
|
const renderSessions = new Map();
|
|
17
|
+
/**
|
|
18
|
+
* The render session id active on the current async execution context.
|
|
19
|
+
* Set via {@link runInRenderSession} so concurrent SSR renders each resolve
|
|
20
|
+
* their own session instead of sharing whichever one started first.
|
|
21
|
+
*/
|
|
22
|
+
const currentSessionIdStorage = new AsyncLocalStorage();
|
|
23
|
+
/**
|
|
24
|
+
* Run `fn` with `sessionId` bound as the active render session for all async
|
|
25
|
+
* work it spawns. Modules fetched inside are attributed to this session.
|
|
26
|
+
*/
|
|
27
|
+
export function runInRenderSession(sessionId, fn) {
|
|
28
|
+
return currentSessionIdStorage.run(sessionId, fn);
|
|
29
|
+
}
|
|
16
30
|
/**
|
|
17
31
|
* Start a render session to track module loading.
|
|
18
32
|
* Call this before rendering a page.
|
|
@@ -66,8 +80,19 @@ export function hasRenderSession(sessionId) {
|
|
|
66
80
|
* Used to record modules during fetch and for per-session in-flight deduplication.
|
|
67
81
|
*/
|
|
68
82
|
function getCurrentSession() {
|
|
69
|
-
const
|
|
70
|
-
|
|
83
|
+
const activeId = currentSessionIdStorage.getStore();
|
|
84
|
+
if (activeId !== undefined) {
|
|
85
|
+
return renderSessions.get(activeId) ?? null;
|
|
86
|
+
}
|
|
87
|
+
// No session bound on the async context (caller not wrapped in
|
|
88
|
+
// runInRenderSession). Fall back to the single-session heuristic only when
|
|
89
|
+
// it is unambiguous; with multiple concurrent sessions, decline rather than
|
|
90
|
+
// mis-attribute modules to the wrong render.
|
|
91
|
+
if (renderSessions.size === 1) {
|
|
92
|
+
const firstSession = renderSessions.values().next();
|
|
93
|
+
return firstSession.done ? null : firstSession.value;
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
71
96
|
}
|
|
72
97
|
export function recordModuleToSession(normalizedPath) {
|
|
73
98
|
const session = getCurrentSession();
|