@reckona/mreact-router 0.0.209 → 0.0.211
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/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +17 -5
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +43 -3
- package/dist/build.js.map +1 -1
- package/dist/built-runtime.d.ts +1 -0
- package/dist/built-runtime.d.ts.map +1 -1
- package/dist/built-runtime.js +4 -0
- package/dist/built-runtime.js.map +1 -1
- package/dist/client-manifest-assets.d.ts +2 -0
- package/dist/client-manifest-assets.d.ts.map +1 -1
- package/dist/client-manifest-assets.js +2 -1
- package/dist/client-manifest-assets.js.map +1 -1
- package/dist/client.d.ts +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +367 -93
- package/dist/client.js.map +1 -1
- package/dist/module-preload-graph.d.ts +5 -0
- package/dist/module-preload-graph.d.ts.map +1 -0
- package/dist/module-preload-graph.js +48 -0
- package/dist/module-preload-graph.js.map +1 -0
- package/dist/reactive-devtools-stub.d.ts +3 -0
- package/dist/reactive-devtools-stub.d.ts.map +1 -0
- package/dist/reactive-devtools-stub.js +10 -0
- package/dist/reactive-devtools-stub.js.map +1 -0
- package/dist/render.d.ts +1 -0
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +47 -10
- package/dist/render.js.map +1 -1
- package/dist/serve.js +1 -0
- package/dist/serve.js.map +1 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +2 -7
- package/dist/vite.js.map +1 -1
- package/package.json +11 -11
- package/src/adapters/cloudflare.ts +22 -5
- package/src/build.ts +50 -3
- package/src/built-runtime.ts +18 -6
- package/src/client-manifest-assets.ts +3 -1
- package/src/client.ts +367 -92
- package/src/module-preload-graph.ts +70 -0
- package/src/reactive-devtools-stub.ts +9 -0
- package/src/render.ts +74 -10
- package/src/serve.ts +1 -0
- package/src/vite.ts +2 -7
package/src/client.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
type CompilerModuleContext,
|
|
27
27
|
} from "@reckona/mreact-compiler/internal";
|
|
28
28
|
import { assetPath } from "./assets.js";
|
|
29
|
+
import { reactiveDevtoolsStubSource } from "./reactive-devtools-stub.js";
|
|
29
30
|
import {
|
|
30
31
|
bundleRouterModule,
|
|
31
32
|
bundleRouterModules,
|
|
@@ -60,6 +61,7 @@ export interface ClientRouteManifestEntry {
|
|
|
60
61
|
clientReferenceManifest?: readonly ClientReferenceMetadata[] | undefined;
|
|
61
62
|
devScript?: string;
|
|
62
63
|
imports?: readonly string[];
|
|
64
|
+
modulePreloads?: readonly string[];
|
|
63
65
|
navigation?: boolean;
|
|
64
66
|
navigationScript?: string;
|
|
65
67
|
routeId?: string;
|
|
@@ -3012,6 +3014,7 @@ export async function buildClientRouteEntrySource(
|
|
|
3012
3014
|
const navigationStateDeclaration = inlineClientNavigation
|
|
3013
3015
|
? `const __mreactNavigationState = __mreactGlobal.__mreactNavigationState ??= {
|
|
3014
3016
|
cache: new Map(),
|
|
3017
|
+
cacheTokens: new Map(),
|
|
3015
3018
|
current: {
|
|
3016
3019
|
from: null,
|
|
3017
3020
|
pending: false,
|
|
@@ -3020,6 +3023,7 @@ export async function buildClientRouteEntrySource(
|
|
|
3020
3023
|
},
|
|
3021
3024
|
fetchRevalidationInstalled: false,
|
|
3022
3025
|
installed: false,
|
|
3026
|
+
navigationFetchInits: new WeakSet(),
|
|
3023
3027
|
pendingHtmlFetches: new Map(),
|
|
3024
3028
|
prefetchedUrls: new Set(),
|
|
3025
3029
|
prefetchedScripts: new Set(),
|
|
@@ -3028,7 +3032,9 @@ export async function buildClientRouteEntrySource(
|
|
|
3028
3032
|
routePrefetchManifestText: undefined,
|
|
3029
3033
|
viewportAnchors: new WeakSet(),
|
|
3030
3034
|
viewportObserver: undefined,
|
|
3031
|
-
}
|
|
3035
|
+
};
|
|
3036
|
+
__mreactNavigationState.cacheTokens ??= new Map();
|
|
3037
|
+
__mreactNavigationState.navigationFetchInits ??= new WeakSet();`
|
|
3032
3038
|
: "";
|
|
3033
3039
|
const deferredNavigationRuntime = deferredClientNavigation
|
|
3034
3040
|
? `
|
|
@@ -3191,10 +3197,10 @@ export async function __mreactNavigate(url, options = {}) {
|
|
|
3191
3197
|
: false;
|
|
3192
3198
|
}
|
|
3193
3199
|
|
|
3194
|
-
export async function __mreactPrefetch(url) {
|
|
3200
|
+
export async function __mreactPrefetch(url, options = {}) {
|
|
3195
3201
|
const runtime = await __mreactLoadNavigationRuntime();
|
|
3196
3202
|
return typeof runtime?.__mreactPrefetch === "function"
|
|
3197
|
-
? runtime.__mreactPrefetch(url)
|
|
3203
|
+
? runtime.__mreactPrefetch(url, options)
|
|
3198
3204
|
: false;
|
|
3199
3205
|
}
|
|
3200
3206
|
|
|
@@ -3240,13 +3246,16 @@ __mreactGlobal.__mreactRouteCell = (nativeCell, initial) => {
|
|
|
3240
3246
|
const stateCell = nativeCell(record.value);
|
|
3241
3247
|
const setStateCell = stateCell.set;
|
|
3242
3248
|
|
|
3243
|
-
|
|
3249
|
+
const setRouteStateCell = (next) => {
|
|
3244
3250
|
setStateCell((previous) => {
|
|
3245
3251
|
const resolved = typeof next === "function" ? next(previous) : next;
|
|
3246
3252
|
record.value = resolved;
|
|
3247
3253
|
return resolved;
|
|
3248
3254
|
});
|
|
3249
3255
|
};
|
|
3256
|
+
stateCell.set = setRouteStateCell;
|
|
3257
|
+
stateCell.setValue = (next) => stateCell.set(() => next);
|
|
3258
|
+
stateCell.update = (updater) => stateCell.set(updater);
|
|
3250
3259
|
|
|
3251
3260
|
__mreactActiveCellRecords.set(cellKey, record);
|
|
3252
3261
|
return stateCell;
|
|
@@ -3673,7 +3682,7 @@ function __mreactRouteAnnouncementElement() {
|
|
|
3673
3682
|
return announcement;
|
|
3674
3683
|
}
|
|
3675
3684
|
|
|
3676
|
-
export async function __mreactPrefetch(url) {
|
|
3685
|
+
export async function __mreactPrefetch(url, options = {}) {
|
|
3677
3686
|
if (!__mreactCanPrefetch()) {
|
|
3678
3687
|
return false;
|
|
3679
3688
|
}
|
|
@@ -3692,10 +3701,6 @@ export async function __mreactPrefetch(url) {
|
|
|
3692
3701
|
return false;
|
|
3693
3702
|
}
|
|
3694
3703
|
|
|
3695
|
-
if (__mreactNavigationState.prefetchedUrls.has(href)) {
|
|
3696
|
-
return true;
|
|
3697
|
-
}
|
|
3698
|
-
|
|
3699
3704
|
__mreactRememberPrefetchedUrl(href);
|
|
3700
3705
|
|
|
3701
3706
|
const script = __mreactRouteScriptForNavigationUrl(href);
|
|
@@ -3704,21 +3709,30 @@ export async function __mreactPrefetch(url) {
|
|
|
3704
3709
|
return __mreactPrefetchNavigationHtml(href);
|
|
3705
3710
|
}
|
|
3706
3711
|
|
|
3707
|
-
|
|
3712
|
+
const scriptPrefetched = __mreactPrefetchRouteScript(script);
|
|
3713
|
+
|
|
3714
|
+
if (options?.trigger === "viewport") {
|
|
3715
|
+
return scriptPrefetched;
|
|
3716
|
+
}
|
|
3717
|
+
|
|
3718
|
+
return Promise.resolve(__mreactPrefetchNavigationHtml(href))
|
|
3719
|
+
.then(() => scriptPrefetched)
|
|
3720
|
+
.catch(() => scriptPrefetched);
|
|
3708
3721
|
}
|
|
3709
3722
|
|
|
3710
3723
|
function __mreactPrefetchNavigationHtml(href) {
|
|
3711
|
-
if (
|
|
3724
|
+
if (__mreactCachedNavigationHtml(href) !== undefined) {
|
|
3712
3725
|
return true;
|
|
3713
3726
|
}
|
|
3714
3727
|
|
|
3715
|
-
return __mreactFetchNavigationHtmlOnce(href)
|
|
3716
|
-
.then((
|
|
3728
|
+
return __mreactFetchNavigationHtmlOnce(href, { speculative: true })
|
|
3729
|
+
.then((result) => result.cacheable && typeof result.html === "string")
|
|
3717
3730
|
.catch(() => false);
|
|
3718
3731
|
}
|
|
3719
3732
|
|
|
3720
3733
|
const __mreactNavigationHtmlCacheMaxEntries = 64;
|
|
3721
3734
|
const __mreactNavigationPrefetchHistoryMaxEntries = 64;
|
|
3735
|
+
const __mreactNavigationHtmlCacheTtlMs = 30_000;
|
|
3722
3736
|
|
|
3723
3737
|
function __mreactRememberPrefetchedUrl(href) {
|
|
3724
3738
|
__mreactRememberPrefetchHistory(__mreactNavigationState.prefetchedUrls, href);
|
|
@@ -3747,23 +3761,49 @@ function __mreactRememberPrefetchHistory(history, href) {
|
|
|
3747
3761
|
}
|
|
3748
3762
|
|
|
3749
3763
|
function __mreactCachedNavigationHtml(href) {
|
|
3750
|
-
const
|
|
3764
|
+
const entry = __mreactNavigationState.cache.get(href);
|
|
3751
3765
|
|
|
3752
|
-
if (
|
|
3766
|
+
if (entry === undefined) {
|
|
3767
|
+
return undefined;
|
|
3768
|
+
}
|
|
3769
|
+
|
|
3770
|
+
if (
|
|
3771
|
+
entry.token !== __mreactNavigationState.cacheTokens.get(href) ||
|
|
3772
|
+
entry.token.valid !== true ||
|
|
3773
|
+
entry.cacheContext !== __mreactNavigationCacheContext() ||
|
|
3774
|
+
Date.now() - entry.fetchedAt >= __mreactNavigationHtmlCacheTtlMs
|
|
3775
|
+
) {
|
|
3776
|
+
__mreactNavigationState.cache.delete(href);
|
|
3777
|
+
__mreactNavigationState.prefetchedUrls.delete(href);
|
|
3778
|
+
__mreactReleaseNavigationCacheToken(href, entry.token);
|
|
3753
3779
|
return undefined;
|
|
3754
3780
|
}
|
|
3755
3781
|
|
|
3756
3782
|
__mreactNavigationState.cache.delete(href);
|
|
3757
|
-
__mreactNavigationState.cache.set(href,
|
|
3758
|
-
return html;
|
|
3783
|
+
__mreactNavigationState.cache.set(href, entry);
|
|
3784
|
+
return entry.html;
|
|
3759
3785
|
}
|
|
3760
3786
|
|
|
3761
|
-
function __mreactRememberNavigationHtml(href, html) {
|
|
3787
|
+
function __mreactRememberNavigationHtml(href, html, token, cacheContext) {
|
|
3788
|
+
if (
|
|
3789
|
+
token === undefined ||
|
|
3790
|
+
token.valid !== true ||
|
|
3791
|
+
__mreactNavigationState.cacheTokens.get(href) !== token ||
|
|
3792
|
+
cacheContext !== __mreactNavigationCacheContext()
|
|
3793
|
+
) {
|
|
3794
|
+
return;
|
|
3795
|
+
}
|
|
3796
|
+
|
|
3762
3797
|
if (__mreactNavigationState.cache.has(href)) {
|
|
3763
3798
|
__mreactNavigationState.cache.delete(href);
|
|
3764
3799
|
}
|
|
3765
3800
|
|
|
3766
|
-
__mreactNavigationState.cache.set(href,
|
|
3801
|
+
__mreactNavigationState.cache.set(href, {
|
|
3802
|
+
cacheContext,
|
|
3803
|
+
fetchedAt: Date.now(),
|
|
3804
|
+
html,
|
|
3805
|
+
token,
|
|
3806
|
+
});
|
|
3767
3807
|
|
|
3768
3808
|
while (__mreactNavigationState.cache.size > __mreactNavigationHtmlCacheMaxEntries) {
|
|
3769
3809
|
const oldestHref = __mreactNavigationState.cache.keys().next().value;
|
|
@@ -3774,37 +3814,100 @@ function __mreactRememberNavigationHtml(href, html) {
|
|
|
3774
3814
|
|
|
3775
3815
|
__mreactNavigationState.cache.delete(oldestHref);
|
|
3776
3816
|
__mreactNavigationState.prefetchedUrls.delete(oldestHref);
|
|
3817
|
+
__mreactReleaseNavigationCacheToken(oldestHref);
|
|
3777
3818
|
}
|
|
3778
3819
|
}
|
|
3779
3820
|
|
|
3780
|
-
function
|
|
3781
|
-
|
|
3782
|
-
|
|
3821
|
+
function __mreactNavigationCacheContext() {
|
|
3822
|
+
const authSession = typeof document === "undefined"
|
|
3823
|
+
? undefined
|
|
3824
|
+
: document.getElementById("__mreact_auth_session")?.textContent ?? undefined;
|
|
3825
|
+
const cookies = __mreactNavigationCookies();
|
|
3826
|
+
|
|
3827
|
+
return JSON.stringify([authSession, cookies]);
|
|
3828
|
+
}
|
|
3829
|
+
|
|
3830
|
+
function __mreactNavigationCookies() {
|
|
3831
|
+
return typeof document === "undefined" ? "" : document.cookie;
|
|
3832
|
+
}
|
|
3833
|
+
|
|
3834
|
+
function __mreactNavigationResponseCacheContext(html, requestCookies) {
|
|
3835
|
+
let authSession;
|
|
3836
|
+
|
|
3837
|
+
if (typeof document !== "undefined") {
|
|
3838
|
+
const template = document.createElement("template");
|
|
3839
|
+
template.innerHTML = html;
|
|
3840
|
+
authSession = template.content.querySelector("#__mreact_auth_session")?.textContent ?? undefined;
|
|
3783
3841
|
}
|
|
3784
3842
|
|
|
3785
|
-
|
|
3843
|
+
return JSON.stringify([authSession, requestCookies]);
|
|
3844
|
+
}
|
|
3786
3845
|
|
|
3787
|
-
|
|
3788
|
-
|
|
3846
|
+
function __mreactReleaseNavigationCacheToken(href, token) {
|
|
3847
|
+
if (
|
|
3848
|
+
__mreactNavigationState.cache.get(href) === undefined &&
|
|
3849
|
+
__mreactNavigationState.pendingHtmlFetches.get(href) === undefined &&
|
|
3850
|
+
(token === undefined || __mreactNavigationState.cacheTokens.get(href) === token)
|
|
3851
|
+
) {
|
|
3852
|
+
__mreactNavigationState.cacheTokens.delete(href);
|
|
3789
3853
|
}
|
|
3854
|
+
}
|
|
3790
3855
|
|
|
3791
|
-
|
|
3792
|
-
|
|
3856
|
+
function __mreactNavigationCacheToken(href) {
|
|
3857
|
+
const existing = __mreactNavigationState.cacheTokens.get(href);
|
|
3858
|
+
|
|
3859
|
+
if (existing !== undefined) {
|
|
3860
|
+
return existing;
|
|
3793
3861
|
}
|
|
3794
3862
|
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3863
|
+
const token = { valid: true };
|
|
3864
|
+
__mreactNavigationState.cacheTokens.set(href, token);
|
|
3865
|
+
return token;
|
|
3866
|
+
}
|
|
3867
|
+
|
|
3868
|
+
function __mreactPrefetchRouteScript(route) {
|
|
3869
|
+
if (typeof document === "undefined") {
|
|
3870
|
+
return false;
|
|
3871
|
+
}
|
|
3872
|
+
|
|
3873
|
+
const files = [route.script, ...(route.modulePreloads ?? [])];
|
|
3874
|
+
let valid = true;
|
|
3875
|
+
|
|
3876
|
+
for (const file of files) {
|
|
3877
|
+
const href = __mreactNormalizeAssetUrl(file);
|
|
3878
|
+
|
|
3879
|
+
if (
|
|
3880
|
+
href === undefined ||
|
|
3881
|
+
!__mreactIsSupportedModulePreloadUrl(file) ||
|
|
3882
|
+
!__mreactModulePreloadMatchesRouteScript(file, route.script)
|
|
3883
|
+
) {
|
|
3884
|
+
valid = false;
|
|
3885
|
+
continue;
|
|
3886
|
+
}
|
|
3887
|
+
|
|
3888
|
+
if (__mreactNavigationState.prefetchedScripts.has(href)) {
|
|
3889
|
+
continue;
|
|
3890
|
+
}
|
|
3891
|
+
|
|
3892
|
+
let found = false;
|
|
3893
|
+
for (const link of Array.from(document.querySelectorAll('link[rel="modulepreload"][href]'))) {
|
|
3894
|
+
if (link.href === href) {
|
|
3895
|
+
found = true;
|
|
3896
|
+
break;
|
|
3897
|
+
}
|
|
3898
|
+
}
|
|
3899
|
+
|
|
3900
|
+
if (!found) {
|
|
3901
|
+
const link = document.createElement("link");
|
|
3902
|
+
link.rel = "modulepreload";
|
|
3903
|
+
link.href = href;
|
|
3904
|
+
document.head.appendChild(link);
|
|
3799
3905
|
}
|
|
3906
|
+
|
|
3907
|
+
__mreactRememberPrefetchedScript(href);
|
|
3800
3908
|
}
|
|
3801
3909
|
|
|
3802
|
-
|
|
3803
|
-
link.rel = "modulepreload";
|
|
3804
|
-
link.href = href;
|
|
3805
|
-
document.head.appendChild(link);
|
|
3806
|
-
__mreactRememberPrefetchedScript(href);
|
|
3807
|
-
return true;
|
|
3910
|
+
return valid;
|
|
3808
3911
|
}
|
|
3809
3912
|
|
|
3810
3913
|
export async function __mreactNavigate(url, options = {}) {
|
|
@@ -3817,19 +3920,46 @@ export async function __mreactNavigate(url, options = {}) {
|
|
|
3817
3920
|
__mreactSetNavigationState(__mreactPendingNavigationState(href, options.type ?? "push"));
|
|
3818
3921
|
|
|
3819
3922
|
try {
|
|
3820
|
-
|
|
3821
|
-
const script = __mreactRouteScriptForNavigationUrl(href);
|
|
3822
|
-
if (script !== undefined) {
|
|
3823
|
-
void __mreactPrefetchRouteScript(script);
|
|
3824
|
-
}
|
|
3825
|
-
const html = cachedHtml ?? await __mreactFetchNavigationHtmlOnce(href);
|
|
3923
|
+
let forceReload = __mreactNavigationState.reloadNextNavigationFetch === true;
|
|
3826
3924
|
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3925
|
+
for (;;) {
|
|
3926
|
+
const cachedHtml = forceReload ? undefined : __mreactCachedNavigationHtml(href);
|
|
3927
|
+
const script = __mreactRouteScriptForNavigationUrl(href);
|
|
3928
|
+
if (script !== undefined) {
|
|
3929
|
+
void __mreactPrefetchRouteScript(script);
|
|
3930
|
+
}
|
|
3931
|
+
const result = cachedHtml === undefined
|
|
3932
|
+
? await __mreactFetchNavigationHtmlOnce(href, { force: forceReload })
|
|
3933
|
+
: {
|
|
3934
|
+
cacheable: true,
|
|
3935
|
+
cacheContext: __mreactNavigationCacheContext(),
|
|
3936
|
+
cacheContextMatches: true,
|
|
3937
|
+
html: cachedHtml,
|
|
3938
|
+
reusable: true,
|
|
3939
|
+
speculative: false,
|
|
3940
|
+
token: undefined,
|
|
3941
|
+
};
|
|
3942
|
+
|
|
3943
|
+
if (result.token !== undefined && result.token.valid !== true) {
|
|
3944
|
+
forceReload = __mreactNavigationState.reloadNextNavigationFetch === true;
|
|
3945
|
+
continue;
|
|
3946
|
+
}
|
|
3830
3947
|
|
|
3831
|
-
|
|
3832
|
-
|
|
3948
|
+
if (result.speculative === true && result.cacheable !== true) {
|
|
3949
|
+
forceReload = true;
|
|
3950
|
+
continue;
|
|
3951
|
+
}
|
|
3952
|
+
|
|
3953
|
+
if (result.reusable === true && result.cacheContextMatches !== true) {
|
|
3954
|
+
return false;
|
|
3955
|
+
}
|
|
3956
|
+
|
|
3957
|
+
if (typeof result.html !== "string") {
|
|
3958
|
+
return false;
|
|
3959
|
+
}
|
|
3960
|
+
|
|
3961
|
+
return await __mreactApplyNavigationHtmlWithOptionalTransition(result.html, href, options);
|
|
3962
|
+
}
|
|
3833
3963
|
} finally {
|
|
3834
3964
|
__mreactSetNavigationState(__mreactIdleNavigationState());
|
|
3835
3965
|
}
|
|
@@ -3964,7 +4094,7 @@ function __mreactViewTransitionsAllowed(transition) {
|
|
|
3964
4094
|
}
|
|
3965
4095
|
}
|
|
3966
4096
|
|
|
3967
|
-
export function __mreactInvalidateNavigationCache(path) {
|
|
4097
|
+
export function __mreactInvalidateNavigationCache(path, excludedRequest) {
|
|
3968
4098
|
const normalizedPath = __mreactNormalizeNavigationPath(path);
|
|
3969
4099
|
|
|
3970
4100
|
if (normalizedPath === undefined) {
|
|
@@ -3978,66 +4108,160 @@ export function __mreactInvalidateNavigationCache(path) {
|
|
|
3978
4108
|
|
|
3979
4109
|
for (const href of hrefs) {
|
|
3980
4110
|
if (__mreactNormalizeNavigationPath(href) === normalizedPath) {
|
|
4111
|
+
const token = __mreactNavigationState.cacheTokens.get(href);
|
|
4112
|
+
if (
|
|
4113
|
+
excludedRequest?.href === href &&
|
|
4114
|
+
excludedRequest.token === token &&
|
|
4115
|
+
token?.valid === true
|
|
4116
|
+
) {
|
|
4117
|
+
continue;
|
|
4118
|
+
}
|
|
4119
|
+
if (token !== undefined) {
|
|
4120
|
+
token.valid = false;
|
|
4121
|
+
}
|
|
3981
4122
|
__mreactNavigationState.cache.delete(href);
|
|
3982
4123
|
__mreactNavigationState.prefetchedUrls.delete(href);
|
|
3983
4124
|
__mreactNavigationState.pendingHtmlFetches.delete(href);
|
|
4125
|
+
__mreactNavigationState.cacheTokens.delete(href);
|
|
3984
4126
|
}
|
|
3985
4127
|
}
|
|
3986
4128
|
}
|
|
3987
4129
|
|
|
3988
4130
|
function __mreactInvalidateAllNavigationCache() {
|
|
4131
|
+
for (const entry of __mreactNavigationState.cache.values()) {
|
|
4132
|
+
entry.token.valid = false;
|
|
4133
|
+
}
|
|
4134
|
+
for (const request of __mreactNavigationState.pendingHtmlFetches.values()) {
|
|
4135
|
+
request.token.valid = false;
|
|
4136
|
+
}
|
|
3989
4137
|
__mreactNavigationState.cache.clear();
|
|
4138
|
+
__mreactNavigationState.cacheTokens.clear();
|
|
3990
4139
|
__mreactNavigationState.prefetchedUrls.clear();
|
|
3991
4140
|
__mreactNavigationState.pendingHtmlFetches.clear();
|
|
3992
4141
|
}
|
|
3993
4142
|
|
|
3994
|
-
function __mreactFetchNavigationHtmlOnce(href) {
|
|
4143
|
+
function __mreactFetchNavigationHtmlOnce(href, options = {}) {
|
|
3995
4144
|
const pending = __mreactNavigationState.pendingHtmlFetches.get(href);
|
|
3996
4145
|
|
|
4146
|
+
if (pending !== undefined && options.force !== true) {
|
|
4147
|
+
return pending.promise;
|
|
4148
|
+
}
|
|
4149
|
+
|
|
3997
4150
|
if (pending !== undefined) {
|
|
3998
|
-
|
|
4151
|
+
pending.token.valid = false;
|
|
4152
|
+
__mreactNavigationState.pendingHtmlFetches.delete(href);
|
|
4153
|
+
__mreactNavigationState.cacheTokens.delete(href);
|
|
3999
4154
|
}
|
|
4000
4155
|
|
|
4001
|
-
const
|
|
4002
|
-
|
|
4156
|
+
const token = __mreactNavigationCacheToken(href);
|
|
4157
|
+
const pendingRequest = {
|
|
4158
|
+
promise: undefined,
|
|
4159
|
+
token,
|
|
4160
|
+
};
|
|
4161
|
+
const request = __mreactFetchNavigationHtml(href, options, pendingRequest)
|
|
4162
|
+
.then((result) => {
|
|
4163
|
+
const enriched = {
|
|
4164
|
+
...result,
|
|
4165
|
+
speculative: options.speculative === true,
|
|
4166
|
+
token,
|
|
4167
|
+
};
|
|
4003
4168
|
if (
|
|
4004
|
-
|
|
4005
|
-
|
|
4169
|
+
enriched.cacheable === true &&
|
|
4170
|
+
typeof enriched.html === "string" &&
|
|
4171
|
+
__mreactNavigationState.pendingHtmlFetches.get(href) === pendingRequest &&
|
|
4172
|
+
token.valid === true &&
|
|
4173
|
+
__mreactNavigationState.cacheTokens.get(href) === token
|
|
4006
4174
|
) {
|
|
4007
|
-
__mreactRememberNavigationHtml(href, html);
|
|
4175
|
+
__mreactRememberNavigationHtml(href, enriched.html, token, enriched.cacheContext);
|
|
4008
4176
|
}
|
|
4009
4177
|
|
|
4010
|
-
return
|
|
4178
|
+
return enriched;
|
|
4011
4179
|
})
|
|
4012
4180
|
.finally(() => {
|
|
4013
|
-
if (__mreactNavigationState.pendingHtmlFetches.get(href) ===
|
|
4181
|
+
if (__mreactNavigationState.pendingHtmlFetches.get(href) === pendingRequest) {
|
|
4014
4182
|
__mreactNavigationState.pendingHtmlFetches.delete(href);
|
|
4183
|
+
__mreactReleaseNavigationCacheToken(href, token);
|
|
4015
4184
|
}
|
|
4016
4185
|
});
|
|
4017
4186
|
|
|
4018
|
-
|
|
4187
|
+
pendingRequest.promise = request;
|
|
4188
|
+
__mreactNavigationState.pendingHtmlFetches.set(href, pendingRequest);
|
|
4019
4189
|
return request;
|
|
4020
4190
|
}
|
|
4021
4191
|
|
|
4022
|
-
function __mreactFetchNavigationHtml(href) {
|
|
4023
|
-
const
|
|
4024
|
-
__mreactNavigationState.reloadNextNavigationFetch
|
|
4192
|
+
function __mreactFetchNavigationHtml(href, options = {}, pendingRequest) {
|
|
4193
|
+
const speculative = options.speculative === true;
|
|
4194
|
+
const reloadRouteCache = !speculative && __mreactNavigationState.reloadNextNavigationFetch === true;
|
|
4195
|
+
if (!speculative) {
|
|
4196
|
+
__mreactNavigationState.reloadNextNavigationFetch = false;
|
|
4197
|
+
}
|
|
4025
4198
|
const headers = reloadRouteCache
|
|
4026
4199
|
? { "x-mreact-navigation": "1", "x-mreact-navigation-cache": "reload" }
|
|
4027
4200
|
: { "x-mreact-navigation": "1" };
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4201
|
+
const requestCacheContext = __mreactNavigationCacheContext();
|
|
4202
|
+
const requestCookies = __mreactNavigationCookies();
|
|
4203
|
+
const navigationRequestInit = { headers };
|
|
4204
|
+
__mreactNavigationState.navigationFetchInits.add(navigationRequestInit);
|
|
4205
|
+
|
|
4206
|
+
return fetch(__mreactStaticNavigationRequestHref(href), navigationRequestInit).then((response) => {
|
|
4207
|
+
const currentRequest =
|
|
4208
|
+
pendingRequest !== undefined &&
|
|
4209
|
+
__mreactNavigationState.pendingHtmlFetches.get(href) === pendingRequest &&
|
|
4210
|
+
__mreactNavigationState.cacheTokens.get(href) === pendingRequest.token &&
|
|
4211
|
+
pendingRequest.token.valid === true
|
|
4212
|
+
? { href, token: pendingRequest.token }
|
|
4213
|
+
: undefined;
|
|
4214
|
+
if (pendingRequest === undefined || currentRequest !== undefined) {
|
|
4215
|
+
__mreactApplyRevalidationHeader(response, currentRequest);
|
|
4216
|
+
}
|
|
4217
|
+
const requiresDocumentReload = __mreactNavigationResponseRequiresDocumentReload(response);
|
|
4218
|
+
const responseIsSuccessful =
|
|
4219
|
+
response.ok === true ||
|
|
4220
|
+
(response.ok === undefined && response.status >= 200 && response.status < 300);
|
|
4221
|
+
const responseIsRedirected = response.redirected === true;
|
|
4222
|
+
const cacheControl = (response.headers.get("cache-control") ?? "").toLowerCase();
|
|
4223
|
+
const responseDisallowsCache = /(?:^|,)\\s*(?:no-store|no-cache)(?:\\s*=|\\s*(?:,|$))/.test(
|
|
4224
|
+
cacheControl,
|
|
4225
|
+
);
|
|
4226
|
+
const reusable =
|
|
4227
|
+
!requiresDocumentReload &&
|
|
4228
|
+
responseIsSuccessful &&
|
|
4229
|
+
!responseIsRedirected &&
|
|
4230
|
+
!responseDisallowsCache;
|
|
4231
|
+
|
|
4232
|
+
if (requiresDocumentReload || responseIsRedirected || speculative && !reusable) {
|
|
4233
|
+
__mreactDiscardNavigationResponse(response);
|
|
4234
|
+
return { cacheable: false, html: undefined };
|
|
4035
4235
|
}
|
|
4036
4236
|
|
|
4037
|
-
return response.text()
|
|
4237
|
+
return response.text().then((html) => {
|
|
4238
|
+
const cacheContext = __mreactNavigationResponseCacheContext(html, requestCookies);
|
|
4239
|
+
const currentCacheContext = __mreactNavigationCacheContext();
|
|
4240
|
+
const cacheContextMatches =
|
|
4241
|
+
cacheContext === currentCacheContext && requestCacheContext === currentCacheContext;
|
|
4242
|
+
|
|
4243
|
+
return {
|
|
4244
|
+
cacheContext,
|
|
4245
|
+
cacheContextMatches,
|
|
4246
|
+
cacheable: reusable && cacheContextMatches,
|
|
4247
|
+
html,
|
|
4248
|
+
reusable,
|
|
4249
|
+
};
|
|
4250
|
+
});
|
|
4038
4251
|
});
|
|
4039
4252
|
}
|
|
4040
4253
|
|
|
4254
|
+
function __mreactDiscardNavigationResponse(response) {
|
|
4255
|
+
try {
|
|
4256
|
+
const result = response?.body?.cancel?.();
|
|
4257
|
+
if (result !== undefined && typeof result.catch === "function") {
|
|
4258
|
+
void result.catch(() => {});
|
|
4259
|
+
}
|
|
4260
|
+
} catch {
|
|
4261
|
+
// Ignore body cancellation failures while falling back to a document navigation.
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4264
|
+
|
|
4041
4265
|
function __mreactStaticNavigationRequestHref(href) {
|
|
4042
4266
|
if (typeof document === "undefined" || typeof location === "undefined") {
|
|
4043
4267
|
return href;
|
|
@@ -4073,7 +4297,7 @@ function __mreactNavigationResponseRequiresDocumentReload(response) {
|
|
|
4073
4297
|
return response.status === 204 || response.headers.get("x-mreact-navigation") === "reload";
|
|
4074
4298
|
}
|
|
4075
4299
|
|
|
4076
|
-
function __mreactApplyRevalidationHeader(response) {
|
|
4300
|
+
function __mreactApplyRevalidationHeader(response, currentRequest) {
|
|
4077
4301
|
const header = typeof response?.headers?.get === "function"
|
|
4078
4302
|
? response.headers.get("x-mreact-revalidate")
|
|
4079
4303
|
: null;
|
|
@@ -4082,18 +4306,34 @@ function __mreactApplyRevalidationHeader(response) {
|
|
|
4082
4306
|
return;
|
|
4083
4307
|
}
|
|
4084
4308
|
|
|
4309
|
+
const currentPath = __mreactNormalizeNavigationPath(currentRequest?.href);
|
|
4310
|
+
|
|
4085
4311
|
for (const path of header.split(",")) {
|
|
4086
|
-
|
|
4312
|
+
const trimmedPath = path.trim();
|
|
4313
|
+
const normalizedPath = __mreactNormalizeNavigationPath(trimmedPath);
|
|
4314
|
+
const excludedRequest =
|
|
4315
|
+
currentRequest !== undefined && normalizedPath === currentPath ? currentRequest : undefined;
|
|
4316
|
+
__mreactInvalidateNavigationCache(trimmedPath, excludedRequest);
|
|
4087
4317
|
}
|
|
4088
4318
|
}
|
|
4089
4319
|
|
|
4320
|
+
function __mreactIsNavigationFetchRequest(_input, init) {
|
|
4321
|
+
return init !== null && typeof init === "object" && __mreactNavigationState.navigationFetchInits.has(init);
|
|
4322
|
+
}
|
|
4323
|
+
|
|
4090
4324
|
function __mreactNormalizeNavigationPath(path) {
|
|
4325
|
+
if (typeof path !== "string" || path.trim() === "") {
|
|
4326
|
+
return undefined;
|
|
4327
|
+
}
|
|
4328
|
+
|
|
4329
|
+
const normalizedInput = path.trim();
|
|
4330
|
+
|
|
4091
4331
|
if (typeof location === "undefined") {
|
|
4092
|
-
return
|
|
4332
|
+
return normalizedInput;
|
|
4093
4333
|
}
|
|
4094
4334
|
|
|
4095
4335
|
try {
|
|
4096
|
-
const url = new URL(
|
|
4336
|
+
const url = new URL(normalizedInput, location.href);
|
|
4097
4337
|
const pathname = url.pathname.replace(/\\/+$/, "");
|
|
4098
4338
|
|
|
4099
4339
|
return pathname === "" ? "/" : pathname;
|
|
@@ -4109,7 +4349,7 @@ export function __mreactRestoreHistoryState(state) {
|
|
|
4109
4349
|
|
|
4110
4350
|
const html = typeof state.html === "string"
|
|
4111
4351
|
? state.html
|
|
4112
|
-
: typeof state.url === "string" ?
|
|
4352
|
+
: typeof state.url === "string" ? __mreactCachedNavigationHtml(state.url) : undefined;
|
|
4113
4353
|
|
|
4114
4354
|
if (typeof html !== "string") {
|
|
4115
4355
|
return false;
|
|
@@ -4485,7 +4725,7 @@ function __mreactRouteScriptForNavigationUrl(url) {
|
|
|
4485
4725
|
|
|
4486
4726
|
for (const route of __mreactClientRoutePrefetchManifest()) {
|
|
4487
4727
|
if (__mreactRoutePathMatches(route.path, nextUrl.pathname)) {
|
|
4488
|
-
return route
|
|
4728
|
+
return route;
|
|
4489
4729
|
}
|
|
4490
4730
|
}
|
|
4491
4731
|
|
|
@@ -4515,12 +4755,28 @@ function __mreactClientRoutePrefetchManifest() {
|
|
|
4515
4755
|
try {
|
|
4516
4756
|
const parsed = JSON.parse(text);
|
|
4517
4757
|
__mreactNavigationState.routePrefetchManifest = Array.isArray(parsed)
|
|
4518
|
-
? parsed.
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4758
|
+
? parsed.flatMap((route) => {
|
|
4759
|
+
if (
|
|
4760
|
+
route === null ||
|
|
4761
|
+
typeof route !== "object" ||
|
|
4762
|
+
typeof route.path !== "string" ||
|
|
4763
|
+
typeof route.script !== "string" ||
|
|
4764
|
+
!__mreactIsSupportedModulePreloadUrl(route.script)
|
|
4765
|
+
) {
|
|
4766
|
+
return [];
|
|
4767
|
+
}
|
|
4768
|
+
|
|
4769
|
+
const modulePreloads = Array.isArray(route.modulePreloads)
|
|
4770
|
+
? route.modulePreloads.filter(
|
|
4771
|
+
(file) =>
|
|
4772
|
+
typeof file === "string" &&
|
|
4773
|
+
__mreactIsSupportedModulePreloadUrl(file) &&
|
|
4774
|
+
__mreactModulePreloadMatchesRouteScript(file, route.script),
|
|
4775
|
+
)
|
|
4776
|
+
: [];
|
|
4777
|
+
|
|
4778
|
+
return [{ ...route, modulePreloads }];
|
|
4779
|
+
})
|
|
4524
4780
|
: [];
|
|
4525
4781
|
} catch {
|
|
4526
4782
|
__mreactNavigationState.routePrefetchManifest = [];
|
|
@@ -4529,6 +4785,29 @@ function __mreactClientRoutePrefetchManifest() {
|
|
|
4529
4785
|
return __mreactNavigationState.routePrefetchManifest;
|
|
4530
4786
|
}
|
|
4531
4787
|
|
|
4788
|
+
function __mreactIsSupportedModulePreloadUrl(value) {
|
|
4789
|
+
if (typeof value !== "string" || value === "" || value.startsWith("javascript:")) {
|
|
4790
|
+
return false;
|
|
4791
|
+
}
|
|
4792
|
+
|
|
4793
|
+
try {
|
|
4794
|
+
const resolved = new URL(value, typeof location === "undefined" ? undefined : location.href);
|
|
4795
|
+
return resolved.protocol === "http:" || resolved.protocol === "https:";
|
|
4796
|
+
} catch {
|
|
4797
|
+
return false;
|
|
4798
|
+
}
|
|
4799
|
+
}
|
|
4800
|
+
|
|
4801
|
+
function __mreactModulePreloadMatchesRouteScript(value, script) {
|
|
4802
|
+
try {
|
|
4803
|
+
const scriptUrl = new URL(__mreactNormalizeAssetUrl(script), location.href);
|
|
4804
|
+
const dependencyUrl = new URL(__mreactNormalizeAssetUrl(value), location.href);
|
|
4805
|
+
return scriptUrl.origin === dependencyUrl.origin;
|
|
4806
|
+
} catch {
|
|
4807
|
+
return false;
|
|
4808
|
+
}
|
|
4809
|
+
}
|
|
4810
|
+
|
|
4532
4811
|
function __mreactRoutePathMatches(routePath, pathname) {
|
|
4533
4812
|
const routeSegments = __mreactNormalizeRoutePath(routePath);
|
|
4534
4813
|
const pathSegments = __mreactNormalizeRoutePath(pathname);
|
|
@@ -4826,9 +5105,12 @@ function __mreactInstallNavigationFetchRevalidation() {
|
|
|
4826
5105
|
const fetchImpl = globalThis.fetch;
|
|
4827
5106
|
globalThis.fetch = function(input, init) {
|
|
4828
5107
|
const mutating = __mreactIsMutatingFetchRequest(input, init);
|
|
5108
|
+
const navigation = __mreactIsNavigationFetchRequest(input, init);
|
|
4829
5109
|
|
|
4830
5110
|
return Promise.resolve(fetchImpl.call(this, input, init)).then((response) => {
|
|
4831
|
-
|
|
5111
|
+
if (!navigation) {
|
|
5112
|
+
__mreactApplyRevalidationHeader(response);
|
|
5113
|
+
}
|
|
4832
5114
|
|
|
4833
5115
|
if (mutating) {
|
|
4834
5116
|
__mreactInvalidateAllNavigationCache();
|
|
@@ -4900,7 +5182,7 @@ function __mreactObserveViewportPrefetchAnchors(root) {
|
|
|
4900
5182
|
}
|
|
4901
5183
|
|
|
4902
5184
|
__mreactNavigationState.viewportObserver?.unobserve(entry.target);
|
|
4903
|
-
void __mreactPrefetch(entry.target.href);
|
|
5185
|
+
void __mreactPrefetch(entry.target.href, { trigger: "viewport" });
|
|
4904
5186
|
}
|
|
4905
5187
|
});
|
|
4906
5188
|
}
|
|
@@ -5540,14 +5822,7 @@ export function cell(initial) {
|
|
|
5540
5822
|
resolveDir: reactiveCoreDir,
|
|
5541
5823
|
}));
|
|
5542
5824
|
buildApi.onLoad({ filter: /^devtools$/, namespace: "mreact-devtools-stub" }, () => ({
|
|
5543
|
-
contents:
|
|
5544
|
-
export function emitReactiveEffectRunDevtoolsEvent() {}
|
|
5545
|
-
export function hasReactiveDevtoolsEmitter() { return false; }
|
|
5546
|
-
export function currentDevtoolsEmitter() { return undefined; }
|
|
5547
|
-
export function currentReactiveDevtools() { return undefined; }
|
|
5548
|
-
export function registerReactiveDevtoolsResource() { return { dispose() {}, update() {} }; }
|
|
5549
|
-
export function invalidateReactiveDevtoolsCache() {}
|
|
5550
|
-
export function prepareReactiveEffectRunDevtoolsEvent() { return undefined; }`,
|
|
5825
|
+
contents: reactiveDevtoolsStubSource,
|
|
5551
5826
|
loader: "ts",
|
|
5552
5827
|
}));
|
|
5553
5828
|
if (options.sourceRegionModulePaths !== undefined) {
|