veryfront 0.1.1126 → 0.1.1127

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 (29) hide show
  1. package/esm/deno.js +1 -1
  2. package/esm/src/config/environment-config.d.ts +5 -0
  3. package/esm/src/config/environment-config.d.ts.map +1 -1
  4. package/esm/src/config/environment-config.js +5 -2
  5. package/esm/src/middleware/builtin/timeout.d.ts +1 -1
  6. package/esm/src/middleware/builtin/timeout.d.ts.map +1 -1
  7. package/esm/src/middleware/builtin/timeout.js +3 -4
  8. package/esm/src/rendering/orchestrator/module-collection.d.ts +2 -2
  9. package/esm/src/rendering/orchestrator/module-collection.js +2 -2
  10. package/esm/src/rendering/orchestrator/pipeline.d.ts.map +1 -1
  11. package/esm/src/rendering/orchestrator/pipeline.js +7 -1
  12. package/esm/src/rendering/orchestrator/types.d.ts +2 -0
  13. package/esm/src/rendering/orchestrator/types.d.ts.map +1 -1
  14. package/esm/src/rendering/renderer.d.ts.map +1 -1
  15. package/esm/src/rendering/renderer.js +18 -8
  16. package/esm/src/rendering/utils/stream-utils.d.ts +19 -7
  17. package/esm/src/rendering/utils/stream-utils.d.ts.map +1 -1
  18. package/esm/src/rendering/utils/stream-utils.js +77 -12
  19. package/esm/src/routing/api/module-loader/loader.js +23 -0
  20. package/esm/src/server/handlers/request/module/page-data-endpoint-handler.d.ts.map +1 -1
  21. package/esm/src/server/handlers/request/module/page-data-endpoint-handler.js +16 -3
  22. package/esm/src/transforms/esm/transform-cache.d.ts.map +1 -1
  23. package/esm/src/transforms/esm/transform-cache.js +2 -16
  24. package/esm/src/utils/singleflight.d.ts +5 -0
  25. package/esm/src/utils/singleflight.d.ts.map +1 -1
  26. package/esm/src/utils/singleflight.js +29 -0
  27. package/esm/src/utils/version-constant.d.ts +1 -1
  28. package/esm/src/utils/version-constant.js +1 -1
  29. package/package.json +5 -5
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.1126",
3
+ "version": "0.1.1127",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "minimumDependencyAge": {
@@ -57,6 +57,11 @@ export interface EnvironmentConfig {
57
57
  v8MaxOldSpaceSize: number | undefined;
58
58
  veryfrontVersion: string | undefined;
59
59
  }
60
+ /**
61
+ * Default incoming request deadline. This must remain above the renderer's
62
+ * 60-second pipeline deadline and below the proxy's 90-second upstream one.
63
+ */
64
+ export declare const DEFAULT_REQUEST_TIMEOUT_MS = 75000;
60
65
  export declare function initEnvironmentConfig(): EnvironmentConfig;
61
66
  export declare function refreshEnvironmentConfig(): EnvironmentConfig;
62
67
  export declare function getEnvironmentConfig(): EnvironmentConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"environment-config.d.ts","sourceRoot":"","sources":["../../../src/src/config/environment-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"environment-config.d.ts","sourceRoot":"","sources":["../../../src/src/config/environment-config.ts"],"names":[],"mappings":"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"}
@@ -3,8 +3,11 @@ import { getHostTelemetryEnv } from "../observability/tracing/telemetry-env.js";
3
3
  import { isTruthyEnvValue } from "../utils/constants/env.js";
4
4
  import { logger } from "../utils/logger/logger.js";
5
5
  import { hasEnvLoaded } from "../utils/env-loader.js";
6
- /** Default timeout for incoming HTTP requests (used when REQUEST_TIMEOUT_MS is set but unparseable) */
7
- const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
6
+ /**
7
+ * Default incoming request deadline. This must remain above the renderer's
8
+ * 60-second pipeline deadline and below the proxy's 90-second upstream one.
9
+ */
10
+ export const DEFAULT_REQUEST_TIMEOUT_MS = 75_000;
8
11
  /** Default timeout for outgoing HTTP fetch calls (used when VF_HTTP_FETCH_TIMEOUT is set but unparseable) */
9
12
  const DEFAULT_HTTP_FETCH_TIMEOUT_MS = 30_000;
10
13
  const DEFAULTS = {
@@ -2,7 +2,7 @@ import type { Middleware } from "./types.js";
2
2
  import { type EnvironmentConfig } from "../../config/environment-config.js";
3
3
  /** Options accepted by timeout. */
4
4
  export interface TimeoutOptions {
5
- /** Timeout in milliseconds (default: 60000) */
5
+ /** Timeout in milliseconds (default: 75000) */
6
6
  timeoutMs?: number;
7
7
  /** Custom message for timeout response */
8
8
  message?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../../../../src/src/middleware/builtin/timeout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,oCAAoC,CAAC;AAS5C,mCAAmC;AACnC,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAoBD;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,UAAU,CAmC5D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,iBAA0C,GAAG,MAAM,CAGzF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,GAAG,UAAU,CAEtF"}
1
+ {"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../../../../src/src/middleware/builtin/timeout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,oCAAoC,CAAC;AAQ5C,mCAAmC;AACnC,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAoBD;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,UAAU,CAmC5D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,iBAA0C,GAAG,MAAM,CAGzF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,GAAG,UAAU,CAEtF"}
@@ -1,9 +1,8 @@
1
1
  import { getRequest } from "./types.js";
2
2
  import { serverLogger } from "../../utils/index.js";
3
- import { getEnvironmentConfig, } from "../../config/environment-config.js";
3
+ import { DEFAULT_REQUEST_TIMEOUT_MS, getEnvironmentConfig, } from "../../config/environment-config.js";
4
4
  import { HTTP_GATEWAY_TIMEOUT } from "../../utils/constants/http.js";
5
5
  const logger = serverLogger.component("timeout");
6
- const DEFAULT_TIMEOUT_MS = 60_000;
7
6
  const TIMEOUT_SENTINEL = Symbol("timeout");
8
7
  const DEFAULT_EXCLUDE_PATHS = ["/healthz", "/readyz", "/_health"];
9
8
  function isExcludedPath(pathname, exclude) {
@@ -26,7 +25,7 @@ function timeoutResponse(pathname, timeoutMs, message) {
26
25
  * returns a 504 Gateway Timeout response.
27
26
  */
28
27
  export function timeout(options) {
29
- const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
28
+ const timeoutMs = options?.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
30
29
  const message = options?.message ?? "Request timeout";
31
30
  const exclude = options?.exclude ?? DEFAULT_EXCLUDE_PATHS;
32
31
  return async (ctx, next) => {
@@ -65,7 +64,7 @@ export function timeout(options) {
65
64
  */
66
65
  export function getTimeoutFromEnv(env = getEnvironmentConfig()) {
67
66
  const timeoutMs = env.requestTimeoutMs;
68
- return timeoutMs && timeoutMs > 0 ? timeoutMs : DEFAULT_TIMEOUT_MS;
67
+ return timeoutMs && timeoutMs > 0 ? timeoutMs : DEFAULT_REQUEST_TIMEOUT_MS;
69
68
  }
70
69
  /**
71
70
  * Creates a timeout middleware with configuration from environment
@@ -9,8 +9,8 @@
9
9
  /** Idle timeout for the module-loading stage. Any concrete module/transform progress resets it. */
10
10
  export declare const MODULE_LOAD_TIMEOUT_MS = 10000;
11
11
  /**
12
- * Absolute module-loading stage cap. Progress is stage-wide, so a single wedged
13
- * module can still run until this hard cap while other modules report progress.
12
+ * Fallback cap when module loading is called without an owner signal.
13
+ * Request and renderer entrypoints supply their own total deadline signal.
14
14
  */
15
15
  export declare const MODULE_LOAD_HARD_TIMEOUT_MS = 45000;
16
16
  /** Timeout for data fetching (getStaticData, getServerData) */
@@ -9,8 +9,8 @@
9
9
  /** Idle timeout for the module-loading stage. Any concrete module/transform progress resets it. */
10
10
  export const MODULE_LOAD_TIMEOUT_MS = 10_000;
11
11
  /**
12
- * Absolute module-loading stage cap. Progress is stage-wide, so a single wedged
13
- * module can still run until this hard cap while other modules report progress.
12
+ * Fallback cap when module loading is called without an owner signal.
13
+ * Request and renderer entrypoints supply their own total deadline signal.
14
14
  */
15
15
  export const MODULE_LOAD_HARD_TIMEOUT_MS = 45_000;
16
16
  /** Timeout for data fetching (getStaticData, getServerData) */
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAUH,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,iCAAiC,CAAC;AASzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA4DhF,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACxE,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrF;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,wBAAwB,CAAC;IAC3C,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,eAAe,EAAE,eAAe,CAAC;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,aAAa,GAAG,YAAY,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wEAAwE;IACxE,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,OAAO,qBAAqB,EAAE,sBAAsB,CAAC;CAC1E;AAqCD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,mBAAmB,CAAgC;gBAE/C,MAAM,EAAE,oBAAoB;IAcxC,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,oBAAoB;IA0B5B;;;;OAIG;YACW,yBAAyB;IAWvC;;;OAGG;IACH,gBAAgB,IAAI,IAAI;IAKxB,OAAO,CAAC,UAAU;YAOJ,0BAA0B;IAaxC;;;;;;;;;OASG;YACW,qBAAqB;IA6EnC;;;OAGG;YACW,mBAAmB;IAoHjC,OAAO,CAAC,uBAAuB;IAkCzB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAqU9E,+EAA+E;IACzE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;YAsHzE,kBAAkB;YA2ClB,cAAc;IAW5B,OAAO,CAAC,uBAAuB;YAYjB,kBAAkB;IA6FhC,OAAO,CAAC,kBAAkB;YAQZ,uBAAuB;IAmBrC;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;CAStB"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAUH,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,iCAAiC,CAAC;AASzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA4DhF,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACxE,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrF;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,wBAAwB,CAAC;IAC3C,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,eAAe,EAAE,eAAe,CAAC;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,aAAa,GAAG,YAAY,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wEAAwE;IACxE,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,OAAO,qBAAqB,EAAE,sBAAsB,CAAC;CAC1E;AAqCD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,mBAAmB,CAAgC;gBAE/C,MAAM,EAAE,oBAAoB;IAcxC,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,oBAAoB;IA0B5B;;;;OAIG;YACW,yBAAyB;IAWvC;;;OAGG;IACH,gBAAgB,IAAI,IAAI;IAKxB,OAAO,CAAC,UAAU;YAOJ,0BAA0B;IAaxC;;;;;;;;;OASG;YACW,qBAAqB;IAiFnC;;;OAGG;YACW,mBAAmB;IAqHjC,OAAO,CAAC,uBAAuB;IAkCzB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAqU9E,+EAA+E;IACzE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;YAsHzE,kBAAkB;YA2ClB,cAAc;IAW5B,OAAO,CAAC,uBAAuB;YAYjB,kBAAkB;IA6FhC,OAAO,CAAC,kBAAkB;YAQZ,uBAAuB;IAmBrC;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;CAStB"}
@@ -147,8 +147,13 @@ export class RenderPipeline {
147
147
  async loadModulesInParallel(modules, options, timeoutControl) {
148
148
  const moduleLoaderConfig = await this.resolveModuleLoaderConfig(options);
149
149
  if (timeoutControl) {
150
+ const completedMilestones = new Set();
150
151
  moduleLoaderConfig.signal = timeoutControl.signal;
151
152
  moduleLoaderConfig.onProgress = ({ phase, filePath }) => {
153
+ const milestone = `${phase}:${filePath ?? ""}`;
154
+ if (completedMilestones.has(milestone))
155
+ return;
156
+ completedMilestones.add(milestone);
152
157
  const fileName = filePath?.split("/").pop();
153
158
  timeoutControl.mark(fileName ? `${phase}:${fileName}` : phase);
154
159
  };
@@ -245,8 +250,9 @@ export class RenderPipeline {
245
250
  }
246
251
  const loadedModules = await profilePhase("render.load_modules", () => withSpan(SpanNames.RENDER_LOAD_MODULES, () => withProgressTimeoutThrow((control) => this.loadModulesInParallel(modulesToLoad, options, control), {
247
252
  idleTimeoutMs: MODULE_LOAD_TIMEOUT_MS,
248
- hardTimeoutMs: MODULE_LOAD_HARD_TIMEOUT_MS,
253
+ hardTimeoutMs: options.abortSignal ? undefined : MODULE_LOAD_HARD_TIMEOUT_MS,
249
254
  label: `Module loading for ${slug}`,
255
+ signal: options.abortSignal,
250
256
  }), { "render.module_count": modulesToLoad.length }));
251
257
  const dataJobs = loadedModules.filter((m) => options?.staticDataOnly
252
258
  ? typeof m.mod.getStaticData === "function"
@@ -30,6 +30,8 @@ export interface RenderOptions {
30
30
  props?: Record<string, unknown>;
31
31
  delivery?: "string" | "stream";
32
32
  request?: Request;
33
+ /** Internal signal for the render owner's total deadline. */
34
+ abortSignal?: AbortSignal;
33
35
  url?: URL;
34
36
  /** Restrict data fetching to static hooks, even when a request context exists. */
35
37
  staticDataOnly?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../../src/src/rendering/renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../../src/src/rendering/renderer.ts"],"names":[],"mappings":"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"}
@@ -49,7 +49,7 @@ import { SSROrchestrator } from "./orchestrator/ssr-orchestrator.js";
49
49
  import { RenderPipeline } from "./orchestrator/pipeline.js";
50
50
  import { createLayoutComponentCache } from "./layouts/utils/component-loader.js";
51
51
  import { TimeoutError, withTimeoutThrow } from "./utils/stream-utils.js";
52
- import { Singleflight } from "../utils/singleflight.js";
52
+ import { Singleflight, waitForSharedPromise } from "../utils/singleflight.js";
53
53
  import { acquireProjectSlot, projectRenderCounts, releaseProjectSlot, RENDER_ACQUIRE_TIMEOUT_MS, RENDER_PER_PROJECT_LIMIT, renderSemaphore, } from "./renderer-concurrency.js";
54
54
  const logger = rendererLogger.component("renderer");
55
55
  /**
@@ -219,7 +219,7 @@ export class Renderer {
219
219
  }
220
220
  return cacheResult.cachedResult;
221
221
  }
222
- const result = await this.doRenderPage(slug, effectiveCtx, effectiveOptions, startTime, cacheKey);
222
+ const result = await this.doRenderPage(slug, effectiveCtx, effectiveOptions, startTime, cacheKey, effectiveOptions.abortSignal ?? effectiveOptions.request?.signal);
223
223
  this.scheduleProductionRenderPrewarm(slug, effectiveCtx, effectiveOptions, cacheKey);
224
224
  return result;
225
225
  }, {
@@ -369,7 +369,7 @@ export class Renderer {
369
369
  });
370
370
  this.rememberProductionPrewarm(refreshKey, promise);
371
371
  setTimeout(() => {
372
- void this.doRenderPage(slug, ctx, refreshOptions, performance.now(), cacheKey)
372
+ void this.doRenderPage(slug, ctx, refreshOptions, performance.now(), cacheKey, undefined)
373
373
  .then(() => {
374
374
  this.scheduleProductionRenderPrewarm(slug, ctx, refreshOptions, cacheKey);
375
375
  resolvePromise();
@@ -429,13 +429,13 @@ export class Renderer {
429
429
  routeCount: slugs.length,
430
430
  });
431
431
  }
432
- async doRenderPage(slug, ctx, options, startTime, cacheKey) {
432
+ async doRenderPage(slug, ctx, options, startTime, cacheKey, callerSignal) {
433
433
  const effectiveKey = cacheKey ?? dntShim.crypto.randomUUID();
434
434
  const flightKey = this.getSingleflightKey(effectiveKey, ctx, options?.colorScheme);
435
435
  const isFollower = cacheKey !== null ? this.renderFlight.has(flightKey) : false;
436
436
  const runRender = async () => {
437
437
  try {
438
- return await this.runRenderWithCapacity(slug, ctx, options, startTime, cacheKey);
438
+ return await this.runRenderWithCapacity(slug, ctx, options, startTime, cacheKey, callerSignal);
439
439
  }
440
440
  catch (error) {
441
441
  if (error instanceof TimeoutError) {
@@ -449,7 +449,7 @@ export class Renderer {
449
449
  }
450
450
  };
451
451
  const cachedData = cacheKey !== null
452
- ? await this.renderFlight.do(flightKey, runRender)
452
+ ? await waitForSharedPromise(this.renderFlight.do(flightKey, runRender), callerSignal)
453
453
  : await runRender();
454
454
  if (isFollower) {
455
455
  logger.debug("Render deduplicated (follower)", {
@@ -468,7 +468,7 @@ export class Renderer {
468
468
  stream: null,
469
469
  };
470
470
  }
471
- async runRenderWithCapacity(slug, ctx, options, startTime, cacheKey) {
471
+ async runRenderWithCapacity(slug, ctx, options, startTime, cacheKey, callerSignal) {
472
472
  if (!(await acquireProjectSlot(ctx.projectId))) {
473
473
  const activeCount = projectRenderCounts.get(ctx.projectId) ?? 0;
474
474
  logger.error("Per-project render limit reached", {
@@ -503,8 +503,14 @@ export class Renderer {
503
503
  }
504
504
  try {
505
505
  const services = this.createServicesForContext(ctx, options?.colorScheme);
506
+ const renderAbortController = new AbortController();
507
+ const request = cacheKey !== null && options?.request
508
+ ? new Request(options.request, { signal: renderAbortController.signal })
509
+ : options?.request;
506
510
  const result = await withTimeoutThrow(services.pipeline.renderPage(slug, {
507
511
  ...options,
512
+ request,
513
+ abortSignal: renderAbortController.signal,
508
514
  delivery: "string",
509
515
  projectId: ctx.projectId,
510
516
  projectSlug: ctx.projectSlug,
@@ -512,7 +518,11 @@ export class Renderer {
512
518
  contentSourceId: ctx.contentSourceId,
513
519
  skipCacheCheck: true,
514
520
  skipCachePersist: true,
515
- }), RENDER_PIPELINE_TIMEOUT_MS, `Render pipeline for ${ctx.projectId}:${slug}`);
521
+ }), RENDER_PIPELINE_TIMEOUT_MS, `Render pipeline for ${ctx.projectId}:${slug}`, {
522
+ signal: cacheKey === null ? callerSignal : undefined,
523
+ onAbort: (reason) => renderAbortController.abort(reason),
524
+ onTimeout: (error) => renderAbortController.abort(error),
525
+ });
516
526
  if (cacheKey !== null) {
517
527
  await this.cache.persistResult(result, slug, ctx, options?.colorScheme, cacheKey);
518
528
  }
@@ -7,7 +7,7 @@ export declare class TimeoutError extends Error {
7
7
  });
8
8
  }
9
9
  export interface ProgressTimeoutControl {
10
- /** Aborted when either the idle deadline or hard cap is reached. */
10
+ /** Aborted when a local deadline or the caller-owned signal is reached. */
11
11
  signal: AbortSignal;
12
12
  /** Reset the idle deadline after a concrete unit of work completes. */
13
13
  mark(label: string): void;
@@ -15,16 +15,28 @@ export interface ProgressTimeoutControl {
15
15
  export interface ProgressTimeoutOptions {
16
16
  label: string;
17
17
  idleTimeoutMs: number;
18
- hardTimeoutMs: number;
18
+ /** Optional local hard cap. Omit when the caller already owns the total deadline. */
19
+ hardTimeoutMs?: number;
20
+ /** Optional deadline owned by the operation's caller. */
21
+ signal?: AbortSignal;
22
+ }
23
+ export interface TimeoutOptions {
24
+ /** Optional caller-owned abort signal that should reject the waiter immediately. */
25
+ signal?: AbortSignal;
26
+ /** Called when the caller-owned signal aborts; failures do not replace the abort reason. */
27
+ onAbort?: (reason: unknown) => void;
28
+ /** Called when the local timeout fires; failures do not replace the timeout error. */
29
+ onTimeout?: (error: TimeoutError) => void;
19
30
  }
20
31
  export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, label: string): Promise<T | undefined>;
21
- export declare function withTimeoutThrow<T>(promise: Promise<T>, timeoutMs: number, label: string): Promise<T>;
32
+ export declare function withTimeoutThrow<T>(promise: Promise<T>, timeoutMs: number, label: string, options?: TimeoutOptions): Promise<T>;
22
33
  /**
23
- * Run an operation with a resettable idle deadline and a non-resettable hard cap.
34
+ * Run an operation with a resettable idle deadline and an optional hard cap.
24
35
  *
25
- * Callers must only call `mark` after meaningful progress. The hard cap keeps a
26
- * noisy or buggy progress source from extending work forever. The supplied
27
- * signal lets cooperative operations stop after either deadline.
36
+ * Callers must only call `mark` after meaningful progress. Use `hardTimeoutMs`
37
+ * when this helper owns the total deadline. Omit it when an outer operation
38
+ * already enforces that deadline. The supplied signal lets cooperative work
39
+ * stop after either configured deadline.
28
40
  */
29
41
  export declare function withProgressTimeoutThrow<T>(operation: (control: ProgressTimeoutControl) => Promise<T>, options: ProgressTimeoutOptions): Promise<T>;
30
42
  export declare class StreamTimeoutError extends Error {
@@ -1 +1 @@
1
- {"version":3,"file":"stream-utils.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/utils/stream-utils.ts"],"names":[],"mappings":"AAGA,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;gBAG7B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE;CAO9D;AAED,MAAM,WAAW,sBAAsB;IACrC,oEAAoE;IACpE,MAAM,EAAE,WAAW,CAAC;IACpB,uEAAuE;IACvE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,WAAW,CAAC,CAAC,EACjC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAkBxB;AAED,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,CAAC,CAAC,CAeZ;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAAC,CAAC,EAC9C,SAAS,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1D,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,CAAC,CAAC,CA2DZ;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;gBAEpB,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;CAKtD;AAcD,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,SAAS,GAAE,MAAuB,GACjC,OAAO,CAAC,MAAM,CAAC,CA+CjB"}
1
+ {"version":3,"file":"stream-utils.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/utils/stream-utils.ts"],"names":[],"mappings":"AAGA,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;gBAG7B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE;CAO9D;AAED,MAAM,WAAW,sBAAsB;IACrC,2EAA2E;IAC3E,MAAM,EAAE,WAAW,CAAC;IACpB,uEAAuE;IACvE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yDAAyD;IACzD,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,oFAAoF;IACpF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,4FAA4F;IAC5F,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,sFAAsF;IACtF,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;CAC3C;AAED,wBAAsB,WAAW,CAAC,CAAC,EACjC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAkBxB;AAED,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,CAAC,CAAC,CAuDZ;AAED;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAAC,CAAC,EAC9C,SAAS,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1D,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,CAAC,CAAC,CAoFZ;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;gBAEpB,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;CAKtD;AAcD,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,SAAS,GAAE,MAAuB,GACjC,OAAO,CAAC,MAAM,CAAC,CA+CjB"}
@@ -29,33 +29,77 @@ export async function withTimeout(promise, timeoutMs, label) {
29
29
  clearTimeout(timeoutId);
30
30
  }
31
31
  }
32
- export async function withTimeoutThrow(promise, timeoutMs, label) {
32
+ export async function withTimeoutThrow(promise, timeoutMs, label, options) {
33
33
  let timeoutId;
34
+ let removeAbortListener;
34
35
  const timeoutPromise = new Promise((_, reject) => {
35
36
  timeoutId = setTimeout(() => {
36
37
  logger.error("TIMEOUT_HARD operation timed out (throwing)", { label, timeoutMs });
37
- reject(new TimeoutError(label, timeoutMs));
38
+ const error = new TimeoutError(label, timeoutMs);
39
+ try {
40
+ options?.onTimeout?.(error);
41
+ }
42
+ catch (callbackError) {
43
+ logger.error("TIMEOUT_HARD onTimeout callback failed", {
44
+ label,
45
+ error: callbackError instanceof Error ? callbackError.message : String(callbackError),
46
+ });
47
+ }
48
+ finally {
49
+ reject(error);
50
+ }
38
51
  }, timeoutMs);
39
52
  });
53
+ const abortSignal = options?.signal;
54
+ const abortPromise = abortSignal
55
+ ? new Promise((_, reject) => {
56
+ const abort = () => {
57
+ const reason = abortSignal.reason ??
58
+ new DOMException("The operation was aborted", "AbortError");
59
+ try {
60
+ options?.onAbort?.(reason);
61
+ }
62
+ catch (callbackError) {
63
+ logger.error("TIMEOUT_HARD onAbort callback failed", {
64
+ label,
65
+ error: callbackError instanceof Error ? callbackError.message : String(callbackError),
66
+ });
67
+ }
68
+ finally {
69
+ reject(reason);
70
+ }
71
+ };
72
+ if (abortSignal.aborted) {
73
+ abort();
74
+ return;
75
+ }
76
+ abortSignal.addEventListener("abort", abort, { once: true });
77
+ removeAbortListener = () => abortSignal.removeEventListener("abort", abort);
78
+ })
79
+ : undefined;
40
80
  try {
41
- return await Promise.race([promise, timeoutPromise]);
81
+ return await Promise.race(abortPromise ? [promise, timeoutPromise, abortPromise] : [promise, timeoutPromise]);
42
82
  }
43
83
  finally {
44
84
  if (timeoutId)
45
85
  clearTimeout(timeoutId);
86
+ removeAbortListener?.();
46
87
  }
47
88
  }
48
89
  /**
49
- * Run an operation with a resettable idle deadline and a non-resettable hard cap.
90
+ * Run an operation with a resettable idle deadline and an optional hard cap.
50
91
  *
51
- * Callers must only call `mark` after meaningful progress. The hard cap keeps a
52
- * noisy or buggy progress source from extending work forever. The supplied
53
- * signal lets cooperative operations stop after either deadline.
92
+ * Callers must only call `mark` after meaningful progress. Use `hardTimeoutMs`
93
+ * when this helper owns the total deadline. Omit it when an outer operation
94
+ * already enforces that deadline. The supplied signal lets cooperative work
95
+ * stop after either configured deadline.
54
96
  */
55
97
  export async function withProgressTimeoutThrow(operation, options) {
56
- const { label, idleTimeoutMs, hardTimeoutMs } = options;
57
- if (idleTimeoutMs <= 0 || hardTimeoutMs <= 0 || hardTimeoutMs < idleTimeoutMs) {
58
- throw new RangeError("Progress timeout requires 0 < idleTimeoutMs <= hardTimeoutMs");
98
+ const { label, idleTimeoutMs, hardTimeoutMs, signal: parentSignal } = options;
99
+ if (idleTimeoutMs <= 0 ||
100
+ (hardTimeoutMs !== undefined &&
101
+ (hardTimeoutMs <= 0 || hardTimeoutMs < idleTimeoutMs))) {
102
+ throw new RangeError("Progress timeout requires idleTimeoutMs > 0 and, when set, hardTimeoutMs >= idleTimeoutMs");
59
103
  }
60
104
  const controller = new AbortController();
61
105
  let idleTimeoutId;
@@ -95,9 +139,29 @@ export async function withProgressTimeoutThrow(operation, options) {
95
139
  scheduleIdleTimeout();
96
140
  },
97
141
  };
98
- scheduleIdleTimeout();
99
- const hardTimeoutId = setTimeout(() => fail("hard", hardTimeoutMs), hardTimeoutMs);
142
+ const abortFromParent = () => {
143
+ if (!active || !parentSignal)
144
+ return;
145
+ active = false;
146
+ const reason = parentSignal.reason ??
147
+ new DOMException("The operation was aborted", "AbortError");
148
+ controller.abort(reason);
149
+ rejectTimeout(reason);
150
+ };
151
+ if (parentSignal?.aborted) {
152
+ abortFromParent();
153
+ }
154
+ else {
155
+ parentSignal?.addEventListener("abort", abortFromParent, { once: true });
156
+ }
157
+ if (active)
158
+ scheduleIdleTimeout();
159
+ const hardTimeoutId = !active || hardTimeoutMs === undefined
160
+ ? undefined
161
+ : setTimeout(() => fail("hard", hardTimeoutMs), hardTimeoutMs);
100
162
  try {
163
+ if (!active)
164
+ return await timeoutPromise;
101
165
  return await Promise.race([
102
166
  Promise.resolve().then(() => operation(control)),
103
167
  timeoutPromise,
@@ -109,6 +173,7 @@ export async function withProgressTimeoutThrow(operation, options) {
109
173
  clearTimeout(idleTimeoutId);
110
174
  if (hardTimeoutId)
111
175
  clearTimeout(hardTimeoutId);
176
+ parentSignal?.removeEventListener("abort", abortFromParent);
112
177
  }
113
178
  }
114
179
  export class StreamTimeoutError extends Error {
@@ -177,6 +177,28 @@ function createNamespaceOnLoadHandler(options) {
177
177
  }
178
178
  });
179
179
  }
180
+ /** Resolves the framework's built-in @/ project alias through the runtime adapter. */
181
+ function createProjectAliasPlugin(adapter, projectDir) {
182
+ const projectRoot = pathHelper.resolve(projectDir);
183
+ return {
184
+ name: "vf-project-alias",
185
+ setup(build) {
186
+ build.onResolve({ filter: /^@\// }, (args) => {
187
+ const absolutePath = pathHelper.resolve(projectRoot, args.path.slice(2));
188
+ if (!isWithinDirectory(projectRoot, absolutePath)) {
189
+ logger.error(`[API] Project alias escapes project: ${args.path} -> ${absolutePath}`);
190
+ return { errors: [{ text: `Project alias escapes project: ${args.path}` }] };
191
+ }
192
+ return { path: absolutePath, namespace: "vf-project-alias" };
193
+ });
194
+ build.onLoad({ filter: /.*/, namespace: "vf-project-alias" }, createNamespaceOnLoadHandler({
195
+ adapter,
196
+ projectDir,
197
+ errorLabel: "via project alias",
198
+ }));
199
+ },
200
+ };
201
+ }
180
202
  /** Resolves relative imports through the adapter's virtual FS for remote projects. */
181
203
  function createAdapterResolvePlugin(adapter, projectDir) {
182
204
  return {
@@ -342,6 +364,7 @@ function loadAndTranspileModule(modulePath, projectDir, adapter, fs, config) {
342
364
  },
343
365
  plugins: [
344
366
  createImportMapPlugin(projectDir, adapter, config),
367
+ createProjectAliasPlugin(adapter, projectDir),
345
368
  createAdapterResolvePlugin(adapter, projectDir),
346
369
  createHTTPPlugin({ allowedHosts, projectDir }),
347
370
  createProjectBoundaryPlugin(await resolveProjectRoots(projectDir)),
@@ -1 +1 @@
1
- {"version":3,"file":"page-data-endpoint-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/module/page-data-endpoint-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AA8EhE,wBAAgB,oCAAoC,IAAI,IAAI,CAE3D;AAED,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,cAAc,EACnB,qBAAqB,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,eAAe,EAC/D,OAAO,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,aAAa,EAC9C,eAAe,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,GAC1C,OAAO,CAAC,aAAa,CAAC,CAoIxB"}
1
+ {"version":3,"file":"page-data-endpoint-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/src/server/handlers/request/module/page-data-endpoint-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAwGhE,wBAAgB,oCAAoC,IAAI,IAAI,CAE3D;AAED,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,cAAc,EACnB,qBAAqB,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,eAAe,EAC/D,OAAO,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,aAAa,EAC9C,eAAe,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,GAC1C,OAAO,CAAC,aAAa,CAAC,CAkIxB"}
@@ -6,7 +6,7 @@ import { withSpan } from "../../../../observability/tracing/otlp-setup.js";
6
6
  import { markRequestProfilePhase } from "../../../../observability/index.js";
7
7
  import { HTTP_GATEWAY_TIMEOUT } from "../../../../utils/constants/http.js";
8
8
  import { serverLogger } from "../../../../utils/index.js";
9
- import { Singleflight } from "../../../../utils/singleflight.js";
9
+ import { Singleflight, waitForSharedPromise } from "../../../../utils/singleflight.js";
10
10
  import { requestHasCacheSensitiveState } from "../../../../cache/request-cacheability.js";
11
11
  import { sanitizeQueryParamsForCacheKey, } from "../../../../cache/keys.js";
12
12
  import { getEnv } from "../../../../platform/compat/process.js";
@@ -47,6 +47,19 @@ function getPageDataCachePolicy(ctx) {
47
47
  function isPageDataCacheEnabled() {
48
48
  return PAGE_DATA_CACHE_MAX_ENTRIES > 0;
49
49
  }
50
+ async function resolvePageDataWithinDeadline(renderer, slug, request, url, callerSignal) {
51
+ const controller = new AbortController();
52
+ const workRequest = callerSignal ? request : new Request(request, { signal: controller.signal });
53
+ return await withTimeoutThrow(renderer.resolvePageData(slug, {
54
+ request: workRequest,
55
+ url,
56
+ abortSignal: controller.signal,
57
+ }), PAGE_DATA_TIMEOUT_MS, `resolvePageData for ${slug}`, {
58
+ signal: callerSignal,
59
+ onAbort: (reason) => controller.abort(reason),
60
+ onTimeout: (error) => controller.abort(error),
61
+ });
62
+ }
50
63
  export function __clearPageDataEndpointCacheForTests() {
51
64
  pageDataCache.clear();
52
65
  }
@@ -66,8 +79,8 @@ export function handlePageDataEndpoint(req, pathname, ctx, createResponseBuilder
66
79
  const cacheKey = canUsePageDataCache ? buildPageDataCacheKey(ctx, slug, url) : null;
67
80
  const cachePolicy = cacheKey ? getPageDataCachePolicy(ctx) : null;
68
81
  const payload = cacheKey
69
- ? await resolveCachedPageData(cacheKey, () => withTimeoutThrow(renderer.resolvePageData(slug, { request: req, url }), PAGE_DATA_TIMEOUT_MS, `resolvePageData for ${slug}`), cachePolicy)
70
- : await resolveUncachedPageData(() => withTimeoutThrow(renderer.resolvePageData(slug, { request: req, url }), PAGE_DATA_TIMEOUT_MS, `resolvePageData for ${slug}`));
82
+ ? await waitForSharedPromise(resolveCachedPageData(cacheKey, () => resolvePageDataWithinDeadline(renderer, slug, req, url, undefined), cachePolicy), req.signal)
83
+ : await resolveUncachedPageData(() => resolvePageDataWithinDeadline(renderer, slug, req, url, req.signal));
71
84
  const cacheStrategy = cacheKey
72
85
  ? {
73
86
  maxAge: cachePolicy.maxAgeSeconds,
@@ -1 +1 @@
1
- {"version":3,"file":"transform-cache.d.ts","sourceRoot":"","sources":["../../../../src/src/transforms/esm/transform-cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transform-cache.d.ts","sourceRoot":"","sources":["../../../../src/src/transforms/esm/transform-cache.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,YAAY,EAIlB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EAEV,yBAAyB,EAC1B,MAAM,gBAAgB,CAAC;AAMxB,eAAO,MAAM,kCAAkC,QAAa,CAAC;AAY7D,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA2FD,UAAU,iBAAiB,CAAC,CAAC,EAAE,CAAC;IAC9B,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAC3B,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;IAC/B,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC;IACxB,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC;IACrB,KAAK,IAAI,IAAI,CAAC;IACd,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;CACrC;AA+DD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE;IACN,aAAa,CAAC,EAAE,iBAAiB,CAAC,MAAM,EAAE,mBAAmB,CAAC,GAAG,IAAI,CAAC;IACtE,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CACpC,GAAG,IAAI,GACP,IAAI,CASN;AAmBD,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,OAAO,CAAC,CAuBjE;AAED,UAAU,eAAe;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,GAAG,GAAE,OAAe,EACpB,WAAW,GAAE,OAAe,EAC5B,OAAO,CAAC,EAAE,eAAe,GACxB,MAAM,CAER;AAED,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAgC1C;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAI/E;AAED,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,MAA4B,EACxC,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC,CAyBf;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,MAA4B,GACvC,IAAI,CAoBN;AAWD,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C;AAED,wBAAsB,8BAA8B,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAKnF;AAED,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mCAAmC;IACnC,QAAQ,EAAE,OAAO,CAAC;CACnB;AA0BD,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,CAAC,cAAc,CAAC,EAAE,yBAAyB,KAAK,OAAO,CAAC,MAAM,CAAC,EAC1E,UAAU,GAAE,MAA4B,EACxC,UAAU,CAAC,EAAE,yBAAyB,EACtC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,oBAAoB,CAAC,CA8E/B"}
@@ -1,7 +1,7 @@
1
1
  import { registerCache } from "../../utils/memory/index.js";
2
2
  import { logger as baseLogger } from "../../utils/index.js";
3
3
  import { buildTransformCacheKey } from "../../cache/keys.js";
4
- import { Singleflight } from "../../utils/singleflight.js";
4
+ import { Singleflight, waitForSharedPromise } from "../../utils/singleflight.js";
5
5
  import { CacheBackends, MemoryCacheBackend, } from "../../cache/backend.js";
6
6
  import { hashCodeHex } from "../../utils/hash-utils.js";
7
7
  import { detokenizeAllCachePaths, tokenizeAllVeryFrontPaths } from "../../cache/paths.js";
@@ -369,24 +369,10 @@ export async function getOrComputeTransform(key, computeFn, ttlSeconds = DEFAULT
369
369
  });
370
370
  },
371
371
  });
372
- if (!signal)
373
- return await flight;
374
372
  // A caller timeout must detach that request without cancelling the shared
375
373
  // singleflight leader: another concurrent render may still depend on the
376
374
  // same cold transform, and completing it warms the cache for later work.
377
- return await new Promise((resolve, reject) => {
378
- const onAbort = () => reject(signal.reason);
379
- if (signal.aborted) {
380
- // The shared flight can still fail after this caller detaches. Attach a
381
- // rejection observer so an already-aborted sole caller does not leave
382
- // the coordinating promise unhandled.
383
- void flight.catch(() => { });
384
- onAbort();
385
- return;
386
- }
387
- signal.addEventListener("abort", onAbort, { once: true });
388
- flight.then(resolve, reject).finally(() => signal.removeEventListener("abort", onAbort));
389
- });
375
+ return await waitForSharedPromise(flight, signal);
390
376
  }
391
377
  finally {
392
378
  unsubscribe();
@@ -8,6 +8,11 @@ export interface SingleflightControl {
8
8
  /** Whether this operation is still the exact leader registered for its key. */
9
9
  isCurrent(): boolean;
10
10
  }
11
+ /**
12
+ * Wait for shared work while allowing this caller to detach independently.
13
+ * Aborting `signal` rejects only this waiter; it never cancels `shared`.
14
+ */
15
+ export declare function waitForSharedPromise<T>(shared: Promise<T>, signal?: AbortSignal): Promise<T>;
11
16
  export declare class Singleflight<T> {
12
17
  private inflight;
13
18
  do(key: string, operation: (control: SingleflightControl) => Promise<T>, options?: SingleflightOptions): Promise<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"singleflight.d.ts","sourceRoot":"","sources":["../../../src/src/utils/singleflight.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,+EAA+E;IAC/E,SAAS,IAAI,OAAO,CAAC;CACtB;AAOD,qBAAa,YAAY,CAAC,CAAC;IACzB,OAAO,CAAC,QAAQ,CAA2C;IAErD,EAAE,CACN,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,CAAC,CAAC,EACvD,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,CAAC,CAAC;IAgDb,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
1
+ {"version":3,"file":"singleflight.d.ts","sourceRoot":"","sources":["../../../src/src/utils/singleflight.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,+EAA+E;IAC/E,SAAS,IAAI,OAAO,CAAC;CACtB;AAOD;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,CAAC,EAC1C,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAClB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,CAAC,CAAC,CA+BZ;AAED,qBAAa,YAAY,CAAC,CAAC;IACzB,OAAO,CAAC,QAAQ,CAA2C;IAErD,EAAE,CACN,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,CAAC,CAAC,EACvD,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,CAAC,CAAC;IAgDb,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
@@ -1,4 +1,33 @@
1
1
  import { unrefTimer } from "../platform/compat/process.js";
2
+ /**
3
+ * Wait for shared work while allowing this caller to detach independently.
4
+ * Aborting `signal` rejects only this waiter; it never cancels `shared`.
5
+ */
6
+ export async function waitForSharedPromise(shared, signal) {
7
+ if (!signal)
8
+ return await shared;
9
+ const abortReason = () => signal.reason ?? new DOMException("The operation was aborted", "AbortError");
10
+ if (signal.aborted) {
11
+ // The shared operation can still fail after this caller detaches.
12
+ // Observe that rejection so a sole detached caller cannot leave it unhandled.
13
+ void shared.catch(() => { });
14
+ throw abortReason();
15
+ }
16
+ return await new Promise((resolve, reject) => {
17
+ const onAbort = () => {
18
+ signal.removeEventListener("abort", onAbort);
19
+ reject(abortReason());
20
+ };
21
+ signal.addEventListener("abort", onAbort, { once: true });
22
+ shared.then((value) => {
23
+ signal.removeEventListener("abort", onAbort);
24
+ resolve(value);
25
+ }, (error) => {
26
+ signal.removeEventListener("abort", onAbort);
27
+ reject(error);
28
+ });
29
+ });
30
+ }
2
31
  export class Singleflight {
3
32
  inflight = new Map();
4
33
  async do(key, operation, options = {}) {
@@ -1,3 +1,3 @@
1
1
  /** Shared version value. */
2
- export declare const VERSION = "0.1.1126";
2
+ export declare const VERSION = "0.1.1127";
3
3
  //# sourceMappingURL=version-constant.d.ts.map
@@ -1,4 +1,4 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
3
  /** Shared version value. */
4
- export const VERSION = "0.1.1126";
4
+ export const VERSION = "0.1.1127";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.1126",
3
+ "version": "0.1.1127",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",
@@ -332,10 +332,10 @@
332
332
  "@types/react": "19.2.14",
333
333
  "@types/react-dom": "19.2.3",
334
334
  "ws": "8.21.0",
335
- "@veryfront/ext-bundler-esbuild": "0.1.1126",
336
- "@veryfront/ext-content-mdx": "0.1.1126",
337
- "@veryfront/ext-css-tailwind": "0.1.1126",
338
- "@veryfront/ext-parser-babel": "0.1.1126"
335
+ "@veryfront/ext-bundler-esbuild": "0.1.1127",
336
+ "@veryfront/ext-content-mdx": "0.1.1127",
337
+ "@veryfront/ext-css-tailwind": "0.1.1127",
338
+ "@veryfront/ext-parser-babel": "0.1.1127"
339
339
  },
340
340
  "devDependencies": {
341
341
  "@types/node": "20.9.0"