@rangojs/router 0.32.0 → 0.33.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/bin/browser-7KIJ5HSV.js +15 -0
- package/dist/bin/chunk-3B7CKBRO.js +463 -0
- package/dist/bin/chunk-524VACCG.js +71 -0
- package/dist/bin/chunk-LD7UBHT4.js +196 -0
- package/dist/bin/chunk-TO6CRWLN.js +1429 -0
- package/dist/bin/chunk-TTXC2U3G.js +2477 -0
- package/dist/bin/client-urls-projection-DQLWPDAT.js +28 -0
- package/dist/bin/forward-user-plugins-URBZKJP4.js +62 -0
- package/dist/bin/rango.js +42 -10173
- package/dist/bin/runtime-EPUDEHO4.js +596 -0
- package/dist/bin/runtime-discovery-CZ2QHT4Q.js +352 -0
- package/dist/bin/state-ACD2MGKJ.js +16 -0
- package/dist/bin/temp-rsc-server-QRR6HD6T.js +3190 -0
- package/dist/types/bin/rango.d.ts +1 -0
- package/dist/types/browser/action-fence.d.ts +20 -0
- package/dist/types/browser/cookie-name.d.ts +51 -10
- package/dist/types/browser/invalidate-client-cache.d.ts +8 -6
- package/dist/types/browser/navigation-bridge.d.ts +36 -1
- package/dist/types/browser/navigation-client.d.ts +19 -0
- package/dist/types/browser/navigation-store-handle.d.ts +37 -4
- package/dist/types/browser/navigation-store.d.ts +2 -2
- package/dist/types/browser/navigation-transaction.d.ts +0 -1
- package/dist/types/browser/partial-update.d.ts +13 -0
- package/dist/types/browser/prefetch/cache.d.ts +96 -8
- package/dist/types/browser/prefetch/fetch.d.ts +26 -2
- package/dist/types/browser/prefetch/queue.d.ts +3 -2
- package/dist/types/browser/rango-state.d.ts +34 -5
- package/dist/types/browser/react/Link.d.ts +15 -6
- package/dist/types/browser/types.d.ts +25 -0
- package/dist/types/build/generate-route-types.d.ts +1 -1
- package/dist/types/build/route-types/include-resolution.d.ts +9 -1
- package/dist/types/build/route-types/router-processing.d.ts +3 -1
- package/dist/types/cache/cache-key-utils.d.ts +12 -8
- package/dist/types/cache/cache-scope.d.ts +4 -2
- package/dist/types/cache/cf/cf-cache-types.d.ts +9 -5
- package/dist/types/cache/document-cache-policy.d.ts +9 -1
- package/dist/types/cache/memory-segment-store.d.ts +3 -2
- package/dist/types/cache/segment-codec.d.ts +2 -2
- package/dist/types/cache/shell-snapshot.d.ts +1 -1
- package/dist/types/cache/types.d.ts +12 -7
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +2 -1
- package/dist/types/client-urls/types.d.ts +7 -5
- package/dist/types/prefetch-markers.d.ts +9 -0
- package/dist/types/prefetch-source-scope.d.ts +66 -0
- package/dist/types/route-definition/helpers-types.d.ts +8 -5
- package/dist/types/router/intercept-resolution.d.ts +25 -11
- package/dist/types/router/match-context.d.ts +1 -0
- package/dist/types/router/match-handlers.d.ts +1 -1
- package/dist/types/router/prefetch-cache-ttl.d.ts +11 -3
- package/dist/types/router/router-context.d.ts +1 -1
- package/dist/types/router/router-options.d.ts +6 -3
- package/dist/types/router/segment-resolution/loader-cache.d.ts +8 -0
- package/dist/types/router/segment-resolution/prefetch-deferral.d.ts +23 -7
- package/dist/types/router/segment-resolution/revalidation.d.ts +19 -0
- package/dist/types/router/source-reads.d.ts +53 -0
- package/dist/types/router/types.d.ts +1 -1
- package/dist/types/rsc/helpers.d.ts +5 -2
- package/dist/types/rsc/prefetch-render-error.d.ts +7 -2
- package/dist/types/rsc/request-stages.d.ts +2 -0
- package/dist/types/rsc/shell-serve.d.ts +6 -1
- package/dist/types/server/context.d.ts +23 -6
- package/dist/types/server/cookie-store.d.ts +15 -1
- package/dist/types/server/document-location-state.d.ts +5 -2
- package/dist/types/server/handle-store.d.ts +2 -0
- package/dist/types/server/request-context.d.ts +43 -7
- package/dist/types/testing/e2e/server.d.ts +16 -1
- package/dist/types/testing/render-route.d.ts +66 -2
- package/dist/types/testing/serve-shell-request.d.ts +6 -3
- package/dist/types/types/handler-context.d.ts +7 -5
- package/dist/types/types/loader-types.d.ts +7 -4
- package/dist/types/types/segments.d.ts +15 -4
- package/dist/types/urls/path-helper-types.d.ts +7 -5
- package/dist/types/vite/temp-rsc-server.d.ts +2 -2
- package/dist/vite/index.js +449 -189
- package/package.json +2 -2
- package/skills/app-structure/SKILL.md +74 -0
- package/skills/app-structure/e-commerce.md +10 -9
- package/skills/app-structure/large-app.md +15 -2
- package/skills/caching/SKILL.md +10 -5
- package/skills/client-urls/SKILL.md +18 -11
- package/skills/comparison/references/framework-comparison.md +13 -8
- package/skills/document-cache/SKILL.md +8 -0
- package/skills/hooks/navigation.md +8 -8
- package/skills/hooks/state.md +24 -8
- package/skills/intercept/SKILL.md +33 -12
- package/skills/layout/SKILL.md +11 -0
- package/skills/links/SKILL.md +101 -4
- package/skills/loader/SKILL.md +49 -22
- package/skills/migrate-nextjs/SKILL.md +8 -2
- package/skills/migrate-react-router/data-and-actions.md +5 -0
- package/skills/ppr/SKILL.md +26 -5
- package/skills/prerender/SKILL.md +4 -1
- package/skills/route/SKILL.md +6 -6
- package/skills/router-setup/SKILL.md +2 -1
- package/skills/server-actions/SKILL.md +41 -8
- package/skills/testing/client-components.md +29 -13
- package/skills/testing/serve-shell-request.md +7 -7
- package/skills/testing/server-actions.md +8 -0
- package/skills/ux-architecture/SKILL.md +67 -18
- package/src/bin/rango.ts +39 -13
- package/src/browser/action-fence.ts +72 -0
- package/src/browser/cookie-name.ts +82 -14
- package/src/browser/invalidate-client-cache.ts +9 -7
- package/src/browser/navigation-bridge.ts +164 -32
- package/src/browser/navigation-client.ts +95 -20
- package/src/browser/navigation-store-handle.ts +67 -5
- package/src/browser/navigation-store.ts +86 -17
- package/src/browser/navigation-transaction.ts +0 -6
- package/src/browser/partial-update.ts +31 -12
- package/src/browser/prefetch/cache.ts +188 -11
- package/src/browser/prefetch/fetch.ts +211 -51
- package/src/browser/prefetch/queue.ts +3 -2
- package/src/browser/rango-state.ts +50 -8
- package/src/browser/react/Link.tsx +20 -9
- package/src/browser/react/use-navigation.ts +1 -1
- package/src/browser/rsc-router.tsx +8 -1
- package/src/browser/server-action-bridge.ts +3 -3
- package/src/browser/types.ts +25 -0
- package/src/build/generate-route-types.ts +1 -0
- package/src/build/route-types/include-resolution.ts +40 -3
- package/src/build/route-types/router-processing.ts +170 -25
- package/src/build/route-types/scan-filter.ts +1 -0
- package/src/cache/cache-key-utils.ts +12 -8
- package/src/cache/cache-runtime.ts +5 -1
- package/src/cache/cache-scope.ts +28 -7
- package/src/cache/cf/cf-cache-types.ts +9 -5
- package/src/cache/document-cache-policy.ts +27 -0
- package/src/cache/document-cache.ts +5 -0
- package/src/cache/memory-segment-store.ts +3 -2
- package/src/cache/segment-codec.ts +2 -2
- package/src/cache/shell-snapshot.ts +1 -1
- package/src/cache/types.ts +12 -7
- package/src/cache/vercel/vercel-cache-store.ts +2 -1
- package/src/client-urls/types.ts +7 -5
- package/src/prefetch-markers.ts +10 -0
- package/src/prefetch-source-scope.ts +137 -0
- package/src/route-definition/helpers-types.ts +8 -5
- package/src/router/intercept-resolution.ts +94 -50
- package/src/router/loader-resolution.ts +8 -6
- package/src/router/match-api.ts +33 -29
- package/src/router/match-context.ts +5 -0
- package/src/router/match-handlers.ts +2 -1
- package/src/router/match-middleware/cache-lookup.ts +21 -13
- package/src/router/match-result.ts +39 -87
- package/src/router/navigation-snapshot.ts +18 -3
- package/src/router/prefetch-cache-ttl.ts +15 -3
- package/src/router/revalidation.ts +53 -23
- package/src/router/router-context.ts +2 -1
- package/src/router/router-options.ts +6 -3
- package/src/router/segment-resolution/loader-cache.ts +21 -3
- package/src/router/segment-resolution/prefetch-deferral.ts +38 -31
- package/src/router/segment-resolution/revalidation.ts +40 -12
- package/src/router/source-reads.ts +122 -0
- package/src/router/types.ts +2 -1
- package/src/router.ts +11 -12
- package/src/rsc/helpers.ts +8 -3
- package/src/rsc/prefetch-render-error.ts +7 -2
- package/src/rsc/progressive-enhancement.ts +3 -2
- package/src/rsc/request-stages.ts +59 -0
- package/src/rsc/rsc-rendering.ts +49 -33
- package/src/rsc/server-action.ts +2 -1
- package/src/rsc/shell-capture.ts +4 -5
- package/src/rsc/shell-serve.ts +12 -1
- package/src/segment-system.tsx +1 -1
- package/src/server/context.ts +37 -6
- package/src/server/cookie-store.ts +22 -1
- package/src/server/document-location-state.ts +23 -2
- package/src/server/handle-store.ts +2 -0
- package/src/server/request-context.ts +113 -28
- package/src/testing/dispatch.ts +3 -0
- package/src/testing/e2e/fixture.ts +4 -12
- package/src/testing/e2e/server.ts +91 -4
- package/src/testing/render-route.tsx +269 -4
- package/src/testing/serve-shell-request.ts +6 -3
- package/src/types/handler-context.ts +7 -5
- package/src/types/loader-types.ts +7 -4
- package/src/types/segments.ts +15 -4
- package/src/urls/path-helper-types.ts +7 -5
- package/src/vite/temp-rsc-server.ts +2 -2
package/README.md
CHANGED
|
@@ -445,8 +445,9 @@ that per link with `prefetch`: `"hover"`, `"viewport"`, `"render"`,
|
|
|
445
445
|
When a navigation has been fully prefetched, the page appears finished, with
|
|
446
446
|
no skeleton or loading flash. If you click while a prefetch is still loading,
|
|
447
447
|
the navigation reuses that request instead of starting a new one. Every
|
|
448
|
-
action
|
|
449
|
-
|
|
448
|
+
action marks prefetches stale by default: a click on a prefetch made before
|
|
449
|
+
the action shows the prefetched page at once, then revalidates it. Call
|
|
450
|
+
`invalidateClientCache()` for a full flush.
|
|
450
451
|
|
|
451
452
|
You can do the same caching work at other times:
|
|
452
453
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// src/deps/browser.ts
|
|
2
|
+
import {
|
|
3
|
+
createFromReadableStream,
|
|
4
|
+
createFromFetch,
|
|
5
|
+
setServerCallback,
|
|
6
|
+
encodeReply,
|
|
7
|
+
createTemporaryReferenceSet
|
|
8
|
+
} from "@vitejs/plugin-rsc/browser";
|
|
9
|
+
export {
|
|
10
|
+
createFromFetch,
|
|
11
|
+
createFromReadableStream,
|
|
12
|
+
createTemporaryReferenceSet,
|
|
13
|
+
encodeReply,
|
|
14
|
+
setServerCallback
|
|
15
|
+
};
|
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
// src/internal-debug.ts
|
|
2
|
+
var INTERNAL_RANGO_DEBUG = typeof process !== "undefined" && Boolean(process.env?.INTERNAL_RANGO_DEBUG);
|
|
3
|
+
|
|
4
|
+
// src/browser/logging.ts
|
|
5
|
+
var IS_BROWSER_DEBUG = INTERNAL_RANGO_DEBUG;
|
|
6
|
+
function debugLog(msg, ...args) {
|
|
7
|
+
if (INTERNAL_RANGO_DEBUG) {
|
|
8
|
+
console.log(msg, ...args);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// src/browser/cookie-name.ts
|
|
13
|
+
var DEFAULT_STATE_COOKIE_PREFIX = "rango-state";
|
|
14
|
+
function getRawCookieValue(cookieString, name) {
|
|
15
|
+
if (!cookieString) return null;
|
|
16
|
+
const target = name + "=";
|
|
17
|
+
for (const part of cookieString.split(";")) {
|
|
18
|
+
const trimmed = part.trim();
|
|
19
|
+
if (trimmed.startsWith(target)) {
|
|
20
|
+
const value = trimmed.slice(target.length);
|
|
21
|
+
return value === "" ? null : value;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
function encodeStateValue(version, timestamp, write = 0) {
|
|
27
|
+
const base = `${encodeURIComponent(version)}:${timestamp}`;
|
|
28
|
+
return write === 0 ? base : `${base}:${write}`;
|
|
29
|
+
}
|
|
30
|
+
function decodeStateValue(raw) {
|
|
31
|
+
const colon = raw.indexOf(":");
|
|
32
|
+
if (colon <= 0) return null;
|
|
33
|
+
const parts = raw.slice(colon + 1).split(":");
|
|
34
|
+
if (parts.length > 2) return null;
|
|
35
|
+
const timestamp = parseStatePart(parts[0]);
|
|
36
|
+
const write = parts.length === 2 ? parseStatePart(parts[1]) : 0;
|
|
37
|
+
if (timestamp === null || write === null) return null;
|
|
38
|
+
let version;
|
|
39
|
+
try {
|
|
40
|
+
version = decodeURIComponent(raw.slice(0, colon));
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return { version, timestamp, write };
|
|
45
|
+
}
|
|
46
|
+
function parseStatePart(part) {
|
|
47
|
+
if (part === "") return null;
|
|
48
|
+
const value = Number(part);
|
|
49
|
+
return Number.isFinite(value) ? value : null;
|
|
50
|
+
}
|
|
51
|
+
function stateEpoch(raw) {
|
|
52
|
+
const first = raw.indexOf(":");
|
|
53
|
+
if (first < 0) return raw;
|
|
54
|
+
const second = raw.indexOf(":", first + 1);
|
|
55
|
+
return second < 0 ? raw : raw.slice(0, second);
|
|
56
|
+
}
|
|
57
|
+
function mintStateValue(version, prevRaw) {
|
|
58
|
+
const prevTs = prevRaw ? decodeStateValue(prevRaw)?.timestamp ?? 0 : 0;
|
|
59
|
+
const ts = Math.max(Date.now(), prevTs + 1);
|
|
60
|
+
return encodeStateValue(version, ts);
|
|
61
|
+
}
|
|
62
|
+
function stateCookieAttributes(secure) {
|
|
63
|
+
return `; Path=/; SameSite=Lax${secure ? "; Secure" : ""}`;
|
|
64
|
+
}
|
|
65
|
+
function serializeStateCookie(name, value, secure) {
|
|
66
|
+
return `${name}=${value}${stateCookieAttributes(secure)}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/browser/rango-state.ts
|
|
70
|
+
var cookieName = DEFAULT_STATE_COOKIE_PREFIX;
|
|
71
|
+
var currentVersion = "0";
|
|
72
|
+
var mirror = null;
|
|
73
|
+
var cookieBacked = false;
|
|
74
|
+
var externalRotationObserver = null;
|
|
75
|
+
var externalWriteObserver = null;
|
|
76
|
+
function notifyExternalRotation(value) {
|
|
77
|
+
externalRotationObserver?.(value);
|
|
78
|
+
}
|
|
79
|
+
function readCookie(name) {
|
|
80
|
+
if (typeof document === "undefined") return { readable: false, value: null };
|
|
81
|
+
let raw;
|
|
82
|
+
try {
|
|
83
|
+
raw = document.cookie;
|
|
84
|
+
} catch {
|
|
85
|
+
return { readable: false, value: null };
|
|
86
|
+
}
|
|
87
|
+
return { readable: true, value: getRawCookieValue(raw, name) };
|
|
88
|
+
}
|
|
89
|
+
function writeCookie(name, value) {
|
|
90
|
+
if (typeof document === "undefined") return;
|
|
91
|
+
const secure = typeof location !== "undefined" && location.protocol === "https:";
|
|
92
|
+
try {
|
|
93
|
+
document.cookie = serializeStateCookie(name, value, secure);
|
|
94
|
+
} catch {
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function mintValue() {
|
|
98
|
+
return mintStateValue(currentVersion, mirror);
|
|
99
|
+
}
|
|
100
|
+
function getRangoState() {
|
|
101
|
+
const read = readCookie(cookieName);
|
|
102
|
+
if (!read.readable) {
|
|
103
|
+
return mirror ?? "0:0";
|
|
104
|
+
}
|
|
105
|
+
if (read.value !== null) {
|
|
106
|
+
if (read.value !== mirror) {
|
|
107
|
+
const rotated = mirror === null || stateEpoch(mirror) !== stateEpoch(read.value);
|
|
108
|
+
mirror = read.value;
|
|
109
|
+
cookieBacked = true;
|
|
110
|
+
if (rotated) notifyExternalRotation(read.value);
|
|
111
|
+
else externalWriteObserver?.();
|
|
112
|
+
} else {
|
|
113
|
+
cookieBacked = true;
|
|
114
|
+
}
|
|
115
|
+
return read.value;
|
|
116
|
+
}
|
|
117
|
+
if (cookieBacked) {
|
|
118
|
+
mirror = mintValue();
|
|
119
|
+
cookieBacked = false;
|
|
120
|
+
writeCookie(cookieName, mirror);
|
|
121
|
+
notifyExternalRotation(mirror);
|
|
122
|
+
} else if (mirror === null) {
|
|
123
|
+
mirror = mintValue();
|
|
124
|
+
writeCookie(cookieName, mirror);
|
|
125
|
+
}
|
|
126
|
+
return mirror;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// src/wire-params.ts
|
|
130
|
+
var WIRE = {
|
|
131
|
+
/** A navigation or prefetch: `true`. */
|
|
132
|
+
partial: "_rsc_partial",
|
|
133
|
+
/** The mounted segment ids, comma-joined. */
|
|
134
|
+
segments: "_rsc_segments",
|
|
135
|
+
/** A JS server action's id, in place of `partial`. */
|
|
136
|
+
action: "_rsc_action",
|
|
137
|
+
/** The client's build version (version-mismatch reload). */
|
|
138
|
+
version: "_rsc_v",
|
|
139
|
+
/** The client's router id (app-switch reload). */
|
|
140
|
+
routerId: "_rsc_rid",
|
|
141
|
+
/** The rewrite target of the page on screen (#1144). */
|
|
142
|
+
rewriteTarget: "_rsc_rt",
|
|
143
|
+
/** A stale request: `true` (router/navigation-snapshot.ts). */
|
|
144
|
+
stale: "_rsc_stale",
|
|
145
|
+
/**
|
|
146
|
+
* The id of an action's error boundary on screen that a stale request
|
|
147
|
+
* holds: read only beside `stale` (router/navigation-snapshot.ts).
|
|
148
|
+
*/
|
|
149
|
+
boundary: "_rsc_boundary",
|
|
150
|
+
/** A fill request (docs/design/prefetch-false.md): `1`. */
|
|
151
|
+
fill: "_rsc_fill",
|
|
152
|
+
/** A loader fetch's loader id (rsc/loader-fetch.ts). */
|
|
153
|
+
loader: "_rsc_loader",
|
|
154
|
+
/** A loader fetch's params, JSON: a query param, or a form field on a POST. */
|
|
155
|
+
loaderParams: "_rsc_loader_params",
|
|
156
|
+
/** The forced-MISS marker of a degraded PPR shell reload (rsc/shell-serve.ts). */
|
|
157
|
+
shellMiss: "_rsc_shell",
|
|
158
|
+
/** A connection warmup HEAD request (browser/connection-warmup.ts). */
|
|
159
|
+
warmup: "_rsc_warmup"
|
|
160
|
+
};
|
|
161
|
+
var WIRE_PREFIX = "_rsc_";
|
|
162
|
+
|
|
163
|
+
// src/prefetch-source-scope.ts
|
|
164
|
+
var PARAMS_SCOPE_PREFIX = "params; ";
|
|
165
|
+
function formatSourceLabel(shape, page) {
|
|
166
|
+
const parts = [];
|
|
167
|
+
if (shape.keys) {
|
|
168
|
+
parts.push(
|
|
169
|
+
"$k=" + Object.keys(page.params).sort().map(encodeURIComponent).join(",")
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
if (shape.route) parts.push(entry("$r", page.routeName));
|
|
173
|
+
for (const name of shape.names) {
|
|
174
|
+
parts.push(entry(encodeURIComponent(name), page.params[name]));
|
|
175
|
+
}
|
|
176
|
+
return parts.join("&");
|
|
177
|
+
}
|
|
178
|
+
function entry(name, value) {
|
|
179
|
+
return value === void 0 ? name : name + "=" + encodeURIComponent(value);
|
|
180
|
+
}
|
|
181
|
+
function paramsScopeLabel(header) {
|
|
182
|
+
if (!header?.startsWith(PARAMS_SCOPE_PREFIX)) return void 0;
|
|
183
|
+
return header.slice(PARAMS_SCOPE_PREFIX.length);
|
|
184
|
+
}
|
|
185
|
+
function parseSourceShape(label) {
|
|
186
|
+
let keys = false;
|
|
187
|
+
let route = false;
|
|
188
|
+
const names = [];
|
|
189
|
+
for (const part of label.split("&")) {
|
|
190
|
+
if (part === "") continue;
|
|
191
|
+
const eq = part.indexOf("=");
|
|
192
|
+
const name = eq === -1 ? part : part.slice(0, eq);
|
|
193
|
+
if (name === "$k") keys = true;
|
|
194
|
+
else if (name === "$r") route = true;
|
|
195
|
+
else names.push(decodeURIComponent(name));
|
|
196
|
+
}
|
|
197
|
+
return { keys, route, names: names.sort() };
|
|
198
|
+
}
|
|
199
|
+
function sourceShapeId(shape) {
|
|
200
|
+
return (shape.keys ? "k" : "") + (shape.route ? "r" : "") + ":" + shape.names.map(encodeURIComponent).join(",");
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// src/browser/prefetch/loader.ts
|
|
204
|
+
var runtime = null;
|
|
205
|
+
var runtimePromise = null;
|
|
206
|
+
var decoder = null;
|
|
207
|
+
var concurrency;
|
|
208
|
+
var requestGeneration = 0;
|
|
209
|
+
function loadRuntime() {
|
|
210
|
+
if (runtime) return Promise.resolve(runtime);
|
|
211
|
+
if (!runtimePromise) {
|
|
212
|
+
runtimePromise = import("./runtime-EPUDEHO4.js").then(
|
|
213
|
+
(loaded) => {
|
|
214
|
+
runtime = loaded;
|
|
215
|
+
if (decoder) loaded.setPrefetchDecoder(decoder);
|
|
216
|
+
if (concurrency !== void 0) {
|
|
217
|
+
loaded.setPrefetchConcurrency(concurrency);
|
|
218
|
+
}
|
|
219
|
+
return loaded;
|
|
220
|
+
},
|
|
221
|
+
(error) => {
|
|
222
|
+
runtimePromise = null;
|
|
223
|
+
throw error;
|
|
224
|
+
}
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
return runtimePromise;
|
|
228
|
+
}
|
|
229
|
+
function withRuntime(run) {
|
|
230
|
+
if (runtime) {
|
|
231
|
+
run(runtime);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const generation2 = requestGeneration;
|
|
235
|
+
void loadRuntime().then((loaded) => {
|
|
236
|
+
if (generation2 === requestGeneration) run(loaded);
|
|
237
|
+
}).catch(() => {
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
function prefetchDirect(url, segmentIds, version, routerId, prefetchKey) {
|
|
241
|
+
withRuntime(
|
|
242
|
+
(loaded) => loaded.prefetchDirect(url, segmentIds, version, routerId, prefetchKey)
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
function prefetchQueued(url, segmentIds, version, routerId, prefetchKey) {
|
|
246
|
+
withRuntime(
|
|
247
|
+
(loaded) => loaded.prefetchQueued(url, segmentIds, version, routerId, prefetchKey)
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
function schedulePrefetchWhenRouterIdle(eventController, callback) {
|
|
251
|
+
const state = eventController.getState();
|
|
252
|
+
if (state.state === "idle" && !state.isStreaming) {
|
|
253
|
+
callback();
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const unsubscribe = eventController.subscribe(() => {
|
|
257
|
+
const nextState = eventController.getState();
|
|
258
|
+
if (nextState.state === "idle" && !nextState.isStreaming) {
|
|
259
|
+
unsubscribe();
|
|
260
|
+
callback();
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
return unsubscribe;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// src/browser/notify-listeners.ts
|
|
267
|
+
function notifyListeners(entries, notify, isActive, shouldContinue) {
|
|
268
|
+
const errors = [];
|
|
269
|
+
for (const entry2 of entries) {
|
|
270
|
+
if (shouldContinue && !shouldContinue()) break;
|
|
271
|
+
if (isActive && !isActive(entry2)) continue;
|
|
272
|
+
try {
|
|
273
|
+
notify(entry2);
|
|
274
|
+
} catch (error) {
|
|
275
|
+
errors.push(error);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (errors.length === 1) throw errors[0];
|
|
279
|
+
if (errors.length > 1) {
|
|
280
|
+
throw new AggregateError(errors, "Multiple listener callbacks failed");
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// src/browser/prefetch/cache.ts
|
|
285
|
+
var cacheTTL = 3e5;
|
|
286
|
+
var fragmentPassthroughEnabled = true;
|
|
287
|
+
var maxPrefetchCacheSize = 100;
|
|
288
|
+
function isPrefetchCacheDisabled() {
|
|
289
|
+
return cacheTTL <= 0;
|
|
290
|
+
}
|
|
291
|
+
var cache = /* @__PURE__ */ new Map();
|
|
292
|
+
var inflight = /* @__PURE__ */ new Set();
|
|
293
|
+
var earliestTimestamp = Infinity;
|
|
294
|
+
var inflightPromises = /* @__PURE__ */ new Map();
|
|
295
|
+
var inflightAliases = /* @__PURE__ */ new Map();
|
|
296
|
+
var adoptedKeys = /* @__PURE__ */ new Set();
|
|
297
|
+
var paramsShapes = /* @__PURE__ */ new Map();
|
|
298
|
+
var generation = 0;
|
|
299
|
+
var staleEpoch = 0;
|
|
300
|
+
function buildPrefetchKey(prefix, targetUrl) {
|
|
301
|
+
const normalizedTarget = new URL(targetUrl);
|
|
302
|
+
normalizedTarget.searchParams.delete(WIRE.segments);
|
|
303
|
+
return prefix + "\0" + normalizedTarget.pathname + normalizedTarget.search;
|
|
304
|
+
}
|
|
305
|
+
function buildSourceKey(rangoState, sourceHref, targetUrl) {
|
|
306
|
+
return rangoState + "\0" + sourceHref + "\0" + targetUrl.pathname + targetUrl.search;
|
|
307
|
+
}
|
|
308
|
+
function buildParamsKey(rangoState, label, targetUrl) {
|
|
309
|
+
return buildPrefetchKey(rangoState + "\0p:" + label, targetUrl);
|
|
310
|
+
}
|
|
311
|
+
function rememberParamsShape(targetUrl, label) {
|
|
312
|
+
const target = buildPrefetchKey("", targetUrl);
|
|
313
|
+
const shape = parseSourceShape(label);
|
|
314
|
+
let shapes = paramsShapes.get(target);
|
|
315
|
+
if (!shapes) {
|
|
316
|
+
if (paramsShapes.size >= maxPrefetchCacheSize) {
|
|
317
|
+
const oldest = paramsShapes.keys().next().value;
|
|
318
|
+
if (oldest !== void 0) paramsShapes.delete(oldest);
|
|
319
|
+
}
|
|
320
|
+
shapes = /* @__PURE__ */ new Map();
|
|
321
|
+
paramsShapes.set(target, shapes);
|
|
322
|
+
}
|
|
323
|
+
shapes.set(sourceShapeId(shape), shape);
|
|
324
|
+
}
|
|
325
|
+
function paramsCandidateKeys(rangoState, targetUrl, page) {
|
|
326
|
+
if (!page) return [];
|
|
327
|
+
const shapes = paramsShapes.get(buildPrefetchKey("", targetUrl));
|
|
328
|
+
if (!shapes) return [];
|
|
329
|
+
return [...shapes.values()].sort((a, b) => weightOf(b) - weightOf(a)).map(
|
|
330
|
+
(shape) => buildParamsKey(rangoState, formatSourceLabel(shape, page), targetUrl)
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
var weightOf = (shape) => shape.names.length + (shape.route ? 1 : 0) + (shape.keys ? 1 : 0);
|
|
334
|
+
function forEachAlias(key, fn) {
|
|
335
|
+
const aliases = inflightAliases.get(key);
|
|
336
|
+
if (aliases) {
|
|
337
|
+
for (const k of aliases) fn(k);
|
|
338
|
+
} else {
|
|
339
|
+
fn(key);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
function hasPrefetch(key) {
|
|
343
|
+
if (inflight.has(key)) return true;
|
|
344
|
+
if (cacheTTL <= 0) return false;
|
|
345
|
+
const entry2 = cache.get(key);
|
|
346
|
+
if (!entry2) return false;
|
|
347
|
+
if (Date.now() - entry2.timestamp > cacheTTL || isPrefetchStale(entry2.entry)) {
|
|
348
|
+
entry2.entry.dispose?.();
|
|
349
|
+
cache.delete(key);
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
function storePrefetch(key, entry2, fetchGeneration, inflightKey = key) {
|
|
355
|
+
if (cacheTTL <= 0) return;
|
|
356
|
+
if (fetchGeneration !== generation) return;
|
|
357
|
+
if (adoptedKeys.has(inflightKey)) {
|
|
358
|
+
forEachAlias(inflightKey, (k) => adoptedKeys.delete(k));
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const now = Date.now();
|
|
362
|
+
if (now - earliestTimestamp > cacheTTL) {
|
|
363
|
+
let min = Infinity;
|
|
364
|
+
for (const [k, cached] of cache) {
|
|
365
|
+
if (now - cached.timestamp > cacheTTL) {
|
|
366
|
+
cached.entry.dispose?.();
|
|
367
|
+
cache.delete(k);
|
|
368
|
+
} else if (cached.timestamp < min) {
|
|
369
|
+
min = cached.timestamp;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
earliestTimestamp = min;
|
|
373
|
+
}
|
|
374
|
+
if (cache.size >= maxPrefetchCacheSize) {
|
|
375
|
+
const oldest = cache.keys().next().value;
|
|
376
|
+
if (oldest) {
|
|
377
|
+
cache.get(oldest)?.entry.dispose?.();
|
|
378
|
+
cache.delete(oldest);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
cache.set(key, { entry: entry2, timestamp: now });
|
|
382
|
+
if (now < earliestTimestamp) earliestTimestamp = now;
|
|
383
|
+
}
|
|
384
|
+
function removePrefetch(key, entry2) {
|
|
385
|
+
if (cache.get(key)?.entry === entry2) {
|
|
386
|
+
entry2.dispose?.();
|
|
387
|
+
cache.delete(key);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
function currentGeneration() {
|
|
391
|
+
return generation;
|
|
392
|
+
}
|
|
393
|
+
function currentPrefetchEpoch() {
|
|
394
|
+
return staleEpoch;
|
|
395
|
+
}
|
|
396
|
+
function isPrefetchStale(entry2) {
|
|
397
|
+
return entry2.epoch < staleEpoch;
|
|
398
|
+
}
|
|
399
|
+
function markPrefetchInflight(key) {
|
|
400
|
+
inflight.add(key);
|
|
401
|
+
}
|
|
402
|
+
function setInflightPromiseWithAliases(keys, promise) {
|
|
403
|
+
for (const k of keys) {
|
|
404
|
+
inflightPromises.set(k, promise);
|
|
405
|
+
inflightAliases.set(k, keys);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
function clearPrefetchInflight(key) {
|
|
409
|
+
forEachAlias(key, (k) => {
|
|
410
|
+
inflight.delete(k);
|
|
411
|
+
inflightPromises.delete(k);
|
|
412
|
+
inflightAliases.delete(k);
|
|
413
|
+
adoptedKeys.delete(k);
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
function isFragmentPassthroughEnabled() {
|
|
417
|
+
return fragmentPassthroughEnabled;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// src/browser/action-fence.ts
|
|
421
|
+
var fenceCount = 0;
|
|
422
|
+
function isActionFenceActive() {
|
|
423
|
+
return fenceCount > 0;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// src/prefetch-markers.ts
|
|
427
|
+
var PREFETCH_HEADER = "X-Rango-Prefetch";
|
|
428
|
+
var PREFETCH_INTENT = "intent";
|
|
429
|
+
var PREFETCH_FAILED_ROW = ":H_0\n";
|
|
430
|
+
|
|
431
|
+
export {
|
|
432
|
+
IS_BROWSER_DEBUG,
|
|
433
|
+
debugLog,
|
|
434
|
+
notifyListeners,
|
|
435
|
+
stateEpoch,
|
|
436
|
+
getRangoState,
|
|
437
|
+
WIRE,
|
|
438
|
+
WIRE_PREFIX,
|
|
439
|
+
paramsScopeLabel,
|
|
440
|
+
isPrefetchCacheDisabled,
|
|
441
|
+
buildPrefetchKey,
|
|
442
|
+
buildSourceKey,
|
|
443
|
+
buildParamsKey,
|
|
444
|
+
rememberParamsShape,
|
|
445
|
+
paramsCandidateKeys,
|
|
446
|
+
hasPrefetch,
|
|
447
|
+
storePrefetch,
|
|
448
|
+
removePrefetch,
|
|
449
|
+
currentGeneration,
|
|
450
|
+
currentPrefetchEpoch,
|
|
451
|
+
isPrefetchStale,
|
|
452
|
+
markPrefetchInflight,
|
|
453
|
+
setInflightPromiseWithAliases,
|
|
454
|
+
clearPrefetchInflight,
|
|
455
|
+
isFragmentPassthroughEnabled,
|
|
456
|
+
isActionFenceActive,
|
|
457
|
+
PREFETCH_HEADER,
|
|
458
|
+
PREFETCH_INTENT,
|
|
459
|
+
PREFETCH_FAILED_ROW,
|
|
460
|
+
prefetchDirect,
|
|
461
|
+
prefetchQueued,
|
|
462
|
+
schedulePrefetchWhenRouterIdle
|
|
463
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// src/vite/discovery/state.ts
|
|
2
|
+
var VIRTUAL_ROUTES_MANIFEST_ID = "virtual:rsc-router/routes-manifest";
|
|
3
|
+
var VIRTUAL_LOADER_MANIFEST_ID = "virtual:rsc-router/loader-manifest";
|
|
4
|
+
function createClientUrlRevalidateIndex() {
|
|
5
|
+
return { fileByKey: /* @__PURE__ */ new Map(), filesByGroup: /* @__PURE__ */ new Map() };
|
|
6
|
+
}
|
|
7
|
+
function recordDiscoveryFailure(state, err) {
|
|
8
|
+
state.lastDiscoveryError = {
|
|
9
|
+
message: err?.message ?? String(err),
|
|
10
|
+
at: Date.now()
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function canRefreshRuntimeDiscovery(state) {
|
|
14
|
+
return state.perRouterManifests.length > 0 || !!state.lastDiscoveryError;
|
|
15
|
+
}
|
|
16
|
+
function createDiscoveryState(entryPath, opts) {
|
|
17
|
+
return {
|
|
18
|
+
resolvedEntryPath: entryPath,
|
|
19
|
+
projectRoot: "",
|
|
20
|
+
isBuildMode: false,
|
|
21
|
+
viteCommand: "build",
|
|
22
|
+
viteMode: "production",
|
|
23
|
+
userResolveAlias: void 0,
|
|
24
|
+
userRunnerConfig: void 0,
|
|
25
|
+
userResolvePlugins: [],
|
|
26
|
+
scanFilter: void 0,
|
|
27
|
+
cachedRouterFiles: void 0,
|
|
28
|
+
opts,
|
|
29
|
+
mergedRouteManifest: null,
|
|
30
|
+
perRouterManifests: [],
|
|
31
|
+
perRouterTrieMap: /* @__PURE__ */ new Map(),
|
|
32
|
+
perRouterPrecomputedMap: /* @__PURE__ */ new Map(),
|
|
33
|
+
perRouterManifestDataMap: /* @__PURE__ */ new Map(),
|
|
34
|
+
clientUrlSourceByReferenceId: /* @__PURE__ */ new Map(),
|
|
35
|
+
clientUrlProjectionMap: /* @__PURE__ */ new Map(),
|
|
36
|
+
clientUrlRevalidate: opts?.clientUrlRevalidate ?? createClientUrlRevalidateIndex(),
|
|
37
|
+
prerenderManifestEntries: null,
|
|
38
|
+
staticManifestEntries: null,
|
|
39
|
+
shellCandidates: null,
|
|
40
|
+
prerenderPayloadValues: null,
|
|
41
|
+
shellPhaseTempServer: null,
|
|
42
|
+
serverBuildGraph: null,
|
|
43
|
+
clientBuildGraph: null,
|
|
44
|
+
ssrBundle: null,
|
|
45
|
+
versionModuleFiles: /* @__PURE__ */ new Map(),
|
|
46
|
+
buildData: [],
|
|
47
|
+
handlerChunkInfoMap: /* @__PURE__ */ new Map(),
|
|
48
|
+
staticHandlerChunkInfoMap: /* @__PURE__ */ new Map(),
|
|
49
|
+
onDemandHandlerIds: /* @__PURE__ */ new Map(),
|
|
50
|
+
rscEntryFileName: null,
|
|
51
|
+
resolvedPrerenderModules: void 0,
|
|
52
|
+
resolvedStaticModules: void 0,
|
|
53
|
+
discoveryDone: null,
|
|
54
|
+
devDiscoveryEpoch: opts?.preset === "cloudflare" ? Date.now() : void 0,
|
|
55
|
+
devServerOrigin: null,
|
|
56
|
+
devServer: null,
|
|
57
|
+
transitionWhenOverlay: null,
|
|
58
|
+
selfWrittenGenFiles: /* @__PURE__ */ new Map(),
|
|
59
|
+
SELF_WRITE_WINDOW_MS: 5e3,
|
|
60
|
+
lastDiscoveryError: null
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export {
|
|
65
|
+
VIRTUAL_ROUTES_MANIFEST_ID,
|
|
66
|
+
VIRTUAL_LOADER_MANIFEST_ID,
|
|
67
|
+
createClientUrlRevalidateIndex,
|
|
68
|
+
recordDiscoveryFailure,
|
|
69
|
+
canRefreshRuntimeDiscovery,
|
|
70
|
+
createDiscoveryState
|
|
71
|
+
};
|