vinext 0.0.51 → 0.0.52
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/dist/build/precompress.d.ts +7 -7
- package/dist/build/precompress.js +18 -17
- package/dist/build/precompress.js.map +1 -1
- package/dist/build/prerender.d.ts +3 -14
- package/dist/build/prerender.js +40 -40
- package/dist/build/prerender.js.map +1 -1
- package/dist/check.js +4 -0
- package/dist/check.js.map +1 -1
- package/dist/cli-args.d.ts +1 -0
- package/dist/cli-args.js +5 -0
- package/dist/cli-args.js.map +1 -1
- package/dist/cli.js +39 -0
- package/dist/cli.js.map +1 -1
- package/dist/client/navigation-runtime.d.ts +47 -0
- package/dist/client/navigation-runtime.js +156 -0
- package/dist/client/navigation-runtime.js.map +1 -0
- package/dist/client/pages-router-link-navigation.d.ts +26 -0
- package/dist/client/pages-router-link-navigation.js +14 -0
- package/dist/client/pages-router-link-navigation.js.map +1 -0
- package/dist/client/vinext-next-data.d.ts +12 -2
- package/dist/client/vinext-next-data.js +50 -1
- package/dist/client/vinext-next-data.js.map +1 -0
- package/dist/cloudflare/kv-cache-handler.js +2 -1
- package/dist/cloudflare/kv-cache-handler.js.map +1 -1
- package/dist/config/config-matchers.d.ts +63 -16
- package/dist/config/config-matchers.js +143 -8
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/next-config.d.ts +20 -2
- package/dist/config/next-config.js +11 -1
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.js +101 -39
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-browser-entry.js +9 -3
- package/dist/entries/app-browser-entry.js.map +1 -1
- package/dist/entries/app-rsc-entry.js +53 -13
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.d.ts +1 -0
- package/dist/entries/app-rsc-manifest.js +53 -6
- package/dist/entries/app-rsc-manifest.js.map +1 -1
- package/dist/entries/app-ssr-entry.d.ts +3 -3
- package/dist/entries/app-ssr-entry.js +4 -4
- package/dist/entries/app-ssr-entry.js.map +1 -1
- package/dist/entries/pages-client-entry.js +18 -2
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-server-entry.js +58 -8
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/entries/runtime-entry-module.d.ts +2 -1
- package/dist/entries/runtime-entry-module.js +9 -3
- package/dist/entries/runtime-entry-module.js.map +1 -1
- package/dist/index.js +132 -40
- package/dist/index.js.map +1 -1
- package/dist/plugins/css-data-url.d.ts +7 -0
- package/dist/plugins/css-data-url.js +81 -0
- package/dist/plugins/css-data-url.js.map +1 -0
- package/dist/plugins/fonts.js +5 -3
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/middleware-server-only.d.ts +54 -0
- package/dist/plugins/middleware-server-only.js +91 -0
- package/dist/plugins/middleware-server-only.js.map +1 -0
- package/dist/plugins/optimize-imports.js +4 -4
- package/dist/plugins/optimize-imports.js.map +1 -1
- package/dist/plugins/strip-server-exports.js +5 -8
- package/dist/plugins/strip-server-exports.js.map +1 -1
- package/dist/routing/app-route-graph.d.ts +20 -1
- package/dist/routing/app-route-graph.js +58 -6
- package/dist/routing/app-route-graph.js.map +1 -1
- package/dist/routing/app-router.d.ts +2 -2
- package/dist/routing/app-router.js +2 -2
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/utils.d.ts +2 -1
- package/dist/routing/utils.js +4 -1
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/api-handler.js +139 -37
- package/dist/server/api-handler.js.map +1 -1
- package/dist/server/app-browser-entry.js +293 -149
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-interception-context.d.ts +24 -0
- package/dist/server/app-browser-interception-context.js +32 -0
- package/dist/server/app-browser-interception-context.js.map +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +3 -1
- package/dist/server/app-browser-navigation-controller.js +5 -1
- package/dist/server/app-browser-navigation-controller.js.map +1 -1
- package/dist/server/app-browser-rsc-redirect.d.ts +2 -1
- package/dist/server/app-browser-rsc-redirect.js +2 -2
- package/dist/server/app-browser-rsc-redirect.js.map +1 -1
- package/dist/server/app-browser-state.d.ts +18 -1
- package/dist/server/app-browser-state.js +19 -1
- package/dist/server/app-browser-state.js.map +1 -1
- package/dist/server/app-browser-stream.d.ts +5 -14
- package/dist/server/app-browser-stream.js +13 -7
- package/dist/server/app-browser-stream.js.map +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +2 -1
- package/dist/server/app-browser-visible-commit.js +1 -0
- package/dist/server/app-browser-visible-commit.js.map +1 -1
- package/dist/server/app-elements-wire.d.ts +10 -5
- package/dist/server/app-elements-wire.js +84 -2
- package/dist/server/app-elements-wire.js.map +1 -1
- package/dist/server/app-elements.d.ts +3 -2
- package/dist/server/app-elements.js +3 -2
- package/dist/server/app-elements.js.map +1 -1
- package/dist/server/app-fallback-renderer.js +5 -3
- package/dist/server/app-fallback-renderer.js.map +1 -1
- package/dist/server/app-middleware.d.ts +13 -0
- package/dist/server/app-middleware.js +3 -1
- package/dist/server/app-middleware.js.map +1 -1
- package/dist/server/app-optimistic-routing.d.ts +54 -0
- package/dist/server/app-optimistic-routing.js +200 -0
- package/dist/server/app-optimistic-routing.js.map +1 -0
- package/dist/server/app-page-cache.d.ts +13 -1
- package/dist/server/app-page-cache.js +61 -6
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +2 -0
- package/dist/server/app-page-dispatch.js +28 -1
- package/dist/server/app-page-dispatch.js.map +1 -1
- package/dist/server/app-page-element-builder.js +2 -1
- package/dist/server/app-page-element-builder.js.map +1 -1
- package/dist/server/app-page-execution.d.ts +28 -1
- package/dist/server/app-page-execution.js +89 -4
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-head.js +21 -2
- package/dist/server/app-page-head.js.map +1 -1
- package/dist/server/app-page-probe.js +1 -1
- package/dist/server/app-page-render.d.ts +2 -0
- package/dist/server/app-page-render.js +2 -1
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-response.js +4 -3
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.js +17 -10
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +3 -0
- package/dist/server/app-page-stream.js +1 -0
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-prerender-static-params.d.ts +2 -1
- package/dist/server/app-prerender-static-params.js +44 -8
- package/dist/server/app-prerender-static-params.js.map +1 -1
- package/dist/server/app-route-handler-cache.d.ts +2 -2
- package/dist/server/app-route-handler-cache.js +3 -2
- package/dist/server/app-route-handler-cache.js.map +1 -1
- package/dist/server/app-route-handler-dispatch.d.ts +6 -1
- package/dist/server/app-route-handler-dispatch.js +1 -1
- package/dist/server/app-route-handler-dispatch.js.map +1 -1
- package/dist/server/app-route-handler-execution.d.ts +17 -2
- package/dist/server/app-route-handler-execution.js.map +1 -1
- package/dist/server/app-route-handler-response.js +5 -4
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-router-entry.js +6 -2
- package/dist/server/app-router-entry.js.map +1 -1
- package/dist/server/app-rsc-handler.d.ts +9 -1
- package/dist/server/app-rsc-handler.js +32 -14
- package/dist/server/app-rsc-handler.js.map +1 -1
- package/dist/server/app-rsc-render-mode.d.ts +4 -3
- package/dist/server/app-rsc-render-mode.js +7 -1
- package/dist/server/app-rsc-render-mode.js.map +1 -1
- package/dist/server/app-rsc-request-normalization.d.ts +4 -1
- package/dist/server/app-rsc-request-normalization.js +4 -1
- package/dist/server/app-rsc-request-normalization.js.map +1 -1
- package/dist/server/app-rsc-response-finalizer.d.ts +8 -1
- package/dist/server/app-rsc-response-finalizer.js +10 -3
- package/dist/server/app-rsc-response-finalizer.js.map +1 -1
- package/dist/server/app-rsc-route-matching.js +2 -2
- package/dist/server/app-rsc-route-matching.js.map +1 -1
- package/dist/server/app-server-action-execution.js +1 -1
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +56 -55
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-stream.d.ts +6 -1
- package/dist/server/app-ssr-stream.js +17 -3
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/artifact-compatibility.d.ts +1 -1
- package/dist/server/artifact-compatibility.js.map +1 -1
- package/dist/server/cache-headers.d.ts +7 -0
- package/dist/server/cache-headers.js +19 -0
- package/dist/server/cache-headers.js.map +1 -0
- package/dist/server/cache-proof.d.ts +49 -3
- package/dist/server/cache-proof.js +78 -22
- package/dist/server/cache-proof.js.map +1 -1
- package/dist/server/client-reuse-manifest.d.ts +99 -0
- package/dist/server/client-reuse-manifest.js +212 -0
- package/dist/server/client-reuse-manifest.js.map +1 -0
- package/dist/server/default-global-error-module.d.ts +20 -0
- package/dist/server/default-global-error-module.js +20 -0
- package/dist/server/default-global-error-module.js.map +1 -0
- package/dist/server/dev-server.d.ts +9 -1
- package/dist/server/dev-server.js +76 -29
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/edge-api-runtime.d.ts +5 -0
- package/dist/server/edge-api-runtime.js +8 -0
- package/dist/server/edge-api-runtime.js.map +1 -0
- package/dist/server/headers.d.ts +18 -1
- package/dist/server/headers.js +18 -1
- package/dist/server/headers.js.map +1 -1
- package/dist/server/http-error-responses.d.ts +16 -1
- package/dist/server/http-error-responses.js +21 -1
- package/dist/server/http-error-responses.js.map +1 -1
- package/dist/server/isr-cache.d.ts +6 -2
- package/dist/server/isr-cache.js +20 -4
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/middleware-runtime.d.ts +15 -0
- package/dist/server/middleware-runtime.js +59 -7
- package/dist/server/middleware-runtime.js.map +1 -1
- package/dist/server/middleware.d.ts +1 -1
- package/dist/server/middleware.js +4 -2
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/navigation-planner.d.ts +9 -3
- package/dist/server/navigation-planner.js +98 -25
- package/dist/server/navigation-planner.js.map +1 -1
- package/dist/server/navigation-trace.d.ts +2 -1
- package/dist/server/navigation-trace.js +1 -0
- package/dist/server/navigation-trace.js.map +1 -1
- package/dist/server/pages-api-route.d.ts +27 -1
- package/dist/server/pages-api-route.js +24 -3
- package/dist/server/pages-api-route.js.map +1 -1
- package/dist/server/pages-data-route.d.ts +77 -0
- package/dist/server/pages-data-route.js +97 -0
- package/dist/server/pages-data-route.js.map +1 -0
- package/dist/server/pages-i18n.d.ts +51 -1
- package/dist/server/pages-i18n.js +61 -1
- package/dist/server/pages-i18n.js.map +1 -1
- package/dist/server/pages-page-data.d.ts +29 -2
- package/dist/server/pages-page-data.js +31 -17
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-response.d.ts +11 -1
- package/dist/server/pages-page-response.js +5 -3
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/prod-server.d.ts +13 -15
- package/dist/server/prod-server.js +109 -56
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/request-pipeline.d.ts +11 -2
- package/dist/server/request-pipeline.js +28 -11
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/server/seed-cache.d.ts +12 -31
- package/dist/server/seed-cache.js +22 -35
- package/dist/server/seed-cache.js.map +1 -1
- package/dist/server/server-action-not-found.js +8 -3
- package/dist/server/server-action-not-found.js.map +1 -1
- package/dist/server/skip-cache-proof.d.ts +41 -0
- package/dist/server/skip-cache-proof.js +101 -0
- package/dist/server/skip-cache-proof.js.map +1 -0
- package/dist/server/static-file-cache.d.ts +1 -1
- package/dist/server/static-file-cache.js +7 -6
- package/dist/server/static-file-cache.js.map +1 -1
- package/dist/shims/client-locale.d.ts +15 -0
- package/dist/shims/client-locale.js +13 -0
- package/dist/shims/client-locale.js.map +1 -0
- package/dist/shims/default-global-error.d.ts +32 -0
- package/dist/shims/default-global-error.js +181 -0
- package/dist/shims/default-global-error.js.map +1 -0
- package/dist/shims/document.d.ts +59 -3
- package/dist/shims/document.js +36 -5
- package/dist/shims/document.js.map +1 -1
- package/dist/shims/error-boundary.d.ts +2 -2
- package/dist/shims/form.js +13 -6
- package/dist/shims/form.js.map +1 -1
- package/dist/shims/link.d.ts +21 -3
- package/dist/shims/link.js +131 -22
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.js +4 -4
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation.d.ts +8 -2
- package/dist/shims/navigation.js +36 -15
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/og.d.ts +18 -2
- package/dist/shims/og.js +49 -1
- package/dist/shims/og.js.map +1 -0
- package/dist/shims/request-state-types.d.ts +1 -1
- package/dist/shims/root-params.d.ts +3 -1
- package/dist/shims/root-params.js +11 -3
- package/dist/shims/root-params.js.map +1 -1
- package/dist/shims/router-state.d.ts +1 -0
- package/dist/shims/router-state.js.map +1 -1
- package/dist/shims/router.d.ts +12 -5
- package/dist/shims/router.js +172 -22
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/server.d.ts +21 -4
- package/dist/shims/server.js +29 -9
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/slot.js +5 -1
- package/dist/shims/slot.js.map +1 -1
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/url-safety.d.ts +23 -1
- package/dist/shims/url-safety.js +29 -2
- package/dist/shims/url-safety.js.map +1 -1
- package/dist/typegen.d.ts +10 -0
- package/dist/typegen.js +242 -0
- package/dist/typegen.js.map +1 -0
- package/dist/utils/asset-prefix.d.ts +33 -5
- package/dist/utils/asset-prefix.js +39 -6
- package/dist/utils/asset-prefix.js.map +1 -1
- package/dist/utils/cache-control-metadata.d.ts +2 -1
- package/dist/utils/cache-control-metadata.js +1 -3
- package/dist/utils/cache-control-metadata.js.map +1 -1
- package/dist/utils/domain-locale.d.ts +2 -1
- package/dist/utils/domain-locale.js +9 -1
- package/dist/utils/domain-locale.js.map +1 -1
- package/dist/utils/lazy-chunks.d.ts +1 -1
- package/dist/utils/lazy-chunks.js +1 -1
- package/dist/utils/lazy-chunks.js.map +1 -1
- package/dist/utils/prerender-output-paths.d.ts +15 -0
- package/dist/utils/prerender-output-paths.js +24 -0
- package/dist/utils/prerender-output-paths.js.map +1 -0
- package/dist/utils/query.d.ts +17 -1
- package/dist/utils/query.js +36 -1
- package/dist/utils/query.js.map +1 -1
- package/dist/utils/record.d.ts +5 -0
- package/dist/utils/record.js +8 -0
- package/dist/utils/record.js.map +1 -0
- package/package.json +11 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-proof.js","names":[],"sources":["../../src/server/cache-proof.ts"],"sourcesContent":["import type { AppRouteSemanticIds } from \"../routing/app-route-graph.js\";\nimport { fnv1a64 } from \"../utils/hash.js\";\nimport { findSortedStringPosition } from \"../utils/sorted-array.js\";\n\nexport const CACHE_PROOF_MODEL_SCHEMA_VERSION = 1;\nexport type CacheProofModelSchemaVersion = 1;\n\nexport type CacheProofRejectionCode =\n | \"CP_MODEL_DISABLED\"\n | \"CP_DIMENSION_COUNT_EXCEEDED\"\n | \"CP_DIMENSION_NAME_MISSING\"\n | \"CP_DIMENSION_NAME_TOO_LONG\"\n | \"CP_DIMENSION_VALUE_COUNT_EXCEEDED\"\n | \"CP_DIMENSION_VALUE_TOO_LONG\"\n | \"CP_DIMENSION_VALUES_MISSING\"\n | \"CP_ENCODED_VARIANT_TOO_LONG\"\n | \"CP_INVALID_VARIANT_BUDGET\"\n | \"CP_ROUTE_VARIANT_BUDGET_ROUTE_MISMATCH\"\n | \"CP_ROUTE_VARIANT_CEILING_EXCEEDED\"\n | \"CP_UNSAFE_PUBLIC_DIMENSION\"\n | \"CP_BOUNDARY_OUTCOME_MISMATCH\"\n | \"CP_BOUNDARY_OUTCOME_UNKNOWN\"\n | \"CP_PRIVATE_DYNAMIC_DOWNGRADE\"\n | \"CP_STATIC_LAYOUT_CANDIDATE_OUTPUT_KIND\"\n | \"CP_STATIC_LAYOUT_CURRENT_OUTPUT_KIND\"\n | \"CP_STATIC_LAYOUT_ID_MISMATCH\"\n | \"CP_STATIC_LAYOUT_OBSERVATION_OUTPUT_KIND\"\n | \"CP_STATIC_LAYOUT_OBSERVATION_OUTPUT_MISMATCH\"\n | \"CP_STATIC_LAYOUT_PRIVATE_DYNAMIC_DOWNGRADE\"\n | \"CP_STATIC_LAYOUT_PRIVATE_VARIANT_DIMENSION\"\n | \"CP_STATIC_LAYOUT_REQUEST_API_OBSERVED\"\n | \"CP_STATIC_LAYOUT_REQUEST_API_UNKNOWN\"\n | \"CP_STATIC_LAYOUT_ROOT_BOUNDARY_MISMATCH\"\n | \"CP_STATIC_LAYOUT_ROOT_BOUNDARY_UNKNOWN\";\n\nexport type CacheProofAcceptanceCode = \"CP_STATIC_LAYOUT_REUSE_PROVEN\";\n\nexport type CacheProofTraceCode = CacheProofAcceptanceCode | CacheProofRejectionCode;\n\nexport type CacheProofTraceFieldValue = string | number | boolean | null | readonly string[];\n\nexport type CacheProofTraceFields = Readonly<Record<string, CacheProofTraceFieldValue>>;\n\nexport type CacheProofBreakerFallbackMode = \"renderFresh\" | \"privateUncacheable\";\nexport type CacheProofFallbackScope = \"affectedOutput\" | \"route\";\n\nexport type CacheProofBreakerFallback = Readonly<{\n kind: \"breakerFallback\";\n code: CacheProofRejectionCode;\n mode: CacheProofBreakerFallbackMode;\n scope: CacheProofFallbackScope;\n fields: CacheProofTraceFields;\n}>;\n\nexport type CacheVariantBudget = Readonly<{\n maxDimensionCount: number;\n maxDimensionNameLength: number;\n maxDimensionValueLength: number;\n maxEncodedLength: number;\n maxValuesPerDimension: number;\n maxVariantsPerRoute: number;\n}>;\n\nexport const DEFAULT_CACHE_VARIANT_BUDGET = {\n maxDimensionCount: 8,\n maxDimensionNameLength: 64,\n maxDimensionValueLength: 256,\n maxEncodedLength: 1024,\n maxValuesPerDimension: 8,\n maxVariantsPerRoute: 64,\n} satisfies CacheVariantBudget;\n\nexport type CacheVariantDimensionSource =\n | \"auth\"\n | \"cookie\"\n | \"custom\"\n | \"draft-mode\"\n | \"header\"\n | \"interception\"\n | \"mounted-slots\"\n | \"params\"\n | \"route\"\n | \"search\"\n | \"session\";\n\nexport type CacheVariantDimensionPrivacy = \"internal\" | \"private\" | \"public\";\n\nexport type CacheVariantDimensionInput = Readonly<{\n name: string;\n privacy: CacheVariantDimensionPrivacy;\n source: CacheVariantDimensionSource;\n values: readonly string[];\n}>;\n\nexport type CacheVariantDimension = Readonly<{\n encoded: string;\n name: string;\n privacy: CacheVariantDimensionPrivacy;\n source: CacheVariantDimensionSource;\n valueCount: number;\n valueHashes: readonly string[];\n}>;\n\nexport type CacheProofOutputScope =\n | Readonly<{\n kind: \"app-html\";\n renderEpoch: string | null;\n rootBoundaryId: string | null;\n routeId: string;\n }>\n | Readonly<{\n kind: \"app-rsc\";\n mountedSlotsFingerprint: string | null;\n renderEpoch: string | null;\n rootBoundaryId: string | null;\n routeId: string;\n }>\n | Readonly<{\n kind: \"layout\";\n layoutId: string;\n rootBoundaryId: string | null;\n routeId: string;\n }>\n | Readonly<{\n kind: \"page\";\n pageId: string;\n rootBoundaryId: string | null;\n routeId: string;\n }>\n | Readonly<{\n kind: \"route-handler\";\n routeHandlerId: string;\n routeId: string;\n }>\n | Readonly<{\n kind: \"slot\";\n rootBoundaryId: string | null;\n routeId: string;\n slotId: string;\n }>\n | Readonly<{\n kind: \"template\";\n rootBoundaryId: string | null;\n routeId: string;\n templateId: string;\n }>;\n\nexport type StaticLayoutCacheProofOutputScope = Extract<CacheProofOutputScope, { kind: \"layout\" }>;\n\nexport type CacheVariant = Readonly<{\n budget: CacheVariantBudget;\n cacheKey: string;\n dimensions: readonly CacheVariantDimension[];\n encodedLength: number;\n output: CacheProofOutputScope;\n schemaVersion: CacheProofModelSchemaVersion;\n}>;\n\nexport type BuildCacheVariantInput = Readonly<{\n budget: CacheVariantBudget;\n dimensions: readonly CacheVariantDimensionInput[];\n output: CacheProofOutputScope;\n}>;\n\nexport type BuildCacheVariantResult =\n | Readonly<{ kind: \"variant\"; variant: CacheVariant }>\n | Readonly<{ kind: \"breakerFallback\"; fallback: CacheProofBreakerFallback }>;\n\nexport type CacheVariantRouteBudget = Readonly<{\n routeId: string;\n variantCacheKeys: readonly string[];\n}>;\n\nexport type CacheVariantRouteBudgetAdmission =\n | Readonly<{\n didConsumeRouteVariantBudget: boolean;\n kind: \"variant\";\n routeBudget: CacheVariantRouteBudget;\n variant: CacheVariant;\n }>\n | Readonly<{\n fallback: CacheProofBreakerFallback;\n kind: \"breakerFallback\";\n routeBudget: CacheVariantRouteBudget | null;\n }>;\n\nexport type BuildCacheVariantWithRouteBudgetInput = BuildCacheVariantInput &\n Readonly<{\n routeBudget: CacheVariantRouteBudget | null;\n }>;\n\nexport type BuildCacheVariantWithRouteBudgetResult = CacheVariantRouteBudgetAdmission;\n\nexport type AppRouteCacheProofGraphScopeInput = Readonly<{\n ids: AppRouteSemanticIds;\n}>;\n\nexport type AppRouteCacheProofGraphScope = Readonly<{\n layoutIds: readonly string[];\n pageId: string | null;\n routeHandlerId: string | null;\n routeId: string;\n slotIds: readonly string[];\n templateIds: readonly string[];\n}>;\n\nexport type BoundaryOutcome =\n | Readonly<{ kind: \"error\"; digest?: string }>\n | Readonly<{ kind: \"forbidden\" }>\n | Readonly<{ kind: \"globalError\"; digest?: string }>\n | Readonly<{ kind: \"notFound\" }>\n | Readonly<{ kind: \"redirect\"; location: string; status: number }>\n | Readonly<{ kind: \"success\" }>\n | Readonly<{ kind: \"unauthorized\" }>\n | Readonly<{ kind: \"unknown\" }>;\n\nexport type BoundaryOutcomeCompatibility =\n | Readonly<{\n kind: \"compatible\";\n outcome: BoundaryOutcome;\n reason: \"CP_BOUNDARY_OUTCOME_MATCH\";\n }>\n | Readonly<{\n candidate: BoundaryOutcome;\n expected: BoundaryOutcome;\n fallback: CacheProofBreakerFallback;\n kind: \"incompatible\";\n }>;\n\nexport type RenderObservationCompleteness = \"complete\" | \"partial\" | \"unknown\";\nexport type RenderCacheability = \"private\" | \"public\" | \"uncacheable\" | \"unknown\";\nexport type RenderRequestApiKind =\n | \"connection\"\n | \"cookies\"\n | \"draftMode\"\n | \"headers\"\n | \"params\"\n | \"searchParams\";\nexport type RenderRequestApiStatus = \"notObserved\" | \"observed\" | \"unknown\";\n\nexport const ALL_RENDER_REQUEST_API_KINDS: readonly RenderRequestApiKind[] = [\n \"connection\",\n \"cookies\",\n \"draftMode\",\n \"headers\",\n \"params\",\n \"searchParams\",\n];\n\nexport type RenderRequestApiObservation = Readonly<{\n kind: RenderRequestApiKind;\n status: RenderRequestApiStatus;\n}>;\n\nexport type CacheProofDowngradeTarget =\n | \"freshRender\"\n | \"private\"\n | \"privateUncacheable\"\n | \"public\"\n | \"publicVariant\";\n\nexport type CacheProofDowngradeReason =\n | Readonly<{\n code: \"CP_DOWNGRADE_CACHEABILITY_PRIVATE\";\n target: \"private\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_CACHEABILITY_UNCACHEABLE\";\n target: \"privateUncacheable\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_CACHEABILITY_UNKNOWN\";\n target: \"freshRender\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_DYNAMIC_FETCH\";\n dynamicFetchCount: number;\n target: \"freshRender\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_DYNAMIC_REQUEST_API\";\n requestApi: \"connection\";\n target: \"freshRender\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_DRAFT_MODE\";\n requestApi: \"draftMode\";\n target: \"privateUncacheable\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_INCOMPLETE_OBSERVATION\";\n completeness: Exclude<RenderObservationCompleteness, \"complete\">;\n target: \"freshRender\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_PRIVATE_DIMENSION\";\n inputClass: \"auth\" | \"draft\" | \"private\" | \"session\";\n source: \"auth\" | \"cookie\" | \"draft-mode\" | \"header\" | \"session\";\n target: \"private\" | \"privateUncacheable\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_PRIVATE_REQUEST_API\";\n requestApi: \"cookies\" | \"headers\";\n target: \"private\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_PUBLIC_REQUEST_API\";\n requestApi: \"params\" | \"searchParams\";\n target: \"publicVariant\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_UNKNOWN_REQUEST_API\";\n requestApi: RenderRequestApiKind;\n target: \"freshRender\";\n }>;\n\nexport type CacheProofDowngradeClassification = Readonly<{\n fallback: CacheProofBreakerFallback | null;\n isPublicCacheCandidate: boolean;\n reasons: readonly CacheProofDowngradeReason[];\n target: CacheProofDowngradeTarget;\n}>;\n\nexport type ClassifyRenderObservationDowngradeInput = Readonly<{\n cacheability: RenderCacheability;\n completeness: RenderObservationCompleteness;\n dynamicFetches: readonly string[];\n requestApis: readonly RenderRequestApiObservation[];\n}>;\n\nexport type ClassifyCacheVariantDimensionDowngradeInput = Pick<\n CacheVariantDimensionInput,\n \"source\"\n>;\n\nexport type RenderObservation = Readonly<{\n boundaryOutcome: BoundaryOutcome;\n cacheTags: readonly string[];\n cacheability: RenderCacheability;\n completeness: RenderObservationCompleteness;\n downgrade: CacheProofDowngradeClassification;\n dynamicFetches: readonly string[];\n output: CacheProofOutputScope;\n pathTags: readonly string[];\n requestApis: readonly RenderRequestApiObservation[];\n schemaVersion: CacheProofModelSchemaVersion;\n}>;\n\nexport type StaticLayoutReuseProof = Readonly<{\n authorizesRuntimeReuse: false;\n candidateOutput: StaticLayoutCacheProofOutputScope;\n code: \"CP_STATIC_LAYOUT_REUSE_PROVEN\";\n currentOutput: StaticLayoutCacheProofOutputScope;\n fields: CacheProofTraceFields;\n observation: RenderObservation;\n requiredNegativeRequestApis: readonly RenderRequestApiKind[];\n reuseClass: \"static-layout\";\n variant: CacheVariant;\n}>;\n\nexport type BuildStaticLayoutReuseProofInput = Readonly<{\n candidateObservation: RenderObservation;\n candidateVariant: CacheVariant;\n currentOutput: CacheProofOutputScope;\n}>;\n\nexport type BuildStaticLayoutReuseProofResult =\n | Readonly<{ kind: \"proof\"; proof: StaticLayoutReuseProof }>\n | Readonly<{ kind: \"rejected\"; fallback: CacheProofBreakerFallback }>;\n\nexport type BuildRenderObservationInput = Readonly<{\n boundaryOutcome: BoundaryOutcome;\n cacheTags: readonly string[];\n cacheability: RenderCacheability;\n completeness: RenderObservationCompleteness;\n dynamicFetches: readonly string[];\n output: CacheProofOutputScope;\n pathTags: readonly string[];\n requestApis: readonly RenderRequestApiObservation[];\n}>;\n\nexport type BuildRenderRequestApiObservationsInput = Readonly<{\n completeness: RenderObservationCompleteness;\n observed: readonly RenderRequestApiKind[];\n}>;\n\nexport type DisabledCacheProofDecision = Readonly<{\n canReuse: false;\n fallback: CacheProofBreakerFallback;\n kind: \"disabled\";\n observation: RenderObservation;\n staticLayoutProof?: StaticLayoutReuseProof;\n variant: CacheVariant;\n}>;\n\nexport type CreateDisabledCacheProofDecisionInput = Readonly<{\n observation: RenderObservation;\n staticLayoutProof?: StaticLayoutReuseProof;\n variant: CacheVariant;\n}>;\n\nconst PUBLIC_UNSAFE_DIMENSION_SOURCES: ReadonlySet<CacheVariantDimensionSource> = new Set([\n \"auth\",\n \"cookie\",\n \"draft-mode\",\n \"header\",\n \"session\",\n]);\n\ntype CacheVariantDimensionAccumulator = {\n name: string;\n privacy: CacheVariantDimensionPrivacy;\n source: CacheVariantDimensionSource;\n values: string[];\n};\n\ntype DimensionAccumulatorByName = Map<string, CacheVariantDimensionAccumulator>;\ntype DimensionAccumulatorByPrivacy = Map<CacheVariantDimensionPrivacy, DimensionAccumulatorByName>;\ntype DimensionAccumulatorBySource = Map<CacheVariantDimensionSource, DimensionAccumulatorByPrivacy>;\n\nfunction buildBreakerFallback(\n code: CacheProofRejectionCode,\n fields: CacheProofTraceFields = {},\n mode: CacheProofBreakerFallbackMode = \"renderFresh\",\n scope: CacheProofFallbackScope = \"affectedOutput\",\n): CacheProofBreakerFallback {\n return {\n kind: \"breakerFallback\",\n code,\n mode,\n scope,\n fields,\n };\n}\n\nfunction sortedUnique(values: readonly string[]): string[] {\n return [...new Set(values)].sort();\n}\n\nfunction normalizeDimensionName(name: string): string {\n return name.trim().toLowerCase();\n}\n\nfunction redactValue(value: string): string {\n return `h:${fnv1a64(value)}`;\n}\n\nfunction sortedUniqueRedacted(values: readonly string[]): string[] {\n return sortedUnique(sortedUnique(values).map(redactValue));\n}\n\nfunction encodeParts(parts: readonly unknown[]): string {\n return JSON.stringify(parts);\n}\n\nfunction compareDimensions(a: CacheVariantDimension, b: CacheVariantDimension): number {\n return (\n a.source.localeCompare(b.source) ||\n a.name.localeCompare(b.name) ||\n a.privacy.localeCompare(b.privacy)\n );\n}\n\nfunction encodeNullable(value: string | null): string | null {\n return value;\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`Unhandled cache proof variant: ${String(value)}`);\n}\n\nfunction encodeOutputScope(output: CacheProofOutputScope): string {\n switch (output.kind) {\n case \"app-html\":\n return encodeParts([\n output.kind,\n output.routeId,\n encodeNullable(output.rootBoundaryId),\n encodeNullable(output.renderEpoch),\n ]);\n case \"app-rsc\":\n return encodeParts([\n output.kind,\n output.routeId,\n encodeNullable(output.rootBoundaryId),\n encodeNullable(output.renderEpoch),\n encodeNullable(output.mountedSlotsFingerprint),\n ]);\n case \"layout\":\n return encodeParts([\n output.kind,\n output.routeId,\n output.layoutId,\n encodeNullable(output.rootBoundaryId),\n ]);\n case \"page\":\n return encodeParts([\n output.kind,\n output.routeId,\n output.pageId,\n encodeNullable(output.rootBoundaryId),\n ]);\n case \"route-handler\":\n return encodeParts([output.kind, output.routeId, output.routeHandlerId]);\n case \"slot\":\n return encodeParts([\n output.kind,\n output.routeId,\n output.slotId,\n encodeNullable(output.rootBoundaryId),\n ]);\n case \"template\":\n return encodeParts([\n output.kind,\n output.routeId,\n output.templateId,\n encodeNullable(output.rootBoundaryId),\n ]);\n default:\n return assertNever(output);\n }\n}\n\nfunction validateBudgetNumber(name: string, value: number): CacheProofBreakerFallback | null {\n if (Number.isInteger(value) && value >= 0) return null;\n return buildBreakerFallback(\"CP_INVALID_VARIANT_BUDGET\", {\n budgetField: name,\n });\n}\n\nfunction validateBudget(budget: CacheVariantBudget): CacheProofBreakerFallback | null {\n return (\n validateBudgetNumber(\"maxDimensionCount\", budget.maxDimensionCount) ??\n validateBudgetNumber(\"maxDimensionNameLength\", budget.maxDimensionNameLength) ??\n validateBudgetNumber(\"maxDimensionValueLength\", budget.maxDimensionValueLength) ??\n validateBudgetNumber(\"maxEncodedLength\", budget.maxEncodedLength) ??\n validateBudgetNumber(\"maxValuesPerDimension\", budget.maxValuesPerDimension) ??\n validateBudgetNumber(\"maxVariantsPerRoute\", budget.maxVariantsPerRoute)\n );\n}\n\nfunction buildDimension(\n input: CacheVariantDimensionInput,\n budget: CacheVariantBudget,\n): CacheVariantDimension | CacheProofBreakerFallback {\n const name = normalizeDimensionName(input.name);\n if (name.length === 0) {\n return buildBreakerFallback(\"CP_DIMENSION_NAME_MISSING\", {\n source: input.source,\n });\n }\n if (name.length > budget.maxDimensionNameLength) {\n return buildBreakerFallback(\"CP_DIMENSION_NAME_TOO_LONG\", {\n maxLength: budget.maxDimensionNameLength,\n nameHash: redactValue(name),\n source: input.source,\n });\n }\n if (input.privacy === \"public\" && PUBLIC_UNSAFE_DIMENSION_SOURCES.has(input.source)) {\n return buildBreakerFallback(\n \"CP_UNSAFE_PUBLIC_DIMENSION\",\n {\n name,\n source: input.source,\n },\n \"privateUncacheable\",\n );\n }\n\n const values = sortedUnique(input.values);\n if (values.length === 0) {\n return buildBreakerFallback(\"CP_DIMENSION_VALUES_MISSING\", {\n name,\n source: input.source,\n });\n }\n if (values.length > budget.maxValuesPerDimension) {\n return buildBreakerFallback(\"CP_DIMENSION_VALUE_COUNT_EXCEEDED\", {\n maxValues: budget.maxValuesPerDimension,\n name,\n source: input.source,\n valueCount: values.length,\n });\n }\n for (const value of values) {\n if (value.length > budget.maxDimensionValueLength) {\n return buildBreakerFallback(\"CP_DIMENSION_VALUE_TOO_LONG\", {\n maxLength: budget.maxDimensionValueLength,\n name,\n source: input.source,\n valueHash: redactValue(value),\n });\n }\n }\n\n const valueHashes = values.map(redactValue);\n const encoded = encodeParts([input.source, input.privacy, name, valueHashes]);\n\n return {\n encoded,\n name,\n privacy: input.privacy,\n source: input.source,\n valueCount: valueHashes.length,\n valueHashes,\n };\n}\n\nfunction isCacheProofBreakerFallback(\n value: CacheVariantDimension | CacheProofBreakerFallback,\n): value is CacheProofBreakerFallback {\n return \"code\" in value;\n}\n\nfunction getDimensionBucket(\n bySource: DimensionAccumulatorBySource,\n source: CacheVariantDimensionSource,\n privacy: CacheVariantDimensionPrivacy,\n): DimensionAccumulatorByName {\n const existingByPrivacy = bySource.get(source);\n const byPrivacy = existingByPrivacy ?? new Map();\n if (!existingByPrivacy) {\n bySource.set(source, byPrivacy);\n }\n\n const existingByName = byPrivacy.get(privacy);\n const byName = existingByName ?? new Map();\n if (!existingByName) {\n byPrivacy.set(privacy, byName);\n }\n\n return byName;\n}\n\nfunction mergeDimensionInputs(\n dimensions: readonly CacheVariantDimensionInput[],\n): CacheVariantDimensionInput[] {\n const bySource: DimensionAccumulatorBySource = new Map();\n const orderedDimensions: CacheVariantDimensionAccumulator[] = [];\n\n for (const dimension of dimensions) {\n const name = normalizeDimensionName(dimension.name);\n const bucket = getDimensionBucket(bySource, dimension.source, dimension.privacy);\n const existing = bucket.get(name);\n if (existing) {\n existing.values.push(...dimension.values);\n continue;\n }\n const accumulator = {\n name,\n privacy: dimension.privacy,\n source: dimension.source,\n values: [...dimension.values],\n };\n bucket.set(name, accumulator);\n orderedDimensions.push(accumulator);\n }\n\n return orderedDimensions;\n}\n\nexport function createAppRouteCacheProofGraphScope(\n route: AppRouteCacheProofGraphScopeInput,\n): AppRouteCacheProofGraphScope {\n return {\n routeId: route.ids.route,\n pageId: route.ids.page,\n routeHandlerId: route.ids.routeHandler,\n layoutIds: [...route.ids.layouts],\n templateIds: [...route.ids.templates],\n slotIds: sortedUnique(Object.values(route.ids.slots)),\n };\n}\n\nexport function buildCacheVariant(input: BuildCacheVariantInput): BuildCacheVariantResult {\n const budgetFallback = validateBudget(input.budget);\n if (budgetFallback) {\n return {\n kind: \"breakerFallback\",\n fallback: budgetFallback,\n };\n }\n const dimensionInputs = mergeDimensionInputs(input.dimensions);\n if (dimensionInputs.length > input.budget.maxDimensionCount) {\n return {\n kind: \"breakerFallback\",\n fallback: buildBreakerFallback(\"CP_DIMENSION_COUNT_EXCEEDED\", {\n dimensionCount: dimensionInputs.length,\n maxDimensionCount: input.budget.maxDimensionCount,\n routeId: input.output.routeId,\n }),\n };\n }\n\n const dimensions: CacheVariantDimension[] = [];\n for (const dimensionInput of dimensionInputs) {\n const dimension = buildDimension(dimensionInput, input.budget);\n if (isCacheProofBreakerFallback(dimension)) {\n return {\n kind: \"breakerFallback\",\n fallback: dimension,\n };\n }\n dimensions.push(dimension);\n }\n dimensions.sort(compareDimensions);\n\n const encoded = [\n `schema:${CACHE_PROOF_MODEL_SCHEMA_VERSION}`,\n encodeOutputScope(input.output),\n ...dimensions.map((dimension) => dimension.encoded),\n ].join(\"|\");\n\n if (encoded.length > input.budget.maxEncodedLength) {\n return {\n kind: \"breakerFallback\",\n fallback: buildBreakerFallback(\"CP_ENCODED_VARIANT_TOO_LONG\", {\n encodedHash: redactValue(encoded),\n encodedLength: encoded.length,\n maxEncodedLength: input.budget.maxEncodedLength,\n routeId: input.output.routeId,\n }),\n };\n }\n\n return {\n kind: \"variant\",\n variant: {\n schemaVersion: CACHE_PROOF_MODEL_SCHEMA_VERSION,\n cacheKey: `cp${CACHE_PROOF_MODEL_SCHEMA_VERSION}:${fnv1a64(encoded)}`,\n output: input.output,\n dimensions,\n encodedLength: encoded.length,\n budget: { ...input.budget },\n },\n };\n}\n\nfunction normalizeRouteBudget(input: CacheVariantRouteBudget): CacheVariantRouteBudget {\n return {\n routeId: input.routeId,\n variantCacheKeys: sortedUnique(input.variantCacheKeys),\n };\n}\n\nfunction buildRouteVariantCeilingFallback(\n variant: CacheVariant,\n existingVariantCount: number,\n): CacheProofBreakerFallback {\n return buildBreakerFallback(\n \"CP_ROUTE_VARIANT_CEILING_EXCEEDED\",\n {\n existingVariantCount,\n maxVariantsPerRoute: variant.budget.maxVariantsPerRoute,\n routeId: variant.output.routeId,\n },\n \"privateUncacheable\",\n \"route\",\n );\n}\n\nexport function enforceCacheVariantRouteBudget(input: {\n routeBudget: CacheVariantRouteBudget | null;\n variant: CacheVariant;\n}): CacheVariantRouteBudgetAdmission {\n if (input.routeBudget && input.routeBudget.routeId !== input.variant.output.routeId) {\n return {\n kind: \"breakerFallback\",\n routeBudget: normalizeRouteBudget(input.routeBudget),\n fallback: buildBreakerFallback(\n \"CP_ROUTE_VARIANT_BUDGET_ROUTE_MISMATCH\",\n {\n budgetRouteId: input.routeBudget.routeId,\n routeId: input.variant.output.routeId,\n },\n \"privateUncacheable\",\n \"route\",\n ),\n };\n }\n\n const routeBudget = normalizeRouteBudget(\n input.routeBudget ?? {\n routeId: input.variant.output.routeId,\n variantCacheKeys: [],\n },\n );\n const existingVariantCount = routeBudget.variantCacheKeys.length;\n const variantKeyPosition = findSortedStringPosition(\n routeBudget.variantCacheKeys,\n input.variant.cacheKey,\n );\n\n if (existingVariantCount > input.variant.budget.maxVariantsPerRoute) {\n return {\n kind: \"breakerFallback\",\n routeBudget,\n fallback: buildRouteVariantCeilingFallback(input.variant, existingVariantCount),\n };\n }\n\n if (variantKeyPosition.found) {\n return {\n kind: \"variant\",\n variant: input.variant,\n routeBudget,\n didConsumeRouteVariantBudget: false,\n };\n }\n\n if (existingVariantCount >= input.variant.budget.maxVariantsPerRoute) {\n return {\n kind: \"breakerFallback\",\n routeBudget,\n fallback: buildRouteVariantCeilingFallback(input.variant, existingVariantCount),\n };\n }\n\n return {\n kind: \"variant\",\n variant: input.variant,\n routeBudget: {\n routeId: routeBudget.routeId,\n variantCacheKeys: [\n ...routeBudget.variantCacheKeys.slice(0, variantKeyPosition.index),\n input.variant.cacheKey,\n ...routeBudget.variantCacheKeys.slice(variantKeyPosition.index),\n ],\n },\n didConsumeRouteVariantBudget: true,\n };\n}\n\nexport function buildCacheVariantWithRouteBudget(\n input: BuildCacheVariantWithRouteBudgetInput,\n): BuildCacheVariantWithRouteBudgetResult {\n const variantResult = buildCacheVariant({\n budget: input.budget,\n dimensions: input.dimensions,\n output: input.output,\n });\n\n if (variantResult.kind === \"breakerFallback\") {\n return {\n kind: \"breakerFallback\",\n routeBudget: input.routeBudget ? normalizeRouteBudget(input.routeBudget) : null,\n fallback: variantResult.fallback,\n };\n }\n\n return enforceCacheVariantRouteBudget({\n routeBudget: input.routeBudget,\n variant: variantResult.variant,\n });\n}\n\nfunction boundaryOutcomesMatch(expected: BoundaryOutcome, candidate: BoundaryOutcome): boolean {\n switch (expected.kind) {\n case \"error\":\n return candidate.kind === \"error\" && (expected.digest ?? \"\") === (candidate.digest ?? \"\");\n case \"forbidden\":\n return candidate.kind === \"forbidden\";\n case \"globalError\":\n return (\n candidate.kind === \"globalError\" && (expected.digest ?? \"\") === (candidate.digest ?? \"\")\n );\n case \"notFound\":\n return candidate.kind === \"notFound\";\n case \"redirect\":\n return (\n candidate.kind === \"redirect\" &&\n expected.status === candidate.status &&\n expected.location === candidate.location\n );\n case \"success\":\n return candidate.kind === \"success\";\n case \"unauthorized\":\n return candidate.kind === \"unauthorized\";\n case \"unknown\":\n return false;\n default:\n return assertNever(expected);\n }\n}\n\nexport function buildBoundaryOutcomeCompatibility(input: {\n candidate: BoundaryOutcome;\n expected: BoundaryOutcome;\n}): BoundaryOutcomeCompatibility {\n if (input.expected.kind === \"unknown\" || input.candidate.kind === \"unknown\") {\n return {\n kind: \"incompatible\",\n expected: input.expected,\n candidate: input.candidate,\n fallback: buildBreakerFallback(\"CP_BOUNDARY_OUTCOME_UNKNOWN\", {\n candidateKind: input.candidate.kind,\n expectedKind: input.expected.kind,\n }),\n };\n }\n\n if (boundaryOutcomesMatch(input.expected, input.candidate)) {\n return {\n kind: \"compatible\",\n outcome: input.candidate,\n reason: \"CP_BOUNDARY_OUTCOME_MATCH\",\n };\n }\n\n return {\n kind: \"incompatible\",\n expected: input.expected,\n candidate: input.candidate,\n fallback: buildBreakerFallback(\"CP_BOUNDARY_OUTCOME_MISMATCH\", {\n candidateKind: input.candidate.kind,\n expectedKind: input.expected.kind,\n }),\n };\n}\n\nfunction requestApiStatusRank(status: RenderRequestApiStatus): number {\n switch (status) {\n case \"notObserved\":\n return 0;\n case \"unknown\":\n return 1;\n case \"observed\":\n return 2;\n default:\n return assertNever(status);\n }\n}\n\nfunction normalizeRequestApiObservations(\n observations: readonly RenderRequestApiObservation[],\n): RenderRequestApiObservation[] {\n const byKind = new Map<RenderRequestApiKind, RenderRequestApiStatus>();\n for (const observation of observations) {\n const current = byKind.get(observation.kind);\n if (\n current === undefined ||\n requestApiStatusRank(observation.status) > requestApiStatusRank(current)\n ) {\n byKind.set(observation.kind, observation.status);\n }\n }\n\n return [...byKind.entries()]\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([kind, status]) => ({ kind, status }));\n}\n\nfunction cacheProofDowngradeTargetRank(target: CacheProofDowngradeTarget): number {\n switch (target) {\n case \"public\":\n return 0;\n case \"publicVariant\":\n return 1;\n case \"private\":\n return 2;\n case \"privateUncacheable\":\n return 3;\n case \"freshRender\":\n return 4;\n default:\n return assertNever(target);\n }\n}\n\nfunction maxCacheProofDowngradeTarget(\n current: CacheProofDowngradeTarget,\n candidate: CacheProofDowngradeTarget,\n): CacheProofDowngradeTarget {\n return cacheProofDowngradeTargetRank(candidate) > cacheProofDowngradeTargetRank(current)\n ? candidate\n : current;\n}\n\nfunction createDowngradeFallback(\n target: CacheProofDowngradeTarget,\n reasons: readonly CacheProofDowngradeReason[],\n): CacheProofBreakerFallback | null {\n switch (target) {\n case \"public\":\n case \"publicVariant\":\n case \"private\":\n return null;\n case \"privateUncacheable\":\n return buildBreakerFallback(\n \"CP_PRIVATE_DYNAMIC_DOWNGRADE\",\n {\n reasonCodes: reasons.map((reason) => reason.code),\n target,\n },\n \"privateUncacheable\",\n );\n case \"freshRender\":\n return buildBreakerFallback(\"CP_PRIVATE_DYNAMIC_DOWNGRADE\", {\n reasonCodes: reasons.map((reason) => reason.code),\n target,\n });\n default:\n return assertNever(target);\n }\n}\n\nfunction classifyObservedRequestApiDowngrade(\n kind: RenderRequestApiKind,\n): CacheProofDowngradeReason {\n switch (kind) {\n case \"connection\":\n return {\n code: \"CP_DOWNGRADE_DYNAMIC_REQUEST_API\",\n requestApi: \"connection\",\n target: \"freshRender\",\n };\n case \"cookies\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_REQUEST_API\",\n requestApi: \"cookies\",\n target: \"private\",\n };\n case \"draftMode\":\n return {\n code: \"CP_DOWNGRADE_DRAFT_MODE\",\n requestApi: \"draftMode\",\n target: \"privateUncacheable\",\n };\n case \"headers\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_REQUEST_API\",\n requestApi: \"headers\",\n target: \"private\",\n };\n case \"params\":\n return {\n code: \"CP_DOWNGRADE_PUBLIC_REQUEST_API\",\n requestApi: \"params\",\n target: \"publicVariant\",\n };\n case \"searchParams\":\n return {\n code: \"CP_DOWNGRADE_PUBLIC_REQUEST_API\",\n requestApi: \"searchParams\",\n target: \"publicVariant\",\n };\n default:\n return assertNever(kind);\n }\n}\n\nexport function classifyCacheVariantDimensionDowngrade(\n input: ClassifyCacheVariantDimensionDowngradeInput,\n): CacheProofDowngradeReason | null {\n switch (input.source) {\n case \"auth\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_DIMENSION\",\n inputClass: \"auth\",\n source: \"auth\",\n target: \"private\",\n };\n case \"cookie\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_DIMENSION\",\n inputClass: \"private\",\n source: \"cookie\",\n target: \"private\",\n };\n case \"draft-mode\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_DIMENSION\",\n inputClass: \"draft\",\n source: \"draft-mode\",\n target: \"privateUncacheable\",\n };\n case \"header\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_DIMENSION\",\n inputClass: \"private\",\n source: \"header\",\n target: \"private\",\n };\n case \"session\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_DIMENSION\",\n inputClass: \"session\",\n source: \"session\",\n target: \"private\",\n };\n case \"custom\":\n case \"interception\":\n case \"mounted-slots\":\n case \"params\":\n case \"route\":\n case \"search\":\n return null;\n default:\n return assertNever(input.source);\n }\n}\n\nexport function classifyRenderObservationDowngrade(\n input: ClassifyRenderObservationDowngradeInput,\n): CacheProofDowngradeClassification {\n const reasons: CacheProofDowngradeReason[] = [];\n let target: CacheProofDowngradeTarget = \"public\";\n\n switch (input.cacheability) {\n case \"public\":\n break;\n case \"private\": {\n const reason = {\n code: \"CP_DOWNGRADE_CACHEABILITY_PRIVATE\",\n target: \"private\",\n } satisfies CacheProofDowngradeReason;\n reasons.push(reason);\n target = maxCacheProofDowngradeTarget(target, reason.target);\n break;\n }\n case \"uncacheable\": {\n const reason = {\n code: \"CP_DOWNGRADE_CACHEABILITY_UNCACHEABLE\",\n target: \"privateUncacheable\",\n } satisfies CacheProofDowngradeReason;\n reasons.push(reason);\n target = maxCacheProofDowngradeTarget(target, reason.target);\n break;\n }\n case \"unknown\": {\n const reason = {\n code: \"CP_DOWNGRADE_CACHEABILITY_UNKNOWN\",\n target: \"freshRender\",\n } satisfies CacheProofDowngradeReason;\n reasons.push(reason);\n target = maxCacheProofDowngradeTarget(target, reason.target);\n break;\n }\n default:\n assertNever(input.cacheability);\n }\n\n if (input.completeness !== \"complete\") {\n const reason = {\n code: \"CP_DOWNGRADE_INCOMPLETE_OBSERVATION\",\n completeness: input.completeness,\n target: \"freshRender\",\n } satisfies CacheProofDowngradeReason;\n reasons.push(reason);\n target = maxCacheProofDowngradeTarget(target, reason.target);\n }\n\n if (input.dynamicFetches.length > 0) {\n const reason = {\n code: \"CP_DOWNGRADE_DYNAMIC_FETCH\",\n dynamicFetchCount: input.dynamicFetches.length,\n target: \"freshRender\",\n } satisfies CacheProofDowngradeReason;\n reasons.push(reason);\n target = maxCacheProofDowngradeTarget(target, reason.target);\n }\n\n const requestApis = normalizeRequestApiObservations(input.requestApis);\n for (const requestApi of requestApis) {\n if (requestApi.status === \"notObserved\") continue;\n const reason =\n requestApi.status === \"unknown\"\n ? ({\n code: \"CP_DOWNGRADE_UNKNOWN_REQUEST_API\",\n requestApi: requestApi.kind,\n target: \"freshRender\",\n } satisfies CacheProofDowngradeReason)\n : classifyObservedRequestApiDowngrade(requestApi.kind);\n reasons.push(reason);\n target = maxCacheProofDowngradeTarget(target, reason.target);\n }\n\n return {\n target,\n reasons,\n fallback: createDowngradeFallback(target, reasons),\n isPublicCacheCandidate: target === \"public\" || target === \"publicVariant\",\n };\n}\n\nexport function buildRenderRequestApiObservations(\n input: BuildRenderRequestApiObservationsInput,\n): RenderRequestApiObservation[] {\n const observedKinds = new Set(input.observed);\n const absentStatus: RenderRequestApiStatus =\n input.completeness === \"complete\" ? \"notObserved\" : \"unknown\";\n\n return ALL_RENDER_REQUEST_API_KINDS.map((kind) => ({\n kind,\n status: observedKinds.has(kind) ? \"observed\" : absentStatus,\n }));\n}\n\nexport function buildRenderObservation(input: BuildRenderObservationInput): RenderObservation {\n const requestApis = normalizeRequestApiObservations(input.requestApis);\n const dynamicFetches = sortedUniqueRedacted(input.dynamicFetches);\n\n return {\n schemaVersion: CACHE_PROOF_MODEL_SCHEMA_VERSION,\n output: input.output,\n completeness: input.completeness,\n boundaryOutcome: input.boundaryOutcome,\n requestApis,\n dynamicFetches,\n cacheTags: sortedUnique(input.cacheTags),\n pathTags: sortedUnique(input.pathTags),\n cacheability: input.cacheability,\n downgrade: classifyRenderObservationDowngrade({\n cacheability: input.cacheability,\n completeness: input.completeness,\n dynamicFetches,\n requestApis,\n }),\n };\n}\n\nexport function hasCompleteNegativeRequestApiProof(\n observation: RenderObservation,\n requiredApis: readonly RenderRequestApiKind[],\n): boolean {\n if (observation.completeness !== \"complete\") return false;\n\n const statuses = new Map<RenderRequestApiKind, RenderRequestApiStatus>();\n for (const requestApi of normalizeRequestApiObservations(observation.requestApis)) {\n statuses.set(requestApi.kind, requestApi.status);\n }\n\n for (const api of requiredApis) {\n if (statuses.get(api) !== \"notObserved\") return false;\n }\n return true;\n}\n\nfunction isStaticLayoutOutputScope(\n output: CacheProofOutputScope,\n): output is StaticLayoutCacheProofOutputScope {\n return output.kind === \"layout\";\n}\n\nfunction rejectStaticLayoutReuseProof(\n code: CacheProofRejectionCode,\n fields: CacheProofTraceFields,\n mode: CacheProofBreakerFallbackMode = \"renderFresh\",\n): BuildStaticLayoutReuseProofResult {\n return {\n kind: \"rejected\",\n fallback: buildBreakerFallback(code, fields, mode),\n };\n}\n\nfunction getRequestApiStatus(\n observations: readonly RenderRequestApiObservation[],\n kind: RenderRequestApiKind,\n): RenderRequestApiStatus | \"missing\" {\n let status: RenderRequestApiStatus | null = null;\n\n for (const requestApi of observations) {\n if (requestApi.kind !== kind) continue;\n if (status === null || requestApiStatusRank(requestApi.status) > requestApiStatusRank(status)) {\n status = requestApi.status;\n }\n }\n\n return status ?? \"missing\";\n}\n\nfunction createStaticLayoutDowngradeFallback(\n downgrade: CacheProofDowngradeClassification,\n): CacheProofBreakerFallback {\n const mode: CacheProofBreakerFallbackMode =\n downgrade.target === \"privateUncacheable\" ? \"privateUncacheable\" : \"renderFresh\";\n return buildBreakerFallback(\n \"CP_STATIC_LAYOUT_PRIVATE_DYNAMIC_DOWNGRADE\",\n {\n reasonCodes: downgrade.reasons.map((reason) => reason.code),\n target: downgrade.target,\n },\n mode,\n );\n}\n\nfunction createPrivateVariantDimensionFallback(\n dimension: CacheVariantDimension,\n): CacheProofBreakerFallback | null {\n const downgrade = classifyCacheVariantDimensionDowngrade({ source: dimension.source });\n if (!downgrade && dimension.privacy !== \"private\") {\n return null;\n }\n\n const target = downgrade?.target ?? \"private\";\n const mode: CacheProofBreakerFallbackMode =\n target === \"privateUncacheable\" ? \"privateUncacheable\" : \"renderFresh\";\n return buildBreakerFallback(\n \"CP_STATIC_LAYOUT_PRIVATE_VARIANT_DIMENSION\",\n {\n dimension: dimension.name,\n privacy: dimension.privacy,\n reasonCode: downgrade?.code ?? null,\n source: dimension.source,\n target,\n },\n mode,\n );\n}\n\nfunction outputFieldMismatch(\n candidate: StaticLayoutCacheProofOutputScope,\n observation: StaticLayoutCacheProofOutputScope,\n): \"layoutId\" | \"rootBoundaryId\" | \"routeId\" | null {\n if (candidate.layoutId !== observation.layoutId) return \"layoutId\";\n if (candidate.rootBoundaryId !== observation.rootBoundaryId) return \"rootBoundaryId\";\n if (candidate.routeId !== observation.routeId) return \"routeId\";\n return null;\n}\n\nexport function buildStaticLayoutReuseProof(\n input: BuildStaticLayoutReuseProofInput,\n): BuildStaticLayoutReuseProofResult {\n if (!isStaticLayoutOutputScope(input.currentOutput)) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_CURRENT_OUTPUT_KIND\", {\n currentOutputKind: input.currentOutput.kind,\n });\n }\n\n if (!isStaticLayoutOutputScope(input.candidateVariant.output)) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_CANDIDATE_OUTPUT_KIND\", {\n candidateOutputKind: input.candidateVariant.output.kind,\n });\n }\n\n if (!isStaticLayoutOutputScope(input.candidateObservation.output)) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_OBSERVATION_OUTPUT_KIND\", {\n observationOutputKind: input.candidateObservation.output.kind,\n });\n }\n\n const currentOutput = input.currentOutput;\n const candidateOutput = input.candidateVariant.output;\n const observationOutput = input.candidateObservation.output;\n const requestApis = normalizeRequestApiObservations(input.candidateObservation.requestApis);\n const candidateObservation = {\n ...input.candidateObservation,\n requestApis,\n downgrade: classifyRenderObservationDowngrade({\n cacheability: input.candidateObservation.cacheability,\n completeness: input.candidateObservation.completeness,\n dynamicFetches: input.candidateObservation.dynamicFetches,\n requestApis,\n }),\n } satisfies RenderObservation;\n const observedOutputMismatch = outputFieldMismatch(candidateOutput, observationOutput);\n if (observedOutputMismatch) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_OBSERVATION_OUTPUT_MISMATCH\", {\n candidateLayoutId: candidateOutput.layoutId,\n candidateRootBoundaryId: candidateOutput.rootBoundaryId,\n candidateRouteId: candidateOutput.routeId,\n field: observedOutputMismatch,\n observationLayoutId: observationOutput.layoutId,\n observationRootBoundaryId: observationOutput.rootBoundaryId,\n observationRouteId: observationOutput.routeId,\n });\n }\n\n if (currentOutput.layoutId !== candidateOutput.layoutId) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_ID_MISMATCH\", {\n candidateLayoutId: candidateOutput.layoutId,\n currentLayoutId: currentOutput.layoutId,\n });\n }\n\n if (currentOutput.rootBoundaryId === null || candidateOutput.rootBoundaryId === null) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_ROOT_BOUNDARY_UNKNOWN\", {\n candidateRootBoundaryId: candidateOutput.rootBoundaryId,\n currentRootBoundaryId: currentOutput.rootBoundaryId,\n });\n }\n\n if (currentOutput.rootBoundaryId !== candidateOutput.rootBoundaryId) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_ROOT_BOUNDARY_MISMATCH\", {\n candidateRootBoundaryId: candidateOutput.rootBoundaryId,\n currentRootBoundaryId: currentOutput.rootBoundaryId,\n });\n }\n\n const boundaryCompatibility = buildBoundaryOutcomeCompatibility({\n candidate: candidateObservation.boundaryOutcome,\n expected: { kind: \"success\" },\n });\n if (boundaryCompatibility.kind === \"incompatible\") {\n return {\n kind: \"rejected\",\n fallback: boundaryCompatibility.fallback,\n };\n }\n\n for (const dimension of input.candidateVariant.dimensions) {\n const fallback = createPrivateVariantDimensionFallback(dimension);\n if (fallback) {\n return {\n kind: \"rejected\",\n fallback,\n };\n }\n }\n\n if (!candidateObservation.downgrade.isPublicCacheCandidate) {\n return {\n kind: \"rejected\",\n fallback: createStaticLayoutDowngradeFallback(candidateObservation.downgrade),\n };\n }\n\n // The loop can use the shared readonly registry; the proof stores a detached evidence copy.\n const requiredNegativeRequestApis = ALL_RENDER_REQUEST_API_KINDS;\n for (const api of requiredNegativeRequestApis) {\n const status = getRequestApiStatus(candidateObservation.requestApis, api);\n if (status === \"notObserved\") continue;\n\n return rejectStaticLayoutReuseProof(\n status === \"missing\"\n ? \"CP_STATIC_LAYOUT_REQUEST_API_UNKNOWN\"\n : \"CP_STATIC_LAYOUT_REQUEST_API_OBSERVED\",\n {\n requestApi: api,\n status,\n },\n );\n }\n\n return {\n kind: \"proof\",\n proof: {\n authorizesRuntimeReuse: false,\n candidateOutput,\n code: \"CP_STATIC_LAYOUT_REUSE_PROVEN\",\n currentOutput,\n fields: {\n candidateRouteId: candidateOutput.routeId,\n currentRouteId: currentOutput.routeId,\n layoutId: currentOutput.layoutId,\n rootBoundaryId: currentOutput.rootBoundaryId,\n },\n observation: candidateObservation,\n requiredNegativeRequestApis: [...requiredNegativeRequestApis],\n reuseClass: \"static-layout\",\n variant: input.candidateVariant,\n },\n };\n}\n\nexport function createDisabledCacheProofDecision(\n input: CreateDisabledCacheProofDecisionInput,\n): DisabledCacheProofDecision {\n return {\n kind: \"disabled\",\n canReuse: false,\n variant: input.variant,\n observation: input.observation,\n ...(input.staticLayoutProof ? { staticLayoutProof: input.staticLayoutProof } : {}),\n fallback: buildBreakerFallback(\"CP_MODEL_DISABLED\"),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cache-proof.js","names":[],"sources":["../../src/server/cache-proof.ts"],"sourcesContent":["import type { AppRouteSemanticIds } from \"../routing/app-route-graph.js\";\nimport { fnv1a64 } from \"../utils/hash.js\";\nimport { findSortedStringPosition } from \"../utils/sorted-array.js\";\nimport {\n evaluateArtifactCompatibility,\n type ArtifactCompatibilityEnvelope,\n type ArtifactCompatibilityEvaluationOptions,\n} from \"./artifact-compatibility.js\";\n\nexport const CACHE_PROOF_MODEL_SCHEMA_VERSION = 1;\nexport type CacheProofModelSchemaVersion = 1;\n\nexport type CacheProofRejectionCode =\n | \"CP_CACHE_ENTRY_PROOF_MISSING\"\n | \"CP_MODEL_DISABLED\"\n | \"CP_ARTIFACT_COMPATIBILITY_INCOMPATIBLE\"\n | \"CP_ARTIFACT_COMPATIBILITY_UNKNOWN\"\n | \"CP_DIMENSION_COUNT_EXCEEDED\"\n | \"CP_DIMENSION_NAME_MISSING\"\n | \"CP_DIMENSION_NAME_TOO_LONG\"\n | \"CP_DIMENSION_VALUE_COUNT_EXCEEDED\"\n | \"CP_DIMENSION_VALUE_TOO_LONG\"\n | \"CP_DIMENSION_VALUES_MISSING\"\n | \"CP_ENCODED_VARIANT_TOO_LONG\"\n | \"CP_INVALID_VARIANT_BUDGET\"\n | \"CP_ROUTE_VARIANT_BUDGET_ROUTE_MISMATCH\"\n | \"CP_ROUTE_VARIANT_CEILING_EXCEEDED\"\n | \"CP_UNSAFE_PUBLIC_DIMENSION\"\n | \"CP_BOUNDARY_OUTCOME_MISMATCH\"\n | \"CP_BOUNDARY_OUTCOME_UNKNOWN\"\n | \"CP_PRIVATE_DYNAMIC_DOWNGRADE\"\n | \"CP_STATIC_LAYOUT_CANDIDATE_OUTPUT_KIND\"\n | \"CP_STATIC_LAYOUT_CURRENT_OUTPUT_KIND\"\n | \"CP_STATIC_LAYOUT_ID_MISMATCH\"\n | \"CP_STATIC_LAYOUT_OBSERVATION_OUTPUT_KIND\"\n | \"CP_STATIC_LAYOUT_OBSERVATION_OUTPUT_MISMATCH\"\n | \"CP_STATIC_LAYOUT_PRIVATE_DYNAMIC_DOWNGRADE\"\n | \"CP_STATIC_LAYOUT_REQUEST_API_OBSERVED\"\n | \"CP_STATIC_LAYOUT_REQUEST_API_UNKNOWN\"\n | \"CP_STATIC_LAYOUT_ROOT_BOUNDARY_MISMATCH\"\n | \"CP_STATIC_LAYOUT_ROOT_BOUNDARY_UNKNOWN\"\n | \"CP_STATIC_LAYOUT_VARIANT_DIMENSION_UNPROVEN\";\n\nexport type CacheProofAcceptanceCode = \"CP_STATIC_LAYOUT_REUSE_PROVEN\";\n\nexport type CacheProofTraceCode = CacheProofAcceptanceCode | CacheProofRejectionCode;\n\nexport type CacheProofTraceFieldValue = string | number | boolean | null | readonly string[];\n\nexport type CacheProofTraceFields = Readonly<Record<string, CacheProofTraceFieldValue>>;\n\nexport type CacheProofBreakerFallbackMode = \"renderFresh\" | \"privateUncacheable\";\nexport type CacheProofFallbackScope = \"affectedOutput\" | \"route\";\n\nexport type CacheProofBreakerFallback = Readonly<{\n kind: \"breakerFallback\";\n code: CacheProofRejectionCode;\n mode: CacheProofBreakerFallbackMode;\n scope: CacheProofFallbackScope;\n fields: CacheProofTraceFields;\n}>;\n\nexport type CacheVariantBudget = Readonly<{\n maxDimensionCount: number;\n maxDimensionNameLength: number;\n maxDimensionValueLength: number;\n maxEncodedLength: number;\n maxValuesPerDimension: number;\n maxVariantsPerRoute: number;\n}>;\n\nexport const DEFAULT_CACHE_VARIANT_BUDGET = {\n maxDimensionCount: 8,\n maxDimensionNameLength: 64,\n maxDimensionValueLength: 256,\n maxEncodedLength: 1024,\n maxValuesPerDimension: 8,\n maxVariantsPerRoute: 64,\n} satisfies CacheVariantBudget;\n\nexport type CacheVariantDimensionSource =\n | \"auth\"\n | \"cookie\"\n | \"custom\"\n | \"draft-mode\"\n | \"header\"\n | \"interception\"\n | \"mounted-slots\"\n | \"params\"\n | \"route\"\n | \"search\"\n | \"session\";\n\nexport type CacheVariantDimensionPrivacy = \"internal\" | \"private\" | \"public\";\n\nexport type CacheVariantDimensionInput = Readonly<{\n name: string;\n privacy: CacheVariantDimensionPrivacy;\n source: CacheVariantDimensionSource;\n values: readonly string[];\n}>;\n\nexport type CacheVariantDimension = Readonly<{\n encoded: string;\n name: string;\n privacy: CacheVariantDimensionPrivacy;\n source: CacheVariantDimensionSource;\n valueCount: number;\n valueHashes: readonly string[];\n}>;\n\nexport type CacheProofOutputScope =\n | Readonly<{\n kind: \"app-html\";\n renderEpoch: string | null;\n rootBoundaryId: string | null;\n routeId: string;\n }>\n | Readonly<{\n kind: \"app-rsc\";\n mountedSlotsFingerprint: string | null;\n renderEpoch: string | null;\n rootBoundaryId: string | null;\n routeId: string;\n }>\n | Readonly<{\n kind: \"layout\";\n layoutId: string;\n rootBoundaryId: string | null;\n routeId: string;\n }>\n | Readonly<{\n kind: \"page\";\n pageId: string;\n rootBoundaryId: string | null;\n routeId: string;\n }>\n | Readonly<{\n kind: \"route-handler\";\n routeHandlerId: string;\n routeId: string;\n }>\n | Readonly<{\n kind: \"slot\";\n rootBoundaryId: string | null;\n routeId: string;\n slotId: string;\n }>\n | Readonly<{\n kind: \"template\";\n rootBoundaryId: string | null;\n routeId: string;\n templateId: string;\n }>;\n\nexport type StaticLayoutCacheProofOutputScope = Extract<CacheProofOutputScope, { kind: \"layout\" }>;\n\nexport type CacheVariant = Readonly<{\n budget: CacheVariantBudget;\n cacheKey: string;\n dimensions: readonly CacheVariantDimension[];\n encodedLength: number;\n output: CacheProofOutputScope;\n schemaVersion: CacheProofModelSchemaVersion;\n}>;\n\nexport type BuildCacheVariantInput = Readonly<{\n budget: CacheVariantBudget;\n dimensions: readonly CacheVariantDimensionInput[];\n output: CacheProofOutputScope;\n}>;\n\nexport type BuildCacheVariantResult =\n | Readonly<{ kind: \"variant\"; variant: CacheVariant }>\n | Readonly<{ kind: \"breakerFallback\"; fallback: CacheProofBreakerFallback }>;\n\nexport type CacheVariantRouteBudget = Readonly<{\n routeId: string;\n variantCacheKeys: readonly string[];\n}>;\n\nexport type CacheVariantRouteBudgetAdmission =\n | Readonly<{\n didConsumeRouteVariantBudget: boolean;\n kind: \"variant\";\n routeBudget: CacheVariantRouteBudget;\n variant: CacheVariant;\n }>\n | Readonly<{\n fallback: CacheProofBreakerFallback;\n kind: \"breakerFallback\";\n routeBudget: CacheVariantRouteBudget | null;\n }>;\n\nexport type BuildCacheVariantWithRouteBudgetInput = BuildCacheVariantInput &\n Readonly<{\n routeBudget: CacheVariantRouteBudget | null;\n }>;\n\nexport type BuildCacheVariantWithRouteBudgetResult = CacheVariantRouteBudgetAdmission;\n\nexport type AppRouteCacheProofGraphScopeInput = Readonly<{\n ids: AppRouteSemanticIds;\n}>;\n\nexport type AppRouteCacheProofGraphScope = Readonly<{\n layoutIds: readonly string[];\n pageId: string | null;\n routeHandlerId: string | null;\n routeId: string;\n slotIds: readonly string[];\n templateIds: readonly string[];\n}>;\n\nexport type BoundaryOutcome =\n | Readonly<{ kind: \"error\"; digest?: string }>\n | Readonly<{ kind: \"forbidden\" }>\n | Readonly<{ kind: \"globalError\"; digest?: string }>\n | Readonly<{ kind: \"notFound\" }>\n | Readonly<{ kind: \"redirect\"; location: string; status: number }>\n | Readonly<{ kind: \"success\" }>\n | Readonly<{ kind: \"unauthorized\" }>\n | Readonly<{ kind: \"unknown\" }>;\n\nexport type BoundaryOutcomeCompatibility =\n | Readonly<{\n kind: \"compatible\";\n outcome: BoundaryOutcome;\n reason: \"CP_BOUNDARY_OUTCOME_MATCH\";\n }>\n | Readonly<{\n candidate: BoundaryOutcome;\n expected: BoundaryOutcome;\n fallback: CacheProofBreakerFallback;\n kind: \"incompatible\";\n }>;\n\nexport type RenderObservationCompleteness = \"complete\" | \"partial\" | \"unknown\";\nexport type RenderCacheability = \"private\" | \"public\" | \"uncacheable\" | \"unknown\";\nexport type RenderRequestApiKind =\n | \"connection\"\n | \"cookies\"\n | \"draftMode\"\n | \"headers\"\n | \"params\"\n | \"searchParams\";\nexport type RenderRequestApiStatus = \"notObserved\" | \"observed\" | \"unknown\";\n\nexport const ALL_RENDER_REQUEST_API_KINDS: readonly RenderRequestApiKind[] = [\n \"connection\",\n \"cookies\",\n \"draftMode\",\n \"headers\",\n \"params\",\n \"searchParams\",\n];\n\nexport type RenderRequestApiObservation = Readonly<{\n kind: RenderRequestApiKind;\n status: RenderRequestApiStatus;\n}>;\n\nexport type CacheProofDowngradeTarget =\n | \"freshRender\"\n | \"private\"\n | \"privateUncacheable\"\n | \"public\"\n | \"publicVariant\";\n\nexport type CacheProofDowngradeReason =\n | Readonly<{\n code: \"CP_DOWNGRADE_CACHEABILITY_PRIVATE\";\n target: \"private\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_CACHEABILITY_UNCACHEABLE\";\n target: \"privateUncacheable\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_CACHEABILITY_UNKNOWN\";\n target: \"freshRender\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_DYNAMIC_FETCH\";\n dynamicFetchCount: number;\n target: \"freshRender\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_DYNAMIC_REQUEST_API\";\n requestApi: \"connection\";\n target: \"freshRender\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_DRAFT_MODE\";\n requestApi: \"draftMode\";\n target: \"privateUncacheable\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_INCOMPLETE_OBSERVATION\";\n completeness: Exclude<RenderObservationCompleteness, \"complete\">;\n target: \"freshRender\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_PRIVATE_DIMENSION\";\n inputClass: \"auth\" | \"draft\" | \"private\" | \"session\";\n source: \"auth\" | \"cookie\" | \"draft-mode\" | \"header\" | \"session\";\n target: \"private\" | \"privateUncacheable\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_PRIVATE_REQUEST_API\";\n requestApi: \"cookies\" | \"headers\";\n target: \"private\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_PUBLIC_REQUEST_API\";\n requestApi: \"params\" | \"searchParams\";\n target: \"publicVariant\";\n }>\n | Readonly<{\n code: \"CP_DOWNGRADE_UNKNOWN_REQUEST_API\";\n requestApi: RenderRequestApiKind;\n target: \"freshRender\";\n }>;\n\nexport type CacheProofDowngradeClassification = Readonly<{\n fallback: CacheProofBreakerFallback | null;\n isPublicCacheCandidate: boolean;\n reasons: readonly CacheProofDowngradeReason[];\n target: CacheProofDowngradeTarget;\n}>;\n\nexport type ClassifyRenderObservationDowngradeInput = Readonly<{\n cacheability: RenderCacheability;\n completeness: RenderObservationCompleteness;\n dynamicFetches: readonly string[];\n requestApis: readonly RenderRequestApiObservation[];\n}>;\n\nexport type ClassifyCacheVariantDimensionDowngradeInput = Pick<\n CacheVariantDimensionInput,\n \"source\"\n>;\n\nexport type RenderObservation = Readonly<{\n boundaryOutcome: BoundaryOutcome;\n cacheTags: readonly string[];\n cacheability: RenderCacheability;\n completeness: RenderObservationCompleteness;\n downgrade: CacheProofDowngradeClassification;\n dynamicFetches: readonly string[];\n output: CacheProofOutputScope;\n pathTags: readonly string[];\n requestApis: readonly RenderRequestApiObservation[];\n schemaVersion: CacheProofModelSchemaVersion;\n}>;\n\nexport type StaticLayoutReuseProof = Readonly<{\n authorizesRuntimeReuse: true;\n candidateOutput: StaticLayoutCacheProofOutputScope;\n code: \"CP_STATIC_LAYOUT_REUSE_PROVEN\";\n currentOutput: StaticLayoutCacheProofOutputScope;\n fields: CacheProofTraceFields;\n observation: RenderObservation;\n requiredNegativeRequestApis: readonly RenderRequestApiKind[];\n reuseClass: \"static-layout\";\n variant: CacheVariant;\n}>;\n\nexport type StaticLayoutArtifactReuseProof = StaticLayoutReuseProof &\n Readonly<{\n candidateArtifactCompatibility: ArtifactCompatibilityEnvelope;\n }>;\n\nexport type BuildStaticLayoutReuseProofInput = Readonly<{\n candidateObservation: RenderObservation;\n candidateVariant: CacheVariant;\n currentOutput: CacheProofOutputScope;\n}>;\n\nexport type BuildStaticLayoutReuseProofResult =\n | Readonly<{ kind: \"proof\"; proof: StaticLayoutReuseProof }>\n | Readonly<{ kind: \"rejected\"; fallback: CacheProofBreakerFallback }>;\n\nexport type CacheProofHotPathMetric = Readonly<{\n code: CacheProofTraceCode;\n fields: CacheProofTraceFields;\n name: \"vinext.cache.static_layout_artifact_reuse\";\n outcome: \"fallback\" | \"reuse\";\n}>;\n\nexport type StaticLayoutArtifactReuseDecision =\n | Readonly<{\n canReuse: true;\n kind: \"reuse\";\n metric: CacheProofHotPathMetric;\n proof: StaticLayoutArtifactReuseProof;\n }>\n | Readonly<{\n canReuse: false;\n fallback: CacheProofBreakerFallback;\n kind: \"fallback\";\n metric: CacheProofHotPathMetric;\n }>;\n\nexport type CacheEntryReuseDecision =\n | Readonly<{\n canReuse: true;\n code: CacheProofAcceptanceCode;\n kind: \"reuse\";\n reuseClass: StaticLayoutReuseProof[\"reuseClass\"];\n }>\n | Readonly<{\n canReuse: false;\n code: CacheProofRejectionCode;\n kind: \"reject\";\n mode: CacheProofBreakerFallbackMode;\n scope: CacheProofFallbackScope;\n }>;\n\nexport type CacheEntryReuseProof = Readonly<{\n decision: CacheEntryReuseDecision | null;\n kind: \"runtime-cache-entry\";\n}>;\n\nexport type CreateStaticLayoutArtifactReuseDecisionInput = Readonly<{\n candidateArtifactCompatibility: ArtifactCompatibilityEnvelope;\n candidateObservation: RenderObservation;\n candidateVariant: BuildCacheVariantWithRouteBudgetResult;\n currentArtifactCompatibility: ArtifactCompatibilityEnvelope;\n currentOutput: CacheProofOutputScope;\n}> &\n ArtifactCompatibilityEvaluationOptions;\n\nexport type BuildRenderObservationInput = Readonly<{\n boundaryOutcome: BoundaryOutcome;\n cacheTags: readonly string[];\n cacheability: RenderCacheability;\n completeness: RenderObservationCompleteness;\n dynamicFetches: readonly string[];\n output: CacheProofOutputScope;\n pathTags: readonly string[];\n requestApis: readonly RenderRequestApiObservation[];\n}>;\n\nexport type BuildRenderRequestApiObservationsInput = Readonly<{\n completeness: RenderObservationCompleteness;\n observed: readonly RenderRequestApiKind[];\n}>;\n\nexport type DisabledCacheProofDecision = Readonly<{\n canReuse: false;\n fallback: CacheProofBreakerFallback;\n kind: \"disabled\";\n observation: RenderObservation;\n staticLayoutProof?: StaticLayoutReuseProof;\n variant: CacheVariant;\n}>;\n\nexport type CreateDisabledCacheProofDecisionInput = Readonly<{\n observation: RenderObservation;\n staticLayoutProof?: StaticLayoutReuseProof;\n variant: CacheVariant;\n}>;\n\nconst PUBLIC_UNSAFE_DIMENSION_SOURCES: ReadonlySet<CacheVariantDimensionSource> = new Set([\n \"auth\",\n \"cookie\",\n \"draft-mode\",\n \"header\",\n \"session\",\n]);\n\ntype CacheVariantDimensionAccumulator = {\n name: string;\n privacy: CacheVariantDimensionPrivacy;\n source: CacheVariantDimensionSource;\n values: string[];\n};\n\ntype DimensionAccumulatorByName = Map<string, CacheVariantDimensionAccumulator>;\ntype DimensionAccumulatorByPrivacy = Map<CacheVariantDimensionPrivacy, DimensionAccumulatorByName>;\ntype DimensionAccumulatorBySource = Map<CacheVariantDimensionSource, DimensionAccumulatorByPrivacy>;\n\nfunction buildBreakerFallback(\n code: CacheProofRejectionCode,\n fields: CacheProofTraceFields = {},\n mode: CacheProofBreakerFallbackMode = \"renderFresh\",\n scope: CacheProofFallbackScope = \"affectedOutput\",\n): CacheProofBreakerFallback {\n return {\n kind: \"breakerFallback\",\n code,\n mode,\n scope,\n fields,\n };\n}\n\nfunction sortedUnique(values: readonly string[]): string[] {\n return [...new Set(values)].sort();\n}\n\nfunction normalizeDimensionName(name: string): string {\n return name.trim().toLowerCase();\n}\n\nfunction redactValue(value: string): string {\n return `h:${fnv1a64(value)}`;\n}\n\nfunction sortedUniqueRedacted(values: readonly string[]): string[] {\n return sortedUnique(sortedUnique(values).map(redactValue));\n}\n\nfunction encodeParts(parts: readonly unknown[]): string {\n return JSON.stringify(parts);\n}\n\nfunction compareDimensions(a: CacheVariantDimension, b: CacheVariantDimension): number {\n return (\n a.source.localeCompare(b.source) ||\n a.name.localeCompare(b.name) ||\n a.privacy.localeCompare(b.privacy)\n );\n}\n\nfunction encodeNullable(value: string | null): string | null {\n return value;\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`Unhandled cache proof variant: ${String(value)}`);\n}\n\nfunction encodeOutputScope(output: CacheProofOutputScope): string {\n switch (output.kind) {\n case \"app-html\":\n return encodeParts([\n output.kind,\n output.routeId,\n encodeNullable(output.rootBoundaryId),\n encodeNullable(output.renderEpoch),\n ]);\n case \"app-rsc\":\n return encodeParts([\n output.kind,\n output.routeId,\n encodeNullable(output.rootBoundaryId),\n encodeNullable(output.renderEpoch),\n encodeNullable(output.mountedSlotsFingerprint),\n ]);\n case \"layout\":\n return encodeParts([\n output.kind,\n output.routeId,\n output.layoutId,\n encodeNullable(output.rootBoundaryId),\n ]);\n case \"page\":\n return encodeParts([\n output.kind,\n output.routeId,\n output.pageId,\n encodeNullable(output.rootBoundaryId),\n ]);\n case \"route-handler\":\n return encodeParts([output.kind, output.routeId, output.routeHandlerId]);\n case \"slot\":\n return encodeParts([\n output.kind,\n output.routeId,\n output.slotId,\n encodeNullable(output.rootBoundaryId),\n ]);\n case \"template\":\n return encodeParts([\n output.kind,\n output.routeId,\n output.templateId,\n encodeNullable(output.rootBoundaryId),\n ]);\n default:\n return assertNever(output);\n }\n}\n\nfunction validateBudgetNumber(name: string, value: number): CacheProofBreakerFallback | null {\n if (Number.isInteger(value) && value >= 0) return null;\n return buildBreakerFallback(\"CP_INVALID_VARIANT_BUDGET\", {\n budgetField: name,\n });\n}\n\nfunction validateBudget(budget: CacheVariantBudget): CacheProofBreakerFallback | null {\n return (\n validateBudgetNumber(\"maxDimensionCount\", budget.maxDimensionCount) ??\n validateBudgetNumber(\"maxDimensionNameLength\", budget.maxDimensionNameLength) ??\n validateBudgetNumber(\"maxDimensionValueLength\", budget.maxDimensionValueLength) ??\n validateBudgetNumber(\"maxEncodedLength\", budget.maxEncodedLength) ??\n validateBudgetNumber(\"maxValuesPerDimension\", budget.maxValuesPerDimension) ??\n validateBudgetNumber(\"maxVariantsPerRoute\", budget.maxVariantsPerRoute)\n );\n}\n\nfunction buildDimension(\n input: CacheVariantDimensionInput,\n budget: CacheVariantBudget,\n): CacheVariantDimension | CacheProofBreakerFallback {\n const name = normalizeDimensionName(input.name);\n if (name.length === 0) {\n return buildBreakerFallback(\"CP_DIMENSION_NAME_MISSING\", {\n source: input.source,\n });\n }\n if (name.length > budget.maxDimensionNameLength) {\n return buildBreakerFallback(\"CP_DIMENSION_NAME_TOO_LONG\", {\n maxLength: budget.maxDimensionNameLength,\n nameHash: redactValue(name),\n source: input.source,\n });\n }\n if (input.privacy === \"public\" && PUBLIC_UNSAFE_DIMENSION_SOURCES.has(input.source)) {\n return buildBreakerFallback(\n \"CP_UNSAFE_PUBLIC_DIMENSION\",\n {\n name,\n source: input.source,\n },\n \"privateUncacheable\",\n );\n }\n\n const values = sortedUnique(input.values);\n if (values.length === 0) {\n return buildBreakerFallback(\"CP_DIMENSION_VALUES_MISSING\", {\n name,\n source: input.source,\n });\n }\n if (values.length > budget.maxValuesPerDimension) {\n return buildBreakerFallback(\"CP_DIMENSION_VALUE_COUNT_EXCEEDED\", {\n maxValues: budget.maxValuesPerDimension,\n name,\n source: input.source,\n valueCount: values.length,\n });\n }\n for (const value of values) {\n if (value.length > budget.maxDimensionValueLength) {\n return buildBreakerFallback(\"CP_DIMENSION_VALUE_TOO_LONG\", {\n maxLength: budget.maxDimensionValueLength,\n name,\n source: input.source,\n valueHash: redactValue(value),\n });\n }\n }\n\n const valueHashes = values.map(redactValue);\n const encoded = encodeParts([input.source, input.privacy, name, valueHashes]);\n\n return {\n encoded,\n name,\n privacy: input.privacy,\n source: input.source,\n valueCount: valueHashes.length,\n valueHashes,\n };\n}\n\nfunction isCacheProofBreakerFallback(\n value: CacheVariantDimension | CacheProofBreakerFallback,\n): value is CacheProofBreakerFallback {\n return \"code\" in value;\n}\n\nfunction getDimensionBucket(\n bySource: DimensionAccumulatorBySource,\n source: CacheVariantDimensionSource,\n privacy: CacheVariantDimensionPrivacy,\n): DimensionAccumulatorByName {\n const existingByPrivacy = bySource.get(source);\n const byPrivacy = existingByPrivacy ?? new Map();\n if (!existingByPrivacy) {\n bySource.set(source, byPrivacy);\n }\n\n const existingByName = byPrivacy.get(privacy);\n const byName = existingByName ?? new Map();\n if (!existingByName) {\n byPrivacy.set(privacy, byName);\n }\n\n return byName;\n}\n\nfunction mergeDimensionInputs(\n dimensions: readonly CacheVariantDimensionInput[],\n): CacheVariantDimensionInput[] {\n const bySource: DimensionAccumulatorBySource = new Map();\n const orderedDimensions: CacheVariantDimensionAccumulator[] = [];\n\n for (const dimension of dimensions) {\n const name = normalizeDimensionName(dimension.name);\n const bucket = getDimensionBucket(bySource, dimension.source, dimension.privacy);\n const existing = bucket.get(name);\n if (existing) {\n existing.values.push(...dimension.values);\n continue;\n }\n const accumulator = {\n name,\n privacy: dimension.privacy,\n source: dimension.source,\n values: [...dimension.values],\n };\n bucket.set(name, accumulator);\n orderedDimensions.push(accumulator);\n }\n\n return orderedDimensions;\n}\n\nexport function createAppRouteCacheProofGraphScope(\n route: AppRouteCacheProofGraphScopeInput,\n): AppRouteCacheProofGraphScope {\n return {\n routeId: route.ids.route,\n pageId: route.ids.page,\n routeHandlerId: route.ids.routeHandler,\n layoutIds: [...route.ids.layouts],\n templateIds: [...route.ids.templates],\n slotIds: sortedUnique(Object.values(route.ids.slots)),\n };\n}\n\nexport function buildCacheVariant(input: BuildCacheVariantInput): BuildCacheVariantResult {\n const budgetFallback = validateBudget(input.budget);\n if (budgetFallback) {\n return {\n kind: \"breakerFallback\",\n fallback: budgetFallback,\n };\n }\n const dimensionInputs = mergeDimensionInputs(input.dimensions);\n if (dimensionInputs.length > input.budget.maxDimensionCount) {\n return {\n kind: \"breakerFallback\",\n fallback: buildBreakerFallback(\"CP_DIMENSION_COUNT_EXCEEDED\", {\n dimensionCount: dimensionInputs.length,\n maxDimensionCount: input.budget.maxDimensionCount,\n routeId: input.output.routeId,\n }),\n };\n }\n\n const dimensions: CacheVariantDimension[] = [];\n for (const dimensionInput of dimensionInputs) {\n const dimension = buildDimension(dimensionInput, input.budget);\n if (isCacheProofBreakerFallback(dimension)) {\n return {\n kind: \"breakerFallback\",\n fallback: dimension,\n };\n }\n dimensions.push(dimension);\n }\n dimensions.sort(compareDimensions);\n\n const encoded = [\n `schema:${CACHE_PROOF_MODEL_SCHEMA_VERSION}`,\n encodeOutputScope(input.output),\n ...dimensions.map((dimension) => dimension.encoded),\n ].join(\"|\");\n\n if (encoded.length > input.budget.maxEncodedLength) {\n return {\n kind: \"breakerFallback\",\n fallback: buildBreakerFallback(\"CP_ENCODED_VARIANT_TOO_LONG\", {\n encodedHash: redactValue(encoded),\n encodedLength: encoded.length,\n maxEncodedLength: input.budget.maxEncodedLength,\n routeId: input.output.routeId,\n }),\n };\n }\n\n return {\n kind: \"variant\",\n variant: {\n schemaVersion: CACHE_PROOF_MODEL_SCHEMA_VERSION,\n cacheKey: `cp${CACHE_PROOF_MODEL_SCHEMA_VERSION}:${fnv1a64(encoded)}`,\n output: input.output,\n dimensions,\n encodedLength: encoded.length,\n budget: { ...input.budget },\n },\n };\n}\n\nfunction normalizeRouteBudget(input: CacheVariantRouteBudget): CacheVariantRouteBudget {\n return {\n routeId: input.routeId,\n variantCacheKeys: sortedUnique(input.variantCacheKeys),\n };\n}\n\nfunction buildRouteVariantCeilingFallback(\n variant: CacheVariant,\n existingVariantCount: number,\n): CacheProofBreakerFallback {\n return buildBreakerFallback(\n \"CP_ROUTE_VARIANT_CEILING_EXCEEDED\",\n {\n existingVariantCount,\n maxVariantsPerRoute: variant.budget.maxVariantsPerRoute,\n routeId: variant.output.routeId,\n },\n \"privateUncacheable\",\n \"route\",\n );\n}\n\nexport function enforceCacheVariantRouteBudget(input: {\n routeBudget: CacheVariantRouteBudget | null;\n variant: CacheVariant;\n}): CacheVariantRouteBudgetAdmission {\n if (input.routeBudget && input.routeBudget.routeId !== input.variant.output.routeId) {\n return {\n kind: \"breakerFallback\",\n routeBudget: normalizeRouteBudget(input.routeBudget),\n fallback: buildBreakerFallback(\n \"CP_ROUTE_VARIANT_BUDGET_ROUTE_MISMATCH\",\n {\n budgetRouteId: input.routeBudget.routeId,\n routeId: input.variant.output.routeId,\n },\n \"privateUncacheable\",\n \"route\",\n ),\n };\n }\n\n const routeBudget = normalizeRouteBudget(\n input.routeBudget ?? {\n routeId: input.variant.output.routeId,\n variantCacheKeys: [],\n },\n );\n const existingVariantCount = routeBudget.variantCacheKeys.length;\n const variantKeyPosition = findSortedStringPosition(\n routeBudget.variantCacheKeys,\n input.variant.cacheKey,\n );\n\n if (existingVariantCount > input.variant.budget.maxVariantsPerRoute) {\n return {\n kind: \"breakerFallback\",\n routeBudget,\n fallback: buildRouteVariantCeilingFallback(input.variant, existingVariantCount),\n };\n }\n\n if (variantKeyPosition.found) {\n return {\n kind: \"variant\",\n variant: input.variant,\n routeBudget,\n didConsumeRouteVariantBudget: false,\n };\n }\n\n if (existingVariantCount >= input.variant.budget.maxVariantsPerRoute) {\n return {\n kind: \"breakerFallback\",\n routeBudget,\n fallback: buildRouteVariantCeilingFallback(input.variant, existingVariantCount),\n };\n }\n\n return {\n kind: \"variant\",\n variant: input.variant,\n routeBudget: {\n routeId: routeBudget.routeId,\n variantCacheKeys: [\n ...routeBudget.variantCacheKeys.slice(0, variantKeyPosition.index),\n input.variant.cacheKey,\n ...routeBudget.variantCacheKeys.slice(variantKeyPosition.index),\n ],\n },\n didConsumeRouteVariantBudget: true,\n };\n}\n\nexport function buildCacheVariantWithRouteBudget(\n input: BuildCacheVariantWithRouteBudgetInput,\n): BuildCacheVariantWithRouteBudgetResult {\n const variantResult = buildCacheVariant({\n budget: input.budget,\n dimensions: input.dimensions,\n output: input.output,\n });\n\n if (variantResult.kind === \"breakerFallback\") {\n return {\n kind: \"breakerFallback\",\n routeBudget: input.routeBudget ? normalizeRouteBudget(input.routeBudget) : null,\n fallback: variantResult.fallback,\n };\n }\n\n return enforceCacheVariantRouteBudget({\n routeBudget: input.routeBudget,\n variant: variantResult.variant,\n });\n}\n\nfunction boundaryOutcomesMatch(expected: BoundaryOutcome, candidate: BoundaryOutcome): boolean {\n switch (expected.kind) {\n case \"error\":\n return candidate.kind === \"error\" && (expected.digest ?? \"\") === (candidate.digest ?? \"\");\n case \"forbidden\":\n return candidate.kind === \"forbidden\";\n case \"globalError\":\n return (\n candidate.kind === \"globalError\" && (expected.digest ?? \"\") === (candidate.digest ?? \"\")\n );\n case \"notFound\":\n return candidate.kind === \"notFound\";\n case \"redirect\":\n return (\n candidate.kind === \"redirect\" &&\n expected.status === candidate.status &&\n expected.location === candidate.location\n );\n case \"success\":\n return candidate.kind === \"success\";\n case \"unauthorized\":\n return candidate.kind === \"unauthorized\";\n case \"unknown\":\n return false;\n default:\n return assertNever(expected);\n }\n}\n\nexport function buildBoundaryOutcomeCompatibility(input: {\n candidate: BoundaryOutcome;\n expected: BoundaryOutcome;\n}): BoundaryOutcomeCompatibility {\n if (input.expected.kind === \"unknown\" || input.candidate.kind === \"unknown\") {\n return {\n kind: \"incompatible\",\n expected: input.expected,\n candidate: input.candidate,\n fallback: buildBreakerFallback(\"CP_BOUNDARY_OUTCOME_UNKNOWN\", {\n candidateKind: input.candidate.kind,\n expectedKind: input.expected.kind,\n }),\n };\n }\n\n if (boundaryOutcomesMatch(input.expected, input.candidate)) {\n return {\n kind: \"compatible\",\n outcome: input.candidate,\n reason: \"CP_BOUNDARY_OUTCOME_MATCH\",\n };\n }\n\n return {\n kind: \"incompatible\",\n expected: input.expected,\n candidate: input.candidate,\n fallback: buildBreakerFallback(\"CP_BOUNDARY_OUTCOME_MISMATCH\", {\n candidateKind: input.candidate.kind,\n expectedKind: input.expected.kind,\n }),\n };\n}\n\nfunction requestApiStatusRank(status: RenderRequestApiStatus): number {\n switch (status) {\n case \"notObserved\":\n return 0;\n case \"unknown\":\n return 1;\n case \"observed\":\n return 2;\n default:\n return assertNever(status);\n }\n}\n\nfunction normalizeRequestApiObservations(\n observations: readonly RenderRequestApiObservation[],\n): RenderRequestApiObservation[] {\n const byKind = new Map<RenderRequestApiKind, RenderRequestApiStatus>();\n for (const observation of observations) {\n const current = byKind.get(observation.kind);\n if (\n current === undefined ||\n requestApiStatusRank(observation.status) > requestApiStatusRank(current)\n ) {\n byKind.set(observation.kind, observation.status);\n }\n }\n\n return [...byKind.entries()]\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([kind, status]) => ({ kind, status }));\n}\n\nfunction cacheProofDowngradeTargetRank(target: CacheProofDowngradeTarget): number {\n switch (target) {\n case \"public\":\n return 0;\n case \"publicVariant\":\n return 1;\n case \"private\":\n return 2;\n case \"privateUncacheable\":\n return 3;\n case \"freshRender\":\n return 4;\n default:\n return assertNever(target);\n }\n}\n\nfunction maxCacheProofDowngradeTarget(\n current: CacheProofDowngradeTarget,\n candidate: CacheProofDowngradeTarget,\n): CacheProofDowngradeTarget {\n return cacheProofDowngradeTargetRank(candidate) > cacheProofDowngradeTargetRank(current)\n ? candidate\n : current;\n}\n\nfunction createDowngradeFallback(\n target: CacheProofDowngradeTarget,\n reasons: readonly CacheProofDowngradeReason[],\n): CacheProofBreakerFallback | null {\n switch (target) {\n case \"public\":\n case \"publicVariant\":\n case \"private\":\n return null;\n case \"privateUncacheable\":\n return buildBreakerFallback(\n \"CP_PRIVATE_DYNAMIC_DOWNGRADE\",\n {\n reasonCodes: reasons.map((reason) => reason.code),\n target,\n },\n \"privateUncacheable\",\n );\n case \"freshRender\":\n return buildBreakerFallback(\"CP_PRIVATE_DYNAMIC_DOWNGRADE\", {\n reasonCodes: reasons.map((reason) => reason.code),\n target,\n });\n default:\n return assertNever(target);\n }\n}\n\nfunction classifyObservedRequestApiDowngrade(\n kind: RenderRequestApiKind,\n): CacheProofDowngradeReason {\n switch (kind) {\n case \"connection\":\n return {\n code: \"CP_DOWNGRADE_DYNAMIC_REQUEST_API\",\n requestApi: \"connection\",\n target: \"freshRender\",\n };\n case \"cookies\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_REQUEST_API\",\n requestApi: \"cookies\",\n target: \"private\",\n };\n case \"draftMode\":\n return {\n code: \"CP_DOWNGRADE_DRAFT_MODE\",\n requestApi: \"draftMode\",\n target: \"privateUncacheable\",\n };\n case \"headers\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_REQUEST_API\",\n requestApi: \"headers\",\n target: \"private\",\n };\n case \"params\":\n return {\n code: \"CP_DOWNGRADE_PUBLIC_REQUEST_API\",\n requestApi: \"params\",\n target: \"publicVariant\",\n };\n case \"searchParams\":\n return {\n code: \"CP_DOWNGRADE_PUBLIC_REQUEST_API\",\n requestApi: \"searchParams\",\n target: \"publicVariant\",\n };\n default:\n return assertNever(kind);\n }\n}\n\nexport function classifyCacheVariantDimensionDowngrade(\n input: ClassifyCacheVariantDimensionDowngradeInput,\n): CacheProofDowngradeReason | null {\n switch (input.source) {\n case \"auth\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_DIMENSION\",\n inputClass: \"auth\",\n source: \"auth\",\n target: \"private\",\n };\n case \"cookie\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_DIMENSION\",\n inputClass: \"private\",\n source: \"cookie\",\n target: \"private\",\n };\n case \"draft-mode\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_DIMENSION\",\n inputClass: \"draft\",\n source: \"draft-mode\",\n target: \"privateUncacheable\",\n };\n case \"header\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_DIMENSION\",\n inputClass: \"private\",\n source: \"header\",\n target: \"private\",\n };\n case \"session\":\n return {\n code: \"CP_DOWNGRADE_PRIVATE_DIMENSION\",\n inputClass: \"session\",\n source: \"session\",\n target: \"private\",\n };\n case \"custom\":\n case \"interception\":\n case \"mounted-slots\":\n case \"params\":\n case \"route\":\n case \"search\":\n return null;\n default:\n return assertNever(input.source);\n }\n}\n\nexport function classifyRenderObservationDowngrade(\n input: ClassifyRenderObservationDowngradeInput,\n): CacheProofDowngradeClassification {\n const reasons: CacheProofDowngradeReason[] = [];\n let target: CacheProofDowngradeTarget = \"public\";\n\n switch (input.cacheability) {\n case \"public\":\n break;\n case \"private\": {\n const reason = {\n code: \"CP_DOWNGRADE_CACHEABILITY_PRIVATE\",\n target: \"private\",\n } satisfies CacheProofDowngradeReason;\n reasons.push(reason);\n target = maxCacheProofDowngradeTarget(target, reason.target);\n break;\n }\n case \"uncacheable\": {\n const reason = {\n code: \"CP_DOWNGRADE_CACHEABILITY_UNCACHEABLE\",\n target: \"privateUncacheable\",\n } satisfies CacheProofDowngradeReason;\n reasons.push(reason);\n target = maxCacheProofDowngradeTarget(target, reason.target);\n break;\n }\n case \"unknown\": {\n const reason = {\n code: \"CP_DOWNGRADE_CACHEABILITY_UNKNOWN\",\n target: \"freshRender\",\n } satisfies CacheProofDowngradeReason;\n reasons.push(reason);\n target = maxCacheProofDowngradeTarget(target, reason.target);\n break;\n }\n default:\n assertNever(input.cacheability);\n }\n\n if (input.completeness !== \"complete\") {\n const reason = {\n code: \"CP_DOWNGRADE_INCOMPLETE_OBSERVATION\",\n completeness: input.completeness,\n target: \"freshRender\",\n } satisfies CacheProofDowngradeReason;\n reasons.push(reason);\n target = maxCacheProofDowngradeTarget(target, reason.target);\n }\n\n if (input.dynamicFetches.length > 0) {\n const reason = {\n code: \"CP_DOWNGRADE_DYNAMIC_FETCH\",\n dynamicFetchCount: input.dynamicFetches.length,\n target: \"freshRender\",\n } satisfies CacheProofDowngradeReason;\n reasons.push(reason);\n target = maxCacheProofDowngradeTarget(target, reason.target);\n }\n\n const requestApis = normalizeRequestApiObservations(input.requestApis);\n for (const requestApi of requestApis) {\n if (requestApi.status === \"notObserved\") continue;\n const reason =\n requestApi.status === \"unknown\"\n ? ({\n code: \"CP_DOWNGRADE_UNKNOWN_REQUEST_API\",\n requestApi: requestApi.kind,\n target: \"freshRender\",\n } satisfies CacheProofDowngradeReason)\n : classifyObservedRequestApiDowngrade(requestApi.kind);\n reasons.push(reason);\n target = maxCacheProofDowngradeTarget(target, reason.target);\n }\n\n return {\n target,\n reasons,\n fallback: createDowngradeFallback(target, reasons),\n isPublicCacheCandidate: target === \"public\" || target === \"publicVariant\",\n };\n}\n\nexport function buildRenderRequestApiObservations(\n input: BuildRenderRequestApiObservationsInput,\n): RenderRequestApiObservation[] {\n const observedKinds = new Set(input.observed);\n const absentStatus: RenderRequestApiStatus =\n input.completeness === \"complete\" ? \"notObserved\" : \"unknown\";\n\n return ALL_RENDER_REQUEST_API_KINDS.map((kind) => ({\n kind,\n status: observedKinds.has(kind) ? \"observed\" : absentStatus,\n }));\n}\n\nexport function buildRenderObservation(input: BuildRenderObservationInput): RenderObservation {\n const requestApis = normalizeRequestApiObservations(input.requestApis);\n const dynamicFetches = sortedUniqueRedacted(input.dynamicFetches);\n\n return {\n schemaVersion: CACHE_PROOF_MODEL_SCHEMA_VERSION,\n output: input.output,\n completeness: input.completeness,\n boundaryOutcome: input.boundaryOutcome,\n requestApis,\n dynamicFetches,\n cacheTags: sortedUnique(input.cacheTags),\n pathTags: sortedUnique(input.pathTags),\n cacheability: input.cacheability,\n downgrade: classifyRenderObservationDowngrade({\n cacheability: input.cacheability,\n completeness: input.completeness,\n dynamicFetches,\n requestApis,\n }),\n };\n}\n\nexport function hasCompleteNegativeRequestApiProof(\n observation: RenderObservation,\n requiredApis: readonly RenderRequestApiKind[],\n): boolean {\n if (observation.completeness !== \"complete\") return false;\n\n const statuses = new Map<RenderRequestApiKind, RenderRequestApiStatus>();\n for (const requestApi of normalizeRequestApiObservations(observation.requestApis)) {\n statuses.set(requestApi.kind, requestApi.status);\n }\n\n for (const api of requiredApis) {\n if (statuses.get(api) !== \"notObserved\") return false;\n }\n return true;\n}\n\nfunction isStaticLayoutOutputScope(\n output: CacheProofOutputScope,\n): output is StaticLayoutCacheProofOutputScope {\n return output.kind === \"layout\";\n}\n\nfunction rejectStaticLayoutReuseProof(\n code: CacheProofRejectionCode,\n fields: CacheProofTraceFields,\n mode: CacheProofBreakerFallbackMode = \"renderFresh\",\n): BuildStaticLayoutReuseProofResult {\n return {\n kind: \"rejected\",\n fallback: buildBreakerFallback(code, fields, mode),\n };\n}\n\nfunction getRequestApiStatus(\n observations: readonly RenderRequestApiObservation[],\n kind: RenderRequestApiKind,\n): RenderRequestApiStatus | \"missing\" {\n let status: RenderRequestApiStatus | null = null;\n\n for (const requestApi of observations) {\n if (requestApi.kind !== kind) continue;\n if (status === null || requestApiStatusRank(requestApi.status) > requestApiStatusRank(status)) {\n status = requestApi.status;\n }\n }\n\n return status ?? \"missing\";\n}\n\nfunction createStaticLayoutDowngradeFallback(\n downgrade: CacheProofDowngradeClassification,\n): CacheProofBreakerFallback {\n const mode: CacheProofBreakerFallbackMode =\n downgrade.target === \"privateUncacheable\" ? \"privateUncacheable\" : \"renderFresh\";\n return buildBreakerFallback(\n \"CP_STATIC_LAYOUT_PRIVATE_DYNAMIC_DOWNGRADE\",\n {\n reasonCodes: downgrade.reasons.map((reason) => reason.code),\n target: downgrade.target,\n },\n mode,\n );\n}\n\nfunction outputFieldMismatch(\n candidate: StaticLayoutCacheProofOutputScope,\n observation: StaticLayoutCacheProofOutputScope,\n): \"layoutId\" | \"rootBoundaryId\" | \"routeId\" | null {\n if (candidate.layoutId !== observation.layoutId) return \"layoutId\";\n if (candidate.rootBoundaryId !== observation.rootBoundaryId) return \"rootBoundaryId\";\n if (candidate.routeId !== observation.routeId) return \"routeId\";\n return null;\n}\n\nexport function buildStaticLayoutReuseProof(\n input: BuildStaticLayoutReuseProofInput,\n): BuildStaticLayoutReuseProofResult {\n if (!isStaticLayoutOutputScope(input.currentOutput)) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_CURRENT_OUTPUT_KIND\", {\n currentOutputKind: input.currentOutput.kind,\n });\n }\n\n if (!isStaticLayoutOutputScope(input.candidateVariant.output)) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_CANDIDATE_OUTPUT_KIND\", {\n candidateOutputKind: input.candidateVariant.output.kind,\n });\n }\n\n if (!isStaticLayoutOutputScope(input.candidateObservation.output)) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_OBSERVATION_OUTPUT_KIND\", {\n observationOutputKind: input.candidateObservation.output.kind,\n });\n }\n\n const currentOutput = input.currentOutput;\n const candidateOutput = input.candidateVariant.output;\n const observationOutput = input.candidateObservation.output;\n const requestApis = normalizeRequestApiObservations(input.candidateObservation.requestApis);\n const candidateObservation = {\n ...input.candidateObservation,\n requestApis,\n downgrade: classifyRenderObservationDowngrade({\n cacheability: input.candidateObservation.cacheability,\n completeness: input.candidateObservation.completeness,\n dynamicFetches: input.candidateObservation.dynamicFetches,\n requestApis,\n }),\n } satisfies RenderObservation;\n const observedOutputMismatch = outputFieldMismatch(candidateOutput, observationOutput);\n if (observedOutputMismatch) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_OBSERVATION_OUTPUT_MISMATCH\", {\n candidateLayoutId: candidateOutput.layoutId,\n candidateRootBoundaryId: candidateOutput.rootBoundaryId,\n candidateRouteId: candidateOutput.routeId,\n field: observedOutputMismatch,\n observationLayoutId: observationOutput.layoutId,\n observationRootBoundaryId: observationOutput.rootBoundaryId,\n observationRouteId: observationOutput.routeId,\n });\n }\n\n if (currentOutput.layoutId !== candidateOutput.layoutId) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_ID_MISMATCH\", {\n candidateLayoutId: candidateOutput.layoutId,\n currentLayoutId: currentOutput.layoutId,\n });\n }\n\n if (currentOutput.rootBoundaryId === null || candidateOutput.rootBoundaryId === null) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_ROOT_BOUNDARY_UNKNOWN\", {\n candidateRootBoundaryId: candidateOutput.rootBoundaryId,\n currentRootBoundaryId: currentOutput.rootBoundaryId,\n });\n }\n\n if (currentOutput.rootBoundaryId !== candidateOutput.rootBoundaryId) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_ROOT_BOUNDARY_MISMATCH\", {\n candidateRootBoundaryId: candidateOutput.rootBoundaryId,\n currentRootBoundaryId: currentOutput.rootBoundaryId,\n });\n }\n\n const boundaryCompatibility = buildBoundaryOutcomeCompatibility({\n candidate: candidateObservation.boundaryOutcome,\n expected: { kind: \"success\" },\n });\n if (boundaryCompatibility.kind === \"incompatible\") {\n return {\n kind: \"rejected\",\n fallback: boundaryCompatibility.fallback,\n };\n }\n\n if (input.candidateVariant.dimensions.length > 0) {\n return rejectStaticLayoutReuseProof(\"CP_STATIC_LAYOUT_VARIANT_DIMENSION_UNPROVEN\", {\n dimensionCount: input.candidateVariant.dimensions.length,\n sources: sortedUnique(input.candidateVariant.dimensions.map((dimension) => dimension.source)),\n });\n }\n\n if (!candidateObservation.downgrade.isPublicCacheCandidate) {\n return {\n kind: \"rejected\",\n fallback: createStaticLayoutDowngradeFallback(candidateObservation.downgrade),\n };\n }\n\n // The loop can use the shared readonly registry; the proof stores a detached evidence copy.\n const requiredNegativeRequestApis = ALL_RENDER_REQUEST_API_KINDS;\n for (const api of requiredNegativeRequestApis) {\n const status = getRequestApiStatus(candidateObservation.requestApis, api);\n if (status === \"notObserved\") continue;\n\n return rejectStaticLayoutReuseProof(\n status === \"missing\"\n ? \"CP_STATIC_LAYOUT_REQUEST_API_UNKNOWN\"\n : \"CP_STATIC_LAYOUT_REQUEST_API_OBSERVED\",\n {\n requestApi: api,\n status,\n },\n );\n }\n\n return {\n kind: \"proof\",\n proof: {\n authorizesRuntimeReuse: true,\n candidateOutput,\n code: \"CP_STATIC_LAYOUT_REUSE_PROVEN\",\n currentOutput,\n fields: {\n candidateRouteId: candidateOutput.routeId,\n currentRouteId: currentOutput.routeId,\n layoutId: currentOutput.layoutId,\n rootBoundaryId: currentOutput.rootBoundaryId,\n },\n observation: candidateObservation,\n requiredNegativeRequestApis: [...requiredNegativeRequestApis],\n reuseClass: \"static-layout\",\n variant: input.candidateVariant,\n },\n };\n}\n\nfunction createCacheProofHotPathMetric(\n outcome: CacheProofHotPathMetric[\"outcome\"],\n code: CacheProofTraceCode,\n fields: CacheProofTraceFields,\n): CacheProofHotPathMetric {\n return {\n name: \"vinext.cache.static_layout_artifact_reuse\",\n outcome,\n code,\n fields,\n };\n}\n\nfunction createStaticLayoutArtifactReuseFallback(\n fallback: CacheProofBreakerFallback,\n): StaticLayoutArtifactReuseDecision {\n return {\n kind: \"fallback\",\n canReuse: false,\n fallback,\n metric: createCacheProofHotPathMetric(\"fallback\", fallback.code, fallback.fields),\n };\n}\n\nexport function createStaticLayoutArtifactReuseDecision(\n input: CreateStaticLayoutArtifactReuseDecisionInput,\n): StaticLayoutArtifactReuseDecision {\n if (input.candidateVariant.kind === \"breakerFallback\") {\n return createStaticLayoutArtifactReuseFallback(input.candidateVariant.fallback);\n }\n\n const artifactCompatibility = evaluateArtifactCompatibility(\n input.currentArtifactCompatibility,\n input.candidateArtifactCompatibility,\n { compatibilityMap: input.compatibilityMap },\n );\n if (artifactCompatibility.kind === \"unknown\") {\n return createStaticLayoutArtifactReuseFallback(\n buildBreakerFallback(\"CP_ARTIFACT_COMPATIBILITY_UNKNOWN\", {\n compatibilityFallback: artifactCompatibility.fallback,\n reason: artifactCompatibility.reason,\n }),\n );\n }\n if (artifactCompatibility.kind === \"incompatible\") {\n return createStaticLayoutArtifactReuseFallback(\n buildBreakerFallback(\"CP_ARTIFACT_COMPATIBILITY_INCOMPATIBLE\", {\n compatibilityFallback: artifactCompatibility.fallback,\n reason: artifactCompatibility.reason,\n }),\n );\n }\n\n const proof = buildStaticLayoutReuseProof({\n candidateObservation: input.candidateObservation,\n candidateVariant: input.candidateVariant.variant,\n currentOutput: input.currentOutput,\n });\n if (proof.kind === \"rejected\") {\n return createStaticLayoutArtifactReuseFallback(proof.fallback);\n }\n\n return {\n kind: \"reuse\",\n canReuse: true,\n proof: {\n ...proof.proof,\n candidateArtifactCompatibility: { ...input.candidateArtifactCompatibility },\n },\n metric: createCacheProofHotPathMetric(\"reuse\", proof.proof.code, proof.proof.fields),\n };\n}\n\nexport function createCacheEntryReuseProof(\n decision: StaticLayoutArtifactReuseDecision | null,\n): CacheEntryReuseProof {\n if (decision === null) {\n return {\n kind: \"runtime-cache-entry\",\n decision: null,\n };\n }\n\n switch (decision.kind) {\n case \"reuse\":\n return {\n kind: \"runtime-cache-entry\",\n decision: {\n canReuse: true,\n code: decision.proof.code,\n kind: \"reuse\",\n reuseClass: decision.proof.reuseClass,\n },\n };\n case \"fallback\":\n return {\n kind: \"runtime-cache-entry\",\n decision: {\n canReuse: false,\n code: decision.fallback.code,\n kind: \"reject\",\n mode: decision.fallback.mode,\n scope: decision.fallback.scope,\n },\n };\n default:\n return assertNever(decision);\n }\n}\n\nexport function createDisabledCacheProofDecision(\n input: CreateDisabledCacheProofDecisionInput,\n): DisabledCacheProofDecision {\n return {\n kind: \"disabled\",\n canReuse: false,\n variant: input.variant,\n observation: input.observation,\n ...(input.staticLayoutProof ? { staticLayoutProof: input.staticLayoutProof } : {}),\n fallback: buildBreakerFallback(\"CP_MODEL_DISABLED\"),\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { ArtifactCompatibilityEnvelope } from "./artifact-compatibility.js";
|
|
2
|
+
|
|
3
|
+
//#region src/server/client-reuse-manifest.d.ts
|
|
4
|
+
declare const CLIENT_REUSE_MANIFEST_SCHEMA_VERSION = 1;
|
|
5
|
+
type ClientReuseManifestSchemaVersion = 1;
|
|
6
|
+
declare const CLIENT_REUSE_MANIFEST_HASH_ALGORITHM = "fnv1a64";
|
|
7
|
+
type ClientReuseManifestHashAlgorithm = typeof CLIENT_REUSE_MANIFEST_HASH_ALGORITHM;
|
|
8
|
+
type ClientReuseManifestLimits = Readonly<{
|
|
9
|
+
maxEntryCount: number;
|
|
10
|
+
maxEntryIdLength: number;
|
|
11
|
+
maxManifestBytes: number;
|
|
12
|
+
maxPayloadHashLength: number;
|
|
13
|
+
maxVariantCacheKeyLength: number;
|
|
14
|
+
}>;
|
|
15
|
+
declare const DEFAULT_CLIENT_REUSE_MANIFEST_LIMITS: {
|
|
16
|
+
maxEntryCount: number;
|
|
17
|
+
maxEntryIdLength: number;
|
|
18
|
+
maxManifestBytes: number;
|
|
19
|
+
maxPayloadHashLength: number;
|
|
20
|
+
maxVariantCacheKeyLength: number;
|
|
21
|
+
};
|
|
22
|
+
type ClientReuseManifestEntryKind = "layout" | "page" | "route" | "slot" | "template";
|
|
23
|
+
type ClientReuseManifestEntryPrivacy = "private" | "public";
|
|
24
|
+
type ClientReuseManifestReplayWindow = Readonly<{
|
|
25
|
+
validFromVisibleCommitVersion: number;
|
|
26
|
+
validUntilVisibleCommitVersion: number;
|
|
27
|
+
}>;
|
|
28
|
+
type ClientReuseManifestEntry = Readonly<{
|
|
29
|
+
artifactCompatibility: ArtifactCompatibilityEnvelope;
|
|
30
|
+
id: string;
|
|
31
|
+
kind: ClientReuseManifestEntryKind;
|
|
32
|
+
payloadHash: string;
|
|
33
|
+
privacy: "public";
|
|
34
|
+
variantCacheKey: string;
|
|
35
|
+
}>;
|
|
36
|
+
type ClientReuseManifestWireEntry = Readonly<{
|
|
37
|
+
artifactCompatibility: ArtifactCompatibilityEnvelope;
|
|
38
|
+
id: string;
|
|
39
|
+
payloadHash: string;
|
|
40
|
+
privacy: ClientReuseManifestEntryPrivacy;
|
|
41
|
+
variantCacheKey: string;
|
|
42
|
+
}>;
|
|
43
|
+
type ClientReuseManifest = Readonly<{
|
|
44
|
+
entries: readonly ClientReuseManifestEntry[];
|
|
45
|
+
hashAlgorithm: ClientReuseManifestHashAlgorithm;
|
|
46
|
+
replayWindow: ClientReuseManifestReplayWindow;
|
|
47
|
+
schemaVersion: ClientReuseManifestSchemaVersion;
|
|
48
|
+
visibleCommitVersion: number;
|
|
49
|
+
}>;
|
|
50
|
+
type ClientReuseManifestWire = Readonly<{
|
|
51
|
+
entries: readonly ClientReuseManifestWireEntry[];
|
|
52
|
+
hashAlgorithm: ClientReuseManifestHashAlgorithm;
|
|
53
|
+
replayWindow: ClientReuseManifestReplayWindow;
|
|
54
|
+
schemaVersion: ClientReuseManifestSchemaVersion;
|
|
55
|
+
visibleCommitVersion: number;
|
|
56
|
+
}>;
|
|
57
|
+
type CreateClientReuseManifestInput = Readonly<{
|
|
58
|
+
entries: readonly ClientReuseManifestWireEntry[];
|
|
59
|
+
replayWindow?: ClientReuseManifestReplayWindow;
|
|
60
|
+
visibleCommitVersion: number;
|
|
61
|
+
}>;
|
|
62
|
+
type ClientReuseManifestRejectionCode = "SKIP_CACHE_ARTIFACT_COMPATIBILITY_INCOMPATIBLE" | "SKIP_CACHE_ARTIFACT_COMPATIBILITY_UNKNOWN" | "SKIP_CACHE_ARTIFACT_PROOF_MISMATCH" | "SKIP_CACHE_ENTRY_ID_MISMATCH" | "SKIP_CACHE_INVALIDATED" | "SKIP_CACHE_INVALIDATION_UNKNOWN" | "SKIP_CACHE_PAYLOAD_HASH_MISMATCH" | "SKIP_CACHE_PAYLOAD_HASH_MISSING" | "SKIP_CACHE_PROOF_MISSING" | "SKIP_CACHE_PROOF_REJECTED" | "SKIP_CACHE_REUSE_CLASS_UNSUPPORTED" | "SKIP_CACHE_VARIANT_MISMATCH" | "SKIP_ARTIFACT_COMPATIBILITY_INVALID" | "SKIP_ENTRY_COUNT_EXCEEDED" | "SKIP_ENTRY_HASH_INVALID" | "SKIP_ENTRY_ID_INVALID" | "SKIP_ENTRY_ID_TOO_LONG" | "SKIP_ENTRY_MALFORMED" | "SKIP_ENTRY_ORDER_NON_CANONICAL" | "SKIP_HASH_ALGORITHM_UNSUPPORTED" | "SKIP_MANIFEST_MALFORMED" | "SKIP_MANIFEST_SCHEMA_UNSUPPORTED" | "SKIP_MANIFEST_TOO_LARGE" | "SKIP_PRIVATE_ENTRY" | "SKIP_REPLAY_WINDOW_INVALID" | "SKIP_UNKNOWN_ENTRY" | "SKIP_VARIANT_CACHE_KEY_INVALID" | "SKIP_VARIANT_CACHE_KEY_TOO_LONG" | "SKIP_VISIBLE_COMMIT_VERSION_INVALID" | "SKIP_VISIBLE_COMMIT_VERSION_MISMATCH";
|
|
63
|
+
type ClientReuseManifestDispositionCode = "SKIP_MODEL_DISABLED";
|
|
64
|
+
type ClientReuseManifestTraceFieldValue = string | number | boolean | null | readonly string[];
|
|
65
|
+
type ClientReuseManifestTraceFields = Readonly<Record<string, ClientReuseManifestTraceFieldValue>>;
|
|
66
|
+
type ClientReuseManifestRejection = Readonly<{
|
|
67
|
+
code: ClientReuseManifestRejectionCode;
|
|
68
|
+
fields: ClientReuseManifestTraceFields;
|
|
69
|
+
}>;
|
|
70
|
+
type ClientReuseManifestEntryRejection = ClientReuseManifestRejection & Readonly<{
|
|
71
|
+
entryId: string | null;
|
|
72
|
+
}>;
|
|
73
|
+
type ClientReuseManifestSkipDisposition = Readonly<{
|
|
74
|
+
code: ClientReuseManifestDispositionCode;
|
|
75
|
+
enabled: false;
|
|
76
|
+
mode: "renderAndSend";
|
|
77
|
+
}>;
|
|
78
|
+
type ClientReuseManifestParseResult = Readonly<{
|
|
79
|
+
kind: "absent";
|
|
80
|
+
}> | Readonly<{
|
|
81
|
+
kind: "rejected";
|
|
82
|
+
rejection: ClientReuseManifestRejection;
|
|
83
|
+
}> | Readonly<{
|
|
84
|
+
entryRejections: readonly ClientReuseManifestEntryRejection[];
|
|
85
|
+
kind: "parsed";
|
|
86
|
+
manifest: ClientReuseManifest;
|
|
87
|
+
skipDisposition: ClientReuseManifestSkipDisposition;
|
|
88
|
+
}>;
|
|
89
|
+
type ParseClientReuseManifestOptions = Readonly<{
|
|
90
|
+
currentVisibleCommitVersion?: number;
|
|
91
|
+
limits?: ClientReuseManifestLimits;
|
|
92
|
+
}>;
|
|
93
|
+
declare function createClientReusePayloadHash(input: string): string;
|
|
94
|
+
declare function createClientReuseManifest(input: CreateClientReuseManifestInput): ClientReuseManifestWire;
|
|
95
|
+
declare function serializeClientReuseManifest(input: CreateClientReuseManifestInput): string;
|
|
96
|
+
declare function parseClientReuseManifestHeader(rawHeader: string | null | undefined, options?: ParseClientReuseManifestOptions): ClientReuseManifestParseResult;
|
|
97
|
+
//#endregion
|
|
98
|
+
export { CLIENT_REUSE_MANIFEST_HASH_ALGORITHM, CLIENT_REUSE_MANIFEST_SCHEMA_VERSION, ClientReuseManifest, ClientReuseManifestDispositionCode, ClientReuseManifestEntry, ClientReuseManifestEntryKind, ClientReuseManifestEntryRejection, ClientReuseManifestHashAlgorithm, ClientReuseManifestParseResult, ClientReuseManifestRejection, ClientReuseManifestRejectionCode, ClientReuseManifestReplayWindow, ClientReuseManifestSchemaVersion, ClientReuseManifestSkipDisposition, ClientReuseManifestTraceFieldValue, ClientReuseManifestTraceFields, DEFAULT_CLIENT_REUSE_MANIFEST_LIMITS, createClientReuseManifest, createClientReusePayloadHash, parseClientReuseManifestHeader, serializeClientReuseManifest };
|
|
99
|
+
//# sourceMappingURL=client-reuse-manifest.d.ts.map
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { fnv1a64 } from "../utils/hash.js";
|
|
2
|
+
import { isUnknownRecord } from "../utils/record.js";
|
|
3
|
+
import { parseArtifactCompatibilityEnvelope } from "./artifact-compatibility.js";
|
|
4
|
+
import { AppElementsWire } from "./app-elements-wire.js";
|
|
5
|
+
//#region src/server/client-reuse-manifest.ts
|
|
6
|
+
const CLIENT_REUSE_MANIFEST_SCHEMA_VERSION = 1;
|
|
7
|
+
const CLIENT_REUSE_MANIFEST_HASH_ALGORITHM = "fnv1a64";
|
|
8
|
+
const DEFAULT_CLIENT_REUSE_MANIFEST_LIMITS = {
|
|
9
|
+
maxEntryCount: 64,
|
|
10
|
+
maxEntryIdLength: 512,
|
|
11
|
+
maxManifestBytes: 4096,
|
|
12
|
+
maxPayloadHashLength: 16,
|
|
13
|
+
maxVariantCacheKeyLength: 256
|
|
14
|
+
};
|
|
15
|
+
const HASH_DIGEST_PATTERN = /^[0-9a-z]+$/;
|
|
16
|
+
const textEncoder = new TextEncoder();
|
|
17
|
+
function createRejection(code, fields = {}) {
|
|
18
|
+
return {
|
|
19
|
+
code,
|
|
20
|
+
fields
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function rejectManifest(code, fields = {}) {
|
|
24
|
+
return {
|
|
25
|
+
kind: "rejected",
|
|
26
|
+
rejection: createRejection(code, fields)
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function rejectEntry(code, entryId, fields = {}) {
|
|
30
|
+
return {
|
|
31
|
+
code,
|
|
32
|
+
entryId,
|
|
33
|
+
fields
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function compareManifestEntries(left, right) {
|
|
37
|
+
if (left.id < right.id) return -1;
|
|
38
|
+
if (left.id > right.id) return 1;
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
function createCanonicalWireEntries(entries) {
|
|
42
|
+
const entriesById = /* @__PURE__ */ new Map();
|
|
43
|
+
for (const entry of entries) if (!entriesById.has(entry.id)) entriesById.set(entry.id, entry);
|
|
44
|
+
return Array.from(entriesById.values()).sort(compareManifestEntries);
|
|
45
|
+
}
|
|
46
|
+
function countUtf8Bytes(input) {
|
|
47
|
+
return textEncoder.encode(input).length;
|
|
48
|
+
}
|
|
49
|
+
function isVisibleCommitVersion(value) {
|
|
50
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
51
|
+
}
|
|
52
|
+
function parseReplayWindow(value, visibleCommitVersion) {
|
|
53
|
+
if (!isUnknownRecord(value)) return {
|
|
54
|
+
kind: "rejected",
|
|
55
|
+
rejection: createRejection("SKIP_REPLAY_WINDOW_INVALID", { field: "replayWindow" })
|
|
56
|
+
};
|
|
57
|
+
const validFromVisibleCommitVersion = value.validFromVisibleCommitVersion;
|
|
58
|
+
const validUntilVisibleCommitVersion = value.validUntilVisibleCommitVersion;
|
|
59
|
+
if (!isVisibleCommitVersion(validFromVisibleCommitVersion) || !isVisibleCommitVersion(validUntilVisibleCommitVersion) || validFromVisibleCommitVersion > validUntilVisibleCommitVersion || visibleCommitVersion < validFromVisibleCommitVersion || visibleCommitVersion > validUntilVisibleCommitVersion) return {
|
|
60
|
+
kind: "rejected",
|
|
61
|
+
rejection: createRejection("SKIP_REPLAY_WINDOW_INVALID", {
|
|
62
|
+
validFromVisibleCommitVersion: isVisibleCommitVersion(validFromVisibleCommitVersion) ? validFromVisibleCommitVersion : null,
|
|
63
|
+
validUntilVisibleCommitVersion: isVisibleCommitVersion(validUntilVisibleCommitVersion) ? validUntilVisibleCommitVersion : null,
|
|
64
|
+
visibleCommitVersion
|
|
65
|
+
})
|
|
66
|
+
};
|
|
67
|
+
return {
|
|
68
|
+
kind: "parsed",
|
|
69
|
+
replayWindow: {
|
|
70
|
+
validFromVisibleCommitVersion,
|
|
71
|
+
validUntilVisibleCommitVersion
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function currentCommitVersionMatchesReplayWindow(currentVisibleCommitVersion, replayWindow) {
|
|
76
|
+
if (currentVisibleCommitVersion === void 0) return true;
|
|
77
|
+
return currentVisibleCommitVersion >= replayWindow.validFromVisibleCommitVersion && currentVisibleCommitVersion <= replayWindow.validUntilVisibleCommitVersion;
|
|
78
|
+
}
|
|
79
|
+
function parseEntryKind(id) {
|
|
80
|
+
const parsed = AppElementsWire.parseElementKey(id);
|
|
81
|
+
if (parsed === null) return null;
|
|
82
|
+
return parsed.kind;
|
|
83
|
+
}
|
|
84
|
+
function isValidPayloadHash(value, limits) {
|
|
85
|
+
return typeof value === "string" && value.length > 0 && value.length <= limits.maxPayloadHashLength && HASH_DIGEST_PATTERN.test(value);
|
|
86
|
+
}
|
|
87
|
+
function parseManifestEntry(value, limits, index) {
|
|
88
|
+
if (!isUnknownRecord(value)) return rejectEntry("SKIP_ENTRY_MALFORMED", null, { index });
|
|
89
|
+
const id = value.id;
|
|
90
|
+
if (typeof id !== "string" || id.length === 0) return rejectEntry("SKIP_ENTRY_ID_INVALID", null, { index });
|
|
91
|
+
if (id.length > limits.maxEntryIdLength) return rejectEntry("SKIP_ENTRY_ID_TOO_LONG", id, {
|
|
92
|
+
idHash: createClientReusePayloadHash(id),
|
|
93
|
+
maxEntryIdLength: limits.maxEntryIdLength
|
|
94
|
+
});
|
|
95
|
+
const kind = parseEntryKind(id);
|
|
96
|
+
if (kind === null) return rejectEntry("SKIP_UNKNOWN_ENTRY", id, { idHash: createClientReusePayloadHash(id) });
|
|
97
|
+
const privacy = value.privacy;
|
|
98
|
+
if (privacy === "private") return rejectEntry("SKIP_PRIVATE_ENTRY", id, { privacy });
|
|
99
|
+
if (privacy !== "public") return rejectEntry("SKIP_ENTRY_MALFORMED", id, { field: "privacy" });
|
|
100
|
+
const payloadHash = value.payloadHash;
|
|
101
|
+
if (!isValidPayloadHash(payloadHash, limits)) return rejectEntry("SKIP_ENTRY_HASH_INVALID", id, { maxPayloadHashLength: limits.maxPayloadHashLength });
|
|
102
|
+
const variantCacheKey = value.variantCacheKey;
|
|
103
|
+
if (typeof variantCacheKey !== "string" || variantCacheKey.length === 0) return rejectEntry("SKIP_VARIANT_CACHE_KEY_INVALID", id, { field: "variantCacheKey" });
|
|
104
|
+
if (variantCacheKey.length > limits.maxVariantCacheKeyLength) return rejectEntry("SKIP_VARIANT_CACHE_KEY_TOO_LONG", id, {
|
|
105
|
+
maxVariantCacheKeyLength: limits.maxVariantCacheKeyLength,
|
|
106
|
+
variantCacheKeyHash: createClientReusePayloadHash(variantCacheKey)
|
|
107
|
+
});
|
|
108
|
+
const artifactCompatibility = parseArtifactCompatibilityEnvelope(value.artifactCompatibility);
|
|
109
|
+
if (artifactCompatibility === null) return rejectEntry("SKIP_ARTIFACT_COMPATIBILITY_INVALID", id, { field: "artifactCompatibility" });
|
|
110
|
+
return {
|
|
111
|
+
artifactCompatibility,
|
|
112
|
+
id,
|
|
113
|
+
kind,
|
|
114
|
+
payloadHash,
|
|
115
|
+
privacy,
|
|
116
|
+
variantCacheKey
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function createClientReusePayloadHash(input) {
|
|
120
|
+
return fnv1a64(input);
|
|
121
|
+
}
|
|
122
|
+
function createClientReuseManifest(input) {
|
|
123
|
+
const replayWindow = input.replayWindow ?? {
|
|
124
|
+
validFromVisibleCommitVersion: input.visibleCommitVersion,
|
|
125
|
+
validUntilVisibleCommitVersion: input.visibleCommitVersion
|
|
126
|
+
};
|
|
127
|
+
return {
|
|
128
|
+
entries: createCanonicalWireEntries(input.entries),
|
|
129
|
+
hashAlgorithm: CLIENT_REUSE_MANIFEST_HASH_ALGORITHM,
|
|
130
|
+
replayWindow,
|
|
131
|
+
schemaVersion: 1,
|
|
132
|
+
visibleCommitVersion: input.visibleCommitVersion
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function serializeClientReuseManifest(input) {
|
|
136
|
+
return JSON.stringify(createClientReuseManifest(input));
|
|
137
|
+
}
|
|
138
|
+
function parseClientReuseManifestHeader(rawHeader, options = {}) {
|
|
139
|
+
const header = rawHeader?.trim();
|
|
140
|
+
if (!header) return { kind: "absent" };
|
|
141
|
+
const limits = options.limits ?? DEFAULT_CLIENT_REUSE_MANIFEST_LIMITS;
|
|
142
|
+
const manifestBytes = countUtf8Bytes(header);
|
|
143
|
+
if (manifestBytes > limits.maxManifestBytes) return rejectManifest("SKIP_MANIFEST_TOO_LARGE", {
|
|
144
|
+
manifestBytes,
|
|
145
|
+
maxManifestBytes: limits.maxManifestBytes
|
|
146
|
+
});
|
|
147
|
+
let decoded;
|
|
148
|
+
try {
|
|
149
|
+
decoded = JSON.parse(header);
|
|
150
|
+
} catch {
|
|
151
|
+
return rejectManifest("SKIP_MANIFEST_MALFORMED");
|
|
152
|
+
}
|
|
153
|
+
if (!isUnknownRecord(decoded)) return rejectManifest("SKIP_MANIFEST_MALFORMED", { field: "manifest" });
|
|
154
|
+
if (decoded.schemaVersion !== 1) return rejectManifest("SKIP_MANIFEST_SCHEMA_UNSUPPORTED", { schemaVersion: typeof decoded.schemaVersion === "number" || typeof decoded.schemaVersion === "string" ? decoded.schemaVersion : null });
|
|
155
|
+
if (decoded.hashAlgorithm !== "fnv1a64") return rejectManifest("SKIP_HASH_ALGORITHM_UNSUPPORTED", { hashAlgorithm: typeof decoded.hashAlgorithm === "string" ? decoded.hashAlgorithm : null });
|
|
156
|
+
const visibleCommitVersion = decoded.visibleCommitVersion;
|
|
157
|
+
if (!isVisibleCommitVersion(visibleCommitVersion)) return rejectManifest("SKIP_VISIBLE_COMMIT_VERSION_INVALID", { visibleCommitVersion: null });
|
|
158
|
+
const replayWindowResult = parseReplayWindow(decoded.replayWindow, visibleCommitVersion);
|
|
159
|
+
if (replayWindowResult.kind === "rejected") return {
|
|
160
|
+
kind: "rejected",
|
|
161
|
+
rejection: replayWindowResult.rejection
|
|
162
|
+
};
|
|
163
|
+
const { replayWindow } = replayWindowResult;
|
|
164
|
+
if (!currentCommitVersionMatchesReplayWindow(options.currentVisibleCommitVersion, replayWindow)) return rejectManifest("SKIP_VISIBLE_COMMIT_VERSION_MISMATCH", {
|
|
165
|
+
currentVisibleCommitVersion: options.currentVisibleCommitVersion ?? null,
|
|
166
|
+
validFromVisibleCommitVersion: replayWindow.validFromVisibleCommitVersion,
|
|
167
|
+
validUntilVisibleCommitVersion: replayWindow.validUntilVisibleCommitVersion,
|
|
168
|
+
visibleCommitVersion
|
|
169
|
+
});
|
|
170
|
+
const entriesValue = decoded.entries;
|
|
171
|
+
if (!Array.isArray(entriesValue)) return rejectManifest("SKIP_MANIFEST_MALFORMED", { field: "entries" });
|
|
172
|
+
if (entriesValue.length > limits.maxEntryCount) return rejectManifest("SKIP_ENTRY_COUNT_EXCEEDED", {
|
|
173
|
+
entryCount: entriesValue.length,
|
|
174
|
+
maxEntryCount: limits.maxEntryCount
|
|
175
|
+
});
|
|
176
|
+
const entries = [];
|
|
177
|
+
const entryRejections = [];
|
|
178
|
+
let previousEntryId = null;
|
|
179
|
+
for (let index = 0; index < entriesValue.length; index++) {
|
|
180
|
+
const value = entriesValue[index];
|
|
181
|
+
if (isUnknownRecord(value) && typeof value.id === "string") {
|
|
182
|
+
if (previousEntryId !== null && value.id <= previousEntryId) return rejectManifest("SKIP_ENTRY_ORDER_NON_CANONICAL", {
|
|
183
|
+
entryIdHash: createClientReusePayloadHash(value.id),
|
|
184
|
+
previousEntryIdHash: createClientReusePayloadHash(previousEntryId)
|
|
185
|
+
});
|
|
186
|
+
previousEntryId = value.id;
|
|
187
|
+
}
|
|
188
|
+
const parsedEntry = parseManifestEntry(value, limits, index);
|
|
189
|
+
if ("code" in parsedEntry) entryRejections.push(parsedEntry);
|
|
190
|
+
else entries.push(parsedEntry);
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
entryRejections,
|
|
194
|
+
kind: "parsed",
|
|
195
|
+
manifest: {
|
|
196
|
+
entries,
|
|
197
|
+
hashAlgorithm: CLIENT_REUSE_MANIFEST_HASH_ALGORITHM,
|
|
198
|
+
replayWindow,
|
|
199
|
+
schemaVersion: 1,
|
|
200
|
+
visibleCommitVersion
|
|
201
|
+
},
|
|
202
|
+
skipDisposition: {
|
|
203
|
+
code: "SKIP_MODEL_DISABLED",
|
|
204
|
+
enabled: false,
|
|
205
|
+
mode: "renderAndSend"
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
//#endregion
|
|
210
|
+
export { CLIENT_REUSE_MANIFEST_HASH_ALGORITHM, CLIENT_REUSE_MANIFEST_SCHEMA_VERSION, DEFAULT_CLIENT_REUSE_MANIFEST_LIMITS, createClientReuseManifest, createClientReusePayloadHash, parseClientReuseManifestHeader, serializeClientReuseManifest };
|
|
211
|
+
|
|
212
|
+
//# sourceMappingURL=client-reuse-manifest.js.map
|