@timber-js/app 0.2.0-alpha.166 → 0.2.0-alpha.168
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/_chunks/{actions-CDPfMp_I.js → actions-O_LsyCE4.js} +3 -3
- package/dist/_chunks/{actions-CDPfMp_I.js.map → actions-O_LsyCE4.js.map} +1 -1
- package/dist/_chunks/{cache-api-DygSeKCB.js → cache-api-B-lhk9p4.js} +107 -58
- package/dist/_chunks/cache-api-B-lhk9p4.js.map +1 -0
- package/dist/_chunks/{cli-schema-sync-EXGYPhI2.js → cli-schema-sync-B73L6pMq.js} +5 -3
- package/dist/_chunks/cli-schema-sync-B73L6pMq.js.map +1 -0
- package/dist/_chunks/cloudflare-AHoWYTYr.js +1188 -0
- package/dist/_chunks/cloudflare-AHoWYTYr.js.map +1 -0
- package/dist/_chunks/json-lossy-check-ClNvBM_3.js +63 -0
- package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +1 -0
- package/dist/_chunks/{logger-t3uxAmbX.js → logger-AWfuX-KJ.js} +2 -19
- package/dist/_chunks/logger-AWfuX-KJ.js.map +1 -0
- package/dist/_chunks/{walkers-DBVzXuWc.js → walkers-CoOC8Hga.js} +2 -2
- package/dist/_chunks/{walkers-DBVzXuWc.js.map → walkers-CoOC8Hga.js.map} +1 -1
- package/dist/adapters/cloudflare-dev.js +1 -1
- package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -1
- package/dist/adapters/cloudflare-kv-cache.js +10 -3
- package/dist/adapters/cloudflare-kv-cache.js.map +1 -1
- package/dist/adapters/cloudflare.d.ts +12 -1
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +2 -461
- package/dist/adapters/types.d.ts +2 -0
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/cache/cache-api.d.ts +33 -11
- package/dist/cache/cache-api.d.ts.map +1 -1
- package/dist/cache/index.d.ts +1 -1
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +1 -1
- package/dist/cache/json-lossy-check.d.ts +11 -0
- package/dist/cache/json-lossy-check.d.ts.map +1 -0
- package/dist/cache/redis-handler.d.ts +42 -0
- package/dist/cache/redis-handler.d.ts.map +1 -1
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cache/stores/cloudflare-kv.d.ts +1 -1
- package/dist/cache/stores/cloudflare-kv.d.ts.map +1 -1
- package/dist/cache/stores/memory.d.ts +1 -1
- package/dist/cache/stores/memory.d.ts.map +1 -1
- package/dist/cache/stores/redis.d.ts +1 -1
- package/dist/cache/stores/redis.d.ts.map +1 -1
- package/dist/cache/stores/vercel.d.ts +1 -1
- package/dist/cache/stores/vercel.d.ts.map +1 -1
- package/dist/cache/tag-aware-handler.d.ts.map +1 -1
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/cdn/cloudflare-purge.d.ts.map +1 -1
- package/dist/cdn/fastly-purge.d.ts.map +1 -1
- package/dist/cdn/workers-cache-purge.d.ts.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -2
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
- package/dist/client/browser-entry/router-init.d.ts +1 -0
- package/dist/client/browser-entry/router-init.d.ts.map +1 -1
- package/dist/client/child-segment-context.d.ts +2 -2
- package/dist/client/child-segment-context.d.ts.map +1 -1
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/history.d.ts +10 -0
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/internal.js +141 -116
- package/dist/client/internal.js.map +1 -1
- package/dist/client/router.d.ts +6 -0
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-update-context.d.ts +3 -3
- package/dist/client/segment-update-context.d.ts.map +1 -1
- package/dist/client/slot-outlet.d.ts +1 -1
- package/dist/codec.d.ts.map +1 -1
- package/dist/codec.js +2 -1
- package/dist/codec.js.map +1 -1
- package/dist/config-types.d.ts +16 -37
- package/dist/config-types.d.ts.map +1 -1
- package/dist/config-validation.d.ts.map +1 -1
- package/dist/dev-tools/instrumentation.d.ts.map +1 -1
- package/dist/fonts/pipeline.d.ts +19 -0
- package/dist/fonts/pipeline.d.ts.map +1 -1
- package/dist/fonts/transform.d.ts.map +1 -1
- package/dist/fonts/virtual-modules.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +378 -109
- package/dist/index.js.map +1 -1
- package/dist/plugin-context.d.ts.map +1 -1
- package/dist/plugins/adapter-build.d.ts +1 -0
- package/dist/plugins/adapter-build.d.ts.map +1 -1
- package/dist/plugins/cache.d.ts +8 -8
- package/dist/plugins/cache.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts +27 -3
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/server-bundle.d.ts.map +1 -1
- package/dist/routing/index.js +2 -2
- package/dist/server/action-client.d.ts +1 -1
- package/dist/server/action-client.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +7 -0
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/body-limits.d.ts.map +1 -1
- package/dist/server/deny-boundary.d.ts +3 -1
- package/dist/server/deny-boundary.d.ts.map +1 -1
- package/dist/server/form-data.d.ts.map +1 -1
- package/dist/server/html-injector-core.d.ts.map +1 -1
- package/dist/server/index.js +20 -3
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.js +28 -41
- package/dist/server/internal.js.map +1 -1
- package/dist/server/middleware-runner.d.ts +0 -17
- package/dist/server/middleware-runner.d.ts.map +1 -1
- package/dist/server/param-coercion.d.ts.map +1 -1
- package/dist/server/pipeline-phases.d.ts +6 -3
- package/dist/server/pipeline-phases.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +18 -0
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/prebuilt/capture-state.d.ts.map +1 -1
- package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -1
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/render-timeout.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts +9 -0
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/rsc-entry/action-middleware-runner.d.ts +14 -14
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts +1 -0
- package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
- package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +8 -0
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +44 -74
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -1
- package/dist/server/safe-load.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/shared/redirect-type.d.ts +2 -2
- package/dist/shared/redirect-type.d.ts.map +1 -1
- package/dist/shims/font-google.d.ts.map +1 -1
- package/dist/shims/image.d.ts +120 -120
- package/dist/shims/image.d.ts.map +1 -1
- package/docs/api/32-api-cache.mdx +116 -4
- package/docs/api/34-api-config.mdx +0 -26
- package/docs/learn/09-caching.mdx +126 -10
- package/docs/learn/12-client-navigation.mdx +9 -1
- package/docs/learn/13-configuration.mdx +6 -8
- package/docs/learn/14-deploying.mdx +18 -18
- package/docs/more/03-coming-from-nextjs.mdx +2 -2
- package/docs/more/04-metadata-and-fonts.mdx +1 -1
- package/docs/more/50-ai-agent-instructions.mdx +5 -5
- package/package.json +6 -5
- package/src/adapters/cloudflare-kv-cache.ts +27 -6
- package/src/adapters/cloudflare.ts +63 -25
- package/src/adapters/types.ts +2 -0
- package/src/cache/cache-api.ts +84 -84
- package/src/cache/index.ts +1 -1
- package/src/cache/json-lossy-check.ts +75 -0
- package/src/cache/redis-handler.ts +65 -14
- package/src/cache/timber-cache.ts +10 -2
- package/src/client/browser-entry/index.ts +2 -0
- package/src/client/browser-entry/post-hydration.ts +16 -9
- package/src/client/browser-entry/router-init.ts +2 -0
- package/src/client/history.ts +11 -0
- package/src/client/router.ts +224 -208
- package/src/codec.ts +3 -1
- package/src/config-types.ts +16 -37
- package/src/config-validation.ts +7 -5
- package/src/fonts/pipeline.ts +32 -0
- package/src/fonts/transform.ts +30 -24
- package/src/plugins/adapter-build.ts +132 -13
- package/src/plugins/cache.ts +45 -30
- package/src/plugins/entries.ts +40 -43
- package/src/plugins/fonts.ts +30 -0
- package/src/plugins/server-bundle.ts +7 -15
- package/src/routing/scanner.ts +7 -0
- package/src/server/action-client.ts +1 -1
- package/src/server/als-registry.ts +7 -0
- package/src/server/deny-boundary.ts +6 -3
- package/src/server/middleware-runner.ts +0 -44
- package/src/server/param-coercion.ts +1 -0
- package/src/server/pipeline-phases.ts +11 -13
- package/src/server/pipeline.ts +51 -3
- package/src/server/route-element-builder.ts +59 -9
- package/src/server/rsc-entry/action-middleware-runner.ts +14 -14
- package/src/server/rsc-entry/index.ts +30 -40
- package/src/server/rsc-entry/render-route.ts +6 -2
- package/src/server/rsc-entry/rsc-payload.ts +21 -4
- package/src/server/rsc-entry/rsc-stream.ts +8 -0
- package/src/server/rsc-entry/wrap-action-dispatch.ts +109 -372
- package/dist/_chunks/cache-api-DygSeKCB.js.map +0 -1
- package/dist/_chunks/cli-schema-sync-EXGYPhI2.js.map +0 -1
- package/dist/_chunks/logger-t3uxAmbX.js.map +0 -1
- package/dist/_chunks/tree-match-D2l830j2.js +0 -102
- package/dist/_chunks/tree-match-D2l830j2.js.map +0 -1
- package/dist/adapters/cloudflare.js.map +0 -1
package/dist/client/internal.js
CHANGED
|
@@ -450,6 +450,7 @@ function createRouter(deps) {
|
|
|
450
450
|
}
|
|
451
451
|
/** Update the segment cache from server-provided segment metadata. */
|
|
452
452
|
function updateSegmentCache(segmentInfo) {
|
|
453
|
+
if (!deps.clientSegmentCache) return;
|
|
453
454
|
if (!segmentInfo || segmentInfo.length === 0) return;
|
|
454
455
|
const tree = buildSegmentTree(segmentInfo);
|
|
455
456
|
if (tree) segmentCache.set("/", tree);
|
|
@@ -458,6 +459,59 @@ function createRouter(deps) {
|
|
|
458
459
|
function renderPayload(payload, navState) {
|
|
459
460
|
if (deps.renderRoot) deps.renderRoot(payload, navState);
|
|
460
461
|
}
|
|
462
|
+
/**
|
|
463
|
+
* Atomically update all navigation-owned state for a new page. Every
|
|
464
|
+
* code path that changes the "current page" must go through this
|
|
465
|
+
* function — making "forgot a field" impossible by construction.
|
|
466
|
+
*
|
|
467
|
+
* The three operations:
|
|
468
|
+
* 1. Segment cache — update from server-provided segment metadata
|
|
469
|
+
* 2. Navigation state — params + pathname for useSegmentParams/usePathname
|
|
470
|
+
* 3. History stack — store the payload for instant back/forward replay
|
|
471
|
+
*/
|
|
472
|
+
function commitNavigation(url, opts) {
|
|
473
|
+
if (opts.segmentInfo && opts.segmentInfo.length > 0) updateSegmentCache(opts.segmentInfo);
|
|
474
|
+
else if (opts.clearSegmentCacheOnEmpty) segmentCache.clear();
|
|
475
|
+
const navState = updateNavigationState(opts.params, url);
|
|
476
|
+
historyStack.push(url, {
|
|
477
|
+
payload: opts.payload,
|
|
478
|
+
params: navState.params,
|
|
479
|
+
segmentInfo: opts.segmentInfo
|
|
480
|
+
});
|
|
481
|
+
return navState;
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Wrap a navigation in the standard abort/pending/cleanup lifecycle.
|
|
485
|
+
* Consolidates the createNavAbort + setPending + staleness-guarded
|
|
486
|
+
* finally that was duplicated across navigate, refresh, and both
|
|
487
|
+
* handlePopState paths. AbortErrors are swallowed (not application
|
|
488
|
+
* errors); all other errors propagate to the caller.
|
|
489
|
+
*/
|
|
490
|
+
async function runNavigation(url, fn, externalSignal) {
|
|
491
|
+
const navAbort = createNavAbort(externalSignal);
|
|
492
|
+
setPending(true, url);
|
|
493
|
+
try {
|
|
494
|
+
await fn(navAbort);
|
|
495
|
+
} catch (error) {
|
|
496
|
+
if (isAbortError(error)) return;
|
|
497
|
+
throw error;
|
|
498
|
+
} finally {
|
|
499
|
+
if (currentNavAbort === navAbort) {
|
|
500
|
+
currentNavAbort = null;
|
|
501
|
+
setPending(false);
|
|
502
|
+
deps.completeRouterNavigation?.();
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Resolve thenable payloads in the test/fallback path (no navigateTransition).
|
|
508
|
+
* In production, React handles thenables from createFromFetch directly via
|
|
509
|
+
* Suspense. In tests, renderRoot is a plain mock that expects resolved values.
|
|
510
|
+
*/
|
|
511
|
+
async function resolveForFallback(payload) {
|
|
512
|
+
if (!deps.navigateTransition && payload != null && typeof payload === "object" && "then" in payload) return await payload;
|
|
513
|
+
return payload;
|
|
514
|
+
}
|
|
461
515
|
function isPartialNavigation(skippedSegments) {
|
|
462
516
|
return skippedSegments != null && skippedSegments.length > 0;
|
|
463
517
|
}
|
|
@@ -499,9 +553,11 @@ function createRouter(deps) {
|
|
|
499
553
|
}
|
|
500
554
|
/**
|
|
501
555
|
* Render a payload via navigateTransition (production) or renderRoot (tests).
|
|
502
|
-
* The perform callback should fetch data,
|
|
503
|
-
* FetchResult plus the NavigationState
|
|
504
|
-
*
|
|
556
|
+
* The perform callback should fetch data, call commitNavigation, and return
|
|
557
|
+
* the FetchResult plus the NavigationState.
|
|
558
|
+
*
|
|
559
|
+
* State management (segmentCache, navState, historyStack) is handled by
|
|
560
|
+
* commitNavigation inside perform — this function only handles rendering.
|
|
505
561
|
*/
|
|
506
562
|
async function renderViaTransition(url, perform) {
|
|
507
563
|
if (deps.navigateTransition) {
|
|
@@ -509,19 +565,11 @@ function createRouter(deps) {
|
|
|
509
565
|
const result = await perform();
|
|
510
566
|
if (isPartialNavigation(result.skippedSegments)) {
|
|
511
567
|
const segmentUpdates = buildSegmentUpdates(result);
|
|
512
|
-
historyStack.push(url, {
|
|
513
|
-
payload: null,
|
|
514
|
-
params: result.params
|
|
515
|
-
});
|
|
516
568
|
return {
|
|
517
569
|
element: wrapPayload(deps._getCurrentPayload?.() ?? result.payload, result.navState, segmentUpdates),
|
|
518
570
|
decodePromise: result.decodePromise
|
|
519
571
|
};
|
|
520
572
|
}
|
|
521
|
-
historyStack.push(url, {
|
|
522
|
-
payload: result.payload,
|
|
523
|
-
params: result.params
|
|
524
|
-
});
|
|
525
573
|
return {
|
|
526
574
|
element: wrapPayload(result.payload, result.navState),
|
|
527
575
|
decodePromise: result.decodePromise
|
|
@@ -530,18 +578,7 @@ function createRouter(deps) {
|
|
|
530
578
|
return;
|
|
531
579
|
}
|
|
532
580
|
const result = await perform();
|
|
533
|
-
if (isPartialNavigation(result.skippedSegments))
|
|
534
|
-
payload: null,
|
|
535
|
-
params: result.params
|
|
536
|
-
});
|
|
537
|
-
else {
|
|
538
|
-
const payload = result.payload != null && typeof result.payload === "object" && "then" in result.payload ? await result.payload : result.payload;
|
|
539
|
-
historyStack.push(url, {
|
|
540
|
-
payload,
|
|
541
|
-
params: result.params
|
|
542
|
-
});
|
|
543
|
-
renderPayload(payload, result.navState);
|
|
544
|
-
}
|
|
581
|
+
if (!isPartialNavigation(result.skippedSegments)) renderPayload(result.payload, result.navState);
|
|
545
582
|
}
|
|
546
583
|
/** Run a callback after the next paint (after React commit). */
|
|
547
584
|
function afterPaint(callback) {
|
|
@@ -584,7 +621,7 @@ function createRouter(deps) {
|
|
|
584
621
|
skippedSegments: prefetched.skippedSegments ?? null
|
|
585
622
|
} : void 0;
|
|
586
623
|
if (result === void 0) {
|
|
587
|
-
const stateTree = segmentCache.serializeStateTree();
|
|
624
|
+
const stateTree = deps.clientSegmentCache ? segmentCache.serializeStateTree() : void 0;
|
|
588
625
|
const rawCurrentUrl = deps.getCurrentUrl();
|
|
589
626
|
result = await fetchRscPayload(url, deps, stateTree, rawCurrentUrl.startsWith("http") ? new URL(rawCurrentUrl).pathname : new URL(rawCurrentUrl, "http://localhost").pathname, options.signal);
|
|
590
627
|
}
|
|
@@ -601,10 +638,15 @@ function createRouter(deps) {
|
|
|
601
638
|
}, "", commitUrl);
|
|
602
639
|
deps.setRouterNavigating?.(false);
|
|
603
640
|
}
|
|
604
|
-
|
|
605
|
-
const navState =
|
|
641
|
+
const payload = await resolveForFallback(result.payload);
|
|
642
|
+
const navState = commitNavigation(url, {
|
|
643
|
+
payload: isPartialNavigation(result.skippedSegments) ? null : payload,
|
|
644
|
+
params: result.params,
|
|
645
|
+
segmentInfo: result.segmentInfo
|
|
646
|
+
});
|
|
606
647
|
return {
|
|
607
648
|
...result,
|
|
649
|
+
payload,
|
|
608
650
|
navState
|
|
609
651
|
};
|
|
610
652
|
}
|
|
@@ -616,7 +658,6 @@ function createRouter(deps) {
|
|
|
616
658
|
const hashIndex = url.indexOf("#");
|
|
617
659
|
const hash = hashIndex === -1 ? "" : url.slice(hashIndex);
|
|
618
660
|
const fetchUrl = hashIndex === -1 ? url : url.slice(0, hashIndex);
|
|
619
|
-
const navAbort = createNavAbort(externalSignal);
|
|
620
661
|
const currentScrollY = deps.getScrollY();
|
|
621
662
|
if (deps.saveNavigationEntryScroll) deps.saveNavigationEntryScroll(currentScrollY);
|
|
622
663
|
else deps.replaceState({
|
|
@@ -624,107 +665,91 @@ function createRouter(deps) {
|
|
|
624
665
|
scrollY: currentScrollY
|
|
625
666
|
}, "", deps.getCurrentUrl());
|
|
626
667
|
let effectiveSkipHistory = skipHistory;
|
|
627
|
-
|
|
628
|
-
deps.
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
setPending(true, url);
|
|
634
|
-
try {
|
|
635
|
-
await renderViaTransition(fetchUrl, () => performNavigationFetch(fetchUrl, {
|
|
636
|
-
replace,
|
|
637
|
-
commitUrl: url,
|
|
638
|
-
signal: navAbort.signal,
|
|
639
|
-
skipHistory: effectiveSkipHistory
|
|
640
|
-
}));
|
|
641
|
-
window.dispatchEvent(new Event("timber:navigation-end"));
|
|
642
|
-
if (scroll && hash) scrollToHashAfterPaint(hash);
|
|
643
|
-
else restoreScrollAfterPaint(scroll ? 0 : currentScrollY);
|
|
644
|
-
} catch (error) {
|
|
645
|
-
if (error instanceof VersionSkewError) {
|
|
646
|
-
setHardNavigating(true);
|
|
647
|
-
window.location.reload();
|
|
648
|
-
return new Promise(() => {});
|
|
649
|
-
}
|
|
650
|
-
if (error instanceof RedirectError) {
|
|
651
|
-
if (currentNavAbort !== navAbort) return;
|
|
652
|
-
await navigate(error.redirectUrl, { replace: true });
|
|
653
|
-
return;
|
|
668
|
+
await runNavigation(url, async (navAbort) => {
|
|
669
|
+
if (!effectiveSkipHistory && deps.navigationNavigate) {
|
|
670
|
+
deps.setRouterNavigating?.(true);
|
|
671
|
+
deps.navigationNavigate(url, replace);
|
|
672
|
+
deps.setRouterNavigating?.(false);
|
|
673
|
+
effectiveSkipHistory = true;
|
|
654
674
|
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
675
|
+
try {
|
|
676
|
+
await renderViaTransition(fetchUrl, () => performNavigationFetch(fetchUrl, {
|
|
677
|
+
replace,
|
|
678
|
+
commitUrl: url,
|
|
679
|
+
signal: navAbort.signal,
|
|
680
|
+
skipHistory: effectiveSkipHistory
|
|
681
|
+
}));
|
|
682
|
+
window.dispatchEvent(new Event("timber:navigation-end"));
|
|
683
|
+
if (scroll && hash) scrollToHashAfterPaint(hash);
|
|
684
|
+
else restoreScrollAfterPaint(scroll ? 0 : currentScrollY);
|
|
685
|
+
} catch (error) {
|
|
686
|
+
if (error instanceof VersionSkewError) {
|
|
687
|
+
setHardNavigating(true);
|
|
688
|
+
window.location.reload();
|
|
689
|
+
await new Promise(() => {});
|
|
690
|
+
}
|
|
691
|
+
if (error instanceof RedirectError) {
|
|
692
|
+
if (currentNavAbort !== navAbort) return;
|
|
693
|
+
await navigate(error.redirectUrl, { replace: true });
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
if (error instanceof ServerErrorResponse) {
|
|
697
|
+
setHardNavigating(true);
|
|
698
|
+
window.location.href = error.url;
|
|
699
|
+
await new Promise(() => {});
|
|
700
|
+
}
|
|
701
|
+
throw error;
|
|
667
702
|
}
|
|
668
|
-
}
|
|
703
|
+
}, externalSignal);
|
|
669
704
|
}
|
|
670
705
|
async function refresh() {
|
|
671
706
|
const currentUrl = deps.getCurrentUrl();
|
|
672
|
-
|
|
673
|
-
setPending(true, currentUrl);
|
|
674
|
-
try {
|
|
707
|
+
await runNavigation(currentUrl, async (navAbort) => {
|
|
675
708
|
await renderViaTransition(currentUrl, async () => {
|
|
676
709
|
const result = await fetchRscPayload(currentUrl, deps, void 0, void 0, navAbort.signal);
|
|
677
|
-
|
|
678
|
-
const navState =
|
|
710
|
+
const payload = await resolveForFallback(result.payload);
|
|
711
|
+
const navState = commitNavigation(currentUrl, {
|
|
712
|
+
payload,
|
|
713
|
+
params: result.params,
|
|
714
|
+
segmentInfo: result.segmentInfo
|
|
715
|
+
});
|
|
679
716
|
return {
|
|
680
717
|
...result,
|
|
718
|
+
payload,
|
|
681
719
|
navState
|
|
682
720
|
};
|
|
683
721
|
});
|
|
684
|
-
}
|
|
685
|
-
if (isAbortError(error)) return;
|
|
686
|
-
throw error;
|
|
687
|
-
} finally {
|
|
688
|
-
if (currentNavAbort === navAbort) {
|
|
689
|
-
currentNavAbort = null;
|
|
690
|
-
setPending(false);
|
|
691
|
-
deps.completeRouterNavigation?.();
|
|
692
|
-
}
|
|
693
|
-
}
|
|
722
|
+
});
|
|
694
723
|
}
|
|
695
724
|
async function handlePopState(url, scrollY = 0, externalSignal) {
|
|
696
725
|
const entry = historyStack.get(url);
|
|
697
|
-
if (entry && entry.payload !== null) {
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
726
|
+
if (entry && entry.payload !== null) await runNavigation(url, async () => {
|
|
727
|
+
const navState = commitNavigation(url, {
|
|
728
|
+
payload: entry.payload,
|
|
729
|
+
params: entry.params,
|
|
730
|
+
segmentInfo: entry.segmentInfo,
|
|
731
|
+
clearSegmentCacheOnEmpty: true
|
|
732
|
+
});
|
|
702
733
|
renderPayload(entry.payload, navState);
|
|
703
734
|
restoreScrollAfterPaint(scrollY);
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
...result,
|
|
714
|
-
navState
|
|
715
|
-
};
|
|
735
|
+
}, externalSignal);
|
|
736
|
+
else await runNavigation(url, async (navAbort) => {
|
|
737
|
+
await renderViaTransition(url, async () => {
|
|
738
|
+
const result = await fetchRscPayload(url, deps, deps.clientSegmentCache ? segmentCache.serializeStateTree() : void 0, void 0, navAbort.signal);
|
|
739
|
+
const payload = await resolveForFallback(result.payload);
|
|
740
|
+
const navState = commitNavigation(url, {
|
|
741
|
+
payload,
|
|
742
|
+
params: result.params,
|
|
743
|
+
segmentInfo: result.segmentInfo
|
|
716
744
|
});
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
}
|
|
745
|
+
return {
|
|
746
|
+
...result,
|
|
747
|
+
payload,
|
|
748
|
+
navState
|
|
749
|
+
};
|
|
750
|
+
});
|
|
751
|
+
restoreScrollAfterPaint(scrollY);
|
|
752
|
+
}, externalSignal);
|
|
728
753
|
}
|
|
729
754
|
/**
|
|
730
755
|
* Prefetch an RSC payload for a URL and store it in the prefetch cache.
|
|
@@ -735,7 +760,7 @@ function createRouter(deps) {
|
|
|
735
760
|
const fetchUrl = hashIndex === -1 ? url : url.slice(0, hashIndex);
|
|
736
761
|
if (prefetchCache.get(fetchUrl) !== void 0) return;
|
|
737
762
|
if (historyStack.has(fetchUrl)) return;
|
|
738
|
-
fetchRscPayload(fetchUrl, deps, segmentCache.serializeStateTree()).then((result) => {
|
|
763
|
+
fetchRscPayload(fetchUrl, deps, deps.clientSegmentCache ? segmentCache.serializeStateTree() : void 0).then((result) => {
|
|
739
764
|
result.decodePromise?.catch(() => {});
|
|
740
765
|
prefetchCache.set(fetchUrl, result);
|
|
741
766
|
}, () => {});
|
|
@@ -753,12 +778,12 @@ function createRouter(deps) {
|
|
|
753
778
|
prefetch,
|
|
754
779
|
applyRevalidation(element) {
|
|
755
780
|
const currentUrl = deps.getCurrentUrl();
|
|
756
|
-
const
|
|
757
|
-
|
|
781
|
+
const existingEntry = historyStack.get(currentUrl);
|
|
782
|
+
renderPayload(element, commitNavigation(currentUrl, {
|
|
758
783
|
payload: element,
|
|
759
|
-
params:
|
|
760
|
-
|
|
761
|
-
|
|
784
|
+
params: getNavigationState().params,
|
|
785
|
+
segmentInfo: existingEntry?.segmentInfo
|
|
786
|
+
}));
|
|
762
787
|
},
|
|
763
788
|
initSegmentCache: (segments) => updateSegmentCache(segments),
|
|
764
789
|
segmentCache,
|