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.
Files changed (118) hide show
  1. package/esm/cli/commands/eval/command.d.ts +2 -70
  2. package/esm/cli/commands/eval/command.d.ts.map +1 -1
  3. package/esm/cli/commands/eval/command.js +207 -550
  4. package/esm/cli/templates/manifest.d.ts +1 -0
  5. package/esm/cli/templates/manifest.js +3 -2
  6. package/esm/deno.js +1 -1
  7. package/esm/src/agent/hosted/chat-execution-runtime.d.ts.map +1 -1
  8. package/esm/src/agent/hosted/chat-execution-runtime.js +16 -33
  9. package/esm/src/agent/hosted/child-fork-tool-sources.d.ts.map +1 -1
  10. package/esm/src/agent/hosted/child-fork-tool-sources.js +6 -38
  11. package/esm/src/agent/hosted/hosted-chat-finalization.d.ts +30 -0
  12. package/esm/src/agent/hosted/hosted-chat-finalization.d.ts.map +1 -0
  13. package/esm/src/agent/hosted/hosted-chat-finalization.js +249 -0
  14. package/esm/src/agent/hosted/project-remote-tool-source.d.ts.map +1 -1
  15. package/esm/src/agent/hosted/project-remote-tool-source.js +4 -23
  16. package/esm/src/agent/mcp-tool-policy.d.ts +19 -0
  17. package/esm/src/agent/mcp-tool-policy.d.ts.map +1 -0
  18. package/esm/src/agent/mcp-tool-policy.js +66 -0
  19. package/esm/src/agent/runtime/mcp-server-tool-sources.d.ts.map +1 -1
  20. package/esm/src/agent/runtime/mcp-server-tool-sources.js +8 -44
  21. package/esm/src/discovery/import-rewriter.d.ts.map +1 -1
  22. package/esm/src/discovery/import-rewriter.js +7 -90
  23. package/esm/src/eval/run-report.d.ts +189 -0
  24. package/esm/src/eval/run-report.d.ts.map +1 -0
  25. package/esm/src/eval/run-report.js +603 -0
  26. package/esm/src/html/hydration-script-builder/dev-client-renderer.js +1 -1
  27. package/esm/src/html/hydration-script-builder/prod-scripts.js +1 -1
  28. package/esm/src/html/hydration-script-builder/templates/router.d.ts.map +1 -1
  29. package/esm/src/html/hydration-script-builder/templates/router.js +35 -11
  30. package/esm/src/html/utils.d.ts.map +1 -1
  31. package/esm/src/html/utils.js +19 -45
  32. package/esm/src/index.client.d.ts +6 -21
  33. package/esm/src/index.client.d.ts.map +1 -1
  34. package/esm/src/index.client.js +6 -21
  35. package/esm/src/modules/server/ssr-import-rewriter.d.ts +2 -26
  36. package/esm/src/modules/server/ssr-import-rewriter.d.ts.map +1 -1
  37. package/esm/src/modules/server/ssr-import-rewriter.js +1 -206
  38. package/esm/src/react/runtime/core.d.ts +22 -0
  39. package/esm/src/react/runtime/core.d.ts.map +1 -1
  40. package/esm/src/react/runtime/core.js +1 -1
  41. package/esm/src/rendering/orchestrator/module-collection.d.ts +8 -0
  42. package/esm/src/rendering/orchestrator/module-collection.d.ts.map +1 -1
  43. package/esm/src/rendering/orchestrator/module-collection.js +10 -0
  44. package/esm/src/rendering/orchestrator/pipeline.d.ts.map +1 -1
  45. package/esm/src/rendering/orchestrator/pipeline.js +2 -2
  46. package/esm/src/routing/api/context-builder.d.ts +7 -0
  47. package/esm/src/routing/api/context-builder.d.ts.map +1 -1
  48. package/esm/src/routing/api/context-builder.js +20 -2
  49. package/esm/src/routing/api/module-loader/external-import-rewriter.d.ts +2 -7
  50. package/esm/src/routing/api/module-loader/external-import-rewriter.d.ts.map +1 -1
  51. package/esm/src/routing/api/module-loader/external-import-rewriter.js +10 -209
  52. package/esm/src/server/dev-server/file-watch-setup.d.ts.map +1 -1
  53. package/esm/src/server/dev-server/file-watch-setup.js +11 -1
  54. package/esm/src/server/dev-server/middleware.d.ts.map +1 -1
  55. package/esm/src/server/dev-server/middleware.js +45 -11
  56. package/esm/src/server/handlers/dev/files/esbuild-plugins.d.ts.map +1 -1
  57. package/esm/src/server/handlers/dev/files/esbuild-plugins.js +22 -0
  58. package/esm/src/server/handlers/request/module/page-data-endpoint-handler.js +24 -1
  59. package/esm/src/server/handlers/response/not-found.d.ts +0 -1
  60. package/esm/src/server/handlers/response/not-found.d.ts.map +1 -1
  61. package/esm/src/server/handlers/response/not-found.js +9 -110
  62. package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
  63. package/esm/src/server/runtime-handler/index.js +66 -145
  64. package/esm/src/server/runtime-handler/project-runtime-context.d.ts +118 -0
  65. package/esm/src/server/runtime-handler/project-runtime-context.d.ts.map +1 -0
  66. package/esm/src/server/runtime-handler/project-runtime-context.js +181 -0
  67. package/esm/src/server/services/rsc/orchestrators/handler.d.ts +3 -1
  68. package/esm/src/server/services/rsc/orchestrators/handler.d.ts.map +1 -1
  69. package/esm/src/server/services/rsc/orchestrators/handler.js +13 -8
  70. package/esm/src/server/services/rsc/orchestrators/render-handler.d.ts +1 -1
  71. package/esm/src/server/services/rsc/orchestrators/render-handler.d.ts.map +1 -1
  72. package/esm/src/server/services/rsc/orchestrators/render-handler.js +2 -2
  73. package/esm/src/transforms/esm/http-cache.d.ts.map +1 -1
  74. package/esm/src/transforms/esm/http-cache.js +132 -46
  75. package/esm/src/transforms/esm/import-attributes.d.ts.map +1 -1
  76. package/esm/src/transforms/esm/import-attributes.js +2 -9
  77. package/esm/src/transforms/esm/in-flight-manager.d.ts +3 -2
  78. package/esm/src/transforms/esm/in-flight-manager.d.ts.map +1 -1
  79. package/esm/src/transforms/esm/in-flight-manager.js +6 -5
  80. package/esm/src/transforms/import-rewriter/core.d.ts +8 -0
  81. package/esm/src/transforms/import-rewriter/core.d.ts.map +1 -0
  82. package/esm/src/transforms/import-rewriter/core.js +27 -0
  83. package/esm/src/transforms/import-rewriter/import-edit.d.ts +57 -0
  84. package/esm/src/transforms/import-rewriter/import-edit.d.ts.map +1 -0
  85. package/esm/src/transforms/import-rewriter/import-edit.js +151 -0
  86. package/esm/src/transforms/import-rewriter/package-resolution.d.ts +12 -0
  87. package/esm/src/transforms/import-rewriter/package-resolution.d.ts.map +1 -0
  88. package/esm/src/transforms/import-rewriter/package-resolution.js +79 -0
  89. package/esm/src/transforms/import-rewriter/parse-cache.d.ts +4 -42
  90. package/esm/src/transforms/import-rewriter/parse-cache.d.ts.map +1 -1
  91. package/esm/src/transforms/import-rewriter/parse-cache.js +3 -134
  92. package/esm/src/transforms/import-rewriter/route-adapter.d.ts +24 -0
  93. package/esm/src/transforms/import-rewriter/route-adapter.d.ts.map +1 -0
  94. package/esm/src/transforms/import-rewriter/route-adapter.js +235 -0
  95. package/esm/src/transforms/import-rewriter/ssr-adapter.d.ts +27 -0
  96. package/esm/src/transforms/import-rewriter/ssr-adapter.d.ts.map +1 -0
  97. package/esm/src/transforms/import-rewriter/ssr-adapter.js +206 -0
  98. package/esm/src/transforms/import-rewriter/strategies/bare-strategy.d.ts.map +1 -1
  99. package/esm/src/transforms/import-rewriter/strategies/bare-strategy.js +16 -2
  100. package/esm/src/transforms/import-rewriter/unified-rewriter.d.ts +0 -4
  101. package/esm/src/transforms/import-rewriter/unified-rewriter.d.ts.map +1 -1
  102. package/esm/src/transforms/import-rewriter/unified-rewriter.js +2 -39
  103. package/esm/src/utils/version-constant.d.ts +1 -1
  104. package/esm/src/utils/version-constant.js +1 -1
  105. package/esm/src/workflow/executor/workflow-executor.d.ts +0 -20
  106. package/esm/src/workflow/executor/workflow-executor.d.ts.map +1 -1
  107. package/esm/src/workflow/executor/workflow-executor.js +41 -320
  108. package/esm/src/workflow/runtime/approval-manager.d.ts.map +1 -1
  109. package/esm/src/workflow/runtime/approval-manager.js +20 -61
  110. package/esm/src/workflow/runtime/workflow-run-control.d.ts +95 -0
  111. package/esm/src/workflow/runtime/workflow-run-control.d.ts.map +1 -0
  112. package/esm/src/workflow/runtime/workflow-run-control.js +529 -0
  113. package/esm/src/workflow/worker/run-manager.d.ts.map +1 -1
  114. package/esm/src/workflow/worker/run-manager.js +18 -92
  115. package/esm/src/workflow/worker/shared.d.ts +1 -1
  116. package/esm/src/workflow/worker/shared.d.ts.map +1 -1
  117. package/esm/src/workflow/worker/shared.js +17 -15
  118. 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;IAY5B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAX7B,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,cAAc,CAAiD;IACvE,OAAO,CAAC,eAAe,CAA8B;IACrD,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;IAqCvC,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,mBAAmB,CAAkB;IACtD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAuB;IAE3C,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;CAejC"}
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.reactVersionPromise,
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.reactVersionPromise, this.isLocalProject ? "fs" : "rsc-module");
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.reactVersionPromise;
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
  }
@@ -5,7 +5,7 @@ interface RenderHandlerModuleOptions {
5
5
  projectId?: string;
6
6
  projectSlug?: string;
7
7
  contentSourceId?: string;
8
- reactVersion?: Promise<string>;
8
+ reactVersion?: () => Promise<string>;
9
9
  }
10
10
  export declare class RenderHandler {
11
11
  private projectDir;
@@ -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;CAChC;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"}
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;AAeH,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;AAe/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;AAwTlC,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"}
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: normalizedUrl,
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: normalizedUrl,
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: normalizedUrl,
212
+ url: safeUrl,
100
213
  });
101
214
  }
102
215
  else {
103
216
  httpCacheLog.debug("Circular dependency detected, file pending write", {
104
- url: normalizedUrl,
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, cacheKey);
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: normalizedUrl,
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: normalizedUrl, hash });
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: normalizedUrl, hash });
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: normalizedUrl,
280
+ url: safeUrl,
168
281
  reason: cacheResult.failReason,
169
282
  });
170
283
  }
171
- httpCacheLog.debug("Fetching from network", { url: normalizedUrl });
172
- const urlObj = new URL(normalizedUrl);
173
- const controller = new AbortController();
174
- const timeout = setTimeout(() => controller.abort(), HTTP_FETCH_TIMEOUT_MS);
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: normalizedUrl,
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 ${normalizedUrl}. The package may not exist or failed to build on esm.sh.`,
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: normalizedUrl,
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: normalizedUrl, error });
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;AAgEH;;;;;;;;;;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"}
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
- function attributeRange(imp) {
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 with timeout + jitter.
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>, cacheKey: string): Promise<string | null | undefined>;
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.