veryfront 0.1.1127 → 0.1.1132
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/commands/eval/command.d.ts +2 -70
- package/esm/cli/commands/eval/command.d.ts.map +1 -1
- package/esm/cli/commands/eval/command.js +207 -550
- package/esm/cli/templates/manifest.d.ts +1 -0
- package/esm/cli/templates/manifest.js +3 -2
- package/esm/deno.js +1 -1
- package/esm/src/agent/hosted/chat-execution-runtime.d.ts.map +1 -1
- package/esm/src/agent/hosted/chat-execution-runtime.js +16 -33
- package/esm/src/agent/hosted/child-fork-tool-sources.d.ts.map +1 -1
- package/esm/src/agent/hosted/child-fork-tool-sources.js +6 -38
- package/esm/src/agent/hosted/hosted-chat-finalization.d.ts +30 -0
- package/esm/src/agent/hosted/hosted-chat-finalization.d.ts.map +1 -0
- package/esm/src/agent/hosted/hosted-chat-finalization.js +249 -0
- package/esm/src/agent/hosted/project-remote-tool-source.d.ts.map +1 -1
- package/esm/src/agent/hosted/project-remote-tool-source.js +4 -23
- package/esm/src/agent/mcp-tool-policy.d.ts +19 -0
- package/esm/src/agent/mcp-tool-policy.d.ts.map +1 -0
- package/esm/src/agent/mcp-tool-policy.js +66 -0
- package/esm/src/agent/runtime/mcp-server-tool-sources.d.ts.map +1 -1
- package/esm/src/agent/runtime/mcp-server-tool-sources.js +8 -44
- package/esm/src/discovery/import-rewriter.d.ts.map +1 -1
- package/esm/src/discovery/import-rewriter.js +7 -90
- package/esm/src/eval/run-report.d.ts +189 -0
- package/esm/src/eval/run-report.d.ts.map +1 -0
- package/esm/src/eval/run-report.js +603 -0
- package/esm/src/html/hydration-script-builder/dev-client-renderer.js +1 -1
- package/esm/src/html/hydration-script-builder/prod-scripts.js +1 -1
- package/esm/src/html/hydration-script-builder/templates/router.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/templates/router.js +35 -11
- package/esm/src/html/utils.d.ts.map +1 -1
- package/esm/src/html/utils.js +19 -45
- package/esm/src/index.client.d.ts +6 -21
- package/esm/src/index.client.d.ts.map +1 -1
- package/esm/src/index.client.js +6 -21
- package/esm/src/modules/server/ssr-import-rewriter.d.ts +2 -26
- package/esm/src/modules/server/ssr-import-rewriter.d.ts.map +1 -1
- package/esm/src/modules/server/ssr-import-rewriter.js +1 -206
- package/esm/src/react/runtime/core.d.ts +22 -0
- package/esm/src/react/runtime/core.d.ts.map +1 -1
- package/esm/src/react/runtime/core.js +1 -1
- package/esm/src/rendering/orchestrator/module-collection.d.ts +8 -0
- package/esm/src/rendering/orchestrator/module-collection.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/module-collection.js +10 -0
- package/esm/src/rendering/orchestrator/pipeline.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/pipeline.js +2 -2
- package/esm/src/routing/api/context-builder.d.ts +7 -0
- package/esm/src/routing/api/context-builder.d.ts.map +1 -1
- package/esm/src/routing/api/context-builder.js +20 -2
- package/esm/src/routing/api/module-loader/external-import-rewriter.d.ts +2 -7
- package/esm/src/routing/api/module-loader/external-import-rewriter.d.ts.map +1 -1
- package/esm/src/routing/api/module-loader/external-import-rewriter.js +10 -209
- package/esm/src/server/dev-server/file-watch-setup.d.ts.map +1 -1
- package/esm/src/server/dev-server/file-watch-setup.js +11 -1
- package/esm/src/server/dev-server/middleware.d.ts.map +1 -1
- package/esm/src/server/dev-server/middleware.js +45 -11
- package/esm/src/server/handlers/dev/files/esbuild-plugins.d.ts.map +1 -1
- package/esm/src/server/handlers/dev/files/esbuild-plugins.js +22 -0
- package/esm/src/server/handlers/request/module/page-data-endpoint-handler.js +24 -1
- package/esm/src/server/handlers/response/not-found.d.ts +0 -1
- package/esm/src/server/handlers/response/not-found.d.ts.map +1 -1
- package/esm/src/server/handlers/response/not-found.js +9 -110
- package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
- package/esm/src/server/runtime-handler/index.js +66 -145
- package/esm/src/server/runtime-handler/project-runtime-context.d.ts +118 -0
- package/esm/src/server/runtime-handler/project-runtime-context.d.ts.map +1 -0
- package/esm/src/server/runtime-handler/project-runtime-context.js +181 -0
- package/esm/src/server/services/rsc/orchestrators/handler.d.ts +3 -1
- package/esm/src/server/services/rsc/orchestrators/handler.d.ts.map +1 -1
- package/esm/src/server/services/rsc/orchestrators/handler.js +13 -8
- package/esm/src/server/services/rsc/orchestrators/render-handler.d.ts +1 -1
- package/esm/src/server/services/rsc/orchestrators/render-handler.d.ts.map +1 -1
- package/esm/src/server/services/rsc/orchestrators/render-handler.js +2 -2
- package/esm/src/transforms/esm/http-cache.d.ts.map +1 -1
- package/esm/src/transforms/esm/http-cache.js +132 -46
- package/esm/src/transforms/esm/import-attributes.d.ts.map +1 -1
- package/esm/src/transforms/esm/import-attributes.js +2 -9
- package/esm/src/transforms/esm/in-flight-manager.d.ts +3 -2
- package/esm/src/transforms/esm/in-flight-manager.d.ts.map +1 -1
- package/esm/src/transforms/esm/in-flight-manager.js +6 -5
- package/esm/src/transforms/import-rewriter/core.d.ts +8 -0
- package/esm/src/transforms/import-rewriter/core.d.ts.map +1 -0
- package/esm/src/transforms/import-rewriter/core.js +27 -0
- package/esm/src/transforms/import-rewriter/import-edit.d.ts +57 -0
- package/esm/src/transforms/import-rewriter/import-edit.d.ts.map +1 -0
- package/esm/src/transforms/import-rewriter/import-edit.js +151 -0
- package/esm/src/transforms/import-rewriter/package-resolution.d.ts +12 -0
- package/esm/src/transforms/import-rewriter/package-resolution.d.ts.map +1 -0
- package/esm/src/transforms/import-rewriter/package-resolution.js +79 -0
- package/esm/src/transforms/import-rewriter/parse-cache.d.ts +4 -42
- package/esm/src/transforms/import-rewriter/parse-cache.d.ts.map +1 -1
- package/esm/src/transforms/import-rewriter/parse-cache.js +3 -134
- package/esm/src/transforms/import-rewriter/route-adapter.d.ts +24 -0
- package/esm/src/transforms/import-rewriter/route-adapter.d.ts.map +1 -0
- package/esm/src/transforms/import-rewriter/route-adapter.js +235 -0
- package/esm/src/transforms/import-rewriter/ssr-adapter.d.ts +27 -0
- package/esm/src/transforms/import-rewriter/ssr-adapter.d.ts.map +1 -0
- package/esm/src/transforms/import-rewriter/ssr-adapter.js +206 -0
- package/esm/src/transforms/import-rewriter/strategies/bare-strategy.d.ts.map +1 -1
- package/esm/src/transforms/import-rewriter/strategies/bare-strategy.js +16 -2
- package/esm/src/transforms/import-rewriter/unified-rewriter.d.ts +0 -4
- package/esm/src/transforms/import-rewriter/unified-rewriter.d.ts.map +1 -1
- package/esm/src/transforms/import-rewriter/unified-rewriter.js +2 -39
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/esm/src/workflow/executor/workflow-executor.d.ts +0 -20
- package/esm/src/workflow/executor/workflow-executor.d.ts.map +1 -1
- package/esm/src/workflow/executor/workflow-executor.js +41 -320
- package/esm/src/workflow/runtime/approval-manager.d.ts.map +1 -1
- package/esm/src/workflow/runtime/approval-manager.js +20 -61
- package/esm/src/workflow/runtime/workflow-run-control.d.ts +95 -0
- package/esm/src/workflow/runtime/workflow-run-control.d.ts.map +1 -0
- package/esm/src/workflow/runtime/workflow-run-control.js +529 -0
- package/esm/src/workflow/worker/run-manager.d.ts.map +1 -1
- package/esm/src/workflow/worker/run-manager.js +18 -92
- package/esm/src/workflow/worker/shared.d.ts +1 -1
- package/esm/src/workflow/worker/shared.d.ts.map +1 -1
- package/esm/src/workflow/worker/shared.js +17 -15
- package/package.json +5 -5
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { getHostEnv } from "../../platform/compat/process.js";
|
|
2
|
+
import { normalizeSourceIntegrationPolicy } from "../../integrations/source-policy.js";
|
|
3
|
+
import { createRequestContext } from "../context/request-context.js";
|
|
4
|
+
import { isProxyTrusted } from "../utils/proxy-trust.js";
|
|
5
|
+
import { getEffectiveRequestHost } from "../utils/request-host.js";
|
|
6
|
+
import { resolveAdapter } from "./adapter-factory.js";
|
|
7
|
+
import { resolveEnvironment } from "./environment-resolution.js";
|
|
8
|
+
import { buildHandlerContext } from "./handler-context-builder.js";
|
|
9
|
+
import { extractRequestHeaders, resolveProject } from "./project-resolution.js";
|
|
10
|
+
import { isLightweightPath, isWebSocketPath, shouldSkipEnrichedContext } from "./request-utils.js";
|
|
11
|
+
export async function prepareProjectRequest(input) {
|
|
12
|
+
const { req, url, isProxyMode } = input;
|
|
13
|
+
const proxyTrusted = isProxyMode
|
|
14
|
+
? await (input.trustProxy ?? isProxyTrusted)(req, {
|
|
15
|
+
publicKeyPem: input.adapterEnv?.get("CHANNEL_DISPATCH_SIGNING_PUBLIC_KEY") ??
|
|
16
|
+
getHostEnv("CHANNEL_DISPATCH_SIGNING_PUBLIC_KEY"),
|
|
17
|
+
})
|
|
18
|
+
: undefined;
|
|
19
|
+
const headers = extractRequestHeaders(req, url, proxyTrusted);
|
|
20
|
+
const requestContext = createRequestContext(req, { proxyTrusted });
|
|
21
|
+
const hostHeader = req.headers.get("host") ?? url.host;
|
|
22
|
+
const domain = hostHeader.replace(/:\d+$/, "");
|
|
23
|
+
return {
|
|
24
|
+
url,
|
|
25
|
+
headers,
|
|
26
|
+
requestContext,
|
|
27
|
+
proxyTrust: { proxyTrusted },
|
|
28
|
+
loggerFacts: {
|
|
29
|
+
domain,
|
|
30
|
+
projectSlug: headers.projectSlug,
|
|
31
|
+
projectId: headers.projectId,
|
|
32
|
+
releaseId: headers.releaseId,
|
|
33
|
+
branchId: headers.branchId,
|
|
34
|
+
branchName: headers.branchName,
|
|
35
|
+
pathname: url.pathname,
|
|
36
|
+
},
|
|
37
|
+
trackingFacts: {
|
|
38
|
+
projectSlug: headers.projectSlug,
|
|
39
|
+
pathname: url.pathname,
|
|
40
|
+
method: req.method,
|
|
41
|
+
environment: headers.environment,
|
|
42
|
+
releaseId: headers.releaseId,
|
|
43
|
+
},
|
|
44
|
+
proxyGuard: createProxyGuard(req, url, isProxyMode, headers, proxyTrusted),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export async function resolveProjectIdentity(input) {
|
|
48
|
+
if (input.operation && input.operation !== "identity") {
|
|
49
|
+
throw new Error(`Unsupported project runtime context operation: ${input.operation}`);
|
|
50
|
+
}
|
|
51
|
+
return await resolveProject(input.req, input.url, input.headers, {
|
|
52
|
+
config: input.config,
|
|
53
|
+
reqCtx: input.requestContext,
|
|
54
|
+
defaultProjectSlug: input.defaultProjectSlug,
|
|
55
|
+
defaultProjectId: input.defaultProjectId,
|
|
56
|
+
defaultReleaseId: input.defaultReleaseId,
|
|
57
|
+
wsSlugOverride: input.wsSlugOverride,
|
|
58
|
+
proxyTrusted: input.proxyTrust.proxyTrusted,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
export async function resolveProjectRuntimeContext(input) {
|
|
62
|
+
const projectRes = input.projectIdentity;
|
|
63
|
+
const reqCtx = input.requestContext;
|
|
64
|
+
const profileAdapter = input.profileAdapter ?? ((operation) => operation());
|
|
65
|
+
const profileEnvVars = input.profileEnvVars ?? ((operation) => operation());
|
|
66
|
+
const adapterRes = await profileAdapter(() => resolveAdapter({
|
|
67
|
+
req: input.req,
|
|
68
|
+
projectDir: input.projectDir,
|
|
69
|
+
adapter: input.adapter,
|
|
70
|
+
config: input.config,
|
|
71
|
+
projectSlug: projectRes.projectSlug,
|
|
72
|
+
projectId: projectRes.projectId,
|
|
73
|
+
proxyToken: reqCtx.token,
|
|
74
|
+
releaseId: projectRes.releaseId,
|
|
75
|
+
proxyEnv: projectRes.proxyEnv,
|
|
76
|
+
branch: reqCtx.branch,
|
|
77
|
+
environmentName: projectRes.environmentName,
|
|
78
|
+
parsedDomain: projectRes.parsedDomain,
|
|
79
|
+
pathname: input.url.pathname,
|
|
80
|
+
isProxyMode: input.isProxyMode,
|
|
81
|
+
proxyTrusted: input.proxyTrust.proxyTrusted,
|
|
82
|
+
}));
|
|
83
|
+
const host = getEffectiveRequestHost(input.req, input.url, input.proxyTrust.proxyTrusted ?? getHostEnv("VERYFRONT_TRUST_FORWARDED_HEADERS") === "1");
|
|
84
|
+
const envRes = resolveEnvironment({
|
|
85
|
+
proxyEnv: projectRes.proxyEnv,
|
|
86
|
+
reqCtxMode: reqCtx.mode,
|
|
87
|
+
releaseId: projectRes.releaseId,
|
|
88
|
+
projectSlug: projectRes.projectSlug,
|
|
89
|
+
projectId: projectRes.projectId,
|
|
90
|
+
environmentName: projectRes.environmentName,
|
|
91
|
+
host,
|
|
92
|
+
isLocalProject: adapterRes.isLocalProject,
|
|
93
|
+
isProxyMode: input.isProxyMode,
|
|
94
|
+
pathname: input.url.pathname,
|
|
95
|
+
defaultEnvironment: input.defaultEnvironment,
|
|
96
|
+
});
|
|
97
|
+
input.onEnvironmentResolved?.(envRes);
|
|
98
|
+
if (envRes.errorResponse) {
|
|
99
|
+
return {
|
|
100
|
+
adapter: adapterRes,
|
|
101
|
+
environment: envRes,
|
|
102
|
+
handlerContext: undefined,
|
|
103
|
+
rawEnvVars: {},
|
|
104
|
+
sourceIntegrationPolicy: normalizeSourceIntegrationPolicy(undefined),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const handlerContext = buildHandlerContext({
|
|
108
|
+
projectDir: adapterRes.projectDir,
|
|
109
|
+
adapter: adapterRes.adapter,
|
|
110
|
+
securityConfig: input.securityConfig,
|
|
111
|
+
cspUserHeader: input.cspUserHeader,
|
|
112
|
+
debug: input.debug,
|
|
113
|
+
config: adapterRes.config,
|
|
114
|
+
parsedDomain: projectRes.parsedDomain,
|
|
115
|
+
projectSlug: projectRes.projectSlug,
|
|
116
|
+
projectId: projectRes.projectId,
|
|
117
|
+
releaseId: envRes.releaseId,
|
|
118
|
+
proxyToken: reqCtx.token,
|
|
119
|
+
environmentName: projectRes.environmentName,
|
|
120
|
+
resolvedEnvironment: envRes.resolvedEnvironment ?? "preview",
|
|
121
|
+
requestContext: reqCtx,
|
|
122
|
+
routeRegistry: input.routeRegistry,
|
|
123
|
+
isLocalProject: adapterRes.isLocalProject,
|
|
124
|
+
moduleServerUrl: input.moduleServerUrl,
|
|
125
|
+
environmentId: input.environmentId ?? input.headers.environmentId,
|
|
126
|
+
skipEnrichedContext: input.skipEnrichedContext ?? shouldSkipEnrichedContext(input.url.pathname),
|
|
127
|
+
});
|
|
128
|
+
let rawEnvVars = {};
|
|
129
|
+
const environmentId = input.environmentId ?? input.headers.environmentId;
|
|
130
|
+
if (!adapterRes.isLocalProject &&
|
|
131
|
+
environmentId &&
|
|
132
|
+
reqCtx.token &&
|
|
133
|
+
projectRes.projectSlug) {
|
|
134
|
+
const projectSlug = projectRes.projectSlug;
|
|
135
|
+
rawEnvVars = await profileEnvVars(() => input.envVarCache.get(environmentId, reqCtx.token, projectSlug));
|
|
136
|
+
input.logDebug?.("[runtime-handler] Project env vars fetched", {
|
|
137
|
+
projectSlug,
|
|
138
|
+
environmentId,
|
|
139
|
+
count: Object.keys(rawEnvVars).length,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
const sourceIntegrationPolicy = normalizeSourceIntegrationPolicy(adapterRes.config?.integrations);
|
|
143
|
+
return {
|
|
144
|
+
adapter: adapterRes,
|
|
145
|
+
environment: envRes,
|
|
146
|
+
handlerContext,
|
|
147
|
+
rawEnvVars,
|
|
148
|
+
sourceIntegrationPolicy,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function createProxyGuard(req, url, isProxyMode, headers, proxyTrusted) {
|
|
152
|
+
if (!isProxyMode || isLightweightPath(url.pathname) || isWebSocketPath(url.pathname)) {
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
const token = req.headers.get("x-token");
|
|
156
|
+
const body = !headers.projectSlug
|
|
157
|
+
? {
|
|
158
|
+
error: "Missing project context",
|
|
159
|
+
detail: "x-project-slug header is required in proxy mode",
|
|
160
|
+
}
|
|
161
|
+
: !token
|
|
162
|
+
? {
|
|
163
|
+
error: "Missing authentication context",
|
|
164
|
+
detail: "x-token header is required in proxy mode",
|
|
165
|
+
}
|
|
166
|
+
: req.headers.get("x-project-path") && !proxyTrusted
|
|
167
|
+
? {
|
|
168
|
+
error: "Untrusted proxy context",
|
|
169
|
+
detail: "proxy context headers require a trusted upstream proxy",
|
|
170
|
+
}
|
|
171
|
+
: undefined;
|
|
172
|
+
if (!body)
|
|
173
|
+
return undefined;
|
|
174
|
+
return {
|
|
175
|
+
detail: body.detail,
|
|
176
|
+
response: new Response(JSON.stringify(body), {
|
|
177
|
+
status: 502,
|
|
178
|
+
headers: { "Content-Type": "application/json" },
|
|
179
|
+
}),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
@@ -16,6 +16,7 @@ export declare class RSCDevServerHandler {
|
|
|
16
16
|
private renderer;
|
|
17
17
|
private clientManifest;
|
|
18
18
|
private rendererPromise;
|
|
19
|
+
private reactVersionPromise;
|
|
19
20
|
private invalidationGeneration;
|
|
20
21
|
private readonly manifestHandler;
|
|
21
22
|
private readonly renderHandler;
|
|
@@ -25,8 +26,8 @@ export declare class RSCDevServerHandler {
|
|
|
25
26
|
private readonly appDir;
|
|
26
27
|
private readonly isLocalProject;
|
|
27
28
|
private readonly mode;
|
|
28
|
-
private readonly reactVersionPromise;
|
|
29
29
|
private readonly fs?;
|
|
30
|
+
private readonly config?;
|
|
30
31
|
handleManifest(): Promise<Response>;
|
|
31
32
|
handleRender(pathname: string, searchParams: URLSearchParams, request?: Request): Promise<Response>;
|
|
32
33
|
handleStream(pathname: string, searchParams: URLSearchParams): Promise<Response>;
|
|
@@ -34,5 +35,6 @@ export declare class RSCDevServerHandler {
|
|
|
34
35
|
invalidate(): void;
|
|
35
36
|
private ensureRenderer;
|
|
36
37
|
private initializeRenderer;
|
|
38
|
+
private getReactVersion;
|
|
37
39
|
}
|
|
38
40
|
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/services/rsc/orchestrators/handler.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;IACpC,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,4BAA4B,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,CAKzF;AAED,qBAAa,mBAAmB;
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/services/rsc/orchestrators/handler.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAE5E,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;IACpC,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,4BAA4B,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,CAKzF;AAED,qBAAa,mBAAmB;IAa5B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAZ7B,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,cAAc,CAAiD;IACvE,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,mBAAmB,CAAgC;IAC3D,OAAO,CAAC,sBAAsB,CAAK;IAEnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,WAAW,CAA4B;gBAG5B,UAAU,EAAE,MAAM,EACnC,OAAO,GAAE,uBAA4B;IAkCvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;IACzC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA+B;IACpD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAuB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAkB;IAE1C,cAAc,IAAI,OAAO,CAAC,QAAQ,CAAC;IAI7B,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,eAAe,EAC7B,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,QAAQ,CAAC;IAKd,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;IAKhF,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,eAAe,EAC7B,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,QAAQ,CAAC;IAWpB,UAAU,IAAI,IAAI;YAOJ,cAAc;YAed,kBAAkB;IAgBhC,OAAO,CAAC,eAAe;CAOxB"}
|
|
@@ -16,6 +16,7 @@ export class RSCDevServerHandler {
|
|
|
16
16
|
renderer = null;
|
|
17
17
|
clientManifest = null;
|
|
18
18
|
rendererPromise = null;
|
|
19
|
+
reactVersionPromise = null;
|
|
19
20
|
invalidationGeneration = 0;
|
|
20
21
|
manifestHandler;
|
|
21
22
|
renderHandler;
|
|
@@ -34,28 +35,25 @@ export class RSCDevServerHandler {
|
|
|
34
35
|
fs: options.adapter?.fs,
|
|
35
36
|
contentSourceId,
|
|
36
37
|
});
|
|
37
|
-
this.reactVersionPromise = resolveProjectReactVersion({
|
|
38
|
-
projectDir,
|
|
39
|
-
config: options.config,
|
|
40
|
-
});
|
|
41
38
|
this.renderHandler = new RenderHandler(projectDir, () => this.renderer, mode, appDir, {
|
|
42
39
|
adapter: options.adapter,
|
|
43
40
|
projectId: options.projectId,
|
|
44
41
|
projectSlug: options.projectSlug,
|
|
45
42
|
contentSourceId,
|
|
46
|
-
reactVersion: this.
|
|
43
|
+
reactVersion: () => this.getReactVersion(),
|
|
47
44
|
});
|
|
48
45
|
this.streamHandler = new StreamHandler(this.renderHandler);
|
|
49
46
|
this.appDir = appDir;
|
|
50
47
|
this.isLocalProject = isLocalProject;
|
|
51
48
|
this.mode = mode;
|
|
52
49
|
this.fs = options.adapter?.fs;
|
|
50
|
+
this.config = options.config;
|
|
53
51
|
}
|
|
54
52
|
appDir;
|
|
55
53
|
isLocalProject;
|
|
56
54
|
mode;
|
|
57
|
-
reactVersionPromise;
|
|
58
55
|
fs;
|
|
56
|
+
config;
|
|
59
57
|
handleManifest() {
|
|
60
58
|
return this.manifestHandler.handle(this.clientManifest);
|
|
61
59
|
}
|
|
@@ -69,7 +67,7 @@ export class RSCDevServerHandler {
|
|
|
69
67
|
}
|
|
70
68
|
async handlePage(pathname, searchParams, nonce) {
|
|
71
69
|
if (!this.pageHandler) {
|
|
72
|
-
this.pageHandler = new PageHandler(this.mode === "development", await this.
|
|
70
|
+
this.pageHandler = new PageHandler(this.mode === "development", await this.getReactVersion(), this.isLocalProject ? "fs" : "rsc-module");
|
|
73
71
|
}
|
|
74
72
|
return this.pageHandler.handle(pathname, searchParams, nonce);
|
|
75
73
|
}
|
|
@@ -96,7 +94,7 @@ export class RSCDevServerHandler {
|
|
|
96
94
|
}
|
|
97
95
|
async initializeRenderer(generation) {
|
|
98
96
|
const clientManifest = await buildClientManifest(this.projectDir, this.appDir, this.fs);
|
|
99
|
-
const reactVersion = await this.
|
|
97
|
+
const reactVersion = await this.getReactVersion();
|
|
100
98
|
if (generation !== this.invalidationGeneration)
|
|
101
99
|
return;
|
|
102
100
|
this.clientManifest = clientManifest;
|
|
@@ -109,4 +107,11 @@ export class RSCDevServerHandler {
|
|
|
109
107
|
reactVersion,
|
|
110
108
|
});
|
|
111
109
|
}
|
|
110
|
+
getReactVersion() {
|
|
111
|
+
this.reactVersionPromise ??= resolveProjectReactVersion({
|
|
112
|
+
projectDir: this.projectDir,
|
|
113
|
+
config: this.config,
|
|
114
|
+
});
|
|
115
|
+
return this.reactVersionPromise;
|
|
116
|
+
}
|
|
112
117
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/services/rsc/orchestrators/render-handler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AActF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAM5E,UAAU,0BAA0B;IAClC,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"render-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/services/rsc/orchestrators/render-handler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AActF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAM5E,UAAU,0BAA0B;IAClC,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACtC;AASD,qBAAa,aAAa;IAEtB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,aAAa;gBAJb,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,WAAW,GAAG,IAAI,EACrC,IAAI,GAAE,aAAa,GAAG,YAA2B,EACjD,MAAM,GAAE,MAAc,EACtB,aAAa,GAAE,0BAA+B;IAGlD,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,eAAe,EAC7B,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,QAAQ,CAAC;YAWN,aAAa;YA+Bb,mBAAmB;IA2CjC,OAAO,CAAC,UAAU;YAOJ,aAAa;IA2B3B,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,mBAAmB;CA6B5B"}
|
|
@@ -61,7 +61,7 @@ export class RenderHandler {
|
|
|
61
61
|
: await fs.readTextFile(componentPath);
|
|
62
62
|
const { body, frontmatter } = extractFrontmatter(source);
|
|
63
63
|
const compiled = await compileContent(this.mode, this.projectDir, body, frontmatter, componentPath, "server");
|
|
64
|
-
return await mdxRenderer.loadModuleESM(compiled.compiledCode, adapter, this.moduleOptions.projectId ?? this.projectDir, this.projectDir, this.moduleOptions.projectSlug, this.moduleOptions.contentSourceId, await this.moduleOptions.reactVersion);
|
|
64
|
+
return await mdxRenderer.loadModuleESM(compiled.compiledCode, adapter, this.moduleOptions.projectId ?? this.projectDir, this.projectDir, this.moduleOptions.projectSlug, this.moduleOptions.contentSourceId, await this.moduleOptions.reactVersion?.());
|
|
65
65
|
}
|
|
66
66
|
if (!adapter) {
|
|
67
67
|
return (await import(componentPath));
|
|
@@ -73,7 +73,7 @@ export class RenderHandler {
|
|
|
73
73
|
contentSourceId: this.moduleOptions.contentSourceId,
|
|
74
74
|
dev: this.mode === "development",
|
|
75
75
|
mode: this.mode === "development" ? "preview" : "production",
|
|
76
|
-
reactVersion: await this.moduleOptions.reactVersion,
|
|
76
|
+
reactVersion: await this.moduleOptions.reactVersion?.(),
|
|
77
77
|
});
|
|
78
78
|
}
|
|
79
79
|
buildProps(pathname, searchParams) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-cache.d.ts","sourceRoot":"","sources":["../../../../src/src/transforms/esm/http-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"http-cache.d.ts","sourceRoot":"","sources":["../../../../src/src/transforms/esm/http-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgBH,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EAGL,KAAK,YAAY,EAKjB,wBAAwB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,aAAa,EAElB,gBAAgB,EAEhB,KAAK,OAAO,EACb,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAA2B,MAAM,4BAA4B,CAAC;AACxF,OAAO,EACL,0BAA0B,EAO3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,sBAAsB,EAKvB,MAAM,uBAAuB,CAAC;AAqJ/B,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,GACnB,CAAC;AAGF,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,CAAC;AACzE,OAAO,EAAE,0BAA0B,EAAE,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAmRlC,wEAAwE;AACxE,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,sBAAsB,CAAC,CAkCjC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,wBAAwB,GAClC,OAAO,CAAC,OAAO,CAAC,CAElB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,wBAAwB,GAClC,OAAO,CAAC,MAAM,EAAE,CAAC,CAEnB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAErF;AAGD,eAAO,MAAM,wBAAwB,0BAAoB,CAAC"}
|
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
import { createFileSystem, exists } from "../../platform/compat/fs.js";
|
|
10
10
|
import { join } from "../../platform/compat/path/index.js";
|
|
11
11
|
import { rendererLogger as logger } from "../../utils/index.js";
|
|
12
|
-
import { BUILD_FAILED, BUNDLE_ERROR, FILE_NOT_FOUND } from "../../errors/index.js";
|
|
12
|
+
import { BUILD_FAILED, BUNDLE_ERROR, FILE_NOT_FOUND, retryWithBackoff } from "../../errors/index.js";
|
|
13
13
|
import { SpanNames } from "../../observability/index.js";
|
|
14
14
|
import { withSpan } from "../../observability/tracing/otlp-setup.js";
|
|
15
|
+
import { sanitizeUrlForSpan } from "../../utils/logger/redact.js";
|
|
15
16
|
import { replaceSpecifiers } from "./lexer.js";
|
|
16
17
|
import { createBundleManifest, storeBundleManifest } from "./bundle-manifest.js";
|
|
17
18
|
import { HTTP_MODULE_DISTRIBUTED_TTL_SEC } from "../../utils/constants/cache.js";
|
|
@@ -32,8 +33,119 @@ import { buildReplacements, rewriteModuleImports } from "./specifier-resolver.js
|
|
|
32
33
|
import { ensureHttpBundlesExist as ensureHttpBundlesExistImpl, invalidateHttpBundle as invalidateHttpBundleImpl, recoverHttpBundleByHash as recoverHttpBundleByHashImpl, } from "./bundle-recovery.js";
|
|
33
34
|
/** Threshold in ms above which an HTTP module fetch is considered slow */
|
|
34
35
|
const SLOW_HTTP_FETCH_THRESHOLD_MS = 500;
|
|
36
|
+
const HTTP_MODULE_FETCH_MAX_ATTEMPTS = 3;
|
|
37
|
+
const HTTP_MODULE_FETCH_RETRY_DELAY_MS = 100;
|
|
38
|
+
const HTTP_MODULE_FETCH_WAIT_GRACE_MS = 5_000;
|
|
39
|
+
const HTTP_MODULE_FETCH_MAX_WAIT_MS = HTTP_FETCH_TIMEOUT_MS * HTTP_MODULE_FETCH_MAX_ATTEMPTS +
|
|
40
|
+
HTTP_MODULE_FETCH_RETRY_DELAY_MS *
|
|
41
|
+
((HTTP_MODULE_FETCH_MAX_ATTEMPTS - 1) * HTTP_MODULE_FETCH_MAX_ATTEMPTS / 2) +
|
|
42
|
+
HTTP_MODULE_FETCH_WAIT_GRACE_MS;
|
|
35
43
|
const httpCacheLog = logger.component("http-cache");
|
|
36
44
|
const contentMetricsLog = logger.component("content-metrics");
|
|
45
|
+
class HttpModuleResponseError extends Error {
|
|
46
|
+
status;
|
|
47
|
+
constructor(status) {
|
|
48
|
+
super(`HTTP module response returned status ${status}`);
|
|
49
|
+
this.status = status;
|
|
50
|
+
this.name = "HttpModuleResponseError";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
class HttpModuleRequestError extends Error {
|
|
54
|
+
requestErrorType;
|
|
55
|
+
constructor(requestErrorType) {
|
|
56
|
+
super(`HTTP module request failed (${requestErrorType})`);
|
|
57
|
+
this.requestErrorType = requestErrorType;
|
|
58
|
+
this.name = "HttpModuleRequestError";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function shouldRetryHttpModuleFetch(status) {
|
|
62
|
+
return status === 408 || status === 425 || status === 429 || status >= 500;
|
|
63
|
+
}
|
|
64
|
+
async function discardResponseBody(response) {
|
|
65
|
+
try {
|
|
66
|
+
await response.body?.cancel();
|
|
67
|
+
}
|
|
68
|
+
catch (_) {
|
|
69
|
+
// The response is already being discarded.
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function fetchHttpModuleAttempt(url, safeUrl, urlObj, signal, attempt) {
|
|
73
|
+
let response;
|
|
74
|
+
try {
|
|
75
|
+
const startedAt = performance.now();
|
|
76
|
+
response = await fetch(url, {
|
|
77
|
+
headers: { "user-agent": "Mozilla/5.0 Veryfront/1.0" },
|
|
78
|
+
signal,
|
|
79
|
+
redirect: "follow",
|
|
80
|
+
});
|
|
81
|
+
const duration = Math.round(performance.now() - startedAt);
|
|
82
|
+
contentMetricsLog.debug("HTTP_MODULE_FETCH", {
|
|
83
|
+
url: safeUrl,
|
|
84
|
+
host: urlObj.host,
|
|
85
|
+
duration_ms: duration,
|
|
86
|
+
status: response.status,
|
|
87
|
+
slow: duration > SLOW_HTTP_FETCH_THRESHOLD_MS,
|
|
88
|
+
attempt: attempt + 1,
|
|
89
|
+
});
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
const status = response.status;
|
|
92
|
+
await discardResponseBody(response);
|
|
93
|
+
throw new HttpModuleResponseError(status);
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
code: await response.text(),
|
|
97
|
+
contentType: response.headers.get("content-type") ?? "",
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
if (error instanceof HttpModuleResponseError)
|
|
102
|
+
throw error;
|
|
103
|
+
if (response)
|
|
104
|
+
await discardResponseBody(response);
|
|
105
|
+
const requestErrorType = error instanceof Error ? error.name : typeof error;
|
|
106
|
+
throw new HttpModuleRequestError(requestErrorType);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async function fetchHttpModule(url) {
|
|
110
|
+
const urlObj = new URL(url);
|
|
111
|
+
const safeUrl = sanitizeUrlForSpan(url);
|
|
112
|
+
try {
|
|
113
|
+
return await retryWithBackoff((signal, attempt) => withSpan(SpanNames.HTTP_CLIENT_FETCH, () => fetchHttpModuleAttempt(url, safeUrl, urlObj, signal, attempt), {
|
|
114
|
+
"http.method": "GET",
|
|
115
|
+
"http.url": safeUrl,
|
|
116
|
+
"http.host": urlObj.host,
|
|
117
|
+
"http.scheme": urlObj.protocol.replace(":", ""),
|
|
118
|
+
"esm.package_fetch": true,
|
|
119
|
+
}), {
|
|
120
|
+
maxAttempts: HTTP_MODULE_FETCH_MAX_ATTEMPTS,
|
|
121
|
+
timeoutMs: HTTP_FETCH_TIMEOUT_MS,
|
|
122
|
+
shouldRetry: (error) => !(error instanceof HttpModuleResponseError) ||
|
|
123
|
+
shouldRetryHttpModuleFetch(error.status),
|
|
124
|
+
computeDelay: (attempt) => HTTP_MODULE_FETCH_RETRY_DELAY_MS * (attempt + 1),
|
|
125
|
+
onRetry: ({ error, attempt }) => {
|
|
126
|
+
httpCacheLog.warn("HTTP module fetch failed, retrying", {
|
|
127
|
+
url: safeUrl,
|
|
128
|
+
status: error instanceof HttpModuleResponseError ? error.status : undefined,
|
|
129
|
+
errorType: error instanceof HttpModuleRequestError
|
|
130
|
+
? error.requestErrorType
|
|
131
|
+
: error.name,
|
|
132
|
+
attempt: attempt + 1,
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
if (error instanceof HttpModuleResponseError) {
|
|
139
|
+
throw BUILD_FAILED.create({ detail: `Failed to fetch ${safeUrl}: ${error.status}` });
|
|
140
|
+
}
|
|
141
|
+
if (error instanceof HttpModuleRequestError) {
|
|
142
|
+
throw BUILD_FAILED.create({
|
|
143
|
+
detail: `Failed to fetch ${safeUrl}: ${error.requestErrorType}`,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
37
149
|
// Re-export for backwards compatibility
|
|
38
150
|
export { CACHE_DIR_TOKEN, detokenizeAllCachePaths, detokenizeCachePaths, tokenizeAllCachePaths, tokenizeCachePaths, };
|
|
39
151
|
export { extractBundleDeps, hasIncompatibleFilePaths, normalizeHttpUrl };
|
|
@@ -42,6 +154,7 @@ export { embedSourceUrl, extractSourceUrl };
|
|
|
42
154
|
export { __injectCachesForTests };
|
|
43
155
|
async function cacheHttpModuleInternal(url, options) {
|
|
44
156
|
const normalizedUrl = normalizeHttpUrl(url);
|
|
157
|
+
const safeUrl = sanitizeUrlForSpan(normalizedUrl);
|
|
45
158
|
const cacheDir = ensureAbsoluteDir(options.cacheDir);
|
|
46
159
|
const cacheIdentity = await buildHttpCacheIdentity(normalizedUrl, options);
|
|
47
160
|
const identityMetadata = await buildHttpCacheIdentityMetadata(normalizedUrl, options);
|
|
@@ -62,7 +175,7 @@ async function cacheHttpModuleInternal(url, options) {
|
|
|
62
175
|
// dependency could not be prefetched. Retry the prefetch instead of
|
|
63
176
|
// handing the degradation on.
|
|
64
177
|
httpCacheLog.debug("Local cache holds a degraded artifact, will re-fetch", {
|
|
65
|
-
url:
|
|
178
|
+
url: safeUrl,
|
|
66
179
|
hash,
|
|
67
180
|
});
|
|
68
181
|
}
|
|
@@ -72,7 +185,7 @@ async function cacheHttpModuleInternal(url, options) {
|
|
|
72
185
|
const depsValid = await validateBundleDepsExist(deps, cacheDir);
|
|
73
186
|
if (!depsValid) {
|
|
74
187
|
httpCacheLog.debug("Local cache has missing deps, will re-fetch", {
|
|
75
|
-
url:
|
|
188
|
+
url: safeUrl,
|
|
76
189
|
hash,
|
|
77
190
|
missingDeps: deps.length,
|
|
78
191
|
});
|
|
@@ -96,12 +209,12 @@ async function cacheHttpModuleInternal(url, options) {
|
|
|
96
209
|
if (processingStack.has(cacheIdentity)) {
|
|
97
210
|
if (await exists(cachePath)) {
|
|
98
211
|
httpCacheLog.debug("Circular dependency detected, file exists", {
|
|
99
|
-
url:
|
|
212
|
+
url: safeUrl,
|
|
100
213
|
});
|
|
101
214
|
}
|
|
102
215
|
else {
|
|
103
216
|
httpCacheLog.debug("Circular dependency detected, file pending write", {
|
|
104
|
-
url:
|
|
217
|
+
url: safeUrl,
|
|
105
218
|
cachePath,
|
|
106
219
|
});
|
|
107
220
|
}
|
|
@@ -109,7 +222,7 @@ async function cacheHttpModuleInternal(url, options) {
|
|
|
109
222
|
}
|
|
110
223
|
let inFlight = inFlightHttpFetches.get(cacheKey);
|
|
111
224
|
while (inFlight) {
|
|
112
|
-
const result = await waitForInFlightFetch(inFlight,
|
|
225
|
+
const result = await waitForInFlightFetch(inFlight, HTTP_MODULE_FETCH_MAX_WAIT_MS);
|
|
113
226
|
if (result !== undefined)
|
|
114
227
|
return result;
|
|
115
228
|
if (inFlightHttpFetches.get(cacheKey) === inFlight) {
|
|
@@ -127,7 +240,7 @@ async function cacheHttpModuleInternal(url, options) {
|
|
|
127
240
|
const depsExist = await validateBundleDepsExist(deps, cacheDir);
|
|
128
241
|
if (!depsExist) {
|
|
129
242
|
httpCacheLog.debug("Cached code has missing bundle deps, will re-fetch", {
|
|
130
|
-
url:
|
|
243
|
+
url: safeUrl,
|
|
131
244
|
hash,
|
|
132
245
|
missingDeps: deps.length,
|
|
133
246
|
});
|
|
@@ -135,7 +248,7 @@ async function cacheHttpModuleInternal(url, options) {
|
|
|
135
248
|
else {
|
|
136
249
|
logger.debug(cacheResult.wasGzipped
|
|
137
250
|
? "[HTTP-CACHE] Distributed cache hit (gzip decoded)"
|
|
138
|
-
: "[HTTP-CACHE] Distributed cache hit", { url:
|
|
251
|
+
: "[HTTP-CACHE] Distributed cache hit", { url: safeUrl, hash });
|
|
139
252
|
await fs.mkdir(cacheDir, { recursive: true });
|
|
140
253
|
await fs.writeTextFile(cachePath, cachedCode);
|
|
141
254
|
if (!(await exists(cachePath))) {
|
|
@@ -150,7 +263,7 @@ async function cacheHttpModuleInternal(url, options) {
|
|
|
150
263
|
else {
|
|
151
264
|
logger.debug(cacheResult.wasGzipped
|
|
152
265
|
? "[HTTP-CACHE] Distributed cache hit (gzip decoded, no deps)"
|
|
153
|
-
: "[HTTP-CACHE] Distributed cache hit", { url:
|
|
266
|
+
: "[HTTP-CACHE] Distributed cache hit", { url: safeUrl, hash });
|
|
154
267
|
await fs.mkdir(cacheDir, { recursive: true });
|
|
155
268
|
await fs.writeTextFile(cachePath, cachedCode);
|
|
156
269
|
if (!(await exists(cachePath))) {
|
|
@@ -164,49 +277,22 @@ async function cacheHttpModuleInternal(url, options) {
|
|
|
164
277
|
}
|
|
165
278
|
else if (cacheResult.failReason && cacheResult.failReason !== "not_found") {
|
|
166
279
|
httpCacheLog.debug("Distributed cache get failed", {
|
|
167
|
-
url:
|
|
280
|
+
url: safeUrl,
|
|
168
281
|
reason: cacheResult.failReason,
|
|
169
282
|
});
|
|
170
283
|
}
|
|
171
|
-
httpCacheLog.debug("Fetching from network", { url:
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
const httpFetchStartTime = performance.now();
|
|
176
|
-
const response = await withSpan(SpanNames.HTTP_CLIENT_FETCH, () => fetch(normalizedUrl, {
|
|
177
|
-
headers: { "user-agent": "Mozilla/5.0 Veryfront/1.0" },
|
|
178
|
-
signal: controller.signal,
|
|
179
|
-
redirect: "follow",
|
|
180
|
-
}), {
|
|
181
|
-
"http.method": "GET",
|
|
182
|
-
"http.url": normalizedUrl,
|
|
183
|
-
"http.host": urlObj.host,
|
|
184
|
-
"http.scheme": urlObj.protocol.replace(":", ""),
|
|
185
|
-
"esm.package_fetch": true,
|
|
186
|
-
});
|
|
187
|
-
clearTimeout(timeout);
|
|
188
|
-
const httpFetchDuration = Math.round(performance.now() - httpFetchStartTime);
|
|
189
|
-
contentMetricsLog.debug("HTTP_MODULE_FETCH", {
|
|
190
|
-
url: normalizedUrl.substring(0, 120),
|
|
191
|
-
host: urlObj.host,
|
|
192
|
-
duration_ms: httpFetchDuration,
|
|
193
|
-
status: response.status,
|
|
194
|
-
slow: httpFetchDuration > SLOW_HTTP_FETCH_THRESHOLD_MS,
|
|
195
|
-
});
|
|
196
|
-
if (!response.ok) {
|
|
197
|
-
throw BUILD_FAILED.create({ detail: `Failed to fetch ${normalizedUrl}: ${response.status}` });
|
|
198
|
-
}
|
|
199
|
-
let code = await response.text();
|
|
200
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
284
|
+
httpCacheLog.debug("Fetching from network", { url: safeUrl });
|
|
285
|
+
const fetchedModule = await fetchHttpModule(normalizedUrl);
|
|
286
|
+
let code = fetchedModule.code;
|
|
287
|
+
const contentType = fetchedModule.contentType;
|
|
201
288
|
const isHtmlContent = contentType.includes("text/html") || looksLikeHtmlNotJs(code);
|
|
202
289
|
if (isHtmlContent) {
|
|
203
290
|
logger.error("[HTTP-CACHE] Received HTML instead of JavaScript, likely an esm.sh error page", {
|
|
204
|
-
url:
|
|
291
|
+
url: safeUrl,
|
|
205
292
|
contentType,
|
|
206
|
-
preview: code.slice(0, 200),
|
|
207
293
|
});
|
|
208
294
|
throw BUNDLE_ERROR.create({
|
|
209
|
-
detail: `Received HTML instead of JavaScript from ${
|
|
295
|
+
detail: `Received HTML instead of JavaScript from ${safeUrl}. The package may not exist or failed to build on esm.sh.`,
|
|
210
296
|
});
|
|
211
297
|
}
|
|
212
298
|
processingStack.add(cacheIdentity);
|
|
@@ -236,9 +322,9 @@ async function cacheHttpModuleInternal(url, options) {
|
|
|
236
322
|
// retries the prefetch instead of inheriting one upstream blip for the
|
|
237
323
|
// lifetime of the distributed entry.
|
|
238
324
|
httpCacheLog.warn("Not caching a module with unresolved dynamic imports", {
|
|
239
|
-
url:
|
|
325
|
+
url: safeUrl,
|
|
240
326
|
hash,
|
|
241
|
-
degraded,
|
|
327
|
+
degraded: degraded.map(sanitizeUrlForSpan),
|
|
242
328
|
});
|
|
243
329
|
return cachePath;
|
|
244
330
|
}
|
|
@@ -249,7 +335,7 @@ async function cacheHttpModuleInternal(url, options) {
|
|
|
249
335
|
if (error instanceof VeryfrontError && error.slug === "cache-invariant-violation") {
|
|
250
336
|
throw error;
|
|
251
337
|
}
|
|
252
|
-
httpCacheLog.debug("Distributed cache set failed", { url:
|
|
338
|
+
httpCacheLog.debug("Distributed cache set failed", { url: safeUrl, error });
|
|
253
339
|
}
|
|
254
340
|
getCachedPaths().set(cacheKey, cachePath);
|
|
255
341
|
const accumulator = bundleAccumulatorStorage.getStore();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-attributes.d.ts","sourceRoot":"","sources":["../../../../src/src/transforms/esm/import-attributes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"import-attributes.d.ts","sourceRoot":"","sources":["../../../../src/src/transforms/esm/import-attributes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAyDH;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiB3E;AAED;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,GAC1C,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* @module transforms/esm/import-attributes
|
|
10
10
|
*/
|
|
11
11
|
import { parseMaskedImports } from "./lexer.js";
|
|
12
|
+
import { importAttributeRange } from "../import-rewriter/import-edit.js";
|
|
12
13
|
const ASSERT_KEYWORD = "assert";
|
|
13
14
|
/**
|
|
14
15
|
* The legacy `assert` keyword following a static import specifier.
|
|
@@ -32,15 +33,7 @@ const JSON_TYPE_ATTRIBUTE = /^\{\s*(["']?)type\1\s*:\s*(["'])json\2\s*,?\s*\}$/;
|
|
|
32
33
|
*
|
|
33
34
|
* The range is empty when the import declares no attributes.
|
|
34
35
|
*/
|
|
35
|
-
|
|
36
|
-
// Static: `e` indexes the closing quote and `se` ends the statement before
|
|
37
|
-
// any semicolon, so the clause and its keyword lie between them.
|
|
38
|
-
if (imp.d === -1)
|
|
39
|
-
return { start: imp.e + 1, end: imp.se };
|
|
40
|
-
// Dynamic: `e` is already past the closing quote and `se` is past the
|
|
41
|
-
// closing paren, so the comma and the options argument lie between them.
|
|
42
|
-
return { start: imp.e, end: imp.se - 1 };
|
|
43
|
-
}
|
|
36
|
+
const attributeRange = importAttributeRange;
|
|
44
37
|
/** Whether the declared attributes are exactly a JSON module type. */
|
|
45
38
|
function declaresJsonTypeOnly(clause, isDynamic) {
|
|
46
39
|
const attributes = (isDynamic ? DYNAMIC_WITH_ARGUMENT : STATIC_WITH_CLAUSE).exec(clause)?.[1];
|
|
@@ -21,10 +21,11 @@ export declare const inFlightHttpFetches: Map<string, Promise<string | null>>;
|
|
|
21
21
|
*/
|
|
22
22
|
export declare function __clearInFlightHttpFetches(): void;
|
|
23
23
|
/**
|
|
24
|
-
* Wait for an in-flight fetch
|
|
24
|
+
* Wait for an in-flight fetch. The default timeout includes jitter; callers
|
|
25
|
+
* with a bounded owner operation can supply its complete wait window.
|
|
25
26
|
* Returns undefined on timeout so caller can retry.
|
|
26
27
|
*/
|
|
27
|
-
export declare function waitForInFlightFetch(promise: Promise<string | null>,
|
|
28
|
+
export declare function waitForInFlightFetch(promise: Promise<string | null>, waitTimeoutMs?: number): Promise<string | null | undefined>;
|
|
28
29
|
/**
|
|
29
30
|
* Asynchronously refresh the distributed cache entry for a local bundle.
|
|
30
31
|
* This is fire-and-forget to avoid blocking the hot path.
|