@rangojs/router 0.21.0 → 0.22.1
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/bin/rango.js +13 -1
- package/dist/types/browser/event-controller.d.ts +30 -13
- package/dist/types/browser/navigation-store.d.ts +9 -0
- package/dist/types/browser/partial-update.d.ts +2 -1
- package/dist/types/browser/prefetch/default-strategy.d.ts +16 -20
- package/dist/types/browser/react/NavigationProvider.d.ts +14 -1
- package/dist/types/browser/react/context.d.ts +14 -0
- package/dist/types/browser/rsc-router.d.ts +13 -2
- package/dist/types/browser/types.d.ts +10 -0
- package/dist/types/build/generate-manifest.d.ts +2 -0
- package/dist/types/cache/background-task.d.ts +22 -0
- package/dist/types/cache/cache-key-utils.d.ts +50 -5
- package/dist/types/cache/cache-policy.d.ts +17 -0
- package/dist/types/cache/cache-scope.d.ts +1 -1
- package/dist/types/cache/cf/cf-cache-store.d.ts +7 -1
- package/dist/types/cache/document-cache.d.ts +8 -5
- package/dist/types/cache/handle-snapshot.d.ts +23 -0
- package/dist/types/cache/index.d.ts +1 -1
- package/dist/types/cache/invalidation-order.d.ts +14 -0
- package/dist/types/cache/memory-segment-store.d.ts +33 -1
- package/dist/types/cache/shell-snapshot.d.ts +10 -1
- package/dist/types/cache/store-scope.d.ts +22 -0
- package/dist/types/cache/tag-invalidation.d.ts +7 -6
- package/dist/types/cache/types.d.ts +63 -14
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +7 -1
- package/dist/types/errors.d.ts +6 -0
- package/dist/types/handles/deferred-resolution.d.ts +7 -0
- package/dist/types/internal-suspense-audit.d.ts +1 -0
- package/dist/types/loader-store.d.ts +4 -8
- package/dist/types/outlet-provider.d.ts +2 -1
- package/dist/types/prerender/cloudflare.d.ts +49 -0
- package/dist/types/prerender/create-prerender-trigger.d.ts +121 -0
- package/dist/types/prerender/index.d.ts +12 -0
- package/dist/types/prerender/memory-prerender-store.d.ts +29 -0
- package/dist/types/prerender/on-demand.d.ts +272 -0
- package/dist/types/prerender/producer-guard.d.ts +33 -0
- package/dist/types/prerender/shell-manifest-key.d.ts +1 -18
- package/dist/types/prerender/warm-request.d.ts +65 -0
- package/dist/types/prerender/warm.d.ts +65 -0
- package/dist/types/prerender/writable-store.d.ts +170 -0
- package/dist/types/prerender.d.ts +27 -0
- package/dist/types/reverse.d.ts +1 -1
- package/dist/types/route-content-wrapper.d.ts +3 -1
- package/dist/types/router/error-handling.d.ts +2 -0
- package/dist/types/router/handler-context.d.ts +1 -1
- package/dist/types/router/match-middleware/cache-lookup.d.ts +14 -0
- package/dist/types/router/pattern-matching.d.ts +2 -0
- package/dist/types/router/prefetch-default.d.ts +4 -4
- package/dist/types/router/prerender-match.d.ts +23 -1
- package/dist/types/router/route-trie-builder.d.ts +8 -1
- package/dist/types/router/router-context.d.ts +1 -0
- package/dist/types/router/router-interfaces.d.ts +30 -0
- package/dist/types/router/router-options.d.ts +24 -0
- package/dist/types/router/segment-resolution/fresh.d.ts +7 -0
- package/dist/types/router/segment-resolution/loader-cache.d.ts +2 -1
- package/dist/types/router/segment-resolution/revalidation.d.ts +5 -1
- package/dist/types/router/segment-resolution/streamed-handler-boundary.d.ts +43 -0
- package/dist/types/router/trie-matching.d.ts +2 -0
- package/dist/types/rsc/shell-build-manifest.d.ts +6 -4
- package/dist/types/rsc/shell-capture-constants.d.ts +20 -5
- package/dist/types/rsc/shell-capture.d.ts +14 -1
- package/dist/types/rsc/shell-serve.d.ts +2 -2
- package/dist/types/rsc/ssr-module-loader.d.ts +15 -0
- package/dist/types/rsc/types.d.ts +8 -0
- package/dist/types/segment-boundary-content.d.ts +17 -0
- package/dist/types/segment-loader-promise.d.ts +2 -6
- package/dist/types/server/build-version-table.d.ts +9 -0
- package/dist/types/server/context.d.ts +12 -4
- package/dist/types/server/handle-store.d.ts +2 -0
- package/dist/types/server/request-context.d.ts +63 -2
- package/dist/types/suspense-audit-react.d.ts +26 -0
- package/dist/types/suspense-audit.d.ts +157 -0
- package/dist/types/testing/action-form.d.ts +34 -0
- package/dist/types/testing/flight.entry.d.ts +2 -0
- package/dist/types/testing/index.d.ts +4 -0
- package/dist/types/testing/internal/server-modules.d.ts +8 -0
- package/dist/types/testing/serve-shell-request.d.ts +34 -4
- package/dist/types/testing/shell-status.d.ts +14 -6
- package/dist/types/testing/vitest-stubs/plugin-rsc.d.ts +9 -6
- package/dist/types/thenable-status.d.ts +6 -0
- package/dist/types/types/handler-context.d.ts +7 -0
- package/dist/types/types/route-entry.d.ts +5 -0
- package/dist/types/urls/path-helper.d.ts +18 -0
- package/dist/types/vite/discovery/state.d.ts +11 -0
- package/dist/types/vite/inject-client-debug.d.ts +6 -25
- package/dist/types/vite/utils/bundle-analysis.d.ts +6 -2
- package/dist/vite/index.js +180 -497
- package/package.json +13 -3
- package/skills/cache-guide/SKILL.md +18 -17
- package/skills/caching/SKILL.md +40 -4
- package/skills/catalog.json +1 -1
- package/skills/cloudflare/SKILL.md +131 -0
- package/skills/comparison/references/framework-comparison.md +1 -1
- package/skills/deployment-caching/SKILL.md +33 -12
- package/skills/document-cache/SKILL.md +16 -14
- package/skills/hooks/SKILL.md +22 -0
- package/skills/hooks/handle-and-actions.md +3 -4
- package/skills/hooks/navigation.md +10 -0
- package/skills/hooks/state.md +5 -4
- package/skills/host-router/SKILL.md +18 -0
- package/skills/loader/SKILL.md +6 -4
- package/skills/middleware/SKILL.md +1 -1
- package/skills/migrate-nextjs/SKILL.md +82 -9
- package/skills/ppr/SKILL.md +31 -8
- package/skills/prerender/SKILL.md +645 -8
- package/skills/rango/SKILL.md +1 -0
- package/skills/response-routes/SKILL.md +5 -5
- package/skills/route/SKILL.md +29 -0
- package/skills/testing/SKILL.md +2 -1
- package/skills/testing/cache-prerender.md +18 -17
- package/skills/testing/serve-shell-request.md +104 -8
- package/skills/use-cache/SKILL.md +9 -5
- package/skills/vercel/SKILL.md +2 -0
- package/skills/view-transitions/SKILL.md +9 -4
- package/src/browser/event-controller.ts +69 -25
- package/src/browser/link-interceptor.ts +2 -2
- package/src/browser/navigation-bridge.ts +75 -35
- package/src/browser/navigation-store.ts +26 -0
- package/src/browser/navigation-transaction.ts +9 -2
- package/src/browser/network-error-handler.ts +2 -0
- package/src/browser/partial-update.ts +48 -12
- package/src/browser/prefetch/default-strategy.ts +22 -42
- package/src/browser/react/Link.tsx +37 -42
- package/src/browser/react/NavigationProvider.tsx +63 -3
- package/src/browser/react/context.ts +17 -0
- package/src/browser/react/location-state.ts +5 -19
- package/src/browser/react/use-action.ts +4 -1
- package/src/browser/react/use-handle.ts +4 -20
- package/src/browser/react/use-link-status.ts +4 -3
- package/src/browser/react/use-navigation.ts +4 -1
- package/src/browser/react/use-params.ts +4 -1
- package/src/browser/react/use-pathname.ts +4 -1
- package/src/browser/react/use-search-params.ts +5 -3
- package/src/browser/react/use-segments.ts +36 -54
- package/src/browser/rsc-router.tsx +79 -39
- package/src/browser/segment-reconciler.ts +3 -3
- package/src/browser/server-action-bridge.ts +26 -6
- package/src/browser/types.ts +11 -0
- package/src/build/generate-manifest.ts +17 -0
- package/src/build/merge-full-manifests.ts +5 -0
- package/src/build/route-trie.ts +1 -0
- package/src/cache/background-task.ts +61 -0
- package/src/cache/cache-key-utils.ts +91 -12
- package/src/cache/cache-policy.ts +11 -2
- package/src/cache/cache-runtime.ts +23 -23
- package/src/cache/cache-scope.ts +38 -36
- package/src/cache/cf/cf-cache-store.ts +16 -11
- package/src/cache/document-cache.ts +35 -14
- package/src/cache/handle-snapshot.ts +50 -0
- package/src/cache/index.ts +1 -0
- package/src/cache/invalidation-order.ts +53 -0
- package/src/cache/memory-segment-store.ts +52 -1
- package/src/cache/shell-snapshot.ts +17 -0
- package/src/cache/store-scope.ts +36 -0
- package/src/cache/tag-invalidation.ts +7 -5
- package/src/cache/types.ts +69 -14
- package/src/cache/vercel/vercel-cache-store.ts +20 -6
- package/src/client.tsx +40 -3
- package/src/errors.ts +13 -6
- package/src/handles/deferred-resolution.ts +7 -2
- package/src/internal-suspense-audit.ts +12 -0
- package/src/loader-store.ts +4 -9
- package/src/outlet-provider.tsx +25 -1
- package/src/prerender/cloudflare.ts +130 -0
- package/src/prerender/create-prerender-trigger.ts +780 -0
- package/src/prerender/index.ts +39 -0
- package/src/prerender/memory-prerender-store.ts +115 -0
- package/src/prerender/on-demand.ts +339 -0
- package/src/prerender/producer-guard.ts +66 -0
- package/src/prerender/shell-manifest-key.ts +12 -17
- package/src/prerender/warm-request.ts +154 -0
- package/src/prerender/warm.ts +193 -0
- package/src/prerender/writable-store.ts +278 -0
- package/src/prerender.ts +29 -0
- package/src/reverse.ts +1 -1
- package/src/route-content-wrapper.tsx +107 -13
- package/src/router/error-handling.ts +12 -12
- package/src/router/find-match.ts +1 -0
- package/src/router/handler-context.ts +2 -0
- package/src/router/intercept-resolution.ts +15 -8
- package/src/router/loader-resolution.ts +2 -10
- package/src/router/match-middleware/background-revalidation.ts +2 -0
- package/src/router/match-middleware/cache-lookup.ts +230 -38
- package/src/router/pattern-matching.ts +14 -0
- package/src/router/prefetch-default.ts +4 -4
- package/src/router/prerender-match.ts +460 -352
- package/src/router/route-trie-builder.ts +9 -0
- package/src/router/router-context.ts +1 -0
- package/src/router/router-interfaces.ts +33 -0
- package/src/router/router-options.ts +30 -0
- package/src/router/segment-resolution/fresh.ts +20 -19
- package/src/router/segment-resolution/loader-cache.ts +15 -17
- package/src/router/segment-resolution/revalidation.ts +34 -24
- package/src/router/segment-resolution/streamed-handler-boundary.ts +133 -0
- package/src/router/trie-matching.ts +3 -0
- package/src/router.ts +107 -1
- package/src/rsc/handler.ts +51 -4
- package/src/rsc/progressive-enhancement.ts +5 -1
- package/src/rsc/response-cache-serve.ts +10 -4
- package/src/rsc/rsc-rendering.ts +53 -11
- package/src/rsc/shell-build-manifest.ts +10 -8
- package/src/rsc/shell-capture-constants.ts +39 -7
- package/src/rsc/shell-capture.ts +108 -19
- package/src/rsc/shell-serve.ts +12 -6
- package/src/rsc/ssr-module-loader.ts +26 -0
- package/src/rsc/types.ts +8 -0
- package/src/segment-boundary-content.ts +25 -0
- package/src/segment-loader-promise.ts +28 -38
- package/src/segment-system.tsx +117 -57
- package/src/server/build-version-table.ts +15 -0
- package/src/server/context.ts +40 -17
- package/src/server/cookie-store.ts +5 -0
- package/src/server/handle-store.ts +13 -0
- package/src/server/loader-registry.ts +6 -1
- package/src/server/request-context.ts +87 -1
- package/src/ssr/ssr-root.tsx +20 -13
- package/src/suspense-audit-react.tsx +98 -0
- package/src/suspense-audit.ts +1030 -0
- package/src/testing/action-form.ts +66 -0
- package/src/testing/flight-runtime.d.ts +27 -0
- package/src/testing/flight.entry.ts +3 -0
- package/src/testing/index.ts +19 -0
- package/src/testing/internal/server-modules.ts +32 -0
- package/src/testing/render-route.tsx +25 -12
- package/src/testing/serve-shell-request.ts +190 -34
- package/src/testing/shell-status.ts +17 -6
- package/src/testing/vitest-stubs/plugin-rsc.ts +37 -11
- package/src/thenable-status.ts +10 -0
- package/src/types/handler-context.ts +7 -0
- package/src/types/route-entry.ts +6 -0
- package/src/urls/path-helper.ts +69 -9
- package/src/use-loader.tsx +57 -30
- package/src/vite/discovery/bundle-postprocess.ts +4 -0
- package/src/vite/discovery/discover-routers.ts +15 -0
- package/src/vite/discovery/shell-prerender-phase.ts +5 -5
- package/src/vite/discovery/state.ts +17 -1
- package/src/vite/inject-client-debug.ts +42 -20
- package/src/vite/plugins/virtual-entries.ts +8 -1
- package/src/vite/router-discovery.ts +14 -0
- package/src/vite/utils/bundle-analysis.ts +39 -7
- package/dist/types/browser/react/subscribe-to-nothing.d.ts +0 -7
- package/dist/types/segment-content-promise.d.ts +0 -13
- package/src/browser/react/subscribe-to-nothing.ts +0 -7
- package/src/segment-content-promise.ts +0 -67
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare KV writable prerender store (`@rangojs/router/prerender/cloudflare`).
|
|
3
|
+
*
|
|
4
|
+
* Backs the durable overlay for on-demand prerender on Cloudflare. Self-contained
|
|
5
|
+
* (no CFCacheStore construction constraints): entries are stored under the
|
|
6
|
+
* versioned key `prerender:{routerId}:{version}:{routeName}:{paramHash}`, and
|
|
7
|
+
* tag invalidation uses the same timestamp-marker technique as the runtime cache
|
|
8
|
+
* — a per-tag KV marker holding the ms epoch of the last invalidation; a read
|
|
9
|
+
* treats the entry as stale (never deleted) when any of its tags' markers is at
|
|
10
|
+
* or after the entry's storedAt.
|
|
11
|
+
*
|
|
12
|
+
* Key design constraints (see docs/design/ondemand-prerender.md, Store Model):
|
|
13
|
+
* - staleAt is SOFT metadata; entries are written with NO KV expirationTtl. Hard
|
|
14
|
+
* expiry would delete the entry SWR needs and re-expose older bundled-manifest
|
|
15
|
+
* content below the overlay.
|
|
16
|
+
* - Prerender keys are route + params + variant only — never host-namespaced, so
|
|
17
|
+
* a refresh from a different host than the serve request still hits.
|
|
18
|
+
* - Invalidation is mark-stale, not delete (deleting would re-expose the manifest
|
|
19
|
+
* entry as the result of an "invalidation").
|
|
20
|
+
* - Tag markers use a prerender-specific prefix, separate from the runtime cache's
|
|
21
|
+
* `updateTag()`/`revalidateTag()` namespace, and are scoped by router id
|
|
22
|
+
* (`{prefix}{encodeURIComponent(routerId)}/{tag}`): routers sharing one KV
|
|
23
|
+
* namespace (an app behind a host router) must not mark each other's entries.
|
|
24
|
+
* - Markers carry no expiry: an entry without a `ttl` never goes stale by
|
|
25
|
+
* itself, so an expired marker would silently drop an invalidation.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import type { KVNamespace } from "../cache/cf/cf-cache-types.js";
|
|
29
|
+
import {
|
|
30
|
+
lowerStoredEntryStaleAt,
|
|
31
|
+
serializePrerenderKey,
|
|
32
|
+
type PrerenderKey,
|
|
33
|
+
type PrerenderStoredEntry,
|
|
34
|
+
type WritablePrerenderStore,
|
|
35
|
+
} from "./writable-store.js";
|
|
36
|
+
|
|
37
|
+
/** Prerender tag markers live in their own namespace, separate from the runtime cache. */
|
|
38
|
+
const PRERENDER_TAG_MARKER_PREFIX = "__rango_pr_tag__/";
|
|
39
|
+
|
|
40
|
+
export interface KVPrerenderStoreOptions {
|
|
41
|
+
/** Injectable clock for `markStale` markers in deterministic tests. Defaults to Date.now. */
|
|
42
|
+
now?: () => number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Create a {@link WritablePrerenderStore} backed by a Cloudflare KV namespace.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* import { createKVPrerenderStore } from "@rangojs/router/prerender/cloudflare";
|
|
51
|
+
*
|
|
52
|
+
* createRouter<Env>({
|
|
53
|
+
* prerender: (env) => ({
|
|
54
|
+
* store: createKVPrerenderStore(env.PRERENDER_KV),
|
|
55
|
+
* ttl: 3600,
|
|
56
|
+
* onRevalidate: (target, e) => e.PRERENDER_QUEUE.send({ target }),
|
|
57
|
+
* }),
|
|
58
|
+
* });
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export function createKVPrerenderStore(
|
|
62
|
+
kv: KVNamespace,
|
|
63
|
+
options: KVPrerenderStoreOptions = {},
|
|
64
|
+
): WritablePrerenderStore {
|
|
65
|
+
const now = options.now ?? (() => Date.now());
|
|
66
|
+
function markerKey(routerId: string, tag: string): string {
|
|
67
|
+
// An encoded id holds no "/", so the id/tag split is unambiguous.
|
|
68
|
+
return `${PRERENDER_TAG_MARKER_PREFIX}${encodeURIComponent(routerId)}/${tag}`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function readTagMarker(
|
|
72
|
+
routerId: string,
|
|
73
|
+
tag: string,
|
|
74
|
+
): Promise<number | null> {
|
|
75
|
+
const raw = await kv.get(markerKey(routerId, tag));
|
|
76
|
+
if (!raw) return null;
|
|
77
|
+
const n = Number(raw);
|
|
78
|
+
return Number.isFinite(n) ? n : null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
async get(key: PrerenderKey): Promise<PrerenderStoredEntry | null> {
|
|
83
|
+
const raw = await kv.get(serializePrerenderKey(key));
|
|
84
|
+
if (!raw) return null;
|
|
85
|
+
|
|
86
|
+
let stored: PrerenderStoredEntry;
|
|
87
|
+
try {
|
|
88
|
+
stored = JSON.parse(raw) as PrerenderStoredEntry;
|
|
89
|
+
} catch {
|
|
90
|
+
// Corrupt entry: treat as a miss rather than crash the serve path.
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Tag invalidation is mark-stale: a tag marked at or after the write
|
|
95
|
+
// forces the entry stale (it still serves). Shape is verified by the
|
|
96
|
+
// router; an already-stale entry skips the marker reads.
|
|
97
|
+
const meta = stored?.meta;
|
|
98
|
+
if (
|
|
99
|
+
meta?.tags?.length &&
|
|
100
|
+
!(meta.staleAt != null && meta.staleAt <= now())
|
|
101
|
+
) {
|
|
102
|
+
const markers = await Promise.all(
|
|
103
|
+
meta.tags.map((tag) => readTagMarker(key.routerId, tag)),
|
|
104
|
+
);
|
|
105
|
+
if (markers.some((m) => m != null && m >= meta.storedAt)) {
|
|
106
|
+
lowerStoredEntryStaleAt(stored, meta.storedAt);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return stored;
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
async set(key: PrerenderKey, stored: PrerenderStoredEntry): Promise<void> {
|
|
114
|
+
// No expirationTtl: staleAt is soft metadata (see file header).
|
|
115
|
+
await kv.put(serializePrerenderKey(key), JSON.stringify(stored));
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
async delete(key: PrerenderKey): Promise<void> {
|
|
119
|
+
await kv.delete(serializePrerenderKey(key));
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
async markStale(routerId: string, tags: string[]): Promise<void> {
|
|
123
|
+
if (tags.length === 0) return;
|
|
124
|
+
const marker = String(now());
|
|
125
|
+
await Promise.all(
|
|
126
|
+
tags.map((tag) => kv.put(markerKey(routerId, tag), marker)),
|
|
127
|
+
);
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|