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.
- package/esm/deno.js +1 -1
- package/esm/src/agent/runtime/agent-runtime-step.d.ts +44 -0
- package/esm/src/agent/runtime/agent-runtime-step.d.ts.map +1 -0
- package/esm/src/agent/runtime/agent-runtime-step.js +23 -0
- package/esm/src/agent/runtime/index.d.ts.map +1 -1
- package/esm/src/agent/runtime/index.js +40 -39
- package/esm/src/agent/runtime/model-transport.d.ts +23 -0
- package/esm/src/agent/runtime/model-transport.d.ts.map +1 -0
- package/esm/src/agent/runtime/model-transport.js +26 -0
- package/esm/src/cache/keys/builders/render.d.ts.map +1 -1
- package/esm/src/cache/keys/builders/render.js +3 -2
- package/esm/src/cache/request-cacheability.d.ts +3 -0
- package/esm/src/cache/request-cacheability.d.ts.map +1 -0
- package/esm/src/cache/request-cacheability.js +26 -0
- package/esm/src/html/hydration-script-builder/hydration-data-generator.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/hydration-data-generator.js +1 -10
- package/esm/src/html/hydration-script-builder/templates/router.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/templates/router.js +41 -10
- package/esm/src/observability/request-profiler.d.ts.map +1 -1
- package/esm/src/observability/request-profiler.js +1 -0
- package/esm/src/proxy/handler.d.ts.map +1 -1
- package/esm/src/proxy/handler.js +39 -29
- package/esm/src/proxy/main.js +21 -20
- package/esm/src/proxy/proxy-error-context.d.ts +20 -0
- package/esm/src/proxy/proxy-error-context.d.ts.map +1 -0
- package/esm/src/proxy/proxy-error-context.js +35 -0
- package/esm/src/proxy/request-lifecycle.d.ts +19 -0
- package/esm/src/proxy/request-lifecycle.d.ts.map +1 -0
- package/esm/src/proxy/request-lifecycle.js +27 -0
- package/esm/src/proxy/upstream-error-response.d.ts +5 -0
- package/esm/src/proxy/upstream-error-response.d.ts.map +1 -0
- package/esm/src/proxy/upstream-error-response.js +15 -0
- package/esm/src/release-assets/client-module-map.d.ts +3 -0
- package/esm/src/release-assets/client-module-map.d.ts.map +1 -0
- package/esm/src/release-assets/client-module-map.js +10 -0
- package/esm/src/rendering/orchestrator/module-loader/index.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/module-loader/index.js +13 -49
- package/esm/src/rendering/orchestrator/module-loader/module-cache-lookup.d.ts +25 -0
- package/esm/src/rendering/orchestrator/module-loader/module-cache-lookup.d.ts.map +1 -0
- package/esm/src/rendering/orchestrator/module-loader/module-cache-lookup.js +69 -0
- package/esm/src/rendering/orchestrator/pipeline.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/pipeline.js +9 -10
- package/esm/src/rendering/orchestrator/types.d.ts +2 -0
- package/esm/src/rendering/orchestrator/types.d.ts.map +1 -1
- package/esm/src/rendering/renderer.d.ts.map +1 -1
- package/esm/src/rendering/renderer.js +24 -19
- package/esm/src/server/handlers/request/module/page-data-endpoint-handler.d.ts +1 -0
- package/esm/src/server/handlers/request/module/page-data-endpoint-handler.d.ts.map +1 -1
- package/esm/src/server/handlers/request/module/page-data-endpoint-handler.js +98 -8
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- 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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAEpF,YAAY,EAAE,YAAY,EAAE,CAAC;AAE7B,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,aAAa,GAAG,YAAY,CAAC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,0GAA0G;IAC1G,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B,4FAA4F;IAC5F,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,yEAAyE;IACzE,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,qDAAqD;IACrD,WAAW,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;IACvC,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6FAA6F;IAC7F,oBAAoB,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnD,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iFAAiF;IACjF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6EAA6E;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0EAA0E;IAC1E,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,mFAAmF;IACnF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;IACrD,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrD,YAAY,EAAE,YAAY,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../../src/src/rendering/renderer.ts"],"names":[],"mappings":"
|
|
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
|
-
|
|
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
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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;
|
|
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
|
|
18
|
-
|
|
19
|
-
|
|
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(
|
|
27
|
-
.withETag(etag)
|
|
28
|
-
.
|
|
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
|
+
}
|