@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/dist/client.js
CHANGED
|
@@ -5,6 +5,7 @@ import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep }
|
|
|
5
5
|
import { analyzeBoundaryGraph, collectClientRouteModuleAnalysis, formatDiagnostic, } from "@reckona/mreact-compiler";
|
|
6
6
|
import { collectClientRouteModuleAnalysisFromContext, createCompilerModuleContext, hasUnguardedBrowserGlobalReference, readTopLevelBooleanExport, readTopLevelBooleanExportFromContext, stripTypeScriptWithOxc, transformCompilerModuleContext, } from "@reckona/mreact-compiler/internal";
|
|
7
7
|
import { assetPath } from "./assets.js";
|
|
8
|
+
import { reactiveDevtoolsStubSource } from "./reactive-devtools-stub.js";
|
|
8
9
|
import { bundleRouterModule, bundleRouterModules, } from "./bundle-pipeline.js";
|
|
9
10
|
import { resolveClientConsolePureFunctions } from "./config.js";
|
|
10
11
|
import { existingRouteShellCandidates } from "./route-shells.js";
|
|
@@ -1923,6 +1924,7 @@ export async function buildClientRouteEntrySource(options) {
|
|
|
1923
1924
|
const navigationStateDeclaration = inlineClientNavigation
|
|
1924
1925
|
? `const __mreactNavigationState = __mreactGlobal.__mreactNavigationState ??= {
|
|
1925
1926
|
cache: new Map(),
|
|
1927
|
+
cacheTokens: new Map(),
|
|
1926
1928
|
current: {
|
|
1927
1929
|
from: null,
|
|
1928
1930
|
pending: false,
|
|
@@ -1931,6 +1933,7 @@ export async function buildClientRouteEntrySource(options) {
|
|
|
1931
1933
|
},
|
|
1932
1934
|
fetchRevalidationInstalled: false,
|
|
1933
1935
|
installed: false,
|
|
1936
|
+
navigationFetchInits: new WeakSet(),
|
|
1934
1937
|
pendingHtmlFetches: new Map(),
|
|
1935
1938
|
prefetchedUrls: new Set(),
|
|
1936
1939
|
prefetchedScripts: new Set(),
|
|
@@ -1939,7 +1942,9 @@ export async function buildClientRouteEntrySource(options) {
|
|
|
1939
1942
|
routePrefetchManifestText: undefined,
|
|
1940
1943
|
viewportAnchors: new WeakSet(),
|
|
1941
1944
|
viewportObserver: undefined,
|
|
1942
|
-
}
|
|
1945
|
+
};
|
|
1946
|
+
__mreactNavigationState.cacheTokens ??= new Map();
|
|
1947
|
+
__mreactNavigationState.navigationFetchInits ??= new WeakSet();`
|
|
1943
1948
|
: "";
|
|
1944
1949
|
const deferredNavigationRuntime = deferredClientNavigation
|
|
1945
1950
|
? `
|
|
@@ -2102,10 +2107,10 @@ export async function __mreactNavigate(url, options = {}) {
|
|
|
2102
2107
|
: false;
|
|
2103
2108
|
}
|
|
2104
2109
|
|
|
2105
|
-
export async function __mreactPrefetch(url) {
|
|
2110
|
+
export async function __mreactPrefetch(url, options = {}) {
|
|
2106
2111
|
const runtime = await __mreactLoadNavigationRuntime();
|
|
2107
2112
|
return typeof runtime?.__mreactPrefetch === "function"
|
|
2108
|
-
? runtime.__mreactPrefetch(url)
|
|
2113
|
+
? runtime.__mreactPrefetch(url, options)
|
|
2109
2114
|
: false;
|
|
2110
2115
|
}
|
|
2111
2116
|
|
|
@@ -2151,13 +2156,16 @@ __mreactGlobal.__mreactRouteCell = (nativeCell, initial) => {
|
|
|
2151
2156
|
const stateCell = nativeCell(record.value);
|
|
2152
2157
|
const setStateCell = stateCell.set;
|
|
2153
2158
|
|
|
2154
|
-
|
|
2159
|
+
const setRouteStateCell = (next) => {
|
|
2155
2160
|
setStateCell((previous) => {
|
|
2156
2161
|
const resolved = typeof next === "function" ? next(previous) : next;
|
|
2157
2162
|
record.value = resolved;
|
|
2158
2163
|
return resolved;
|
|
2159
2164
|
});
|
|
2160
2165
|
};
|
|
2166
|
+
stateCell.set = setRouteStateCell;
|
|
2167
|
+
stateCell.setValue = (next) => stateCell.set(() => next);
|
|
2168
|
+
stateCell.update = (updater) => stateCell.set(updater);
|
|
2161
2169
|
|
|
2162
2170
|
__mreactActiveCellRecords.set(cellKey, record);
|
|
2163
2171
|
return stateCell;
|
|
@@ -2578,7 +2586,7 @@ function __mreactRouteAnnouncementElement() {
|
|
|
2578
2586
|
return announcement;
|
|
2579
2587
|
}
|
|
2580
2588
|
|
|
2581
|
-
export async function __mreactPrefetch(url) {
|
|
2589
|
+
export async function __mreactPrefetch(url, options = {}) {
|
|
2582
2590
|
if (!__mreactCanPrefetch()) {
|
|
2583
2591
|
return false;
|
|
2584
2592
|
}
|
|
@@ -2597,10 +2605,6 @@ export async function __mreactPrefetch(url) {
|
|
|
2597
2605
|
return false;
|
|
2598
2606
|
}
|
|
2599
2607
|
|
|
2600
|
-
if (__mreactNavigationState.prefetchedUrls.has(href)) {
|
|
2601
|
-
return true;
|
|
2602
|
-
}
|
|
2603
|
-
|
|
2604
2608
|
__mreactRememberPrefetchedUrl(href);
|
|
2605
2609
|
|
|
2606
2610
|
const script = __mreactRouteScriptForNavigationUrl(href);
|
|
@@ -2609,21 +2613,30 @@ export async function __mreactPrefetch(url) {
|
|
|
2609
2613
|
return __mreactPrefetchNavigationHtml(href);
|
|
2610
2614
|
}
|
|
2611
2615
|
|
|
2612
|
-
|
|
2616
|
+
const scriptPrefetched = __mreactPrefetchRouteScript(script);
|
|
2617
|
+
|
|
2618
|
+
if (options?.trigger === "viewport") {
|
|
2619
|
+
return scriptPrefetched;
|
|
2620
|
+
}
|
|
2621
|
+
|
|
2622
|
+
return Promise.resolve(__mreactPrefetchNavigationHtml(href))
|
|
2623
|
+
.then(() => scriptPrefetched)
|
|
2624
|
+
.catch(() => scriptPrefetched);
|
|
2613
2625
|
}
|
|
2614
2626
|
|
|
2615
2627
|
function __mreactPrefetchNavigationHtml(href) {
|
|
2616
|
-
if (
|
|
2628
|
+
if (__mreactCachedNavigationHtml(href) !== undefined) {
|
|
2617
2629
|
return true;
|
|
2618
2630
|
}
|
|
2619
2631
|
|
|
2620
|
-
return __mreactFetchNavigationHtmlOnce(href)
|
|
2621
|
-
.then((
|
|
2632
|
+
return __mreactFetchNavigationHtmlOnce(href, { speculative: true })
|
|
2633
|
+
.then((result) => result.cacheable && typeof result.html === "string")
|
|
2622
2634
|
.catch(() => false);
|
|
2623
2635
|
}
|
|
2624
2636
|
|
|
2625
2637
|
const __mreactNavigationHtmlCacheMaxEntries = 64;
|
|
2626
2638
|
const __mreactNavigationPrefetchHistoryMaxEntries = 64;
|
|
2639
|
+
const __mreactNavigationHtmlCacheTtlMs = 30_000;
|
|
2627
2640
|
|
|
2628
2641
|
function __mreactRememberPrefetchedUrl(href) {
|
|
2629
2642
|
__mreactRememberPrefetchHistory(__mreactNavigationState.prefetchedUrls, href);
|
|
@@ -2652,23 +2665,49 @@ function __mreactRememberPrefetchHistory(history, href) {
|
|
|
2652
2665
|
}
|
|
2653
2666
|
|
|
2654
2667
|
function __mreactCachedNavigationHtml(href) {
|
|
2655
|
-
const
|
|
2668
|
+
const entry = __mreactNavigationState.cache.get(href);
|
|
2656
2669
|
|
|
2657
|
-
if (
|
|
2670
|
+
if (entry === undefined) {
|
|
2671
|
+
return undefined;
|
|
2672
|
+
}
|
|
2673
|
+
|
|
2674
|
+
if (
|
|
2675
|
+
entry.token !== __mreactNavigationState.cacheTokens.get(href) ||
|
|
2676
|
+
entry.token.valid !== true ||
|
|
2677
|
+
entry.cacheContext !== __mreactNavigationCacheContext() ||
|
|
2678
|
+
Date.now() - entry.fetchedAt >= __mreactNavigationHtmlCacheTtlMs
|
|
2679
|
+
) {
|
|
2680
|
+
__mreactNavigationState.cache.delete(href);
|
|
2681
|
+
__mreactNavigationState.prefetchedUrls.delete(href);
|
|
2682
|
+
__mreactReleaseNavigationCacheToken(href, entry.token);
|
|
2658
2683
|
return undefined;
|
|
2659
2684
|
}
|
|
2660
2685
|
|
|
2661
2686
|
__mreactNavigationState.cache.delete(href);
|
|
2662
|
-
__mreactNavigationState.cache.set(href,
|
|
2663
|
-
return html;
|
|
2687
|
+
__mreactNavigationState.cache.set(href, entry);
|
|
2688
|
+
return entry.html;
|
|
2664
2689
|
}
|
|
2665
2690
|
|
|
2666
|
-
function __mreactRememberNavigationHtml(href, html) {
|
|
2691
|
+
function __mreactRememberNavigationHtml(href, html, token, cacheContext) {
|
|
2692
|
+
if (
|
|
2693
|
+
token === undefined ||
|
|
2694
|
+
token.valid !== true ||
|
|
2695
|
+
__mreactNavigationState.cacheTokens.get(href) !== token ||
|
|
2696
|
+
cacheContext !== __mreactNavigationCacheContext()
|
|
2697
|
+
) {
|
|
2698
|
+
return;
|
|
2699
|
+
}
|
|
2700
|
+
|
|
2667
2701
|
if (__mreactNavigationState.cache.has(href)) {
|
|
2668
2702
|
__mreactNavigationState.cache.delete(href);
|
|
2669
2703
|
}
|
|
2670
2704
|
|
|
2671
|
-
__mreactNavigationState.cache.set(href,
|
|
2705
|
+
__mreactNavigationState.cache.set(href, {
|
|
2706
|
+
cacheContext,
|
|
2707
|
+
fetchedAt: Date.now(),
|
|
2708
|
+
html,
|
|
2709
|
+
token,
|
|
2710
|
+
});
|
|
2672
2711
|
|
|
2673
2712
|
while (__mreactNavigationState.cache.size > __mreactNavigationHtmlCacheMaxEntries) {
|
|
2674
2713
|
const oldestHref = __mreactNavigationState.cache.keys().next().value;
|
|
@@ -2679,37 +2718,100 @@ function __mreactRememberNavigationHtml(href, html) {
|
|
|
2679
2718
|
|
|
2680
2719
|
__mreactNavigationState.cache.delete(oldestHref);
|
|
2681
2720
|
__mreactNavigationState.prefetchedUrls.delete(oldestHref);
|
|
2721
|
+
__mreactReleaseNavigationCacheToken(oldestHref);
|
|
2682
2722
|
}
|
|
2683
2723
|
}
|
|
2684
2724
|
|
|
2685
|
-
function
|
|
2686
|
-
|
|
2687
|
-
|
|
2725
|
+
function __mreactNavigationCacheContext() {
|
|
2726
|
+
const authSession = typeof document === "undefined"
|
|
2727
|
+
? undefined
|
|
2728
|
+
: document.getElementById("__mreact_auth_session")?.textContent ?? undefined;
|
|
2729
|
+
const cookies = __mreactNavigationCookies();
|
|
2730
|
+
|
|
2731
|
+
return JSON.stringify([authSession, cookies]);
|
|
2732
|
+
}
|
|
2733
|
+
|
|
2734
|
+
function __mreactNavigationCookies() {
|
|
2735
|
+
return typeof document === "undefined" ? "" : document.cookie;
|
|
2736
|
+
}
|
|
2737
|
+
|
|
2738
|
+
function __mreactNavigationResponseCacheContext(html, requestCookies) {
|
|
2739
|
+
let authSession;
|
|
2740
|
+
|
|
2741
|
+
if (typeof document !== "undefined") {
|
|
2742
|
+
const template = document.createElement("template");
|
|
2743
|
+
template.innerHTML = html;
|
|
2744
|
+
authSession = template.content.querySelector("#__mreact_auth_session")?.textContent ?? undefined;
|
|
2745
|
+
}
|
|
2746
|
+
|
|
2747
|
+
return JSON.stringify([authSession, requestCookies]);
|
|
2748
|
+
}
|
|
2749
|
+
|
|
2750
|
+
function __mreactReleaseNavigationCacheToken(href, token) {
|
|
2751
|
+
if (
|
|
2752
|
+
__mreactNavigationState.cache.get(href) === undefined &&
|
|
2753
|
+
__mreactNavigationState.pendingHtmlFetches.get(href) === undefined &&
|
|
2754
|
+
(token === undefined || __mreactNavigationState.cacheTokens.get(href) === token)
|
|
2755
|
+
) {
|
|
2756
|
+
__mreactNavigationState.cacheTokens.delete(href);
|
|
2688
2757
|
}
|
|
2758
|
+
}
|
|
2689
2759
|
|
|
2690
|
-
|
|
2760
|
+
function __mreactNavigationCacheToken(href) {
|
|
2761
|
+
const existing = __mreactNavigationState.cacheTokens.get(href);
|
|
2691
2762
|
|
|
2692
|
-
if (
|
|
2693
|
-
return
|
|
2763
|
+
if (existing !== undefined) {
|
|
2764
|
+
return existing;
|
|
2694
2765
|
}
|
|
2695
2766
|
|
|
2696
|
-
|
|
2697
|
-
|
|
2767
|
+
const token = { valid: true };
|
|
2768
|
+
__mreactNavigationState.cacheTokens.set(href, token);
|
|
2769
|
+
return token;
|
|
2770
|
+
}
|
|
2771
|
+
|
|
2772
|
+
function __mreactPrefetchRouteScript(route) {
|
|
2773
|
+
if (typeof document === "undefined") {
|
|
2774
|
+
return false;
|
|
2698
2775
|
}
|
|
2699
2776
|
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2777
|
+
const files = [route.script, ...(route.modulePreloads ?? [])];
|
|
2778
|
+
let valid = true;
|
|
2779
|
+
|
|
2780
|
+
for (const file of files) {
|
|
2781
|
+
const href = __mreactNormalizeAssetUrl(file);
|
|
2782
|
+
|
|
2783
|
+
if (
|
|
2784
|
+
href === undefined ||
|
|
2785
|
+
!__mreactIsSupportedModulePreloadUrl(file) ||
|
|
2786
|
+
!__mreactModulePreloadMatchesRouteScript(file, route.script)
|
|
2787
|
+
) {
|
|
2788
|
+
valid = false;
|
|
2789
|
+
continue;
|
|
2704
2790
|
}
|
|
2791
|
+
|
|
2792
|
+
if (__mreactNavigationState.prefetchedScripts.has(href)) {
|
|
2793
|
+
continue;
|
|
2794
|
+
}
|
|
2795
|
+
|
|
2796
|
+
let found = false;
|
|
2797
|
+
for (const link of Array.from(document.querySelectorAll('link[rel="modulepreload"][href]'))) {
|
|
2798
|
+
if (link.href === href) {
|
|
2799
|
+
found = true;
|
|
2800
|
+
break;
|
|
2801
|
+
}
|
|
2802
|
+
}
|
|
2803
|
+
|
|
2804
|
+
if (!found) {
|
|
2805
|
+
const link = document.createElement("link");
|
|
2806
|
+
link.rel = "modulepreload";
|
|
2807
|
+
link.href = href;
|
|
2808
|
+
document.head.appendChild(link);
|
|
2809
|
+
}
|
|
2810
|
+
|
|
2811
|
+
__mreactRememberPrefetchedScript(href);
|
|
2705
2812
|
}
|
|
2706
2813
|
|
|
2707
|
-
|
|
2708
|
-
link.rel = "modulepreload";
|
|
2709
|
-
link.href = href;
|
|
2710
|
-
document.head.appendChild(link);
|
|
2711
|
-
__mreactRememberPrefetchedScript(href);
|
|
2712
|
-
return true;
|
|
2814
|
+
return valid;
|
|
2713
2815
|
}
|
|
2714
2816
|
|
|
2715
2817
|
export async function __mreactNavigate(url, options = {}) {
|
|
@@ -2722,19 +2824,46 @@ export async function __mreactNavigate(url, options = {}) {
|
|
|
2722
2824
|
__mreactSetNavigationState(__mreactPendingNavigationState(href, options.type ?? "push"));
|
|
2723
2825
|
|
|
2724
2826
|
try {
|
|
2725
|
-
|
|
2726
|
-
const script = __mreactRouteScriptForNavigationUrl(href);
|
|
2727
|
-
if (script !== undefined) {
|
|
2728
|
-
void __mreactPrefetchRouteScript(script);
|
|
2729
|
-
}
|
|
2730
|
-
const html = cachedHtml ?? await __mreactFetchNavigationHtmlOnce(href);
|
|
2827
|
+
let forceReload = __mreactNavigationState.reloadNextNavigationFetch === true;
|
|
2731
2828
|
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2829
|
+
for (;;) {
|
|
2830
|
+
const cachedHtml = forceReload ? undefined : __mreactCachedNavigationHtml(href);
|
|
2831
|
+
const script = __mreactRouteScriptForNavigationUrl(href);
|
|
2832
|
+
if (script !== undefined) {
|
|
2833
|
+
void __mreactPrefetchRouteScript(script);
|
|
2834
|
+
}
|
|
2835
|
+
const result = cachedHtml === undefined
|
|
2836
|
+
? await __mreactFetchNavigationHtmlOnce(href, { force: forceReload })
|
|
2837
|
+
: {
|
|
2838
|
+
cacheable: true,
|
|
2839
|
+
cacheContext: __mreactNavigationCacheContext(),
|
|
2840
|
+
cacheContextMatches: true,
|
|
2841
|
+
html: cachedHtml,
|
|
2842
|
+
reusable: true,
|
|
2843
|
+
speculative: false,
|
|
2844
|
+
token: undefined,
|
|
2845
|
+
};
|
|
2846
|
+
|
|
2847
|
+
if (result.token !== undefined && result.token.valid !== true) {
|
|
2848
|
+
forceReload = __mreactNavigationState.reloadNextNavigationFetch === true;
|
|
2849
|
+
continue;
|
|
2850
|
+
}
|
|
2735
2851
|
|
|
2736
|
-
|
|
2737
|
-
|
|
2852
|
+
if (result.speculative === true && result.cacheable !== true) {
|
|
2853
|
+
forceReload = true;
|
|
2854
|
+
continue;
|
|
2855
|
+
}
|
|
2856
|
+
|
|
2857
|
+
if (result.reusable === true && result.cacheContextMatches !== true) {
|
|
2858
|
+
return false;
|
|
2859
|
+
}
|
|
2860
|
+
|
|
2861
|
+
if (typeof result.html !== "string") {
|
|
2862
|
+
return false;
|
|
2863
|
+
}
|
|
2864
|
+
|
|
2865
|
+
return await __mreactApplyNavigationHtmlWithOptionalTransition(result.html, href, options);
|
|
2866
|
+
}
|
|
2738
2867
|
} finally {
|
|
2739
2868
|
__mreactSetNavigationState(__mreactIdleNavigationState());
|
|
2740
2869
|
}
|
|
@@ -2869,7 +2998,7 @@ function __mreactViewTransitionsAllowed(transition) {
|
|
|
2869
2998
|
}
|
|
2870
2999
|
}
|
|
2871
3000
|
|
|
2872
|
-
export function __mreactInvalidateNavigationCache(path) {
|
|
3001
|
+
export function __mreactInvalidateNavigationCache(path, excludedRequest) {
|
|
2873
3002
|
const normalizedPath = __mreactNormalizeNavigationPath(path);
|
|
2874
3003
|
|
|
2875
3004
|
if (normalizedPath === undefined) {
|
|
@@ -2883,64 +3012,158 @@ export function __mreactInvalidateNavigationCache(path) {
|
|
|
2883
3012
|
|
|
2884
3013
|
for (const href of hrefs) {
|
|
2885
3014
|
if (__mreactNormalizeNavigationPath(href) === normalizedPath) {
|
|
3015
|
+
const token = __mreactNavigationState.cacheTokens.get(href);
|
|
3016
|
+
if (
|
|
3017
|
+
excludedRequest?.href === href &&
|
|
3018
|
+
excludedRequest.token === token &&
|
|
3019
|
+
token?.valid === true
|
|
3020
|
+
) {
|
|
3021
|
+
continue;
|
|
3022
|
+
}
|
|
3023
|
+
if (token !== undefined) {
|
|
3024
|
+
token.valid = false;
|
|
3025
|
+
}
|
|
2886
3026
|
__mreactNavigationState.cache.delete(href);
|
|
2887
3027
|
__mreactNavigationState.prefetchedUrls.delete(href);
|
|
2888
3028
|
__mreactNavigationState.pendingHtmlFetches.delete(href);
|
|
3029
|
+
__mreactNavigationState.cacheTokens.delete(href);
|
|
2889
3030
|
}
|
|
2890
3031
|
}
|
|
2891
3032
|
}
|
|
2892
3033
|
|
|
2893
3034
|
function __mreactInvalidateAllNavigationCache() {
|
|
3035
|
+
for (const entry of __mreactNavigationState.cache.values()) {
|
|
3036
|
+
entry.token.valid = false;
|
|
3037
|
+
}
|
|
3038
|
+
for (const request of __mreactNavigationState.pendingHtmlFetches.values()) {
|
|
3039
|
+
request.token.valid = false;
|
|
3040
|
+
}
|
|
2894
3041
|
__mreactNavigationState.cache.clear();
|
|
3042
|
+
__mreactNavigationState.cacheTokens.clear();
|
|
2895
3043
|
__mreactNavigationState.prefetchedUrls.clear();
|
|
2896
3044
|
__mreactNavigationState.pendingHtmlFetches.clear();
|
|
2897
3045
|
}
|
|
2898
3046
|
|
|
2899
|
-
function __mreactFetchNavigationHtmlOnce(href) {
|
|
3047
|
+
function __mreactFetchNavigationHtmlOnce(href, options = {}) {
|
|
2900
3048
|
const pending = __mreactNavigationState.pendingHtmlFetches.get(href);
|
|
2901
3049
|
|
|
3050
|
+
if (pending !== undefined && options.force !== true) {
|
|
3051
|
+
return pending.promise;
|
|
3052
|
+
}
|
|
3053
|
+
|
|
2902
3054
|
if (pending !== undefined) {
|
|
2903
|
-
|
|
3055
|
+
pending.token.valid = false;
|
|
3056
|
+
__mreactNavigationState.pendingHtmlFetches.delete(href);
|
|
3057
|
+
__mreactNavigationState.cacheTokens.delete(href);
|
|
2904
3058
|
}
|
|
2905
3059
|
|
|
2906
|
-
const
|
|
2907
|
-
|
|
3060
|
+
const token = __mreactNavigationCacheToken(href);
|
|
3061
|
+
const pendingRequest = {
|
|
3062
|
+
promise: undefined,
|
|
3063
|
+
token,
|
|
3064
|
+
};
|
|
3065
|
+
const request = __mreactFetchNavigationHtml(href, options, pendingRequest)
|
|
3066
|
+
.then((result) => {
|
|
3067
|
+
const enriched = {
|
|
3068
|
+
...result,
|
|
3069
|
+
speculative: options.speculative === true,
|
|
3070
|
+
token,
|
|
3071
|
+
};
|
|
2908
3072
|
if (
|
|
2909
|
-
|
|
2910
|
-
|
|
3073
|
+
enriched.cacheable === true &&
|
|
3074
|
+
typeof enriched.html === "string" &&
|
|
3075
|
+
__mreactNavigationState.pendingHtmlFetches.get(href) === pendingRequest &&
|
|
3076
|
+
token.valid === true &&
|
|
3077
|
+
__mreactNavigationState.cacheTokens.get(href) === token
|
|
2911
3078
|
) {
|
|
2912
|
-
__mreactRememberNavigationHtml(href, html);
|
|
3079
|
+
__mreactRememberNavigationHtml(href, enriched.html, token, enriched.cacheContext);
|
|
2913
3080
|
}
|
|
2914
3081
|
|
|
2915
|
-
return
|
|
3082
|
+
return enriched;
|
|
2916
3083
|
})
|
|
2917
3084
|
.finally(() => {
|
|
2918
|
-
if (__mreactNavigationState.pendingHtmlFetches.get(href) ===
|
|
3085
|
+
if (__mreactNavigationState.pendingHtmlFetches.get(href) === pendingRequest) {
|
|
2919
3086
|
__mreactNavigationState.pendingHtmlFetches.delete(href);
|
|
3087
|
+
__mreactReleaseNavigationCacheToken(href, token);
|
|
2920
3088
|
}
|
|
2921
3089
|
});
|
|
2922
3090
|
|
|
2923
|
-
|
|
3091
|
+
pendingRequest.promise = request;
|
|
3092
|
+
__mreactNavigationState.pendingHtmlFetches.set(href, pendingRequest);
|
|
2924
3093
|
return request;
|
|
2925
3094
|
}
|
|
2926
3095
|
|
|
2927
|
-
function __mreactFetchNavigationHtml(href) {
|
|
2928
|
-
const
|
|
2929
|
-
__mreactNavigationState.reloadNextNavigationFetch
|
|
3096
|
+
function __mreactFetchNavigationHtml(href, options = {}, pendingRequest) {
|
|
3097
|
+
const speculative = options.speculative === true;
|
|
3098
|
+
const reloadRouteCache = !speculative && __mreactNavigationState.reloadNextNavigationFetch === true;
|
|
3099
|
+
if (!speculative) {
|
|
3100
|
+
__mreactNavigationState.reloadNextNavigationFetch = false;
|
|
3101
|
+
}
|
|
2930
3102
|
const headers = reloadRouteCache
|
|
2931
3103
|
? { "x-mreact-navigation": "1", "x-mreact-navigation-cache": "reload" }
|
|
2932
3104
|
: { "x-mreact-navigation": "1" };
|
|
3105
|
+
const requestCacheContext = __mreactNavigationCacheContext();
|
|
3106
|
+
const requestCookies = __mreactNavigationCookies();
|
|
3107
|
+
const navigationRequestInit = { headers };
|
|
3108
|
+
__mreactNavigationState.navigationFetchInits.add(navigationRequestInit);
|
|
3109
|
+
|
|
3110
|
+
return fetch(__mreactStaticNavigationRequestHref(href), navigationRequestInit).then((response) => {
|
|
3111
|
+
const currentRequest =
|
|
3112
|
+
pendingRequest !== undefined &&
|
|
3113
|
+
__mreactNavigationState.pendingHtmlFetches.get(href) === pendingRequest &&
|
|
3114
|
+
__mreactNavigationState.cacheTokens.get(href) === pendingRequest.token &&
|
|
3115
|
+
pendingRequest.token.valid === true
|
|
3116
|
+
? { href, token: pendingRequest.token }
|
|
3117
|
+
: undefined;
|
|
3118
|
+
if (pendingRequest === undefined || currentRequest !== undefined) {
|
|
3119
|
+
__mreactApplyRevalidationHeader(response, currentRequest);
|
|
3120
|
+
}
|
|
3121
|
+
const requiresDocumentReload = __mreactNavigationResponseRequiresDocumentReload(response);
|
|
3122
|
+
const responseIsSuccessful =
|
|
3123
|
+
response.ok === true ||
|
|
3124
|
+
(response.ok === undefined && response.status >= 200 && response.status < 300);
|
|
3125
|
+
const responseIsRedirected = response.redirected === true;
|
|
3126
|
+
const cacheControl = (response.headers.get("cache-control") ?? "").toLowerCase();
|
|
3127
|
+
const responseDisallowsCache = /(?:^|,)\\s*(?:no-store|no-cache)(?:\\s*=|\\s*(?:,|$))/.test(
|
|
3128
|
+
cacheControl,
|
|
3129
|
+
);
|
|
3130
|
+
const reusable =
|
|
3131
|
+
!requiresDocumentReload &&
|
|
3132
|
+
responseIsSuccessful &&
|
|
3133
|
+
!responseIsRedirected &&
|
|
3134
|
+
!responseDisallowsCache;
|
|
3135
|
+
|
|
3136
|
+
if (requiresDocumentReload || responseIsRedirected || speculative && !reusable) {
|
|
3137
|
+
__mreactDiscardNavigationResponse(response);
|
|
3138
|
+
return { cacheable: false, html: undefined };
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
return response.text().then((html) => {
|
|
3142
|
+
const cacheContext = __mreactNavigationResponseCacheContext(html, requestCookies);
|
|
3143
|
+
const currentCacheContext = __mreactNavigationCacheContext();
|
|
3144
|
+
const cacheContextMatches =
|
|
3145
|
+
cacheContext === currentCacheContext && requestCacheContext === currentCacheContext;
|
|
3146
|
+
|
|
3147
|
+
return {
|
|
3148
|
+
cacheContext,
|
|
3149
|
+
cacheContextMatches,
|
|
3150
|
+
cacheable: reusable && cacheContextMatches,
|
|
3151
|
+
html,
|
|
3152
|
+
reusable,
|
|
3153
|
+
};
|
|
3154
|
+
});
|
|
3155
|
+
});
|
|
3156
|
+
}
|
|
2933
3157
|
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
return undefined;
|
|
3158
|
+
function __mreactDiscardNavigationResponse(response) {
|
|
3159
|
+
try {
|
|
3160
|
+
const result = response?.body?.cancel?.();
|
|
3161
|
+
if (result !== undefined && typeof result.catch === "function") {
|
|
3162
|
+
void result.catch(() => {});
|
|
2940
3163
|
}
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
}
|
|
3164
|
+
} catch {
|
|
3165
|
+
// Ignore body cancellation failures while falling back to a document navigation.
|
|
3166
|
+
}
|
|
2944
3167
|
}
|
|
2945
3168
|
|
|
2946
3169
|
function __mreactStaticNavigationRequestHref(href) {
|
|
@@ -2978,7 +3201,7 @@ function __mreactNavigationResponseRequiresDocumentReload(response) {
|
|
|
2978
3201
|
return response.status === 204 || response.headers.get("x-mreact-navigation") === "reload";
|
|
2979
3202
|
}
|
|
2980
3203
|
|
|
2981
|
-
function __mreactApplyRevalidationHeader(response) {
|
|
3204
|
+
function __mreactApplyRevalidationHeader(response, currentRequest) {
|
|
2982
3205
|
const header = typeof response?.headers?.get === "function"
|
|
2983
3206
|
? response.headers.get("x-mreact-revalidate")
|
|
2984
3207
|
: null;
|
|
@@ -2987,18 +3210,34 @@ function __mreactApplyRevalidationHeader(response) {
|
|
|
2987
3210
|
return;
|
|
2988
3211
|
}
|
|
2989
3212
|
|
|
3213
|
+
const currentPath = __mreactNormalizeNavigationPath(currentRequest?.href);
|
|
3214
|
+
|
|
2990
3215
|
for (const path of header.split(",")) {
|
|
2991
|
-
|
|
3216
|
+
const trimmedPath = path.trim();
|
|
3217
|
+
const normalizedPath = __mreactNormalizeNavigationPath(trimmedPath);
|
|
3218
|
+
const excludedRequest =
|
|
3219
|
+
currentRequest !== undefined && normalizedPath === currentPath ? currentRequest : undefined;
|
|
3220
|
+
__mreactInvalidateNavigationCache(trimmedPath, excludedRequest);
|
|
2992
3221
|
}
|
|
2993
3222
|
}
|
|
2994
3223
|
|
|
3224
|
+
function __mreactIsNavigationFetchRequest(_input, init) {
|
|
3225
|
+
return init !== null && typeof init === "object" && __mreactNavigationState.navigationFetchInits.has(init);
|
|
3226
|
+
}
|
|
3227
|
+
|
|
2995
3228
|
function __mreactNormalizeNavigationPath(path) {
|
|
3229
|
+
if (typeof path !== "string" || path.trim() === "") {
|
|
3230
|
+
return undefined;
|
|
3231
|
+
}
|
|
3232
|
+
|
|
3233
|
+
const normalizedInput = path.trim();
|
|
3234
|
+
|
|
2996
3235
|
if (typeof location === "undefined") {
|
|
2997
|
-
return
|
|
3236
|
+
return normalizedInput;
|
|
2998
3237
|
}
|
|
2999
3238
|
|
|
3000
3239
|
try {
|
|
3001
|
-
const url = new URL(
|
|
3240
|
+
const url = new URL(normalizedInput, location.href);
|
|
3002
3241
|
const pathname = url.pathname.replace(/\\/+$/, "");
|
|
3003
3242
|
|
|
3004
3243
|
return pathname === "" ? "/" : pathname;
|
|
@@ -3014,7 +3253,7 @@ export function __mreactRestoreHistoryState(state) {
|
|
|
3014
3253
|
|
|
3015
3254
|
const html = typeof state.html === "string"
|
|
3016
3255
|
? state.html
|
|
3017
|
-
: typeof state.url === "string" ?
|
|
3256
|
+
: typeof state.url === "string" ? __mreactCachedNavigationHtml(state.url) : undefined;
|
|
3018
3257
|
|
|
3019
3258
|
if (typeof html !== "string") {
|
|
3020
3259
|
return false;
|
|
@@ -3390,7 +3629,7 @@ function __mreactRouteScriptForNavigationUrl(url) {
|
|
|
3390
3629
|
|
|
3391
3630
|
for (const route of __mreactClientRoutePrefetchManifest()) {
|
|
3392
3631
|
if (__mreactRoutePathMatches(route.path, nextUrl.pathname)) {
|
|
3393
|
-
return route
|
|
3632
|
+
return route;
|
|
3394
3633
|
}
|
|
3395
3634
|
}
|
|
3396
3635
|
|
|
@@ -3420,12 +3659,28 @@ function __mreactClientRoutePrefetchManifest() {
|
|
|
3420
3659
|
try {
|
|
3421
3660
|
const parsed = JSON.parse(text);
|
|
3422
3661
|
__mreactNavigationState.routePrefetchManifest = Array.isArray(parsed)
|
|
3423
|
-
? parsed.
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3662
|
+
? parsed.flatMap((route) => {
|
|
3663
|
+
if (
|
|
3664
|
+
route === null ||
|
|
3665
|
+
typeof route !== "object" ||
|
|
3666
|
+
typeof route.path !== "string" ||
|
|
3667
|
+
typeof route.script !== "string" ||
|
|
3668
|
+
!__mreactIsSupportedModulePreloadUrl(route.script)
|
|
3669
|
+
) {
|
|
3670
|
+
return [];
|
|
3671
|
+
}
|
|
3672
|
+
|
|
3673
|
+
const modulePreloads = Array.isArray(route.modulePreloads)
|
|
3674
|
+
? route.modulePreloads.filter(
|
|
3675
|
+
(file) =>
|
|
3676
|
+
typeof file === "string" &&
|
|
3677
|
+
__mreactIsSupportedModulePreloadUrl(file) &&
|
|
3678
|
+
__mreactModulePreloadMatchesRouteScript(file, route.script),
|
|
3679
|
+
)
|
|
3680
|
+
: [];
|
|
3681
|
+
|
|
3682
|
+
return [{ ...route, modulePreloads }];
|
|
3683
|
+
})
|
|
3429
3684
|
: [];
|
|
3430
3685
|
} catch {
|
|
3431
3686
|
__mreactNavigationState.routePrefetchManifest = [];
|
|
@@ -3434,6 +3689,29 @@ function __mreactClientRoutePrefetchManifest() {
|
|
|
3434
3689
|
return __mreactNavigationState.routePrefetchManifest;
|
|
3435
3690
|
}
|
|
3436
3691
|
|
|
3692
|
+
function __mreactIsSupportedModulePreloadUrl(value) {
|
|
3693
|
+
if (typeof value !== "string" || value === "" || value.startsWith("javascript:")) {
|
|
3694
|
+
return false;
|
|
3695
|
+
}
|
|
3696
|
+
|
|
3697
|
+
try {
|
|
3698
|
+
const resolved = new URL(value, typeof location === "undefined" ? undefined : location.href);
|
|
3699
|
+
return resolved.protocol === "http:" || resolved.protocol === "https:";
|
|
3700
|
+
} catch {
|
|
3701
|
+
return false;
|
|
3702
|
+
}
|
|
3703
|
+
}
|
|
3704
|
+
|
|
3705
|
+
function __mreactModulePreloadMatchesRouteScript(value, script) {
|
|
3706
|
+
try {
|
|
3707
|
+
const scriptUrl = new URL(__mreactNormalizeAssetUrl(script), location.href);
|
|
3708
|
+
const dependencyUrl = new URL(__mreactNormalizeAssetUrl(value), location.href);
|
|
3709
|
+
return scriptUrl.origin === dependencyUrl.origin;
|
|
3710
|
+
} catch {
|
|
3711
|
+
return false;
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
|
|
3437
3715
|
function __mreactRoutePathMatches(routePath, pathname) {
|
|
3438
3716
|
const routeSegments = __mreactNormalizeRoutePath(routePath);
|
|
3439
3717
|
const pathSegments = __mreactNormalizeRoutePath(pathname);
|
|
@@ -3731,9 +4009,12 @@ function __mreactInstallNavigationFetchRevalidation() {
|
|
|
3731
4009
|
const fetchImpl = globalThis.fetch;
|
|
3732
4010
|
globalThis.fetch = function(input, init) {
|
|
3733
4011
|
const mutating = __mreactIsMutatingFetchRequest(input, init);
|
|
4012
|
+
const navigation = __mreactIsNavigationFetchRequest(input, init);
|
|
3734
4013
|
|
|
3735
4014
|
return Promise.resolve(fetchImpl.call(this, input, init)).then((response) => {
|
|
3736
|
-
|
|
4015
|
+
if (!navigation) {
|
|
4016
|
+
__mreactApplyRevalidationHeader(response);
|
|
4017
|
+
}
|
|
3737
4018
|
|
|
3738
4019
|
if (mutating) {
|
|
3739
4020
|
__mreactInvalidateAllNavigationCache();
|
|
@@ -3805,7 +4086,7 @@ function __mreactObserveViewportPrefetchAnchors(root) {
|
|
|
3805
4086
|
}
|
|
3806
4087
|
|
|
3807
4088
|
__mreactNavigationState.viewportObserver?.unobserve(entry.target);
|
|
3808
|
-
void __mreactPrefetch(entry.target.href);
|
|
4089
|
+
void __mreactPrefetch(entry.target.href, { trigger: "viewport" });
|
|
3809
4090
|
}
|
|
3810
4091
|
});
|
|
3811
4092
|
}
|
|
@@ -4425,14 +4706,7 @@ export function cell(initial) {
|
|
|
4425
4706
|
resolveDir: reactiveCoreDir,
|
|
4426
4707
|
}));
|
|
4427
4708
|
buildApi.onLoad({ filter: /^devtools$/, namespace: "mreact-devtools-stub" }, () => ({
|
|
4428
|
-
contents:
|
|
4429
|
-
export function emitReactiveEffectRunDevtoolsEvent() {}
|
|
4430
|
-
export function hasReactiveDevtoolsEmitter() { return false; }
|
|
4431
|
-
export function currentDevtoolsEmitter() { return undefined; }
|
|
4432
|
-
export function currentReactiveDevtools() { return undefined; }
|
|
4433
|
-
export function registerReactiveDevtoolsResource() { return { dispose() {}, update() {} }; }
|
|
4434
|
-
export function invalidateReactiveDevtoolsCache() {}
|
|
4435
|
-
export function prepareReactiveEffectRunDevtoolsEvent() { return undefined; }`,
|
|
4709
|
+
contents: reactiveDevtoolsStubSource,
|
|
4436
4710
|
loader: "ts",
|
|
4437
4711
|
}));
|
|
4438
4712
|
if (options.sourceRegionModulePaths !== undefined) {
|