@rebask/core 0.1.1 → 0.1.3
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/components/link.js +5 -5
- package/dist/components/prefetch-links.js +5 -5
- package/dist/entry.browser.js +4 -1
- package/dist/handlers/rsc/index.d.ts.map +1 -1
- package/dist/handlers/rsc/index.js +2 -1
- package/dist/lib/deployment-reload.d.ts +3 -0
- package/dist/lib/deployment-reload.d.ts.map +1 -0
- package/dist/lib/deployment-reload.js +9 -0
- package/dist/lib/errors.d.ts +5 -1
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +8 -1
- package/dist/lib/ppr/headers.d.ts +1 -1
- package/dist/lib/ppr/headers.d.ts.map +1 -1
- package/dist/lib/ppr/headers.js +1 -1
- package/dist/lib/router-cache.d.ts.map +1 -1
- package/dist/lib/router-cache.js +6 -3
- package/dist/observe-navigations.d.ts.map +1 -1
- package/dist/observe-navigations.js +35 -13
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +25 -15
- package/package.json +1 -1
package/dist/components/link.js
CHANGED
|
@@ -16,10 +16,10 @@ export function Link({ href, prefetch, scroll, onClick, ref, ...props }) {
|
|
|
16
16
|
if (!import.meta.env.PROD || !link || !isPrefetchable(link) || !isLinkVisible(link))
|
|
17
17
|
return;
|
|
18
18
|
if (getPrefetchStrategy(prefetch) === "viewport") {
|
|
19
|
-
router.prefetch(link.href, { skipShell: true });
|
|
19
|
+
router.prefetch(link.href, { skipShell: true }).catch(() => { });
|
|
20
20
|
}
|
|
21
21
|
else {
|
|
22
|
-
router.prefetchStatic(link.href);
|
|
22
|
+
router.prefetchStatic(link.href).catch(() => { });
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
useEffect(() => {
|
|
@@ -31,17 +31,17 @@ export function Link({ href, prefetch, scroll, onClick, ref, ...props }) {
|
|
|
31
31
|
const strategy = getPrefetchStrategy(prefetch);
|
|
32
32
|
const onPrefetchStatic = () => {
|
|
33
33
|
if (isPrefetchable(link))
|
|
34
|
-
router.prefetchStatic(link.href);
|
|
34
|
+
router.prefetchStatic(link.href).catch(() => { });
|
|
35
35
|
};
|
|
36
36
|
const onPrefetchFull = () => {
|
|
37
37
|
if (isPrefetchable(link))
|
|
38
|
-
router.prefetch(link.href);
|
|
38
|
+
router.prefetch(link.href).catch(() => { });
|
|
39
39
|
};
|
|
40
40
|
if (strategy === "viewport") {
|
|
41
41
|
// A viewport full prefetch goes for the full RSC directly instead of a shell.
|
|
42
42
|
return listenLinkViewport(link, () => {
|
|
43
43
|
if (isPrefetchable(link))
|
|
44
|
-
router.prefetch(link.href, { skipShell: true });
|
|
44
|
+
router.prefetch(link.href, { skipShell: true }).catch(() => { });
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
if (strategy === "intent") {
|
|
@@ -18,10 +18,10 @@ export function PrefetchLinks({ prefetch }) {
|
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
20
|
if (strategy === "viewport") {
|
|
21
|
-
router.prefetch(el.href, { skipShell: true });
|
|
21
|
+
router.prefetch(el.href, { skipShell: true }).catch(() => { });
|
|
22
22
|
}
|
|
23
23
|
else {
|
|
24
|
-
router.prefetchStatic(el.href);
|
|
24
|
+
router.prefetchStatic(el.href).catch(() => { });
|
|
25
25
|
}
|
|
26
26
|
});
|
|
27
27
|
};
|
|
@@ -48,19 +48,19 @@ export function PrefetchLinks({ prefetch }) {
|
|
|
48
48
|
const strategy = getPrefetchStrategy(prefetch);
|
|
49
49
|
const onPrefetchStatic = (el) => {
|
|
50
50
|
if (el instanceof HTMLAnchorElement && isPrefetchable(el)) {
|
|
51
|
-
router.prefetchStatic(el.href);
|
|
51
|
+
router.prefetchStatic(el.href).catch(() => { });
|
|
52
52
|
}
|
|
53
53
|
};
|
|
54
54
|
const onPrefetchFull = (el) => {
|
|
55
55
|
if (el instanceof HTMLAnchorElement && isPrefetchable(el)) {
|
|
56
|
-
router.prefetch(el.href);
|
|
56
|
+
router.prefetch(el.href).catch(() => { });
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
59
|
if (strategy === "viewport") {
|
|
60
60
|
// A viewport full prefetch goes for the full RSC directly, never a shell.
|
|
61
61
|
return listenViewport((el) => {
|
|
62
62
|
if (el instanceof HTMLAnchorElement && isPrefetchable(el)) {
|
|
63
|
-
router.prefetch(el.href, { skipShell: true });
|
|
63
|
+
router.prefetch(el.href, { skipShell: true }).catch(() => { });
|
|
64
64
|
}
|
|
65
65
|
});
|
|
66
66
|
}
|
package/dist/entry.browser.js
CHANGED
|
@@ -6,6 +6,7 @@ import { AppRoot } from "./components/app-root.js";
|
|
|
6
6
|
import { learnRoutePrediction } from "./lib/client-route-prediction.js";
|
|
7
7
|
import { captureClientTraceData, getClientTraceHeaders, setClientTraceData, } from "./lib/client-trace.js";
|
|
8
8
|
import { getDeploymentIdHeader } from "./lib/deployment-id.js";
|
|
9
|
+
import { reloadForDeploymentMismatch } from "./lib/deployment-reload.js";
|
|
9
10
|
import { readDocumentRoute } from "./lib/document-route.js";
|
|
10
11
|
import { HandledDeploymentMismatch, isRebaskServerError, ServerFunctionError, } from "./lib/errors.js";
|
|
11
12
|
import { REBASK_ACTION_HEADER } from "./lib/ppr/headers.js";
|
|
@@ -55,8 +56,10 @@ async function main() {
|
|
|
55
56
|
cache.handleDeploymentMismatch(response, url, "action");
|
|
56
57
|
}
|
|
57
58
|
catch (error) {
|
|
58
|
-
if (error instanceof HandledDeploymentMismatch)
|
|
59
|
+
if (error instanceof HandledDeploymentMismatch) {
|
|
60
|
+
reloadForDeploymentMismatch(error.event);
|
|
59
61
|
return;
|
|
62
|
+
}
|
|
60
63
|
throw error;
|
|
61
64
|
}
|
|
62
65
|
// Non-Flight responses happen when the server rejects the request before action
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/handlers/rsc/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/handlers/rsc/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAsBzE,MAAM,MAAM,kBAAkB,GAAG;IAChC,QAAQ,EAAE,OAAO,CAAA;IACjB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IACrE;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,gEAAgE;IAChE,QAAQ,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,WAAW,sBAAsB;IACtC,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAA;IACzD,wFAAwF;IACxF,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC5B;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACpC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,WAAW,EACnB,aAAa,CAAC,EAAE,sBAAsB,GACpC,OAAO,CAAC,QAAQ,CAAC,CAqLnB"}
|
|
@@ -3,7 +3,7 @@ import { STATIC } from "../../lib/cache-storage.js";
|
|
|
3
3
|
import { getDeploymentIdHeader } from "../../lib/deployment-id.js";
|
|
4
4
|
import { resetDevOverlayReady } from "../../lib/dev-server.js";
|
|
5
5
|
import { pageChannel } from "../../lib/devtools-channels.js";
|
|
6
|
-
import { getCacheControlHeader, REBASK_HTML_VARY_HEADER, REBASK_SHELL_HEADER, REBASK_TAIL_HEADER, } from "../../lib/ppr/headers.js";
|
|
6
|
+
import { getCacheControlHeader, REBASK_HTML_VARY_HEADER, REBASK_SHELL_HEADER, REBASK_TAIL_HEADER, REBASK_TREE_HEADER, } from "../../lib/ppr/headers.js";
|
|
7
7
|
import { parseResumeState } from "../../lib/ppr/postponed-state.js";
|
|
8
8
|
import { prerenderPaths } from "../../lib/prerender-paths.js";
|
|
9
9
|
import {} from "../../lib/route-matcher.js";
|
|
@@ -62,6 +62,7 @@ export async function handlePageRoute(request, route, params, handleOptions) {
|
|
|
62
62
|
return respond(new Response(JSON.stringify(payload), {
|
|
63
63
|
headers: {
|
|
64
64
|
"content-type": "application/json",
|
|
65
|
+
[REBASK_TREE_HEADER]: "1",
|
|
65
66
|
"cache-control": getCacheControlHeader({ revalidate: STATIC }),
|
|
66
67
|
vary: REBASK_HTML_VARY_HEADER,
|
|
67
68
|
...getDeploymentIdHeader(),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployment-reload.d.ts","sourceRoot":"","sources":["../../src/lib/deployment-reload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAI/D,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,uBAAuB,QAOzE"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const RELOAD_KEY = "rebask:deployment-reload";
|
|
2
|
+
export function reloadForDeploymentMismatch(event) {
|
|
3
|
+
// A mismatch can survive a reload when a CDN keeps serving an older asset, so reload at most
|
|
4
|
+
// once for each deployment.
|
|
5
|
+
if (sessionStorage.getItem(RELOAD_KEY) === event.receivedDeploymentId)
|
|
6
|
+
return;
|
|
7
|
+
sessionStorage.setItem(RELOAD_KEY, event.receivedDeploymentId);
|
|
8
|
+
window.location.reload();
|
|
9
|
+
}
|
package/dist/lib/errors.d.ts
CHANGED
|
@@ -25,13 +25,17 @@ export declare class DeploymentMismatchError extends Error {
|
|
|
25
25
|
readonly event: DeploymentMismatchEvent;
|
|
26
26
|
constructor(event: DeploymentMismatchEvent);
|
|
27
27
|
}
|
|
28
|
+
export declare class DocumentNavigation extends Error {
|
|
29
|
+
constructor();
|
|
30
|
+
}
|
|
28
31
|
export declare class ServerFunctionError extends Error {
|
|
29
32
|
readonly status: number;
|
|
30
33
|
constructor(message: string, status: number);
|
|
31
34
|
}
|
|
32
35
|
/** Internal error used when there's a mismatch error in the router */
|
|
33
36
|
export declare class HandledDeploymentMismatch extends Error {
|
|
34
|
-
|
|
37
|
+
readonly event: DeploymentMismatchEvent;
|
|
38
|
+
constructor(event: DeploymentMismatchEvent);
|
|
35
39
|
}
|
|
36
40
|
export declare function isHangingPromiseError(error: unknown): error is HangingPromiseError;
|
|
37
41
|
export declare function isPrerenderAbortError(error: unknown): error is PrerenderAbortError;
|
package/dist/lib/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAM/D,eAAO,MAAM,0BAA0B,+BAA+B,CAAA;AActE;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,MAAM,4BAAyB;IAExC,YAAY,UAAU,EAAE,MAAM,EAE7B;CACD;AAED,yFAAyF;AACzF,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,MAAM,4BAAyB;IAExC,cAGC;CACD;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,MAAM,kCAAyB;IAExC,YAAY,OAAO,EAAE,MAAM,EAK1B;CACD;AAED,8EAA8E;AAC9E,qBAAa,kBAAmB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,MAAM,kCAAyB;IAExC,YAAY,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAExC;CACD;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IACrC,QAAQ,CAAC,KAAK,EAAE,uBAAuB;IAAnD,YAAqB,KAAK,EAAE,uBAAuB,EAElD;CACD;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAG5C,QAAQ,CAAC,MAAM,EAAE,MAAM;IAFxB,YACC,OAAO,EAAE,MAAM,EACN,MAAM,EAAE,MAAM,EAIvB;CACD;AAED,sEAAsE;AACtE,qBAAa,yBAA0B,SAAQ,KAAK;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAM/D,eAAO,MAAM,0BAA0B,+BAA+B,CAAA;AActE;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,MAAM,4BAAyB;IAExC,YAAY,UAAU,EAAE,MAAM,EAE7B;CACD;AAED,yFAAyF;AACzF,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,MAAM,4BAAyB;IAExC,cAGC;CACD;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,MAAM,kCAAyB;IAExC,YAAY,OAAO,EAAE,MAAM,EAK1B;CACD;AAED,8EAA8E;AAC9E,qBAAa,kBAAmB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,MAAM,kCAAyB;IAExC,YAAY,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAExC;CACD;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IACrC,QAAQ,CAAC,KAAK,EAAE,uBAAuB;IAAnD,YAAqB,KAAK,EAAE,uBAAuB,EAElD;CACD;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC5C,cAEC;CACD;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAG5C,QAAQ,CAAC,MAAM,EAAE,MAAM;IAFxB,YACC,OAAO,EAAE,MAAM,EACN,MAAM,EAAE,MAAM,EAIvB;CACD;AAED,sEAAsE;AACtE,qBAAa,yBAA0B,SAAQ,KAAK;IACvC,QAAQ,CAAC,KAAK,EAAE,uBAAuB;IAAnD,YAAqB,KAAK,EAAE,uBAAuB,EAElD;CACD;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAElF;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAElF;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAG3D"}
|
package/dist/lib/errors.js
CHANGED
|
@@ -52,6 +52,11 @@ export class DeploymentMismatchError extends Error {
|
|
|
52
52
|
this.event = event;
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
+
export class DocumentNavigation extends Error {
|
|
56
|
+
constructor() {
|
|
57
|
+
super("document navigation required");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
55
60
|
export class ServerFunctionError extends Error {
|
|
56
61
|
status;
|
|
57
62
|
constructor(message, status) {
|
|
@@ -62,8 +67,10 @@ export class ServerFunctionError extends Error {
|
|
|
62
67
|
}
|
|
63
68
|
/** Internal error used when there's a mismatch error in the router */
|
|
64
69
|
export class HandledDeploymentMismatch extends Error {
|
|
65
|
-
|
|
70
|
+
event;
|
|
71
|
+
constructor(event) {
|
|
66
72
|
super("handled deployment mismatch");
|
|
73
|
+
this.event = event;
|
|
67
74
|
}
|
|
68
75
|
}
|
|
69
76
|
export function isHangingPromiseError(error) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CacheControl } from "./types.js";
|
|
2
2
|
/** Header used for RSC server functions. */
|
|
3
3
|
export declare const REBASK_ACTION_HEADER = "x-rsc-action";
|
|
4
|
-
/**
|
|
4
|
+
/** Requests the route tree. Page routes echo it to identify the response as a route tree. */
|
|
5
5
|
export declare const REBASK_TREE_HEADER = "x-rebask-tree";
|
|
6
6
|
/** Header set to "1" when requesting a page segment's Flight shell. */
|
|
7
7
|
export declare const REBASK_SHELL_HEADER = "x-rebask-shell";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../../src/lib/ppr/headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,4CAA4C;AAC5C,eAAO,MAAM,oBAAoB,iBAAiB,CAAA;AAElD,
|
|
1
|
+
{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../../src/lib/ppr/headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,4CAA4C;AAC5C,eAAO,MAAM,oBAAoB,iBAAiB,CAAA;AAElD,6FAA6F;AAC7F,eAAO,MAAM,kBAAkB,kBAAkB,CAAA;AAEjD,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,mBAAmB,CAAA;AAEnD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,kBAAkB,CAAA;AAEjD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,uBAAuB,CAAA;AAE3D,gEAAgE;AAChE,eAAO,MAAM,mBAAmB,mBAAmB,CAAA;AAEnD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,qBAAqB,CAAA;AAEvD,eAAO,MAAM,uBAAuB,0BAAkC,CAAA;AAEtE,eAAO,MAAM,sBAAsB,yDAAiF,CAAA;AAEpH,oBAAY,iBAAiB;IAC5B,mCAAmC;IACnC,GAAG,QAAQ;IACX,wEAAwE;IACxE,KAAK,UAAU;IACf,8BAA8B;IAC9B,IAAI,SAAS;CACb;AAED,yEAAyE;AACzE,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,YAAY,EAAE,IAAI,UAAQ,GAAG,MAAM,CAoBtF;AAED,0FAA0F;AAC1F,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAO/E"}
|
package/dist/lib/ppr/headers.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Header used for RSC server functions. */
|
|
2
2
|
export const REBASK_ACTION_HEADER = "x-rsc-action";
|
|
3
|
-
/**
|
|
3
|
+
/** Requests the route tree. Page routes echo it to identify the response as a route tree. */
|
|
4
4
|
export const REBASK_TREE_HEADER = "x-rebask-tree";
|
|
5
5
|
/** Header set to "1" when requesting a page segment's Flight shell. */
|
|
6
6
|
export const REBASK_SHELL_HEADER = "x-rebask-shell";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-cache.d.ts","sourceRoot":"","sources":["../../src/lib/router-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,EAAQ,MAAM,cAAc,CAAA;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AACtE,OAAO,KAAK,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"router-cache.d.ts","sourceRoot":"","sources":["../../src/lib/router-cache.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/router-cache.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { atom } from "@lfades/atom";
|
|
2
2
|
import { getDeploymentId, REBASK_DEPLOYMENT_ID_HEADER } from "./deployment-id.js";
|
|
3
|
+
import { reloadForDeploymentMismatch } from "./deployment-reload.js";
|
|
3
4
|
import { DeploymentMismatchError, HandledDeploymentMismatch } from "./errors.js";
|
|
4
5
|
import { getRouteTreeUrl } from "./route-prediction.js";
|
|
5
6
|
import { buildSlotKey, FLAG_LAYOUT, getNodeKey, KEY_SEPARATOR, segmentLocationMatches, segmentPathToShellPattern, segmentToCacheKey, } from "./segment-utils.js";
|
|
@@ -655,11 +656,13 @@ export class RouterCache {
|
|
|
655
656
|
if (!id || !deploymentId || id === deploymentId)
|
|
656
657
|
return;
|
|
657
658
|
const event = { kind, url: String(url), deploymentId, receivedDeploymentId: id };
|
|
658
|
-
const action = this.onDeploymentMismatch?.(event)
|
|
659
|
+
const action = this.onDeploymentMismatch?.(event);
|
|
659
660
|
if (action === "throw") {
|
|
660
661
|
throw new DeploymentMismatchError(event);
|
|
661
662
|
}
|
|
662
|
-
|
|
663
|
-
|
|
663
|
+
if (action === "reload") {
|
|
664
|
+
reloadForDeploymentMismatch(event);
|
|
665
|
+
}
|
|
666
|
+
throw new HandledDeploymentMismatch(event);
|
|
664
667
|
}
|
|
665
668
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe-navigations.d.ts","sourceRoot":"","sources":["../src/observe-navigations.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"observe-navigations.d.ts","sourceRoot":"","sources":["../src/observe-navigations.tsx"],"names":[],"mappings":"AAcA;;;GAGG;AACH,wBAAgB,kBAAkB,SAqGjC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { useEffect } from "react";
|
|
2
2
|
import { useRouterCache } from "./components/cache-slot.js";
|
|
3
|
+
import { reloadForDeploymentMismatch } from "./lib/deployment-reload.js";
|
|
4
|
+
import { DocumentNavigation, HandledDeploymentMismatch } from "./lib/errors.js";
|
|
3
5
|
import { beginNavigation, createNavigationIntent, isCurrentNavigation, pendingScrollAtom, } from "./lib/scroll.js";
|
|
4
6
|
import { useRouter } from "./router.js";
|
|
5
7
|
/**
|
|
@@ -16,39 +18,59 @@ export function ObserveNavigations() {
|
|
|
16
18
|
cache.shellError = false;
|
|
17
19
|
router.refresh(window.location.href).catch(() => { });
|
|
18
20
|
}
|
|
19
|
-
function onNavigation(intent, scrollIntent) {
|
|
20
|
-
cache.pathnameAtom.set(window.location.pathname);
|
|
21
|
+
function onNavigation(intent, scrollIntent, url, commitHistory, onDocument) {
|
|
21
22
|
const isCurrent = cache.captureRouteTransaction();
|
|
23
|
+
let committed = false;
|
|
24
|
+
const commit = () => {
|
|
25
|
+
if (committed)
|
|
26
|
+
return;
|
|
27
|
+
committed = true;
|
|
28
|
+
// A same-document entry followed by a document reload breaks back/forward for non-page responses.
|
|
29
|
+
commitHistory?.();
|
|
30
|
+
cache.pathnameAtom.set(window.location.pathname);
|
|
31
|
+
};
|
|
22
32
|
const activate = (routeTreeResponse, complete = false) => {
|
|
23
33
|
if (!isCurrentNavigation(intent) || !isCurrent())
|
|
24
34
|
return;
|
|
35
|
+
commit();
|
|
25
36
|
router.activate(routeTreeResponse);
|
|
26
37
|
if (scrollIntent && (complete || scrollIntent.type !== "hash")) {
|
|
27
38
|
pendingScrollAtom.set(scrollIntent);
|
|
28
39
|
}
|
|
29
40
|
};
|
|
30
41
|
router
|
|
31
|
-
.prefetch(
|
|
42
|
+
.prefetch(url, { onRouteTree: activate })
|
|
32
43
|
.then((response) => activate(response, true))
|
|
33
44
|
// React receives rendering failures separately. This catch prevents a duplicate unhandled rejection.
|
|
34
|
-
.catch(() => {
|
|
45
|
+
.catch((error) => {
|
|
46
|
+
if (error instanceof DocumentNavigation) {
|
|
47
|
+
if (!isCurrentNavigation(intent) || !isCurrent())
|
|
48
|
+
return;
|
|
49
|
+
onDocument?.();
|
|
50
|
+
}
|
|
51
|
+
if (error instanceof HandledDeploymentMismatch) {
|
|
52
|
+
if (!isCurrentNavigation(intent) || !isCurrent())
|
|
53
|
+
return;
|
|
54
|
+
commit();
|
|
55
|
+
reloadForDeploymentMismatch(error.event);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
35
58
|
}
|
|
36
59
|
function onPopstate() {
|
|
37
|
-
|
|
60
|
+
const url = window.location.href;
|
|
61
|
+
onNavigation(beginNavigation(), null, url, undefined, () => window.location.replace(url));
|
|
38
62
|
}
|
|
39
63
|
const { pushState, replaceState } = window.history;
|
|
40
64
|
window.addEventListener("popstate", onPopstate);
|
|
41
65
|
window.history.pushState = function (...args) {
|
|
42
|
-
const
|
|
43
|
-
const intent = createNavigationIntent(
|
|
44
|
-
onNavigation(intent, intent);
|
|
45
|
-
return res;
|
|
66
|
+
const url = new URL(args[2] || window.location.href, window.location.href).href;
|
|
67
|
+
const intent = createNavigationIntent(url);
|
|
68
|
+
onNavigation(intent, intent, url, () => pushState.apply(this, args), () => window.location.assign(url));
|
|
46
69
|
};
|
|
47
70
|
window.history.replaceState = function (...args) {
|
|
48
|
-
const
|
|
49
|
-
const intent = createNavigationIntent(
|
|
50
|
-
onNavigation(intent, intent);
|
|
51
|
-
return res;
|
|
71
|
+
const url = new URL(args[2] || window.location.href, window.location.href).href;
|
|
72
|
+
const intent = createNavigationIntent(url);
|
|
73
|
+
onNavigation(intent, intent, url, () => replaceState.apply(this, args), () => window.location.replace(url));
|
|
52
74
|
};
|
|
53
75
|
return () => {
|
|
54
76
|
window.removeEventListener("popstate", onPopstate);
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAcrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAazD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAGN,KAAK,iBAAiB,EACtB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAmB,KAAK,WAAW,EAAqB,MAAM,uBAAuB,CAAA;AAC5F,OAAO,KAAK,EAAoB,OAAO,EAA+B,MAAM,uBAAuB,CAAA;AAyCnG,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAC7D,YAAY,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAEpD,MAAM,MAAM,iBAAiB,GAAG;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC7B,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AASD,eAAO,MAAM,iBAAiB,mDAAoD,CAAA;AAElF,gEAAgE;AAChE,KAAK,iBAAiB,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAsL5D;;GAEG;AACH,cAAM,MAAM;IAEV,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,OAAO;IAFhB,YACS,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,OAAO,GAAG,IAAW,EACnC;IAEJ;;OAEG;IACH,IAAI,QAAS,MAAM,GAAG,GAAG,YAAY,eAAe,KAAG,IAAI,CAG1D;IAED;;;OAGG;IACH,aAAa,UAAW,kBAAkB,KAAG,IAAI,CAGhD;IAED,yBAAyB,YAAa,OAAO,KAAG,IAAI,CAMnD;IAED;;OAEG;IACH,OAAO,QAAS,MAAM,GAAG,GAAG,YAAY,eAAe,KAAG,IAAI,CAG7D;IAED;;;;;;OAMG;YACW,cAAc;IAsC5B,4FAA4F;IAC5F,OAAO,CAAC,eAAe;IAIvB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IASxB,0FAA0F;IAC1F,OAAO,CAAC,YAAY;IAmBpB;;;;;;;OAOG;YACW,eAAe;IA6M7B,8EAA8E;YAChE,WAAW;YA0DX,iBAAiB;IAgC/B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,gBAAgB,CAiBvB;IAED;;;;;;;;OAQG;IACH,OAAO,CAAC,iBAAiB,CA2DxB;IAED,mCAAmC;IACnC,QAAQ,QACF,MAAM,YACD;QACT,yDAAyD;QACzD,SAAS,CAAC,EAAE,OAAO,CAAA;QACnB;;;WAGG;QACH,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAA;KACnD,KACC,OAAO,CAAC,iBAAiB,CAAC,CA+B5B;IAED;;;OAGG;IACH,cAAc,QAAe,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CA4ElD;IAED;;;;;;;OAOG;IACH,iBAAiB,QAAe,MAAM,GAAG,GAAG,KAAG,OAAO,CAAC,IAAI,CAAC,CAU3D;IAED;;;;;;OAMG;IACH,OAAO,QACD,MAAM,GAAG,GAAG,UACV,cAAc,uBAEnB,OAAO,CAAC,iBAAiB,CAAC,CAoC5B;IAED,mDAAmD;IACnD,QAAQ,sBAAuB,iBAAiB,KAAG,IAAI,CAItD;IAED;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IAW5B;;;;;;;;;;;;;;;;;OAiBG;IACH,UAAU,YACA,OAAO,GAAG,MAAM,GAAG,GAAG,YACtB,iBAAiB,KACxB,OAAO,CAAC,OAAO,CAAC,CAkClB;IAED;;;;;;OAMG;IACH,aAAa,QACP,MAAM,GAAG,MAAM,EAAE,YACb,iBAAiB,KACxB,OAAO,CAAC,MAAM,CAAC,CAUjB;IAED,sDAAsD;IACtD,OAAO,CAAC,iBAAiB,CA6DxB;CACD;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,WAKxB;AAED,iEAAiE;AACjE,wBAAgB,WAAW,WAQ1B;AAED,qDAAqD;AACrD,wBAAgB,SAAS,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,KAAK,CAAC,CAwBlE;AAED,mDAAmD;AACnD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,CAAC,YAAY,EAAE,iBAAiB,KAAK,IAAI,QAYzF"}
|
package/dist/router.js
CHANGED
|
@@ -8,7 +8,8 @@ import { useSegment } from "./components/segment-boundary.js";
|
|
|
8
8
|
import { denyRoutePrediction, getRoutePathInfo, learnedPredictions, learnRoutePrediction, predictRouteTree, } from "./lib/client-route-prediction.js";
|
|
9
9
|
import { captureClientTraceData, getClientTraceHeaders } from "./lib/client-trace.js";
|
|
10
10
|
import { getDeploymentIdHeader } from "./lib/deployment-id.js";
|
|
11
|
-
import {
|
|
11
|
+
import { reloadForDeploymentMismatch } from "./lib/deployment-reload.js";
|
|
12
|
+
import { DocumentNavigation, HandledDeploymentMismatch, DeploymentMismatchError, } from "./lib/errors.js";
|
|
12
13
|
import { extractSegmentHints } from "./lib/extract-segment-hints.js";
|
|
13
14
|
import { REBASK_SHELL_HEADER, REBASK_TAIL_HEADER, REBASK_TRAILER_HEADER, REBASK_TREE_HEADER, } from "./lib/ppr/headers.js";
|
|
14
15
|
import { getRouteTreeUrl, } from "./lib/route-prediction.js";
|
|
@@ -242,6 +243,11 @@ class Router {
|
|
|
242
243
|
})
|
|
243
244
|
.then(async (response) => {
|
|
244
245
|
captureClientTraceData(response);
|
|
246
|
+
if (response.headers.get(REBASK_TREE_HEADER) !== "1") {
|
|
247
|
+
if (response.body)
|
|
248
|
+
await response.body.cancel();
|
|
249
|
+
throw new DocumentNavigation();
|
|
250
|
+
}
|
|
245
251
|
this.cache.handleDeploymentMismatch(response, url, "tree");
|
|
246
252
|
const [tree, routePrediction] = (await response.json());
|
|
247
253
|
return { tree, routePrediction, url: getUrl(url).href };
|
|
@@ -540,14 +546,7 @@ class Router {
|
|
|
540
546
|
const { routePrediction: expectedRoutePrediction } = routeTreeResponse;
|
|
541
547
|
const missing = this.cache.findMissingSegmentLocations(routeTreeResponse);
|
|
542
548
|
if (missing.length > 0) {
|
|
543
|
-
|
|
544
|
-
await Promise.all(missing.map((segment) => this.prefetchSegment(segment, dedupe, expectedRoutePrediction, skipShell)));
|
|
545
|
-
}
|
|
546
|
-
catch (error) {
|
|
547
|
-
if (error instanceof HandledDeploymentMismatch)
|
|
548
|
-
return;
|
|
549
|
-
throw error;
|
|
550
|
-
}
|
|
549
|
+
await Promise.all(missing.map((segment) => this.prefetchSegment(segment, dedupe, expectedRoutePrediction, skipShell)));
|
|
551
550
|
}
|
|
552
551
|
if (isCurrent())
|
|
553
552
|
this.applyRoutePrediction(routeTreeResponse);
|
|
@@ -580,10 +579,10 @@ class Router {
|
|
|
580
579
|
this.cache.registerRouteTree(predicted);
|
|
581
580
|
return predicted;
|
|
582
581
|
}
|
|
583
|
-
if (inflightSiblingTree) {
|
|
582
|
+
if (inflightSiblingTree && isCurrentNavigation(inflightSiblingTree.navigation)) {
|
|
584
583
|
// An in-flight fetch under the same parent teaches this route's prediction, so the
|
|
585
584
|
// retry can avoid a second tree request.
|
|
586
|
-
await inflightSiblingTree.catch(() => { });
|
|
585
|
+
await inflightSiblingTree.response.catch(() => { });
|
|
587
586
|
return isCurrent()
|
|
588
587
|
? this.prefetchRouteTree(url, cache, dedupe)
|
|
589
588
|
: this.fetchRouteTree(url, dedupe);
|
|
@@ -597,11 +596,12 @@ class Router {
|
|
|
597
596
|
return routeTreeResponse;
|
|
598
597
|
});
|
|
599
598
|
if (cache) {
|
|
600
|
-
|
|
599
|
+
const inflight = { response: routeTreeRequest, navigation: captureNavigationIntent() };
|
|
600
|
+
inflightRouteTreeByParent.set(parentPathname, inflight);
|
|
601
601
|
routeTreeRequest
|
|
602
602
|
.catch(() => { })
|
|
603
603
|
.finally(() => {
|
|
604
|
-
if (inflightRouteTreeByParent.get(parentPathname) ===
|
|
604
|
+
if (inflightRouteTreeByParent.get(parentPathname) === inflight) {
|
|
605
605
|
inflightRouteTreeByParent.delete(parentPathname);
|
|
606
606
|
}
|
|
607
607
|
});
|
|
@@ -738,12 +738,18 @@ class Router {
|
|
|
738
738
|
const target = getUrl(url);
|
|
739
739
|
learnedPredictions.clear();
|
|
740
740
|
this.cache.markRouteDataStale(scope === "page");
|
|
741
|
-
const routeTreeResponse = await this.prefetchRouteTree(target.href, false, dedupe)
|
|
741
|
+
const routeTreeResponse = await this.prefetchRouteTree(target.href, false, dedupe).catch((error) => {
|
|
742
|
+
if (error instanceof HandledDeploymentMismatch)
|
|
743
|
+
reloadForDeploymentMismatch(error.event);
|
|
744
|
+
throw error;
|
|
745
|
+
});
|
|
742
746
|
if (!isCurrent())
|
|
743
747
|
return routeTreeResponse;
|
|
744
748
|
const pending = this.prefetchSegments(routeTreeResponse, dedupe, true).catch((error) => {
|
|
745
|
-
if (error instanceof HandledDeploymentMismatch)
|
|
749
|
+
if (error instanceof HandledDeploymentMismatch) {
|
|
750
|
+
reloadForDeploymentMismatch(error.event);
|
|
746
751
|
return;
|
|
752
|
+
}
|
|
747
753
|
console.error("[rebask] refresh failed to prefetch segments:", error);
|
|
748
754
|
});
|
|
749
755
|
if (isCurrent() && isCurrentNavigation(navigationIntent)) {
|
|
@@ -860,6 +866,8 @@ class Router {
|
|
|
860
866
|
}
|
|
861
867
|
})
|
|
862
868
|
.catch((error) => {
|
|
869
|
+
if (error instanceof HandledDeploymentMismatch)
|
|
870
|
+
return;
|
|
863
871
|
console.error("[rebask] revalidate failed to prefetch active segments:", error);
|
|
864
872
|
}));
|
|
865
873
|
this.cache.restoreRouteTree(currentResponse);
|
|
@@ -879,6 +887,8 @@ class Router {
|
|
|
879
887
|
!segmentLocationMatches(segmentLocation, currentSearchParams));
|
|
880
888
|
}
|
|
881
889
|
work.push(...inactive.map((segmentLocation) => this.prefetchSegment(segmentLocation, false).catch((error) => {
|
|
890
|
+
if (error instanceof HandledDeploymentMismatch)
|
|
891
|
+
return;
|
|
882
892
|
console.error("[rebask] revalidate failed to prefetch segment:", error);
|
|
883
893
|
})));
|
|
884
894
|
}
|