veryfront 0.1.812 → 0.1.813

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 (52) hide show
  1. package/esm/deno.js +1 -1
  2. package/esm/src/agent/runtime/agent-runtime-step.d.ts +44 -0
  3. package/esm/src/agent/runtime/agent-runtime-step.d.ts.map +1 -0
  4. package/esm/src/agent/runtime/agent-runtime-step.js +23 -0
  5. package/esm/src/agent/runtime/index.d.ts.map +1 -1
  6. package/esm/src/agent/runtime/index.js +40 -39
  7. package/esm/src/agent/runtime/model-transport.d.ts +23 -0
  8. package/esm/src/agent/runtime/model-transport.d.ts.map +1 -0
  9. package/esm/src/agent/runtime/model-transport.js +26 -0
  10. package/esm/src/cache/keys/builders/render.d.ts.map +1 -1
  11. package/esm/src/cache/keys/builders/render.js +3 -2
  12. package/esm/src/cache/request-cacheability.d.ts +3 -0
  13. package/esm/src/cache/request-cacheability.d.ts.map +1 -0
  14. package/esm/src/cache/request-cacheability.js +26 -0
  15. package/esm/src/html/hydration-script-builder/hydration-data-generator.d.ts.map +1 -1
  16. package/esm/src/html/hydration-script-builder/hydration-data-generator.js +1 -10
  17. package/esm/src/html/hydration-script-builder/templates/router.d.ts.map +1 -1
  18. package/esm/src/html/hydration-script-builder/templates/router.js +41 -10
  19. package/esm/src/observability/request-profiler.d.ts.map +1 -1
  20. package/esm/src/observability/request-profiler.js +1 -0
  21. package/esm/src/proxy/handler.d.ts.map +1 -1
  22. package/esm/src/proxy/handler.js +39 -29
  23. package/esm/src/proxy/main.js +21 -20
  24. package/esm/src/proxy/proxy-error-context.d.ts +20 -0
  25. package/esm/src/proxy/proxy-error-context.d.ts.map +1 -0
  26. package/esm/src/proxy/proxy-error-context.js +35 -0
  27. package/esm/src/proxy/request-lifecycle.d.ts +19 -0
  28. package/esm/src/proxy/request-lifecycle.d.ts.map +1 -0
  29. package/esm/src/proxy/request-lifecycle.js +27 -0
  30. package/esm/src/proxy/upstream-error-response.d.ts +5 -0
  31. package/esm/src/proxy/upstream-error-response.d.ts.map +1 -0
  32. package/esm/src/proxy/upstream-error-response.js +15 -0
  33. package/esm/src/release-assets/client-module-map.d.ts +3 -0
  34. package/esm/src/release-assets/client-module-map.d.ts.map +1 -0
  35. package/esm/src/release-assets/client-module-map.js +10 -0
  36. package/esm/src/rendering/orchestrator/module-loader/index.d.ts.map +1 -1
  37. package/esm/src/rendering/orchestrator/module-loader/index.js +13 -49
  38. package/esm/src/rendering/orchestrator/module-loader/module-cache-lookup.d.ts +25 -0
  39. package/esm/src/rendering/orchestrator/module-loader/module-cache-lookup.d.ts.map +1 -0
  40. package/esm/src/rendering/orchestrator/module-loader/module-cache-lookup.js +69 -0
  41. package/esm/src/rendering/orchestrator/pipeline.d.ts.map +1 -1
  42. package/esm/src/rendering/orchestrator/pipeline.js +9 -10
  43. package/esm/src/rendering/orchestrator/types.d.ts +2 -0
  44. package/esm/src/rendering/orchestrator/types.d.ts.map +1 -1
  45. package/esm/src/rendering/renderer.d.ts.map +1 -1
  46. package/esm/src/rendering/renderer.js +24 -19
  47. package/esm/src/server/handlers/request/module/page-data-endpoint-handler.d.ts +1 -0
  48. package/esm/src/server/handlers/request/module/page-data-endpoint-handler.d.ts.map +1 -1
  49. package/esm/src/server/handlers/request/module/page-data-endpoint-handler.js +98 -8
  50. package/esm/src/utils/version-constant.d.ts +1 -1
  51. package/esm/src/utils/version-constant.js +1 -1
  52. package/package.json +1 -1
@@ -21,6 +21,7 @@ import { SpanNames } from "../../observability/tracing/span-names.js";
21
21
  import { VeryfrontError } from "../../errors/index.js";
22
22
  import { FILE_NOT_FOUND, RENDER_ERROR } from "../../errors/error-registry.js";
23
23
  import { buildQueryAwareCacheKey } from "../../cache/keys.js";
24
+ import { requestHasCacheSensitiveState } from "../../cache/request-cacheability.js";
24
25
  import { extractRelativePath as extractRelativePathShared, extractRouteParams as extractRouteParamsShared, } from "../../utils/route-path-utils.js";
25
26
  import { extractRenderedCssHash, hasRenderedReleaseAssetCss, serializeLayoutProps, serializeLayouts, } from "./pipeline-helpers.js";
26
27
  import { join } from "../../platform/compat/path/index.js";
@@ -31,6 +32,7 @@ import { setupSSRGlobals } from "../ssr-globals.js";
31
32
  import { LAYOUT_EXTENSIONS } from "../layouts/types.js";
32
33
  import { withTimeout, withTimeoutThrow } from "../utils/stream-utils.js";
33
34
  import { extractCandidates, generateTailwindCSS } from "../../html/styles-builder/index.js";
35
+ import { buildReleaseAssetModules } from "../../release-assets/client-module-map.js";
34
36
  import { getCSSByHashAsync, regenerateCSSByHash, } from "../../html/styles-builder/tailwind-compiler.js";
35
37
  import { getReadyManifestForRender } from "../../release-assets/manifest-cache.js";
36
38
  import { createEsmCache, createModuleCache, loadModule } from "./module-loader/index.js";
@@ -233,7 +235,7 @@ export class RenderPipeline {
233
235
  const projectId = options?.projectId ?? this.config.projectDir;
234
236
  const cacheKey = this.buildCacheKey(slug, options);
235
237
  let cacheResult = null;
236
- const shouldCache = !!cacheKey && options?.delivery !== "stream";
238
+ const shouldCache = cacheKey !== null && options?.delivery !== "stream";
237
239
  if (shouldCache && !options?.skipCacheCheck) {
238
240
  const cacheCheckStart = performance.now();
239
241
  cacheResult = await this.config.cacheCoordinator.checkCache(slug, cacheKey);
@@ -423,6 +425,7 @@ export class RenderPipeline {
423
425
  layoutProps,
424
426
  buildVersion: createBuildVersion(projectUpdatedAt),
425
427
  appPath,
428
+ releaseAssetModules: buildReleaseAssetModules(options?.releaseAssetManifest),
426
429
  headings,
427
430
  css,
428
431
  cssAction,
@@ -535,7 +538,9 @@ export class RenderPipeline {
535
538
  hasReadyReleaseCss(options) {
536
539
  if (options?.environment !== "production")
537
540
  return false;
538
- const releaseManifest = getReadyManifestForRender(options?.releaseId);
541
+ const releaseManifest = options.releaseAssetManifest !== undefined
542
+ ? options.releaseAssetManifest
543
+ : getReadyManifestForRender(options?.releaseId);
539
544
  return (releaseManifest?.css?.length ?? 0) > 0;
540
545
  }
541
546
  async generatePageCssFromHtml(slug, html, options) {
@@ -562,15 +567,9 @@ export class RenderPipeline {
562
567
  return options.cacheKey;
563
568
  const req = options?.request;
564
569
  if (req) {
565
- const hasAuth = req.headers.has("authorization") ||
566
- req.headers.has("cookie") ||
567
- req.headers.has("x-api-key");
568
- if (hasAuth)
570
+ if (requestHasCacheSensitiveState(req))
569
571
  return null;
570
572
  }
571
- const url = options?.url;
572
- if (!url)
573
- return slug;
574
- return buildQueryAwareCacheKey(slug, url, this.config.queryParamOptions);
573
+ return buildQueryAwareCacheKey(slug, options?.url, this.config.queryParamOptions);
575
574
  }
576
575
  }
@@ -81,6 +81,8 @@ export interface PageDataResponse {
81
81
  layoutProps: Record<string, Record<string, unknown>>;
82
82
  buildVersion: BuildVersion;
83
83
  appPath?: string;
84
+ /** Production release asset URLs keyed by logical source path. */
85
+ releaseAssetModules?: Record<string, string>;
84
86
  /** Headings extracted from MDX for sidebar/TOC navigation */
85
87
  headings?: Array<{
86
88
  id: string;
@@ -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":"AA6CA,OAAO,EACL,mBAAmB,EACnB,+BAA+B,EAC/B,KAAK,0BAA0B,EAC/B,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAKL,KAAK,qBAAqB,EAC3B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,iCAAiC,CAAC;AAgBzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC7F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAwBxD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,oBAAoB;IACpB,KAAK,CAAC,EAAE,wBAAwB,CAAC;CAClC;AAeD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,oBAAoB,CAAgC;IAC5D,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,qBAAqB,CAA8B;IAE3D;;;;OAIG;IACH,OAAO,CAAC,YAAY,CAAwC;gBAEhD,OAAO,GAAE,eAAoB;IAInC,UAAU,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBhE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;YAwF9E,2BAA2B;IAWzC,OAAO,CAAC,uBAAuB;IAiB/B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAQ1B;;;;;;;;;OASG;IACH,OAAO,CAAC,aAAa;YAwBP,YAAY;IAoF1B,eAAe,CACb,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,aAAa,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,gBAAgB,CAAC;IAkB5B,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAU5C,UAAU,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ5D,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B,OAAO,CAAC,wBAAwB;CA4FjC;AAED,OAAO,EACL,mBAAmB,EACnB,+BAA+B,EAC/B,KAAK,0BAA0B,EAC/B,KAAK,aAAa,GACnB,CAAC;AAMF,wBAAgB,WAAW,IAAI,QAAQ,CAOtC;AAED,wBAAsB,kBAAkB,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsBrF;AAED,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAQrD;AAED,wBAAsB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYnF;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,aAAa,EACvB,cAAc,CAAC,EAAE,0BAA0B,GAC1C,OAAO,CAAC,YAAY,CAAC,CAIvB"}
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../../src/src/rendering/renderer.ts"],"names":[],"mappings":"AA8CA,OAAO,EACL,mBAAmB,EACnB,+BAA+B,EAC/B,KAAK,0BAA0B,EAC/B,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAKL,KAAK,qBAAqB,EAC3B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,iCAAiC,CAAC;AAgBzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC7F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAwBxD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,oBAAoB;IACpB,KAAK,CAAC,EAAE,wBAAwB,CAAC;CAClC;AAeD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,oBAAoB,CAAgC;IAC5D,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,qBAAqB,CAA8B;IAE3D;;;;OAIG;IACH,OAAO,CAAC,YAAY,CAAwC;gBAEhD,OAAO,GAAE,eAAoB;IAInC,UAAU,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBhE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;YAwF9E,2BAA2B;IAWzC,OAAO,CAAC,uBAAuB;IAiB/B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAQ1B;;;;;;;;;OASG;IACH,OAAO,CAAC,aAAa;YAkBP,YAAY;IAoF1B,eAAe,CACb,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,aAAa,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,gBAAgB,CAAC;IA4B5B,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAU5C,UAAU,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ5D,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B,OAAO,CAAC,wBAAwB;CA4FjC;AAED,OAAO,EACL,mBAAmB,EACnB,+BAA+B,EAC/B,KAAK,0BAA0B,EAC/B,KAAK,aAAa,GACnB,CAAC;AAMF,wBAAgB,WAAW,IAAI,QAAQ,CAOtC;AAED,wBAAsB,kBAAkB,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsBrF;AAED,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAQrD;AAED,wBAAsB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYnF;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,aAAa,EACvB,cAAc,CAAC,EAAE,0BAA0B,GAC1C,OAAO,CAAC,YAAY,CAAC,CAIvB"}
@@ -35,6 +35,7 @@ import { MDXCacheAdapter } from "../transforms/mdx/index.js";
35
35
  import { INITIALIZATION_ERROR, SERVICE_OVERLOADED } from "../errors/error-registry.js";
36
36
  import { withSpan } from "../observability/tracing/otlp-setup.js";
37
37
  import { buildQueryAwareCacheKey, buildRenderCachePrefix, } from "../cache/keys.js";
38
+ import { requestHasCacheSensitiveState } from "../cache/request-cacheability.js";
38
39
  import { getEnvNumber } from "../platform/compat/process.js";
39
40
  import { getReadyManifestForRenderAsync } from "../release-assets/manifest-cache.js";
40
41
  import { createRenderContext, createRenderContextFromEnriched, } from "./context/render-context.js";
@@ -128,7 +129,7 @@ export class Renderer {
128
129
  releaseAssetManifest: releaseManifest,
129
130
  };
130
131
  const cacheKey = this.buildCacheKey(slug, effectiveCtx, effectiveOptions);
131
- const cacheResult = cacheKey
132
+ const cacheResult = cacheKey !== null
132
133
  ? await this.cache.checkCache(slug, effectiveCtx, effectiveOptions?.colorScheme, cacheKey)
133
134
  : { hit: false, cacheKey: "", status: "miss", lookupDurationMs: 0 };
134
135
  if (cacheResult.hit && cacheResult.cachedResult) {
@@ -224,23 +225,17 @@ export class Renderer {
224
225
  return options.cacheKey;
225
226
  const req = options?.request;
226
227
  if (req) {
227
- const hasAuth = req.headers.has("authorization") ||
228
- req.headers.has("cookie") ||
229
- req.headers.has("x-api-key");
230
- if (hasAuth)
228
+ if (requestHasCacheSensitiveState(req))
231
229
  return null;
232
230
  }
233
- const url = options?.url;
234
- if (!url)
235
- return slug;
236
231
  // Get query param handling options from config
237
232
  const queryParamOptions = ctx.config?.cache?.queryParams;
238
- return buildQueryAwareCacheKey(slug, url, queryParamOptions);
233
+ return buildQueryAwareCacheKey(slug, options?.url, queryParamOptions);
239
234
  }
240
235
  async doRenderPage(slug, ctx, options, startTime, cacheKey) {
241
236
  const effectiveKey = cacheKey ?? dntShim.crypto.randomUUID();
242
237
  const flightKey = this.getSingleflightKey(effectiveKey, ctx, options?.colorScheme);
243
- const isFollower = cacheKey ? this.renderFlight.has(flightKey) : false;
238
+ const isFollower = cacheKey !== null ? this.renderFlight.has(flightKey) : false;
244
239
  const runRender = async () => {
245
240
  const services = this.createServicesForContext(ctx, options?.colorScheme);
246
241
  let result;
@@ -266,7 +261,7 @@ export class Renderer {
266
261
  }
267
262
  throw error;
268
263
  }
269
- if (cacheKey) {
264
+ if (cacheKey !== null) {
270
265
  await this.cache.persistResult(result, slug, ctx, options?.colorScheme, cacheKey);
271
266
  }
272
267
  logger.debug("Render complete (leader)", {
@@ -283,7 +278,7 @@ export class Renderer {
283
278
  pageModule: result.pageModule,
284
279
  };
285
280
  };
286
- const cachedData = cacheKey
281
+ const cachedData = cacheKey !== null
287
282
  ? await this.renderFlight.do(flightKey, runRender)
288
283
  : await runRender();
289
284
  if (isFollower) {
@@ -309,13 +304,23 @@ export class Renderer {
309
304
  detail: "Renderer not initialized. Call initialize() first.",
310
305
  });
311
306
  }
312
- const services = this.createServicesForContext(ctx);
313
- return services.pipeline.resolvePageData(slug, {
314
- ...options,
315
- projectId: ctx.projectId,
316
- projectSlug: ctx.projectSlug,
317
- environment: ctx.environment,
318
- contentSourceId: ctx.contentSourceId,
307
+ return withSpan("renderer.resolvePageData", async () => {
308
+ const releaseManifest = await this.resolveReleaseAssetManifest(ctx, options);
309
+ const effectiveCtx = this.withManifestCachePrefix(ctx, releaseManifest);
310
+ const services = this.createServicesForContext(effectiveCtx);
311
+ return services.pipeline.resolvePageData(slug, {
312
+ ...options,
313
+ projectId: effectiveCtx.projectId,
314
+ projectSlug: effectiveCtx.projectSlug,
315
+ environment: effectiveCtx.environment,
316
+ contentSourceId: effectiveCtx.contentSourceId,
317
+ releaseId: effectiveCtx.releaseId,
318
+ releaseAssetManifest: releaseManifest,
319
+ });
320
+ }, {
321
+ "renderer.slug": slug,
322
+ "renderer.projectId": ctx.projectId,
323
+ "renderer.environment": ctx.environment,
319
324
  });
320
325
  }
321
326
  getAllPages(ctx) {
@@ -1,4 +1,5 @@
1
1
  import type { HandlerContext, HandlerResult } from "../../types.js";
2
2
  import { ResponseBuilder } from "../../../../security/index.js";
3
+ export declare function __clearPageDataEndpointCacheForTests(): void;
3
4
  export declare function handlePageDataEndpoint(req: Request, pathname: string, ctx: HandlerContext, createResponseBuilder: (ctx: HandlerContext) => ResponseBuilder, respond: (response: Response) => HandlerResult, getErrorMessage: (error: unknown) => string): Promise<HandlerResult>;
4
5
  //# sourceMappingURL=page-data-endpoint-handler.d.ts.map
@@ -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;AAShE,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,CAyFxB"}
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;AAwBhE,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,CAoGxB"}
@@ -3,9 +3,19 @@ import { ResponseBuilder } from "../../../../security/index.js";
3
3
  import { getRendererForProject } from "../../../shared/renderer-factory.js";
4
4
  import { TimeoutError, withTimeoutThrow } from "../../../../rendering/utils/stream-utils.js";
5
5
  import { withSpan } from "../../../../observability/tracing/otlp-setup.js";
6
+ import { markRequestProfilePhase } from "../../../../observability/request-profiler.js";
6
7
  import { HTTP_GATEWAY_TIMEOUT } from "../../../../utils/constants/http.js";
7
8
  import { serverLogger } from "../../../../utils/index.js";
9
+ import { Singleflight } from "../../../../utils/singleflight.js";
10
+ import { requestHasCacheSensitiveState } from "../../../../cache/request-cacheability.js";
8
11
  const PAGE_DATA_TIMEOUT_MS = 25_000;
12
+ const PAGE_DATA_CACHE_TTL_MS = 60_000;
13
+ const PAGE_DATA_CACHE_MAX_ENTRIES = 500;
14
+ const pageDataCache = new Map();
15
+ const pageDataFlight = new Singleflight();
16
+ export function __clearPageDataEndpointCacheForTests() {
17
+ pageDataCache.clear();
18
+ }
9
19
  export function handlePageDataEndpoint(req, pathname, ctx, createResponseBuilder, respond, getErrorMessage) {
10
20
  return withSpan("module.pageData.handle", async () => {
11
21
  try {
@@ -14,18 +24,23 @@ export function handlePageDataEndpoint(req, pathname, ctx, createResponseBuilder
14
24
  .replace(/\.json$/, "") || "";
15
25
  const url = new URL(req.url);
16
26
  const renderer = await getRendererForProject(ctx);
17
- const pageData = await withTimeoutThrow(renderer.resolvePageData(slug, { request: req, url }), PAGE_DATA_TIMEOUT_MS, `resolvePageData for ${slug}`);
18
- const body = JSON.stringify(pageData);
19
- const etag = computeEtag(body);
27
+ const cacheKey = requestHasCacheSensitiveState(req)
28
+ ? null
29
+ : buildPageDataCacheKey(ctx, slug, url);
30
+ const payload = cacheKey
31
+ ? await resolveCachedPageData(cacheKey, () => withTimeoutThrow(renderer.resolvePageData(slug, { request: req, url }), PAGE_DATA_TIMEOUT_MS, `resolvePageData for ${slug}`))
32
+ : await resolveUncachedPageData(() => withTimeoutThrow(renderer.resolvePageData(slug, { request: req, url }), PAGE_DATA_TIMEOUT_MS, `resolvePageData for ${slug}`));
33
+ const cacheStrategy = cacheKey ? { maxAge: 60, public: true } : "no-cache";
20
34
  const builder = createResponseBuilder(ctx).withCORS(req, ctx.securityConfig?.cors);
21
- if (hasMatchingEtag(req, etag)) {
22
- return respond(builder.notModified(etag));
35
+ if (hasMatchingEtag(req, payload.etag)) {
36
+ return respond(builder.notModified(payload.etag));
23
37
  }
24
38
  return respond(builder
25
39
  .withSecurity(ctx.securityConfig ?? undefined, req)
26
- .withCache({ maxAge: 60, public: true })
27
- .withETag(etag)
28
- .json(pageData, 200));
40
+ .withCache(cacheStrategy)
41
+ .withETag(payload.etag)
42
+ .withHeaders({ "content-type": "application/json" })
43
+ .build(payload.body, 200));
29
44
  }
30
45
  catch (e) {
31
46
  if (e instanceof TimeoutError) {
@@ -63,3 +78,78 @@ export function handlePageDataEndpoint(req, pathname, ctx, createResponseBuilder
63
78
  "module.pageData.projectSlug": ctx.projectSlug || "unknown",
64
79
  });
65
80
  }
81
+ async function resolveCachedPageData(cacheKey, resolve) {
82
+ const cached = getCachedPageData(cacheKey);
83
+ if (cached) {
84
+ markRequestProfilePhase("page_data.cache_hit");
85
+ return cached;
86
+ }
87
+ markRequestProfilePhase("page_data.cache_miss");
88
+ return await pageDataFlight.do(cacheKey, async () => {
89
+ const concurrentCached = getCachedPageData(cacheKey);
90
+ if (concurrentCached) {
91
+ markRequestProfilePhase("page_data.cache_hit_after_wait");
92
+ return concurrentCached;
93
+ }
94
+ const payload = await resolveUncachedPageData(resolve);
95
+ setCachedPageData(cacheKey, payload);
96
+ return payload;
97
+ });
98
+ }
99
+ async function resolveUncachedPageData(resolve) {
100
+ const startedAt = performance.now();
101
+ const pageData = await resolve();
102
+ markRequestProfilePhase("page_data.resolve", performance.now() - startedAt);
103
+ const bodyStart = performance.now();
104
+ const body = JSON.stringify(pageData);
105
+ const etag = computeEtag(body);
106
+ markRequestProfilePhase("page_data.serialize", performance.now() - bodyStart);
107
+ return {
108
+ body,
109
+ etag,
110
+ expiresAt: Date.now() + PAGE_DATA_CACHE_TTL_MS,
111
+ };
112
+ }
113
+ function getCachedPageData(cacheKey) {
114
+ const entry = pageDataCache.get(cacheKey);
115
+ if (!entry)
116
+ return null;
117
+ if (Date.now() <= entry.expiresAt)
118
+ return entry;
119
+ pageDataCache.delete(cacheKey);
120
+ markRequestProfilePhase("page_data.cache_expired");
121
+ return null;
122
+ }
123
+ function setCachedPageData(cacheKey, entry) {
124
+ if (pageDataCache.size >= PAGE_DATA_CACHE_MAX_ENTRIES && !pageDataCache.has(cacheKey)) {
125
+ const oldestKey = pageDataCache.keys().next().value;
126
+ if (oldestKey)
127
+ pageDataCache.delete(oldestKey);
128
+ }
129
+ pageDataCache.set(cacheKey, entry);
130
+ }
131
+ function buildPageDataCacheKey(ctx, slug, url) {
132
+ const projectKey = ctx.projectId ?? ctx.projectSlug ?? ctx.projectDir;
133
+ const environment = ctx.resolvedEnvironment ?? ctx.requestContext?.mode ?? "preview";
134
+ const contentSource = ctx.enriched?.contentSourceId ??
135
+ (environment === "production"
136
+ ? ctx.releaseId ?? "release"
137
+ : ctx.requestContext?.branch ?? "main");
138
+ const query = buildSortedQueryKey(url);
139
+ return [
140
+ projectKey,
141
+ environment,
142
+ contentSource,
143
+ slug || "index",
144
+ query,
145
+ ].join("|");
146
+ }
147
+ function buildSortedQueryKey(url) {
148
+ const entries = Array.from(url.searchParams.entries());
149
+ if (entries.length === 0)
150
+ return "";
151
+ return entries
152
+ .sort(([leftKey, leftValue], [rightKey, rightValue]) => leftKey === rightKey ? leftValue.localeCompare(rightValue) : leftKey.localeCompare(rightKey))
153
+ .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
154
+ .join("&");
155
+ }
@@ -1,3 +1,3 @@
1
1
  /** Shared version value. */
2
- export declare const VERSION = "0.1.812";
2
+ export declare const VERSION = "0.1.813";
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.812";
4
+ export const VERSION = "0.1.813";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.812",
3
+ "version": "0.1.813",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",