@rangojs/router 0.18.0 → 0.19.0
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/types/browser/event-controller.d.ts +3 -3
- package/dist/types/browser/history-state.d.ts +2 -0
- package/dist/types/browser/navigation-transaction.d.ts +20 -2
- package/dist/types/browser/partial-update.d.ts +16 -1
- package/dist/types/browser/prefetch/cache.d.ts +6 -6
- package/dist/types/browser/react/Link.d.ts +19 -9
- package/dist/types/browser/react/context.d.ts +2 -2
- package/dist/types/browser/react/location-state-shared.d.ts +95 -56
- package/dist/types/browser/react/location-state.d.ts +1 -1
- package/dist/types/browser/transition-when.d.ts +80 -0
- package/dist/types/browser/types.d.ts +104 -9
- package/dist/types/build/generate-manifest.d.ts +8 -0
- package/dist/types/cache/background-task.d.ts +24 -2
- package/dist/types/cache/cache-exec-scope.d.ts +31 -0
- package/dist/types/cache/cache-key-utils.d.ts +44 -13
- package/dist/types/cache/cache-policy.d.ts +1 -1
- package/dist/types/cache/cache-runtime.d.ts +7 -0
- package/dist/types/cache/cache-scope.d.ts +117 -35
- package/dist/types/cache/cache-tag.d.ts +24 -4
- package/dist/types/cache/cf/cf-cache-store.d.ts +55 -44
- package/dist/types/cache/cf/cf-shell-frame.d.ts +1 -1
- package/dist/types/cache/cf/cf-tag-marker-memo.d.ts +0 -15
- package/dist/types/cache/document-cache.d.ts +10 -0
- package/dist/types/cache/handle-snapshot.d.ts +40 -8
- package/dist/types/cache/invalidation-order.d.ts +23 -0
- package/dist/types/cache/request-tag-mask.d.ts +54 -0
- package/dist/types/cache/shell-snapshot.d.ts +88 -141
- package/dist/types/cache/tag-invalidation.d.ts +38 -14
- package/dist/types/cache/types.d.ts +68 -61
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +23 -16
- package/dist/types/client-urls/navigation.d.ts +28 -2
- package/dist/types/client-urls/server-projection.d.ts +5 -2
- package/dist/types/client-urls/types.d.ts +5 -5
- package/dist/types/client.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.rsc.d.ts +1 -1
- package/dist/types/route-definition/helpers-types.d.ts +11 -11
- package/dist/types/route-name.d.ts +7 -0
- package/dist/types/router/error-handling.d.ts +1 -1
- package/dist/types/router/intercept-resolution.d.ts +2 -0
- package/dist/types/router/match-context.d.ts +5 -0
- package/dist/types/router/match-middleware/background-revalidation.d.ts +0 -4
- package/dist/types/router/router-options.d.ts +4 -1
- package/dist/types/router/segment-resolution/loader-cache.d.ts +18 -1
- package/dist/types/router/segment-resolution/loader-mask.d.ts +3 -4
- package/dist/types/router/segment-resolution/loader-snapshot.d.ts +14 -40
- package/dist/types/router/segment-resolution/mask-nested.d.ts +11 -3
- package/dist/types/router/segment-resolution/view-transition-default.d.ts +7 -5
- package/dist/types/router/transition-when.d.ts +24 -10
- package/dist/types/rsc/attach-transition-when.d.ts +18 -0
- package/dist/types/rsc/full-payload.d.ts +14 -7
- package/dist/types/rsc/response-cache-serve.d.ts +15 -12
- package/dist/types/rsc/shell-build-manifest.d.ts +4 -3
- package/dist/types/rsc/shell-capture-constants.d.ts +77 -20
- package/dist/types/rsc/shell-capture.d.ts +78 -81
- package/dist/types/rsc/shell-serve.d.ts +19 -48
- package/dist/types/rsc/types.d.ts +2 -0
- package/dist/types/segment-system.d.ts +7 -0
- package/dist/types/server/context.d.ts +89 -61
- package/dist/types/server/cookie-store.d.ts +30 -18
- package/dist/types/server/handle-store.d.ts +52 -1
- package/dist/types/server/request-context.d.ts +66 -45
- package/dist/types/server/request-headers.d.ts +44 -0
- package/dist/types/server.d.ts +1 -0
- package/dist/types/testing/e2e/index.d.ts +1 -1
- package/dist/types/testing/index.d.ts +3 -2
- package/dist/types/testing/internal/action-id.d.ts +7 -0
- package/dist/types/testing/location-state-key.d.ts +24 -0
- package/dist/types/testing/render-route.d.ts +17 -1
- package/dist/types/testing/run-transition-when.d.ts +44 -69
- package/dist/types/testing/serve-shell-request.d.ts +7 -6
- package/dist/types/testing/shell-status.d.ts +34 -22
- package/dist/types/transition-when-ref.d.ts +79 -0
- package/dist/types/types/cache-types.d.ts +15 -3
- package/dist/types/types/index.d.ts +1 -1
- package/dist/types/types/segments.d.ts +86 -71
- package/dist/types/urls/path-helper-types.d.ts +3 -4
- package/dist/types/urls/pattern-types.d.ts +3 -4
- package/dist/types/vite/plugins/transition-when-hoist.d.ts +45 -0
- package/dist/vite/index.js +960 -97
- package/package.json +1 -1
- package/skills/cache-guide/SKILL.md +76 -49
- package/skills/caching/SKILL.md +167 -69
- package/skills/client-urls/SKILL.md +1 -1
- package/skills/comparison/references/framework-comparison.md +8 -5
- package/skills/document-cache/SKILL.md +24 -0
- package/skills/hooks/SKILL.md +3 -1
- package/skills/hooks/navigation.md +23 -2
- package/skills/hooks/state.md +98 -6
- package/skills/intercept/SKILL.md +29 -12
- package/skills/loader/SKILL.md +52 -21
- package/skills/middleware/SKILL.md +18 -0
- package/skills/migrate-nextjs/SKILL.md +3 -3
- package/skills/observability/SKILL.md +6 -5
- package/skills/parallel/SKILL.md +1 -1
- package/skills/ppr/SKILL.md +129 -77
- package/skills/prerender/SKILL.md +3 -3
- package/skills/rango/SKILL.md +25 -6
- package/skills/route/SKILL.md +2 -0
- package/skills/testing/SKILL.md +27 -25
- package/skills/testing/cache-prerender.md +9 -9
- package/skills/testing/client-components.md +45 -3
- package/skills/testing/loader.md +3 -2
- package/skills/testing/middleware.md +1 -0
- package/skills/testing/predicates.md +49 -49
- package/skills/testing/render-handler.md +1 -0
- package/skills/testing/serve-shell-request.md +14 -0
- package/skills/testing/server-actions.md +9 -3
- package/skills/theme/SKILL.md +8 -4
- package/skills/typesafety/env-and-bindings.md +8 -0
- package/skills/use-cache/SKILL.md +64 -19
- package/skills/view-transitions/SKILL.md +150 -29
- package/src/__augment-tests__/augmented.check.ts +23 -0
- package/src/browser/event-controller.ts +4 -4
- package/src/browser/history-state.ts +52 -1
- package/src/browser/link-interceptor.ts +4 -0
- package/src/browser/navigation-bridge.ts +77 -18
- package/src/browser/navigation-client.ts +4 -3
- package/src/browser/navigation-store.ts +43 -1
- package/src/browser/navigation-transaction.ts +31 -11
- package/src/browser/partial-update.ts +146 -35
- package/src/browser/prefetch/cache.ts +6 -6
- package/src/browser/prefetch/fetch.ts +2 -2
- package/src/browser/react/Link.tsx +38 -33
- package/src/browser/react/NavigationProvider.tsx +2 -2
- package/src/browser/react/context.ts +2 -2
- package/src/browser/react/location-state-shared.ts +241 -49
- package/src/browser/react/location-state.ts +5 -2
- package/src/browser/rsc-router.tsx +4 -0
- package/src/browser/server-action-bridge.ts +84 -15
- package/src/browser/transition-when.ts +205 -0
- package/src/browser/types.ts +124 -10
- package/src/build/generate-manifest.ts +77 -1
- package/src/cache/background-task.ts +55 -2
- package/src/cache/cache-exec-scope.ts +48 -1
- package/src/cache/cache-key-utils.ts +56 -16
- package/src/cache/cache-policy.ts +9 -4
- package/src/cache/cache-runtime.ts +197 -144
- package/src/cache/cache-scope.ts +304 -112
- package/src/cache/cache-tag.ts +105 -13
- package/src/cache/cf/cf-cache-store.ts +152 -76
- package/src/cache/cf/cf-shell-frame.ts +2 -2
- package/src/cache/cf/cf-tag-marker-memo.ts +11 -100
- package/src/cache/document-cache.ts +53 -7
- package/src/cache/handle-snapshot.ts +52 -9
- package/src/cache/invalidation-order.ts +84 -0
- package/src/cache/request-tag-mask.ts +147 -0
- package/src/cache/shell-snapshot.ts +130 -348
- package/src/cache/tag-invalidation.ts +57 -51
- package/src/cache/types.ts +71 -67
- package/src/cache/vercel/vercel-cache-store.ts +61 -58
- package/src/client-urls/client-root.tsx +8 -4
- package/src/client-urls/client-urls.ts +8 -6
- package/src/client-urls/navigation.ts +55 -4
- package/src/client-urls/server-projection.ts +31 -10
- package/src/client-urls/types.ts +12 -5
- package/src/client.tsx +2 -0
- package/src/host/cookie-handler.ts +2 -1
- package/src/index.rsc.ts +3 -0
- package/src/index.ts +3 -0
- package/src/loader-redirect.tsx +7 -3
- package/src/prerender/build-shell-capture.ts +155 -146
- package/src/route-definition/dsl-helpers.ts +2 -0
- package/src/route-definition/helpers-types.ts +11 -11
- package/src/route-name.ts +12 -0
- package/src/router/content-negotiation.ts +4 -1
- package/src/router/error-handling.ts +5 -2
- package/src/router/handler-context.ts +10 -7
- package/src/router/intercept-resolution.ts +11 -1
- package/src/router/loader-resolution.ts +28 -3
- package/src/router/logging.ts +5 -3
- package/src/router/match-api.ts +62 -34
- package/src/router/match-context.ts +5 -0
- package/src/router/match-handlers.ts +9 -29
- package/src/router/match-middleware/background-revalidation.ts +3 -5
- package/src/router/match-middleware/cache-lookup.ts +35 -19
- package/src/router/match-middleware/cache-store.ts +15 -9
- package/src/router/match-result.ts +1 -0
- package/src/router/middleware.ts +2 -5
- package/src/router/navigation-snapshot.ts +6 -5
- package/src/router/prerender-match.ts +4 -0
- package/src/router/request-classification.ts +7 -4
- package/src/router/router-options.ts +4 -1
- package/src/router/segment-resolution/fresh.ts +0 -4
- package/src/router/segment-resolution/loader-cache.ts +150 -25
- package/src/router/segment-resolution/loader-mask.ts +3 -4
- package/src/router/segment-resolution/loader-snapshot.ts +15 -78
- package/src/router/segment-resolution/mask-nested.ts +47 -22
- package/src/router/segment-resolution/revalidation.ts +0 -3
- package/src/router/segment-resolution/view-transition-default.ts +6 -21
- package/src/router/telemetry.ts +6 -3
- package/src/router/transition-when.ts +34 -52
- package/src/router.ts +2 -1
- package/src/rsc/attach-transition-when.ts +47 -0
- package/src/rsc/full-payload.ts +30 -10
- package/src/rsc/handler.ts +12 -10
- package/src/rsc/loader-fetch.ts +2 -1
- package/src/rsc/manifest-init.ts +4 -0
- package/src/rsc/origin-guard.ts +8 -5
- package/src/rsc/progressive-enhancement.ts +7 -30
- package/src/rsc/response-cache-serve.ts +68 -80
- package/src/rsc/response-route-handler.ts +2 -2
- package/src/rsc/rsc-rendering.ts +206 -252
- package/src/rsc/server-action.ts +8 -20
- package/src/rsc/shell-build-manifest.ts +22 -20
- package/src/rsc/shell-capture-constants.ts +136 -20
- package/src/rsc/shell-capture.ts +352 -589
- package/src/rsc/shell-serve.ts +73 -109
- package/src/rsc/ssr-setup.ts +3 -2
- package/src/rsc/types.ts +2 -0
- package/src/segment-system.tsx +40 -7
- package/src/server/context.ts +189 -124
- package/src/server/cookie-store.ts +153 -127
- package/src/server/handle-store.ts +245 -27
- package/src/server/request-context.ts +123 -84
- package/src/server/request-headers.ts +134 -0
- package/src/server.ts +4 -0
- package/src/testing/dispatch.ts +4 -7
- package/src/testing/e2e/index.ts +1 -0
- package/src/testing/index.ts +5 -0
- package/src/testing/internal/action-id.ts +25 -0
- package/src/testing/internal/context.ts +1 -1
- package/src/testing/location-state-key.ts +45 -0
- package/src/testing/render-handler.ts +1 -1
- package/src/testing/render-route.tsx +109 -16
- package/src/testing/run-client-revalidate.ts +3 -19
- package/src/testing/run-loader.ts +5 -1
- package/src/testing/run-transition-when.ts +109 -172
- package/src/testing/serve-shell-request.ts +10 -7
- package/src/testing/shell-status.ts +60 -56
- package/src/transition-when-ref.ts +220 -0
- package/src/types/cache-types.ts +15 -3
- package/src/types/index.ts +3 -0
- package/src/types/segments.ts +94 -91
- package/src/urls/path-helper-types.ts +3 -4
- package/src/urls/pattern-types.ts +3 -4
- package/src/vite/discovery/discover-routers.ts +3 -0
- package/src/vite/discovery/shell-prerender-phase.ts +0 -2
- package/src/vite/discovery/virtual-module-codegen.ts +16 -6
- package/src/vite/plugins/transition-when-hoist.ts +1064 -0
- package/src/vite/rango.ts +2 -0
- package/src/vite/router-discovery.ts +75 -5
- package/dist/types/rsc/transition-gate.d.ts +0 -23
- package/src/rsc/transition-gate.ts +0 -86
|
@@ -3,24 +3,27 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Owns the single response-cache contract — cache-scope resolution from the
|
|
5
5
|
* matched entry tree, condition eval, key resolution (route key() > store
|
|
6
|
-
* keyGenerator > default), tag resolution,
|
|
7
|
-
* fresh-hit / SWR-revalidate /
|
|
6
|
+
* keyGenerator > default, CacheScope.resolveKeyFrom), tag resolution,
|
|
7
|
+
* pre-handler-callback timing, and the fresh-hit / SWR-revalidate /
|
|
8
|
+
* miss-write branches — for BOTH the production
|
|
8
9
|
* response-route handler (rsc/response-route-handler.ts) and the dispatch testing
|
|
9
10
|
* primitive (testing/dispatch.ts), so the two can never drift.
|
|
10
11
|
*
|
|
11
12
|
* Plugin-rsc hazard: cache-scope.ts pulls @vitejs/plugin-rsc (via segment-codec),
|
|
12
13
|
* which the non-Vite unit-test runner cannot resolve, and this module is on the
|
|
13
|
-
* testing barrel's EAGER graph (dispatch imports it). So `createCacheScope`
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* testing barrel's EAGER graph (dispatch imports it). So `createCacheScope` is
|
|
15
|
+
* NOT imported here at runtime — it is INJECTED by the caller (production
|
|
16
|
+
* imports it statically; dispatch lazy-imports it only once a response route
|
|
17
|
+
* matches). The only runtime imports here are plugin-rsc-free
|
|
17
18
|
* (helpers' isCacheableStatus/finalizeResponse, traverseBack); cache-scope is a
|
|
18
19
|
* type-only import (erased at build).
|
|
19
20
|
*/
|
|
20
21
|
|
|
21
22
|
import type { CacheScope } from "../cache/cache-scope.js";
|
|
22
|
-
import
|
|
23
|
-
|
|
23
|
+
import {
|
|
24
|
+
_getRequestContext,
|
|
25
|
+
type RequestContext,
|
|
26
|
+
} from "../server/request-context.js";
|
|
24
27
|
import type { SegmentCacheStore } from "../cache/types.js";
|
|
25
28
|
import type { EntryCacheConfig, EntryData } from "../server/context.js";
|
|
26
29
|
import { traverseBack } from "../router/pattern-matching.js";
|
|
@@ -31,18 +34,19 @@ import {
|
|
|
31
34
|
} from "./helpers.js";
|
|
32
35
|
import { reportCacheError } from "../cache/cache-error.js";
|
|
33
36
|
import { cacheKeyBase } from "../cache/cache-key-utils.js";
|
|
37
|
+
import {
|
|
38
|
+
executionStart,
|
|
39
|
+
predatesInvalidation,
|
|
40
|
+
type ExecutionStart,
|
|
41
|
+
} from "../cache/tag-invalidation.js";
|
|
34
42
|
import { hasPerClientSignal } from "../browser/cookie-name.js";
|
|
35
43
|
|
|
36
|
-
/** Injected cache-scope
|
|
44
|
+
/** Injected cache-scope builder (kept off this module's runtime import graph). */
|
|
37
45
|
export interface CacheScopeDeps {
|
|
38
46
|
createCacheScope: (
|
|
39
47
|
config: EntryCacheConfig | undefined,
|
|
40
48
|
parent?: CacheScope | null,
|
|
41
49
|
) => CacheScope | null;
|
|
42
|
-
resolveCacheTags: (
|
|
43
|
-
config: PartialCacheOptions | false,
|
|
44
|
-
ctx: RequestContext | undefined,
|
|
45
|
-
) => string[] | undefined;
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
export interface ServeResponseRouteWithCacheArgs {
|
|
@@ -60,8 +64,12 @@ export interface ServeResponseRouteWithCacheArgs {
|
|
|
60
64
|
* applies (no scope, disabled, condition false, or store lacks get/putResponse)
|
|
61
65
|
* so the caller falls through to a plain `executeHandler()` run.
|
|
62
66
|
*
|
|
63
|
-
* Must run inside runWithRequestContext (reads the ambient
|
|
64
|
-
* the helpers and reqCtx.waitUntil for background writes).
|
|
67
|
+
* Must run inside runWithRequestContext for `reqCtx` (reads the ambient
|
|
68
|
+
* request context via the helpers and reqCtx.waitUntil for background writes).
|
|
69
|
+
* Outside it, the route runs uncached: the scope resolves `key()`, a store
|
|
70
|
+
* keyGenerator and `condition()` against the ambient context, and without
|
|
71
|
+
* it a keyGenerator was skipped and the entry landed on the broad default
|
|
72
|
+
* key.
|
|
65
73
|
*/
|
|
66
74
|
export async function serveResponseRouteWithCache(
|
|
67
75
|
args: ServeResponseRouteWithCacheArgs,
|
|
@@ -75,6 +83,7 @@ export async function serveResponseRouteWithCache(
|
|
|
75
83
|
if (method !== "GET" && method !== "HEAD") {
|
|
76
84
|
return undefined;
|
|
77
85
|
}
|
|
86
|
+
if (_getRequestContext() !== reqCtx) return undefined;
|
|
78
87
|
|
|
79
88
|
let cacheScope: CacheScope | null = null;
|
|
80
89
|
for (const entry of traverseBack(manifestEntry)) {
|
|
@@ -83,20 +92,12 @@ export async function serveResponseRouteWithCache(
|
|
|
83
92
|
}
|
|
84
93
|
}
|
|
85
94
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
let conditionPassed = true;
|
|
90
|
-
if (cacheScope.config !== false && cacheScope.config.condition) {
|
|
91
|
-
try {
|
|
92
|
-
conditionPassed = !!cacheScope.config.condition(reqCtx);
|
|
93
|
-
} catch {
|
|
94
|
-
conditionPassed = false;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
95
|
+
// Skip the response cache when a condition() of the scope, or of any
|
|
96
|
+
// cache() enclosing it (#974), refuses this request.
|
|
97
|
+
if (!cacheScope?.allowsCache("read")) return undefined;
|
|
97
98
|
|
|
98
99
|
const store = cacheScope.getStore() ?? reqCtx._cacheStore;
|
|
99
|
-
if (!
|
|
100
|
+
if (!store?.getResponse || !store?.putResponse) {
|
|
100
101
|
return undefined;
|
|
101
102
|
}
|
|
102
103
|
|
|
@@ -105,11 +106,12 @@ export async function serveResponseRouteWithCache(
|
|
|
105
106
|
// the host-namespacing and search-normalization rules cannot drift.
|
|
106
107
|
let cacheKey = `response:${responseType}:${cacheKeyBase(url.host, url.pathname, url.searchParams, undefined, reqCtx._searchParamsFilter)}`;
|
|
107
108
|
|
|
108
|
-
//
|
|
109
|
-
// cache()
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
109
|
+
// Keyed like the segment record (CacheScope.resolveKeyFrom): with key()
|
|
110
|
+
// results on the cache() chain (a full override, namespaced, #975) or an
|
|
111
|
+
// enclosing scope on another store whose keyGenerator partitions (#974),
|
|
112
|
+
// `response:` plus the composed key, so a nested cache() never shares an
|
|
113
|
+
// entry across the enclosing partitions (#970); otherwise the store's
|
|
114
|
+
// keyGenerator result (it modifies the default key), else the default key.
|
|
113
115
|
//
|
|
114
116
|
// A CONFIGURED key()/keyGenerator that THROWS must DEGRADE TO A MISS, not fall
|
|
115
117
|
// back to the broad default key. The default key is intentionally broad; if the
|
|
@@ -118,45 +120,26 @@ export async function serveResponseRouteWithCache(
|
|
|
118
120
|
// poisoning). Mirrors the segment-cache behavior (cache-scope.ts lookupRoute):
|
|
119
121
|
// a throwing key degrades to a cache miss, never a collision onto the default
|
|
120
122
|
// slot, and so does a key() with no ambient request context to run in
|
|
121
|
-
// (resolveKeyFrom rejects).
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
} else if (store.keyGenerator) {
|
|
137
|
-
try {
|
|
138
|
-
cacheKey = await store.keyGenerator(reqCtx, cacheKey);
|
|
139
|
-
} catch (error) {
|
|
140
|
-
keyResolutionFailed = true;
|
|
141
|
-
reportCacheError(
|
|
142
|
-
error,
|
|
143
|
-
"cache-read",
|
|
144
|
-
"[ResponseCache] keyGenerator failed",
|
|
145
|
-
reqCtx,
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Degrade to a MISS: return undefined so the caller runs the route UNCACHED.
|
|
151
|
-
// This early-returns BEFORE _onResponseCallbacks is saved/cleared below, so the
|
|
152
|
-
// pre-handler onResponse callbacks are still intact for the uncached run.
|
|
153
|
-
if (keyResolutionFailed) {
|
|
123
|
+
// (resolveKeyFrom rejects).
|
|
124
|
+
try {
|
|
125
|
+
cacheKey = await cacheScope.resolveKeyFrom(cacheKey, "response:");
|
|
126
|
+
} catch (error) {
|
|
127
|
+
reportCacheError(
|
|
128
|
+
error,
|
|
129
|
+
"cache-read",
|
|
130
|
+
"[ResponseCache] Key resolution failed",
|
|
131
|
+
reqCtx,
|
|
132
|
+
);
|
|
133
|
+
// Degrade to a MISS: the caller runs the route UNCACHED. This returns
|
|
134
|
+
// BEFORE _onResponseCallbacks is saved/cleared below, so the pre-handler
|
|
135
|
+
// onResponse callbacks are still intact for the uncached run.
|
|
154
136
|
return undefined;
|
|
155
137
|
}
|
|
156
138
|
|
|
157
|
-
// Resolve cache tags for this
|
|
158
|
-
// request context is available, so the
|
|
159
|
-
|
|
139
|
+
// Resolve cache tags for this entry (static or dynamic, the enclosing
|
|
140
|
+
// scopes' included, #974) while the request context is available, so the
|
|
141
|
+
// stored entry is tag-invalidatable.
|
|
142
|
+
const responseTags = cacheScope.resolveTags(reqCtx);
|
|
160
143
|
|
|
161
144
|
// Pre-handler callbacks (registered by app-level middleware before the cache
|
|
162
145
|
// block) are saved and the live array is cleared:
|
|
@@ -183,17 +166,26 @@ export async function serveResponseRouteWithCache(
|
|
|
183
166
|
const canServeCached = (response: Response): boolean =>
|
|
184
167
|
isCacheableStatus(response.status) && !hasPerClientSignal(response.headers);
|
|
185
168
|
|
|
186
|
-
|
|
169
|
+
// A handler run that started before one of the entry's tags was
|
|
170
|
+
// invalidated is not written (#977, predatesInvalidation).
|
|
171
|
+
const putFresh = async (
|
|
187
172
|
store2: SegmentCacheStore,
|
|
188
173
|
fresh: Response,
|
|
189
|
-
|
|
190
|
-
|
|
174
|
+
start: ExecutionStart,
|
|
175
|
+
): Promise<void> => {
|
|
176
|
+
if (await predatesInvalidation(store2, responseTags, start)) {
|
|
177
|
+
// Nothing reads the copy now: release it (a tee branch buffers).
|
|
178
|
+
await fresh.body?.cancel();
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
await store2.putResponse!(
|
|
191
182
|
cacheKey,
|
|
192
|
-
fresh
|
|
183
|
+
fresh,
|
|
193
184
|
cacheScope!.ttl,
|
|
194
185
|
cacheScope!.swr,
|
|
195
186
|
responseTags,
|
|
196
187
|
);
|
|
188
|
+
};
|
|
197
189
|
|
|
198
190
|
try {
|
|
199
191
|
const cached = await store.getResponse(cacheKey);
|
|
@@ -204,8 +196,9 @@ export async function serveResponseRouteWithCache(
|
|
|
204
196
|
// Stale hit (SWR): return cached, revalidate in background.
|
|
205
197
|
reqCtx.waitUntil(async () => {
|
|
206
198
|
try {
|
|
199
|
+
const start = executionStart();
|
|
207
200
|
const fresh = finalizeResponse(await executeHandler());
|
|
208
|
-
if (canStore(fresh)) await putFresh(store, fresh);
|
|
201
|
+
if (canStore(fresh)) await putFresh(store, fresh, start);
|
|
209
202
|
} catch (error) {
|
|
210
203
|
reportCacheError(
|
|
211
204
|
error,
|
|
@@ -227,6 +220,7 @@ export async function serveResponseRouteWithCache(
|
|
|
227
220
|
}
|
|
228
221
|
|
|
229
222
|
// Cache miss: execute the handler and cache the result when storeable.
|
|
223
|
+
const start = executionStart();
|
|
230
224
|
const response = finalizeResponse(await executeHandler());
|
|
231
225
|
if (canStore(response)) {
|
|
232
226
|
// Clone SYNCHRONOUSLY here, before returning. The original `response` is
|
|
@@ -241,13 +235,7 @@ export async function serveResponseRouteWithCache(
|
|
|
241
235
|
const toCache = response.clone();
|
|
242
236
|
reqCtx.waitUntil(async () => {
|
|
243
237
|
try {
|
|
244
|
-
await store
|
|
245
|
-
cacheKey,
|
|
246
|
-
toCache,
|
|
247
|
-
cacheScope!.ttl,
|
|
248
|
-
cacheScope!.swr,
|
|
249
|
-
responseTags,
|
|
250
|
-
);
|
|
238
|
+
await putFresh(store, toCache, start);
|
|
251
239
|
} catch (error) {
|
|
252
240
|
reportCacheError(
|
|
253
241
|
error,
|
|
@@ -11,7 +11,7 @@ import { getRequestContext } from "../server/request-context.js";
|
|
|
11
11
|
import { contextGet, isNonCacheable } from "../context-var.js";
|
|
12
12
|
import { NOCACHE_SYMBOL } from "../cache/taint.js";
|
|
13
13
|
import { RESPONSE_TYPE_MIME } from "../router/content-negotiation.js";
|
|
14
|
-
import { createCacheScope
|
|
14
|
+
import { createCacheScope } from "../cache/cache-scope.js";
|
|
15
15
|
import { serveResponseRouteWithCache } from "./response-cache-serve.js";
|
|
16
16
|
import { executeMiddleware } from "../router/middleware.js";
|
|
17
17
|
import {
|
|
@@ -220,7 +220,7 @@ export async function handleResponseRoute<TEnv>(
|
|
|
220
220
|
responseType: preview.responseType,
|
|
221
221
|
url,
|
|
222
222
|
executeHandler,
|
|
223
|
-
deps: { createCacheScope
|
|
223
|
+
deps: { createCacheScope },
|
|
224
224
|
});
|
|
225
225
|
if (cached !== undefined) return cached;
|
|
226
226
|
}
|