@rangojs/router 0.17.0 → 0.18.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/README.md +3 -2
- package/dist/types/browser/cookie-name.d.ts +6 -0
- package/dist/types/browser/history-state.d.ts +16 -0
- package/dist/types/cache/cache-key-utils.d.ts +17 -2
- package/dist/types/cache/cache-policy.d.ts +17 -0
- package/dist/types/cache/cache-scope.d.ts +98 -14
- package/dist/types/cache/cache-tag.d.ts +92 -7
- package/dist/types/cache/cf/cf-base64.d.ts +6 -0
- package/dist/types/cache/cf/cf-cache-constants.d.ts +11 -0
- package/dist/types/cache/cf/cf-cache-store.d.ts +185 -44
- package/dist/types/cache/cf/cf-cache-types.d.ts +31 -4
- package/dist/types/cache/cf/cf-shell-frame.d.ts +95 -0
- package/dist/types/cache/cf/cf-tag-marker-memo.d.ts +34 -0
- package/dist/types/cache/handle-snapshot.d.ts +4 -3
- package/dist/types/cache/index.d.ts +1 -0
- package/dist/types/cache/isolate-tag-memo.d.ts +149 -0
- package/dist/types/cache/shell-memo.d.ts +178 -0
- package/dist/types/cache/shell-snapshot.d.ts +110 -21
- package/dist/types/cache/tag-invalidation.d.ts +30 -3
- package/dist/types/cache/types.d.ts +207 -43
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +111 -13
- package/dist/types/prerender/build-shell-capture.d.ts +11 -4
- package/dist/types/router/instrument.d.ts +8 -0
- package/dist/types/router/middleware-types.d.ts +6 -1
- package/dist/types/router/segment-resolution/loader-cache.d.ts +40 -11
- package/dist/types/router/segment-resolution/loader-snapshot.d.ts +21 -10
- package/dist/types/router/segment-resolution/mask-nested.d.ts +65 -24
- package/dist/types/rsc/full-payload.d.ts +14 -0
- package/dist/types/rsc/handler.d.ts +1 -1
- package/dist/types/rsc/shell-build-manifest.d.ts +8 -0
- package/dist/types/rsc/shell-capture-constants.d.ts +53 -6
- package/dist/types/rsc/shell-capture.d.ts +146 -15
- package/dist/types/rsc/shell-serve.d.ts +140 -17
- package/dist/types/rsc/types.d.ts +7 -0
- package/dist/types/server/context.d.ts +109 -15
- package/dist/types/server/cookie-store.d.ts +21 -0
- package/dist/types/server/request-context.d.ts +159 -33
- package/dist/types/ssr/index.d.ts +9 -0
- package/dist/types/ssr/ssr-root.d.ts +9 -8
- package/dist/types/testing/flight.entry.d.ts +7 -0
- package/dist/types/testing/run-loader.d.ts +18 -3
- package/dist/types/testing/serve-shell-request.d.ts +132 -0
- package/dist/types/testing/shell-status.d.ts +23 -10
- package/dist/types/types/handler-context.d.ts +14 -1
- package/dist/types/urls/pattern-types.d.ts +22 -18
- package/dist/types/vite/router-discovery.d.ts +29 -2
- package/dist/vite/index.js +46 -9
- package/package.json +1 -1
- package/skills/breadcrumbs/SKILL.md +17 -7
- package/skills/cache-guide/SKILL.md +123 -51
- package/skills/caching/SKILL.md +253 -23
- package/skills/catalog.json +1 -1
- package/skills/client-urls/SKILL.md +11 -6
- package/skills/cloudflare/SKILL.md +15 -0
- package/skills/comparison/references/framework-comparison.md +44 -32
- package/skills/defer-hydration/SKILL.md +50 -30
- package/skills/deployment-caching/SKILL.md +5 -2
- package/skills/document-cache/SKILL.md +8 -2
- package/skills/handler-use/SKILL.md +2 -0
- package/skills/hooks/handle-and-actions.md +3 -1
- package/skills/hooks/state.md +3 -1
- package/skills/loader/SKILL.md +161 -39
- package/skills/middleware/SKILL.md +16 -9
- package/skills/migrate-nextjs/SKILL.md +67 -36
- package/skills/migrate-react-router/SKILL.md +2 -1
- package/skills/migrate-react-router/component-migration.md +3 -1
- package/skills/migrate-react-router/data-and-actions.md +3 -1
- package/skills/migrate-react-router/route-mapping.md +7 -4
- package/skills/observability/SKILL.md +64 -0
- package/skills/parallel/SKILL.md +13 -8
- package/skills/ppr/SKILL.md +655 -363
- package/skills/prerender/SKILL.md +27 -14
- package/skills/rango/SKILL.md +52 -33
- package/skills/route/SKILL.md +12 -7
- package/skills/router-setup/SKILL.md +4 -2
- package/skills/scripts/SKILL.md +8 -1
- package/skills/server-actions/SKILL.md +11 -0
- package/skills/shell-manifest/SKILL.md +21 -12
- package/skills/testing/SKILL.md +25 -21
- package/skills/testing/cache-prerender.md +15 -14
- package/skills/testing/loader.md +18 -1
- package/skills/testing/serve-shell-request.md +188 -0
- package/skills/theme/SKILL.md +52 -4
- package/skills/typesafety/env-and-bindings.md +10 -2
- package/skills/use-cache/SKILL.md +39 -16
- package/skills/vercel/SKILL.md +14 -2
- package/skills/view-transitions/SKILL.md +1 -1
- package/src/browser/cookie-name.ts +23 -0
- package/src/browser/history-state.ts +23 -0
- package/src/browser/rsc-router.tsx +5 -0
- package/src/cache/cache-key-utils.ts +22 -2
- package/src/cache/cache-policy.ts +22 -0
- package/src/cache/cache-runtime.ts +34 -7
- package/src/cache/cache-scope.ts +345 -33
- package/src/cache/cache-tag.ts +375 -11
- package/src/cache/cf/cf-base64.ts +36 -4
- package/src/cache/cf/cf-cache-constants.ts +12 -0
- package/src/cache/cf/cf-cache-store.ts +990 -348
- package/src/cache/cf/cf-cache-types.ts +32 -4
- package/src/cache/cf/cf-shell-frame.ts +258 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +143 -39
- package/src/cache/handle-snapshot.ts +4 -3
- package/src/cache/index.ts +2 -0
- package/src/cache/isolate-tag-memo.ts +308 -0
- package/src/cache/shell-memo.ts +341 -0
- package/src/cache/shell-snapshot.ts +217 -27
- package/src/cache/tag-invalidation.ts +104 -19
- package/src/cache/types.ts +211 -43
- package/src/cache/vercel/vercel-cache-store.ts +545 -61
- package/src/prerender/build-shell-capture.ts +65 -11
- package/src/route-definition/dsl-helpers.ts +4 -3
- package/src/router/handler-context.ts +38 -4
- package/src/router/instrument.ts +54 -2
- package/src/router/intercept-resolution.ts +19 -7
- package/src/router/loader-resolution.ts +63 -32
- package/src/router/match-api.ts +28 -9
- package/src/router/match-handlers.ts +5 -0
- package/src/router/match-middleware/cache-lookup.ts +17 -0
- package/src/router/match-middleware/cache-store.ts +31 -11
- package/src/router/middleware-types.ts +6 -1
- package/src/router/middleware.ts +23 -4
- package/src/router/prerender-match.ts +6 -0
- package/src/router/segment-resolution/fresh.ts +18 -9
- package/src/router/segment-resolution/helpers.ts +4 -2
- package/src/router/segment-resolution/loader-cache.ts +227 -56
- package/src/router/segment-resolution/loader-snapshot.ts +203 -51
- package/src/router/segment-resolution/mask-nested.ts +136 -42
- package/src/router/segment-resolution/revalidation.ts +27 -10
- package/src/rsc/full-payload.ts +25 -1
- package/src/rsc/handler.ts +14 -2
- package/src/rsc/progressive-enhancement.ts +3 -2
- package/src/rsc/response-cache-serve.ts +9 -6
- package/src/rsc/rsc-rendering.ts +601 -181
- package/src/rsc/shell-build-manifest.ts +27 -9
- package/src/rsc/shell-capture-constants.ts +60 -6
- package/src/rsc/shell-capture.ts +1001 -250
- package/src/rsc/shell-serve.ts +316 -34
- package/src/rsc/types.ts +7 -0
- package/src/server/context.ts +219 -28
- package/src/server/cookie-store.ts +87 -62
- package/src/server/request-context.ts +263 -38
- package/src/ssr/index.tsx +96 -37
- package/src/ssr/ssr-root.tsx +9 -8
- package/src/testing/flight.entry.ts +14 -0
- package/src/testing/run-loader.ts +63 -5
- package/src/testing/serve-shell-request.ts +378 -0
- package/src/testing/shell-status.ts +34 -12
- package/src/theme/ThemeProvider.tsx +7 -6
- package/src/types/handler-context.ts +14 -1
- package/src/urls/pattern-types.ts +22 -18
- package/src/vite/discovery/shell-prerender-phase.ts +9 -0
- package/src/vite/router-discovery.ts +14 -4
|
@@ -81,16 +81,16 @@ function loadManifest(): Promise<ShellManifestModule | null> {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
|
-
* Per-spec verdict memo for the version +
|
|
84
|
+
* Per-spec verdict memo for the version + structural gates. A manifest record
|
|
85
85
|
* is immutable for the process lifetime (content-hashed asset module), so its
|
|
86
|
-
* gate verdict is constant
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
86
|
+
* gate verdict is constant: a fresh build hit never populates the runtime
|
|
87
|
+
* store, so the store MISS + read-through is the steady state, not a warm-up.
|
|
88
|
+
* Only the per-request gates (tag markers, staleness) stay outside the memo;
|
|
89
|
+
* the document HIT decodes the prelude once per serve (openShellDocument),
|
|
90
|
+
* partial replay never does. `null` memoizes a failed verdict —
|
|
91
|
+
* deterministically invalid. Spec-only keying is sound because buildVersion is
|
|
92
|
+
* process-constant on the manifest path (folded into the shipped worker; dev
|
|
93
|
+
* never loads a manifest).
|
|
94
94
|
*/
|
|
95
95
|
const validatedSpecs = new Map<string, ValidatedBuildShellEntry | null>();
|
|
96
96
|
|
|
@@ -259,6 +259,24 @@ async function fetchDevShellEntry(
|
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
+
/**
|
|
263
|
+
* Whether a build-time shell exists for `pathname` (the caller checks the
|
|
264
|
+
* request is search-less, like the entries lookupBuildShell serves): a
|
|
265
|
+
* manifest entry for the path in production, a Prerender route in dev. No
|
|
266
|
+
* asset load and no dev capture: it only decides whether a request that
|
|
267
|
+
* cannot read the build shell deserves a warning.
|
|
268
|
+
*/
|
|
269
|
+
export async function hasBuildShell(
|
|
270
|
+
pathname: string,
|
|
271
|
+
dev?: DevShellLookup,
|
|
272
|
+
): Promise<boolean> {
|
|
273
|
+
if (globalThis.__loadShellManifestModule === undefined) {
|
|
274
|
+
return dev?.isPrerenderRoute === true;
|
|
275
|
+
}
|
|
276
|
+
const mod = await loadManifest();
|
|
277
|
+
return mod?.default[buildShellManifestKey(pathname)] !== undefined;
|
|
278
|
+
}
|
|
279
|
+
|
|
262
280
|
/**
|
|
263
281
|
* Look up the baked shell entry for a request, applying every serve gate:
|
|
264
282
|
* search-less requests only (the build captured the bare pathname; a
|
|
@@ -14,18 +14,72 @@
|
|
|
14
14
|
* costs latency-to-HIT only — never a served response — and 5s spuriously
|
|
15
15
|
* refused legitimately-slow deferred shell material (a real storefront's meta
|
|
16
16
|
* chains settle at ~7s). Ceiling math: workerd's waitUntil lifetime is ~30s
|
|
17
|
-
* past response completion
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
17
|
+
* past response completion. An attempt that consumed the whole budget is not
|
|
18
|
+
* retried in place (shell-capture.ts noShellCauses), so the envelope is one
|
|
19
|
+
* budget plus store I/O; the retry follows only an attempt that ended early
|
|
20
|
+
* (a cold-module abort). Past the ceiling the platform kill degrades to the
|
|
21
|
+
* existing best-effort contract (the key stays MISS; a later request
|
|
22
|
+
* re-captures).
|
|
23
23
|
* Node/dev and build-time captures have no waitUntil ceiling. The per-route
|
|
24
24
|
* `ppr.captureTimeout` knob remains for tightening below the default. See
|
|
25
25
|
* docs/design/ppr-shell-resume.md (Cost model).
|
|
26
26
|
*/
|
|
27
27
|
export const SHELL_CAPTURE_MAX_WAIT_MS = 15_000;
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* The shell key for one request partition (cache-scope.ts
|
|
31
|
+
* resolveShellPartition): the route cache() `key()` or store keyGenerator
|
|
32
|
+
* result that partitions the route's record partitions its shell too, so
|
|
33
|
+
* each partition captures and serves its own. Here, in the leaf module, so
|
|
34
|
+
* the testing helper `shellCacheKey` (testing/shell-status.ts) calls it
|
|
35
|
+
* without pulling shell-serve.ts.
|
|
36
|
+
*
|
|
37
|
+
* The partition is URI-encoded: it is request-derived, and raw it could end
|
|
38
|
+
* in a suffix another key is built with (navigationShellKey), so a partition
|
|
39
|
+
* `gold:navigation` named gold's navigation entry and its document shell
|
|
40
|
+
* replayed to gold's navigations. Encoded, it holds no `:` or `|`.
|
|
41
|
+
*/
|
|
42
|
+
export function partitionShellKey(key: string, partition: string): string {
|
|
43
|
+
return `${key}|${encodeURIComponent(partition)}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The navigation-only entry beside a document shell key (a cold partial
|
|
48
|
+
* request's capture, rsc-rendering.ts). A suffix after the (encoded)
|
|
49
|
+
* partition: partitionShellKey keeps the two unambiguous.
|
|
50
|
+
*/
|
|
51
|
+
export function navigationShellKey(key: string): string {
|
|
52
|
+
return `${key}:navigation`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Fixed number of macrotask hops between `quiesce` resolving and the abort. These
|
|
57
|
+
* give React's fizz worker turns to flush the settled shell into the prelude and
|
|
58
|
+
* mark still-pending boundaries as POSTPONED (rather than errored) before
|
|
59
|
+
* controller.abort() lands. Not a wall-clock wait. Taken by captureShellHTML
|
|
60
|
+
* (ssr/index.tsx) and by the testing SSR stub (testing/serve-shell-request.ts),
|
|
61
|
+
* so the stub freezes the same Flight the real capture would.
|
|
62
|
+
*
|
|
63
|
+
* Why 16 and not the original 2: under the REPLAY-ONLY capture model
|
|
64
|
+
* (docs/design/ppr-shell-resume.md), the capture Flight render serializes ring-3
|
|
65
|
+
* cached segments that are ALREADY serialized, so it emits the whole shell payload
|
|
66
|
+
* in the first tick and the gate declares quiesce almost immediately (~a few ms).
|
|
67
|
+
* On the old fresh-execution path the Flight dribbled out as handlers ran, so
|
|
68
|
+
* Flight-quiet effectively meant "the shell has rendered" and 2 hops sufficed.
|
|
69
|
+
*
|
|
70
|
+
* Hops alone are NOT render-readiness: fizz cannot emit even <html> until the
|
|
71
|
+
* payload root settles, nor complete a shell whose client components are
|
|
72
|
+
* still loading — real module-runner I/O in dev (100ms+ cold), which no fixed
|
|
73
|
+
* count of near-zero-cost task hops can buy. captureShellHTML therefore
|
|
74
|
+
* awaits the payload-settled signal (SsrRootOptions.onPayloadSettled) and
|
|
75
|
+
* then the client-reference loads in flight in the isolate (captureClientLoads),
|
|
76
|
+
* deadline-bounded, between quiesce and these hops; the hops then only flush
|
|
77
|
+
* the settled tree and mark pending boundaries POSTPONED. Still task-based
|
|
78
|
+
* (masked loaders never emit, so more hops never lets a hole settle). Bounded
|
|
79
|
+
* by maxWaitMs end to end.
|
|
80
|
+
*/
|
|
81
|
+
export const POST_QUIESCE_TASK_HOPS = 16;
|
|
82
|
+
|
|
29
83
|
/**
|
|
30
84
|
* Hard cap on one capture TASK — runShellCapture end to end (both attempts +
|
|
31
85
|
* the in-place retry delay). SHELL_CAPTURE_MAX_WAIT_MS arms only inside
|