@timber-js/app 0.2.0-alpha.122 → 0.2.0-alpha.124
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/LICENSE +8 -0
- package/dist/_chunks/{actions-Dy8vOjFt.js → actions-418ygYKC.js} +5 -5
- package/dist/_chunks/{actions-Dy8vOjFt.js.map → actions-418ygYKC.js.map} +1 -1
- package/dist/_chunks/{cli-schema-sync-VcCf1TFY.js → cli-schema-sync-DFHBj6yZ.js} +59 -12
- package/dist/_chunks/{cli-schema-sync-VcCf1TFY.js.map → cli-schema-sync-DFHBj6yZ.js.map} +1 -1
- package/dist/_chunks/cli-schema-sync-vdobDWwX.js +2 -0
- package/dist/_chunks/{define-CPVQaWbx.js → define-BJMwm0c4.js} +6 -18
- package/dist/_chunks/define-BJMwm0c4.js.map +1 -0
- package/dist/_chunks/{handler-store-CcwNX-gk.js → handler-store-bIAstrxQ.js} +1 -1
- package/dist/_chunks/{handler-store-CcwNX-gk.js.map → handler-store-bIAstrxQ.js.map} +1 -1
- package/dist/_chunks/{merge-search-params-az6ZiBeU.js → merge-search-params-Cm1j99HC.js} +1 -1
- package/dist/_chunks/{merge-search-params-az6ZiBeU.js.map → merge-search-params-Cm1j99HC.js.map} +1 -1
- package/dist/_chunks/{navigation-root-DoRTeBm5.js → navigation-root-DaERBEGV.js} +2 -2
- package/dist/_chunks/{navigation-root-DoRTeBm5.js.map → navigation-root-DaERBEGV.js.map} +1 -1
- package/dist/_chunks/{resolve-schema-cURaYvaD.js → resolve-schema-DU2nbVOi.js} +1 -1
- package/dist/_chunks/{resolve-schema-cURaYvaD.js.map → resolve-schema-DU2nbVOi.js.map} +1 -1
- package/dist/_chunks/{router-ref-CpvjBqdu.js → router-ref-B2-2kIIC.js} +2 -2
- package/dist/_chunks/{router-ref-CpvjBqdu.js.map → router-ref-B2-2kIIC.js.map} +1 -1
- package/dist/_chunks/{segment-context-EsfQpS--.js → segment-context-Bg0pFbLT.js} +1 -1
- package/dist/_chunks/{segment-context-EsfQpS--.js.map → segment-context-Bg0pFbLT.js.map} +1 -1
- package/dist/_chunks/{ssr-data-m9-cNEIw.js → ssr-data-DVX8S7vj.js} +1 -1
- package/dist/_chunks/{ssr-data-m9-cNEIw.js.map → ssr-data-DVX8S7vj.js.map} +1 -1
- package/dist/_chunks/{use-segment-params-CtIAjqK0.js → use-segment-params-ByGqwUuO.js} +5 -9
- package/dist/_chunks/use-segment-params-ByGqwUuO.js.map +1 -0
- package/dist/_chunks/{validation-BMU5MPzP.js → validation-AfEFM5ze.js} +1 -1
- package/dist/_chunks/{validation-BMU5MPzP.js.map → validation-AfEFM5ze.js.map} +1 -1
- package/dist/_chunks/{walkers-tkw7sDlj.js → walkers-DMSGZeCk.js} +2 -2
- package/dist/_chunks/{walkers-tkw7sDlj.js.map → walkers-DMSGZeCk.js.map} +1 -1
- package/dist/cache/index.js +1 -1
- package/dist/cli-schema-sync.d.ts +6 -4
- package/dist/cli-schema-sync.d.ts.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +12 -6
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
- package/dist/client/error-boundary.js +2 -2
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +47 -14
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.js +87 -64
- package/dist/client/internal.js.map +1 -1
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/navigation-context.d.ts +1 -0
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +8 -0
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/shallow-url.d.ts +10 -0
- package/dist/client/shallow-url.d.ts.map +1 -0
- package/dist/client/use-search-params.d.ts +7 -5
- package/dist/client/use-search-params.d.ts.map +1 -1
- package/dist/cookies/index.js +2 -2
- package/dist/index.js +3 -3
- package/dist/params/index.js +1 -1
- package/dist/routing/index.js +2 -2
- package/dist/segment-params/define.d.ts +0 -6
- package/dist/segment-params/define.d.ts.map +1 -1
- package/dist/segment-params/index.js +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/internal.js +3 -3
- package/package.json +6 -7
- package/src/cli-schema-sync.ts +80 -13
- package/src/cli.ts +18 -7
- package/src/client/browser-entry/action-dispatch.ts +9 -10
- package/src/client/browser-entry/hydrate.ts +2 -0
- package/src/client/browser-entry/post-hydration.ts +13 -6
- package/src/client/index.ts +1 -5
- package/src/client/link.tsx +25 -12
- package/src/client/navigation-context.ts +2 -1
- package/src/client/router.ts +78 -27
- package/src/client/rsc-fetch.ts +20 -5
- package/src/client/shallow-url.ts +22 -0
- package/src/client/use-search-params.ts +25 -44
- package/src/segment-params/define.ts +2 -29
- package/dist/_chunks/cli-schema-sync-4HcQIziG.js +0 -2
- package/dist/_chunks/define-CPVQaWbx.js.map +0 -1
- package/dist/_chunks/use-segment-params-CtIAjqK0.js.map +0 -1
package/dist/client/internal.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { t as bindUseQueryStates } from "../_chunks/use-query-states-C9G6LP0F.js";
|
|
2
|
-
import { c as cachedSearchParams, i as _setCachedSearch, n as getSsrData, r as setSsrData, s as cachedSearch, t as clearSsrData } from "../_chunks/ssr-data-
|
|
3
|
-
import {
|
|
2
|
+
import { c as cachedSearchParams, i as _setCachedSearch, n as getSsrData, r as setSsrData, s as cachedSearch, t as clearSsrData } from "../_chunks/ssr-data-DVX8S7vj.js";
|
|
3
|
+
import { a as setNavigationState, i as getNavigationState, o as useNavigationContext, r as NavigationProvider, t as setCurrentParams } from "../_chunks/use-segment-params-ByGqwUuO.js";
|
|
4
|
+
import { n as getRouterOrNull, r as setGlobalRouter, t as getRouter } from "../_chunks/router-ref-B2-2kIIC.js";
|
|
4
5
|
import { TimberErrorBoundary } from "./error-boundary.js";
|
|
5
|
-
import { n as useSegmentContext, t as SegmentProvider } from "../_chunks/segment-context-
|
|
6
|
-
import { t as setHardNavigating } from "../_chunks/navigation-root-
|
|
7
|
-
import {
|
|
8
|
-
import { cloneElement, isValidElement, useSyncExternalStore } from "react";
|
|
6
|
+
import { n as useSegmentContext, t as SegmentProvider } from "../_chunks/segment-context-Bg0pFbLT.js";
|
|
7
|
+
import { t as setHardNavigating } from "../_chunks/navigation-root-DaERBEGV.js";
|
|
8
|
+
import { cloneElement, isValidElement } from "react";
|
|
9
9
|
//#region src/client/segment-cache.ts
|
|
10
10
|
/**
|
|
11
11
|
* Maintains the client-side segment tree representing currently mounted
|
|
@@ -558,8 +558,12 @@ async function fetchRscPayload(url, deps, stateTree, currentUrl, signal) {
|
|
|
558
558
|
return response;
|
|
559
559
|
});
|
|
560
560
|
await wrappedPromise;
|
|
561
|
+
const payload = deps.decodeRsc(wrappedPromise);
|
|
562
|
+
const decodePromise = Promise.resolve(payload).then(() => void 0);
|
|
563
|
+
decodePromise.catch(() => {});
|
|
561
564
|
return {
|
|
562
|
-
payload
|
|
565
|
+
payload,
|
|
566
|
+
decodePromise,
|
|
563
567
|
headElements,
|
|
564
568
|
segmentInfo,
|
|
565
569
|
params,
|
|
@@ -577,6 +581,7 @@ async function fetchRscPayload(url, deps, stateTree, currentUrl, signal) {
|
|
|
577
581
|
}
|
|
578
582
|
return {
|
|
579
583
|
payload: await response.text(),
|
|
584
|
+
decodePromise: null,
|
|
580
585
|
headElements: extractHeadElements(response),
|
|
581
586
|
segmentInfo: extractSegmentInfo(response),
|
|
582
587
|
params: extractParams(response),
|
|
@@ -600,6 +605,7 @@ function createRouter(deps) {
|
|
|
600
605
|
const historyStack = new HistoryStack();
|
|
601
606
|
const segmentElementCache = new SegmentElementCache();
|
|
602
607
|
let routerPhase = { phase: "idle" };
|
|
608
|
+
let navigationId = 0;
|
|
603
609
|
const pendingListeners = /* @__PURE__ */ new Set();
|
|
604
610
|
let currentNavAbort = null;
|
|
605
611
|
/**
|
|
@@ -636,14 +642,29 @@ function createRouter(deps) {
|
|
|
636
642
|
}
|
|
637
643
|
/**
|
|
638
644
|
* Merge a partial RSC payload with cached segment elements if segments
|
|
639
|
-
* were skipped
|
|
640
|
-
*
|
|
645
|
+
* were skipped. Returns the merged payload ready for rendering.
|
|
646
|
+
*
|
|
647
|
+
* Segment element caching is deferred to after paint by the caller
|
|
648
|
+
* so it doesn't block the render path.
|
|
649
|
+
*/
|
|
650
|
+
async function mergePayload(payload, skippedSegments) {
|
|
651
|
+
if (skippedSegments && skippedSegments.length > 0) return mergeSegmentTree(payload != null && typeof payload === "object" && "then" in payload ? await payload : payload, skippedSegments, segmentElementCache);
|
|
652
|
+
return payload;
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* Schedule segment element caching after paint. Resolves thenable
|
|
656
|
+
* payloads first since tree walking requires resolved React elements.
|
|
657
|
+
* Guards against stale writes: if a newer navigation started before
|
|
658
|
+
* this callback fires, the cache write is skipped.
|
|
641
659
|
*/
|
|
642
|
-
function
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
660
|
+
function deferSegmentCaching(payload) {
|
|
661
|
+
const capturedNavId = navigationId;
|
|
662
|
+
afterPaint(async () => {
|
|
663
|
+
if (capturedNavId !== navigationId) return;
|
|
664
|
+
const resolved = payload != null && typeof payload === "object" && "then" in payload ? await payload : payload;
|
|
665
|
+
if (capturedNavId !== navigationId) return;
|
|
666
|
+
cacheSegmentElements(resolved, segmentElementCache);
|
|
667
|
+
});
|
|
647
668
|
}
|
|
648
669
|
/**
|
|
649
670
|
* Update navigation state (params + pathname) for the next render.
|
|
@@ -656,44 +677,50 @@ function createRouter(deps) {
|
|
|
656
677
|
function updateNavigationState(params, url) {
|
|
657
678
|
const resolvedParams = params ?? {};
|
|
658
679
|
setCurrentParams(resolvedParams);
|
|
680
|
+
const parsed = new URL(url, "http://localhost");
|
|
659
681
|
const navState = {
|
|
660
682
|
params: resolvedParams,
|
|
661
|
-
pathname:
|
|
683
|
+
pathname: parsed.pathname || "/",
|
|
684
|
+
search: parsed.search
|
|
662
685
|
};
|
|
663
686
|
setNavigationState(navState);
|
|
664
687
|
return navState;
|
|
665
688
|
}
|
|
666
|
-
/**
|
|
667
|
-
* Render a payload via navigateTransition (production) or renderRoot (tests).
|
|
668
|
-
* The perform callback should fetch data, update state, and return the
|
|
669
|
-
* FetchResult plus the NavigationState (so it can be passed explicitly
|
|
670
|
-
* to wrapPayload/renderRoot without temporal coupling).
|
|
671
|
-
*/
|
|
672
689
|
async function renderViaTransition(url, perform) {
|
|
673
690
|
if (deps.navigateTransition) {
|
|
674
691
|
let headElements = null;
|
|
692
|
+
let decodePromise = null;
|
|
675
693
|
await deps.navigateTransition(url, async (wrapPayload) => {
|
|
676
694
|
const result = await perform();
|
|
677
695
|
headElements = result.headElements;
|
|
678
|
-
|
|
696
|
+
decodePromise = result.decodePromise;
|
|
697
|
+
const merged = await mergePayload(result.payload, result.skippedSegments);
|
|
679
698
|
historyStack.push(url, {
|
|
680
699
|
payload: merged,
|
|
681
700
|
headElements: result.headElements,
|
|
682
701
|
params: result.params
|
|
683
702
|
});
|
|
703
|
+
deferSegmentCaching(merged);
|
|
684
704
|
return wrapPayload(merged, result.navState);
|
|
685
705
|
});
|
|
686
|
-
return
|
|
706
|
+
return {
|
|
707
|
+
headElements,
|
|
708
|
+
decodePromise
|
|
709
|
+
};
|
|
687
710
|
}
|
|
688
711
|
const result = await perform();
|
|
689
|
-
const merged =
|
|
712
|
+
const merged = await mergePayload(result.payload, result.skippedSegments);
|
|
690
713
|
historyStack.push(url, {
|
|
691
714
|
payload: merged,
|
|
692
715
|
headElements: result.headElements,
|
|
693
716
|
params: result.params
|
|
694
717
|
});
|
|
718
|
+
deferSegmentCaching(merged);
|
|
695
719
|
renderPayload(merged, result.navState);
|
|
696
|
-
return
|
|
720
|
+
return {
|
|
721
|
+
headElements: result.headElements,
|
|
722
|
+
decodePromise: result.decodePromise
|
|
723
|
+
};
|
|
697
724
|
}
|
|
698
725
|
/** Apply head elements (title, meta tags) to the DOM if available. */
|
|
699
726
|
function applyHead(elements) {
|
|
@@ -722,6 +749,7 @@ function createRouter(deps) {
|
|
|
722
749
|
const prefetched = prefetchCache.consume(url);
|
|
723
750
|
let result = prefetched ? {
|
|
724
751
|
payload: prefetched.payload,
|
|
752
|
+
decodePromise: null,
|
|
725
753
|
headElements: prefetched.headElements,
|
|
726
754
|
segmentInfo: prefetched.segmentInfo ?? null,
|
|
727
755
|
params: prefetched.params ?? null,
|
|
@@ -756,6 +784,7 @@ function createRouter(deps) {
|
|
|
756
784
|
const replace = options.replace === true;
|
|
757
785
|
const externalSignal = options._signal;
|
|
758
786
|
const skipHistory = options._skipHistory === true;
|
|
787
|
+
navigationId++;
|
|
759
788
|
const navAbort = createNavAbort(externalSignal);
|
|
760
789
|
const currentScrollY = deps.getScrollY();
|
|
761
790
|
if (deps.saveNavigationEntryScroll) deps.saveNavigationEntryScroll(currentScrollY);
|
|
@@ -772,11 +801,13 @@ function createRouter(deps) {
|
|
|
772
801
|
}
|
|
773
802
|
setPending(true, url);
|
|
774
803
|
try {
|
|
775
|
-
|
|
804
|
+
const { headElements, decodePromise } = await renderViaTransition(url, () => performNavigationFetch(url, {
|
|
776
805
|
replace,
|
|
777
806
|
signal: navAbort.signal,
|
|
778
807
|
skipHistory: effectiveSkipHistory
|
|
779
|
-
}))
|
|
808
|
+
}));
|
|
809
|
+
if (decodePromise) await decodePromise;
|
|
810
|
+
applyHead(headElements);
|
|
780
811
|
window.dispatchEvent(new Event("timber:navigation-end"));
|
|
781
812
|
restoreScrollAfterPaint(scroll ? 0 : currentScrollY);
|
|
782
813
|
} catch (error) {
|
|
@@ -807,10 +838,11 @@ function createRouter(deps) {
|
|
|
807
838
|
}
|
|
808
839
|
async function refresh() {
|
|
809
840
|
const currentUrl = deps.getCurrentUrl();
|
|
841
|
+
navigationId++;
|
|
810
842
|
const navAbort = createNavAbort();
|
|
811
843
|
setPending(true, currentUrl);
|
|
812
844
|
try {
|
|
813
|
-
|
|
845
|
+
const { headElements, decodePromise } = await renderViaTransition(currentUrl, async () => {
|
|
814
846
|
const result = await fetchRscPayload(currentUrl, deps, void 0, void 0, navAbort.signal);
|
|
815
847
|
updateSegmentCache(result.segmentInfo);
|
|
816
848
|
const navState = updateNavigationState(result.params, currentUrl);
|
|
@@ -818,7 +850,9 @@ function createRouter(deps) {
|
|
|
818
850
|
...result,
|
|
819
851
|
navState
|
|
820
852
|
};
|
|
821
|
-
})
|
|
853
|
+
});
|
|
854
|
+
if (decodePromise) await decodePromise;
|
|
855
|
+
applyHead(headElements);
|
|
822
856
|
} catch (error) {
|
|
823
857
|
if (isAbortError(error)) return;
|
|
824
858
|
throw error;
|
|
@@ -829,6 +863,7 @@ function createRouter(deps) {
|
|
|
829
863
|
}
|
|
830
864
|
}
|
|
831
865
|
async function handlePopState(url, scrollY = 0, externalSignal) {
|
|
866
|
+
navigationId++;
|
|
832
867
|
const entry = historyStack.get(url);
|
|
833
868
|
if (entry && entry.payload !== null) {
|
|
834
869
|
const navState = updateNavigationState(entry.params, url);
|
|
@@ -839,7 +874,7 @@ function createRouter(deps) {
|
|
|
839
874
|
const navAbort = createNavAbort(externalSignal);
|
|
840
875
|
setPending(true, url);
|
|
841
876
|
try {
|
|
842
|
-
|
|
877
|
+
const { headElements, decodePromise } = await renderViaTransition(url, async () => {
|
|
843
878
|
const result = await fetchRscPayload(url, deps, segmentCache.serializeStateTree(segmentElementCache.getMergeablePaths()), void 0, navAbort.signal);
|
|
844
879
|
updateSegmentCache(result.segmentInfo);
|
|
845
880
|
const navState = updateNavigationState(result.params, url);
|
|
@@ -847,7 +882,9 @@ function createRouter(deps) {
|
|
|
847
882
|
...result,
|
|
848
883
|
navState
|
|
849
884
|
};
|
|
850
|
-
})
|
|
885
|
+
});
|
|
886
|
+
if (decodePromise) await decodePromise;
|
|
887
|
+
applyHead(headElements);
|
|
851
888
|
restoreScrollAfterPaint(scrollY);
|
|
852
889
|
} catch (error) {
|
|
853
890
|
if (isAbortError(error)) return;
|
|
@@ -882,12 +919,12 @@ function createRouter(deps) {
|
|
|
882
919
|
prefetch,
|
|
883
920
|
applyRevalidation(element, headElements) {
|
|
884
921
|
const currentUrl = deps.getCurrentUrl();
|
|
885
|
-
const merged = mergeAndCachePayload(element, null);
|
|
886
922
|
historyStack.push(currentUrl, {
|
|
887
|
-
payload:
|
|
923
|
+
payload: element,
|
|
888
924
|
headElements
|
|
889
925
|
});
|
|
890
|
-
|
|
926
|
+
deferSegmentCaching(element);
|
|
927
|
+
renderPayload(element, getNavigationState());
|
|
891
928
|
applyHead(headElements);
|
|
892
929
|
},
|
|
893
930
|
initSegmentCache: (segments) => updateSegmentCache(segments),
|
|
@@ -905,9 +942,12 @@ function createRouter(deps) {
|
|
|
905
942
|
* Returns a read-only URLSearchParams instance reflecting the current
|
|
906
943
|
* URL's query string. Updates when client-side navigation changes the URL.
|
|
907
944
|
*
|
|
908
|
-
*
|
|
909
|
-
*
|
|
910
|
-
*
|
|
945
|
+
* On the client, reads from NavigationContext which is updated atomically
|
|
946
|
+
* with the RSC tree render. This replaces the previous useSyncExternalStore
|
|
947
|
+
* approach which read window.location.search directly — causing React to
|
|
948
|
+
* detect external store tearing during transitions and fall back to
|
|
949
|
+
* synchronous rendering (renderRootSync instead of renderRootConcurrent),
|
|
950
|
+
* blocking the main thread and freezing animations.
|
|
911
951
|
*
|
|
912
952
|
* Unlike Next.js's ReadonlyURLSearchParams, this returns a standard
|
|
913
953
|
* URLSearchParams. Mutation methods (set, delete, append) work on the
|
|
@@ -916,28 +956,9 @@ function createRouter(deps) {
|
|
|
916
956
|
* During SSR, reads the request search params from the SSR ALS context
|
|
917
957
|
* (populated by ssr-entry.ts) instead of window.location.
|
|
918
958
|
*
|
|
919
|
-
*
|
|
920
|
-
* See design/18-build-system.md §"Singleton State Registry"
|
|
959
|
+
* Compatible with Next.js's `useSearchParams()` from `next/navigation`.
|
|
921
960
|
*/
|
|
922
|
-
function
|
|
923
|
-
if (typeof window !== "undefined") return window.location.search;
|
|
924
|
-
const data = getSsrData();
|
|
925
|
-
if (!data) return "";
|
|
926
|
-
const str = new URLSearchParams(data.searchParams).toString();
|
|
927
|
-
return str ? `?${str}` : "";
|
|
928
|
-
}
|
|
929
|
-
function getServerSearch() {
|
|
930
|
-
const data = getSsrData();
|
|
931
|
-
if (!data) return "";
|
|
932
|
-
const str = new URLSearchParams(data.searchParams).toString();
|
|
933
|
-
return str ? `?${str}` : "";
|
|
934
|
-
}
|
|
935
|
-
function subscribe(callback) {
|
|
936
|
-
window.addEventListener("popstate", callback);
|
|
937
|
-
return () => window.removeEventListener("popstate", callback);
|
|
938
|
-
}
|
|
939
|
-
function getSearchParams() {
|
|
940
|
-
const search = getSearch();
|
|
961
|
+
function getSearchParams(search) {
|
|
941
962
|
if (search !== cachedSearch) {
|
|
942
963
|
const params = new URLSearchParams(search);
|
|
943
964
|
_setCachedSearch(search, params);
|
|
@@ -945,18 +966,20 @@ function getSearchParams() {
|
|
|
945
966
|
}
|
|
946
967
|
return cachedSearchParams;
|
|
947
968
|
}
|
|
948
|
-
function getServerSearchParams() {
|
|
949
|
-
const data = getSsrData();
|
|
950
|
-
return data ? new URLSearchParams(data.searchParams) : new URLSearchParams();
|
|
951
|
-
}
|
|
952
969
|
/**
|
|
953
970
|
* Read the current URL search params.
|
|
954
971
|
*
|
|
955
972
|
* Compatible with Next.js's `useSearchParams()` from `next/navigation`.
|
|
956
973
|
*/
|
|
957
974
|
function useSearchParams() {
|
|
958
|
-
|
|
959
|
-
|
|
975
|
+
try {
|
|
976
|
+
const navContext = useNavigationContext();
|
|
977
|
+
if (navContext !== null) return getSearchParams(navContext.search);
|
|
978
|
+
} catch {}
|
|
979
|
+
const ssrData = getSsrData();
|
|
980
|
+
if (ssrData) return new URLSearchParams(ssrData.searchParams);
|
|
981
|
+
if (typeof window !== "undefined") return getSearchParams(window.location.search);
|
|
982
|
+
return new URLSearchParams();
|
|
960
983
|
}
|
|
961
984
|
//#endregion
|
|
962
985
|
export { HistoryStack, NavigationProvider, PrefetchCache, SegmentCache, SegmentProvider, TimberErrorBoundary, bindUseQueryStates, clearSsrData, createRouter, getNavigationState, getRouter, getRouterOrNull, getSsrData, setCurrentParams, setGlobalRouter, setNavigationState, setSsrData, useSearchParams, useSegmentContext };
|