@tanstack/react-router 1.40.0 → 1.41.0
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/cjs/CatchBoundary.d.cts +2 -2
- package/dist/cjs/Match.cjs +238 -0
- package/dist/cjs/Match.cjs.map +1 -0
- package/dist/cjs/Match.d.cts +5 -0
- package/dist/cjs/Matches.cjs +8 -249
- package/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/Matches.d.cts +2 -11
- package/dist/cjs/RouterProvider.cjs.map +1 -1
- package/dist/cjs/RouterProvider.d.cts +2 -2
- package/dist/cjs/SafeFragment.cjs +8 -0
- package/dist/cjs/SafeFragment.cjs.map +1 -0
- package/dist/cjs/SafeFragment.d.cts +1 -0
- package/dist/cjs/ScriptOnce.cjs +28 -0
- package/dist/cjs/ScriptOnce.cjs.map +1 -0
- package/dist/cjs/ScriptOnce.d.cts +5 -0
- package/dist/cjs/Transitioner.cjs +2 -1
- package/dist/cjs/Transitioner.cjs.map +1 -1
- package/dist/cjs/awaited.cjs +14 -71
- package/dist/cjs/awaited.cjs.map +1 -1
- package/dist/cjs/awaited.d.cts +3 -6
- package/dist/cjs/defer.cjs +7 -13
- package/dist/cjs/defer.cjs.map +1 -1
- package/dist/cjs/defer.d.cts +2 -6
- package/dist/cjs/index.cjs +11 -7
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +8 -3
- package/dist/cjs/isServerSideError.cjs +22 -0
- package/dist/cjs/isServerSideError.cjs.map +1 -0
- package/dist/cjs/isServerSideError.d.cts +5 -0
- package/dist/cjs/link.cjs +1 -0
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/matchContext.cjs +23 -0
- package/dist/cjs/matchContext.cjs.map +1 -0
- package/dist/cjs/matchContext.d.cts +2 -0
- package/dist/cjs/not-found.cjs.map +1 -1
- package/dist/cjs/not-found.d.cts +2 -2
- package/dist/cjs/qss.cjs.map +1 -1
- package/dist/cjs/qss.d.cts +1 -1
- package/dist/cjs/redirects.cjs.map +1 -1
- package/dist/cjs/renderRouteNotFound.cjs +22 -0
- package/dist/cjs/renderRouteNotFound.cjs.map +1 -0
- package/dist/cjs/renderRouteNotFound.d.cts +4 -0
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/router.cjs +26 -22
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +14 -9
- package/dist/cjs/useMatch.cjs +2 -2
- package/dist/cjs/useMatch.cjs.map +1 -1
- package/dist/cjs/utils.cjs +4 -3
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +3 -2
- package/dist/esm/CatchBoundary.d.ts +2 -2
- package/dist/esm/Match.d.ts +5 -0
- package/dist/esm/Match.js +221 -0
- package/dist/esm/Match.js.map +1 -0
- package/dist/esm/Matches.d.ts +2 -11
- package/dist/esm/Matches.js +5 -246
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/RouterProvider.d.ts +2 -2
- package/dist/esm/RouterProvider.js.map +1 -1
- package/dist/esm/SafeFragment.d.ts +1 -0
- package/dist/esm/SafeFragment.js +8 -0
- package/dist/esm/SafeFragment.js.map +1 -0
- package/dist/esm/ScriptOnce.d.ts +5 -0
- package/dist/esm/ScriptOnce.js +28 -0
- package/dist/esm/ScriptOnce.js.map +1 -0
- package/dist/esm/Transitioner.js +2 -1
- package/dist/esm/Transitioner.js.map +1 -1
- package/dist/esm/awaited.d.ts +3 -6
- package/dist/esm/awaited.js +16 -73
- package/dist/esm/awaited.js.map +1 -1
- package/dist/esm/defer.d.ts +2 -6
- package/dist/esm/defer.js +8 -14
- package/dist/esm/defer.js.map +1 -1
- package/dist/esm/index.d.ts +8 -3
- package/dist/esm/index.js +9 -5
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/isServerSideError.d.ts +5 -0
- package/dist/esm/isServerSideError.js +22 -0
- package/dist/esm/isServerSideError.js.map +1 -0
- package/dist/esm/link.js +1 -0
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/matchContext.d.ts +2 -0
- package/dist/esm/matchContext.js +6 -0
- package/dist/esm/matchContext.js.map +1 -0
- package/dist/esm/not-found.d.ts +2 -2
- package/dist/esm/not-found.js.map +1 -1
- package/dist/esm/qss.d.ts +1 -1
- package/dist/esm/qss.js.map +1 -1
- package/dist/esm/redirects.js.map +1 -1
- package/dist/esm/renderRouteNotFound.d.ts +4 -0
- package/dist/esm/renderRouteNotFound.js +22 -0
- package/dist/esm/renderRouteNotFound.js.map +1 -0
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +14 -9
- package/dist/esm/router.js +26 -22
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/useMatch.js +1 -1
- package/dist/esm/useMatch.js.map +1 -1
- package/dist/esm/utils.d.ts +3 -2
- package/dist/esm/utils.js +4 -3
- package/dist/esm/utils.js.map +1 -1
- package/package.json +4 -4
- package/src/Match.tsx +296 -0
- package/src/Matches.tsx +4 -333
- package/src/RouterProvider.tsx +1 -1
- package/src/SafeFragment.tsx +5 -0
- package/src/ScriptOnce.tsx +27 -0
- package/src/Transitioner.tsx +1 -1
- package/src/awaited.tsx +17 -89
- package/src/defer.ts +9 -26
- package/src/index.tsx +7 -13
- package/src/isServerSideError.tsx +23 -0
- package/src/link.tsx +2 -0
- package/src/matchContext.tsx +3 -0
- package/src/not-found.tsx +1 -1
- package/src/qss.ts +5 -6
- package/src/redirects.ts +0 -1
- package/src/renderRouteNotFound.tsx +28 -0
- package/src/route.ts +1 -1
- package/src/router.ts +50 -39
- package/src/useMatch.tsx +1 -1
- package/src/utils.ts +11 -9
package/dist/cjs/router.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Store, NoInfer } from '@tanstack/react-store';
|
|
2
2
|
import { Manifest } from './manifest.cjs';
|
|
3
3
|
import { HistoryState, RouterHistory } from '@tanstack/history';
|
|
4
|
-
import { AnyContext, AnyRoute, AnySearchSchema, ErrorRouteComponent, NotFoundRouteComponent, RootRoute,
|
|
4
|
+
import { AnyContext, AnyRoute, AnySearchSchema, ErrorRouteComponent, NotFoundRouteComponent, RootRoute, RouteComponent, RouteMask } from './route.cjs';
|
|
5
5
|
import { FullSearchSchema, RouteById, RoutePaths, RoutesById, RoutesByPath } from './routeInfo.cjs';
|
|
6
6
|
import { ControlledPromise, NonNullableUpdater, PickAsRequired, Updater } from './utils.cjs';
|
|
7
7
|
import { AnyRouteMatch, MakeRouteMatch, MatchRouteOptions } from './Matches.cjs';
|
|
@@ -11,14 +11,14 @@ import { BuildLocationFn, CommitLocationOptions, NavigateFn } from './RouterProv
|
|
|
11
11
|
import { AnyRedirect, ResolvedRedirect } from './redirects.cjs';
|
|
12
12
|
import { NotFoundError } from './not-found.cjs';
|
|
13
13
|
import { NavigateOptions, ResolveRelativePath, ToOptions } from './link.cjs';
|
|
14
|
-
import { DeferredPromiseState } from './defer.cjs';
|
|
15
|
-
import { ErrorInfo } from 'react';
|
|
16
14
|
|
|
17
15
|
import type * as React from 'react';
|
|
18
16
|
declare global {
|
|
19
17
|
interface Window {
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
__TSR__?: {
|
|
19
|
+
matches: Array<any>;
|
|
20
|
+
cleanScripts: () => void;
|
|
21
|
+
dehydrated?: any;
|
|
22
22
|
};
|
|
23
23
|
__TSR_ROUTER_CONTEXT__?: React.Context<Router<any, any>>;
|
|
24
24
|
}
|
|
@@ -136,7 +136,7 @@ export interface RouterOptions<TRouteTree extends AnyRoute, TTrailingSlashOption
|
|
|
136
136
|
* @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultoncatch-property)
|
|
137
137
|
* @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#handling-errors-with-routeoptionsoncatch)
|
|
138
138
|
*/
|
|
139
|
-
defaultOnCatch?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
139
|
+
defaultOnCatch?: (error: Error, errorInfo: React.ErrorInfo) => void;
|
|
140
140
|
defaultViewTransition?: boolean;
|
|
141
141
|
/**
|
|
142
142
|
* @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/not-found-errors#the-notfoundmode-option)
|
|
@@ -345,6 +345,14 @@ export declare class Router<in out TRouteTree extends AnyRoute, in out TTrailing
|
|
|
345
345
|
dehydratedData?: TDehydrated;
|
|
346
346
|
viewTransitionPromise?: ControlledPromise<true>;
|
|
347
347
|
manifest?: Manifest;
|
|
348
|
+
AfterEachMatch?: (props: {
|
|
349
|
+
match: Pick<AnyRouteMatch, 'id' | 'status' | 'error' | 'loadPromise' | 'minPendingPromise'>;
|
|
350
|
+
matchIndex: number;
|
|
351
|
+
}) => any;
|
|
352
|
+
serializeLoaderData?: (data: any, ctx: {
|
|
353
|
+
router: AnyRouter;
|
|
354
|
+
match: AnyRouteMatch;
|
|
355
|
+
}) => any;
|
|
348
356
|
__store: Store<RouterState<TRouteTree>>;
|
|
349
357
|
options: PickAsRequired<Omit<RouterOptions<TRouteTree, TTrailingSlashOption, TDehydrated, TSerializedError>, 'transformer'> & {
|
|
350
358
|
transformer: RouterTransformer;
|
|
@@ -395,9 +403,6 @@ export declare class Router<in out TRouteTree extends AnyRoute, in out TTrailing
|
|
|
395
403
|
cleanCache: () => void;
|
|
396
404
|
preloadRoute: <TFrom extends string | import('./routeInfo').ParseRoute<TRouteTree, TRouteTree>["fullPath"] = string, TTo extends string = "", TMaskFrom extends string | import('./routeInfo').ParseRoute<TRouteTree, TRouteTree>["fullPath"] = TFrom, TMaskTo extends string = "">(opts: NavigateOptions<Router<TRouteTree, TTrailingSlashOption, TDehydrated, TSerializedError>, TFrom, TTo, TMaskFrom, TMaskTo>) => Promise<Array<AnyRouteMatch> | undefined>;
|
|
397
405
|
matchRoute: <TFrom extends RoutePaths<TRouteTree> = "/", TTo extends string = "", TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>>(location: ToOptions<Router<TRouteTree, TTrailingSlashOption, TDehydrated, TSerializedError>, TFrom, TTo>, opts?: MatchRouteOptions) => false | RouteById<TRouteTree, TResolved>['types']['allParams'];
|
|
398
|
-
registeredDeferredsIds: Map<string, {}>;
|
|
399
|
-
registeredDeferreds: WeakMap<{}, DeferredPromiseState<any>>;
|
|
400
|
-
getDeferred: (uid: string) => DeferredPromiseState<any> | undefined;
|
|
401
406
|
dehydrate: () => DehydratedRouter;
|
|
402
407
|
hydrate: (__do_not_use_server_ctx?: string) => Promise<void>;
|
|
403
408
|
handleNotFound: (matches: Array<AnyRouteMatch>, err: NotFoundError) => void;
|
package/dist/cjs/useMatch.cjs
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const React = require("react");
|
|
4
4
|
const invariant = require("tiny-invariant");
|
|
5
5
|
const useRouterState = require("./useRouterState.cjs");
|
|
6
|
-
const
|
|
6
|
+
const matchContext = require("./matchContext.cjs");
|
|
7
7
|
function _interopNamespaceDefault(e) {
|
|
8
8
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
9
9
|
if (e) {
|
|
@@ -22,7 +22,7 @@ function _interopNamespaceDefault(e) {
|
|
|
22
22
|
}
|
|
23
23
|
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
|
|
24
24
|
function useMatch(opts) {
|
|
25
|
-
const nearestMatchId = React__namespace.useContext(
|
|
25
|
+
const nearestMatchId = React__namespace.useContext(matchContext.matchContext);
|
|
26
26
|
const matchSelection = useRouterState.useRouterState({
|
|
27
27
|
select: (state) => {
|
|
28
28
|
const match = state.matches.find(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMatch.cjs","sources":["../../src/useMatch.tsx"],"sourcesContent":["import * as React from 'react'\nimport invariant from 'tiny-invariant'\nimport { useRouterState } from './useRouterState'\nimport { type RegisteredRouter } from './router'\nimport { type AnyRoute } from './route'\nimport { matchContext } from './
|
|
1
|
+
{"version":3,"file":"useMatch.cjs","sources":["../../src/useMatch.tsx"],"sourcesContent":["import * as React from 'react'\nimport invariant from 'tiny-invariant'\nimport { useRouterState } from './useRouterState'\nimport { type RegisteredRouter } from './router'\nimport { type AnyRoute } from './route'\nimport { matchContext } from './matchContext'\nimport type { MakeRouteMatch } from './Matches'\nimport type { RouteIds } from './routeInfo'\nimport type { StrictOrFrom } from './utils'\n\nexport type UseMatchOptions<\n TFrom,\n TStrict extends boolean,\n TRouteMatch,\n TSelected,\n> = StrictOrFrom<TFrom, TStrict> & {\n select?: (match: TRouteMatch) => TSelected\n}\n\nexport function useMatch<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>,\n TStrict extends boolean = true,\n TRouteMatch = MakeRouteMatch<TRouteTree, TFrom, TStrict>,\n TSelected = TRouteMatch,\n>(opts: UseMatchOptions<TFrom, TStrict, TRouteMatch, TSelected>): TSelected {\n const nearestMatchId = React.useContext(matchContext)\n\n const matchSelection = useRouterState({\n select: (state) => {\n const match = state.matches.find((d) =>\n opts.from ? opts.from === d.routeId : d.id === nearestMatchId,\n )\n\n invariant(\n match,\n `Could not find ${opts.from ? `an active match from \"${opts.from}\"` : 'a nearest match!'}`,\n )\n\n return opts.select ? opts.select(match as any) : match\n },\n })\n\n return matchSelection as TSelected\n}\n"],"names":["React","matchContext","useRouterState"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAmBO,SAAS,SAMd,MAA0E;AACpE,QAAA,iBAAiBA,iBAAM,WAAWC,aAAY,YAAA;AAEpD,QAAM,iBAAiBC,eAAAA,eAAe;AAAA,IACpC,QAAQ,CAAC,UAAU;AACX,YAAA,QAAQ,MAAM,QAAQ;AAAA,QAAK,CAAC,MAChC,KAAK,OAAO,KAAK,SAAS,EAAE,UAAU,EAAE,OAAO;AAAA,MAAA;AAGjD;AAAA,QACE;AAAA,QACA,kBAAkB,KAAK,OAAO,yBAAyB,KAAK,IAAI,MAAM,kBAAkB;AAAA,MAAA;AAG1F,aAAO,KAAK,SAAS,KAAK,OAAO,KAAY,IAAI;AAAA,IACnD;AAAA,EAAA,CACD;AAEM,SAAA;AACT;;"}
|
package/dist/cjs/utils.cjs
CHANGED
|
@@ -146,10 +146,11 @@ function createControlledPromise(onResolve) {
|
|
|
146
146
|
rejectLoadPromise = reject;
|
|
147
147
|
});
|
|
148
148
|
controlledPromise.status = "pending";
|
|
149
|
-
controlledPromise.resolve = () => {
|
|
149
|
+
controlledPromise.resolve = (value) => {
|
|
150
150
|
controlledPromise.status = "resolved";
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
controlledPromise.value = value;
|
|
152
|
+
resolveLoadPromise(value);
|
|
153
|
+
onResolve == null ? void 0 : onResolve(value);
|
|
153
154
|
};
|
|
154
155
|
controlledPromise.reject = (e) => {
|
|
155
156
|
controlledPromise.status = "rejected";
|
package/dist/cjs/utils.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","sources":["../../src/utils.ts"],"sourcesContent":["import * as React from 'react'\n\nexport type NoInfer<T> = [T][T extends any ? 0 : never]\nexport type IsAny<TValue, TYesResult, TNoResult = TValue> = 1 extends 0 & TValue\n ? TYesResult\n : TNoResult\nexport type PickAsRequired<TValue, TKey extends keyof TValue> = Omit<\n TValue,\n TKey\n> &\n Required<Pick<TValue, TKey>>\n\nexport type PickRequired<T> = {\n [K in keyof T as undefined extends T[K] ? never : K]: T[K]\n}\n\n// from https://stackoverflow.com/a/76458160\nexport type WithoutEmpty<T> = T extends any ? ({} extends T ? never : T) : never\n\n// export type Expand<T> = T\nexport type Expand<T> = T extends object\n ? T extends infer O\n ? O extends Function\n ? O\n : { [K in keyof O]: O[K] }\n : never\n : T\n\nexport type DeepPartial<T> = T extends object\n ? {\n [P in keyof T]?: DeepPartial<T[P]>\n }\n : T\n\nexport type MakeDifferenceOptional<TLeft, TRight> = Omit<\n TRight,\n keyof TLeft\n> & {\n [K in keyof TLeft & keyof TRight]?: TRight[K]\n}\n\n// from https://stackoverflow.com/a/53955431\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type IsUnion<T, U extends T = T> = (\n T extends any ? (U extends T ? false : true) : never\n) extends false\n ? false\n : true\n\nexport type Assign<TLeft, TRight> = keyof TLeft extends never\n ? TRight\n : keyof TRight extends never\n ? TLeft\n : keyof TLeft & keyof TRight extends never\n ? TLeft & TRight\n : Omit<TLeft, keyof TRight> & TRight\n\nexport type Timeout = ReturnType<typeof setTimeout>\n\nexport type Updater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev?: TPrevious) => TResult)\n\nexport type NonNullableUpdater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev: TPrevious) => TResult)\n\nexport type MergeUnionObjects<TUnion> = TUnion extends MergeUnionPrimitive\n ? never\n : TUnion\n\nexport type MergeUnionObject<TUnion> =\n MergeUnionObjects<TUnion> extends infer TObj\n ? {\n [TKey in TObj extends any ? keyof TObj : never]?: TObj extends any\n ? TKey extends keyof TObj\n ? TObj[TKey]\n : never\n : never\n }\n : never\n\nexport type MergeUnionPrimitive =\n | ReadonlyArray<any>\n | number\n | string\n | bigint\n | boolean\n | symbol\n\nexport type MergeUnionPrimitives<TUnion> = TUnion extends MergeUnionPrimitive\n ? TUnion\n : TUnion extends object\n ? never\n : TUnion\n\nexport type MergeUnion<TUnion> =\n | MergeUnionPrimitives<TUnion>\n | MergeUnionObject<TUnion>\n\nexport function last<T>(arr: Array<T>) {\n return arr[arr.length - 1]\n}\n\nfunction isFunction(d: any): d is Function {\n return typeof d === 'function'\n}\n\nexport function functionalUpdate<TResult>(\n updater: Updater<TResult> | NonNullableUpdater<TResult>,\n previous: TResult,\n): TResult {\n if (isFunction(updater)) {\n return updater(previous)\n }\n\n return updater\n}\n\nexport function pick<TValue, TKey extends keyof TValue>(\n parent: TValue,\n keys: Array<TKey>,\n): Pick<TValue, TKey> {\n return keys.reduce((obj: any, key: TKey) => {\n obj[key] = parent[key]\n return obj\n }, {} as any)\n}\n\n/**\n * This function returns `prev` if `_next` is deeply equal.\n * If not, it will replace any deeply equal children of `b` with those of `a`.\n * This can be used for structural sharing between immutable JSON values for example.\n * Do not use this with signals\n */\nexport function replaceEqualDeep<T>(prev: any, _next: T): T {\n if (prev === _next) {\n return prev\n }\n\n const next = _next as any\n\n const array = isPlainArray(prev) && isPlainArray(next)\n\n if (array || (isPlainObject(prev) && isPlainObject(next))) {\n const prevItems = array ? prev : Object.keys(prev)\n const prevSize = prevItems.length\n const nextItems = array ? next : Object.keys(next)\n const nextSize = nextItems.length\n const copy: any = array ? [] : {}\n\n let equalItems = 0\n\n for (let i = 0; i < nextSize; i++) {\n const key = array ? i : nextItems[i]\n if (\n ((!array && prevItems.includes(key)) || array) &&\n prev[key] === undefined &&\n next[key] === undefined\n ) {\n copy[key] = undefined\n equalItems++\n } else {\n copy[key] = replaceEqualDeep(prev[key], next[key])\n if (copy[key] === prev[key] && prev[key] !== undefined) {\n equalItems++\n }\n }\n }\n\n return prevSize === nextSize && equalItems === prevSize ? prev : copy\n }\n\n return next\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\nexport function isPlainObject(o: any) {\n if (!hasObjectPrototype(o)) {\n return false\n }\n\n // If has modified constructor\n const ctor = o.constructor\n if (typeof ctor === 'undefined') {\n return true\n }\n\n // If has modified prototype\n const prot = ctor.prototype\n if (!hasObjectPrototype(prot)) {\n return false\n }\n\n // If constructor does not have an Object-specific method\n if (!prot.hasOwnProperty('isPrototypeOf')) {\n return false\n }\n\n // Most likely a plain Object\n return true\n}\n\nfunction hasObjectPrototype(o: any) {\n return Object.prototype.toString.call(o) === '[object Object]'\n}\n\nexport function isPlainArray(value: unknown) {\n return Array.isArray(value) && value.length === Object.keys(value).length\n}\n\nexport function deepEqual(a: any, b: any, partial: boolean = false): boolean {\n if (a === b) {\n return true\n }\n\n if (typeof a !== typeof b) {\n return false\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n\n if (!partial && aKeys.length !== bKeys.length) {\n return false\n }\n\n return !bKeys.some(\n (key) => !(key in a) || !deepEqual(a[key], b[key], partial),\n )\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n return !a.some((item, index) => !deepEqual(item, b[index], partial))\n }\n\n return false\n}\n\nexport function useStableCallback<T extends (...args: Array<any>) => any>(\n fn: T,\n): T {\n const fnRef = React.useRef(fn)\n fnRef.current = fn\n\n const ref = React.useRef((...args: Array<any>) => fnRef.current(...args))\n return ref.current as T\n}\n\nexport function shallow<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n const keysA = Object.keys(objA)\n if (keysA.length !== Object.keys(objB).length) {\n return false\n }\n\n for (const item of keysA) {\n if (\n !Object.prototype.hasOwnProperty.call(objB, item) ||\n !Object.is(objA[item as keyof T], objB[item as keyof T])\n ) {\n return false\n }\n }\n return true\n}\n\nexport type StringLiteral<T> = T extends string\n ? string extends T\n ? string\n : T\n : never\n\nexport type StrictOrFrom<\n TFrom,\n TStrict extends boolean = true,\n> = TStrict extends false\n ? {\n from?: never\n strict: TStrict\n }\n : {\n from: StringLiteral<TFrom> | TFrom\n strict?: TStrict\n }\n\nexport const useLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\n\n/**\n *\n * @deprecated use `jsesc` instead\n */\nexport function escapeJSON(jsonString: string) {\n return jsonString\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes\n .replace(/'/g, \"\\\\'\") // Escape single quotes\n .replace(/\"/g, '\\\\\"') // Escape double quotes\n}\n\nexport type ControlledPromise<T> = Promise<T> & {\n resolve: (value: T) => void\n reject: (value: any) => void\n status: 'pending' | 'resolved' | 'rejected'\n}\n\nexport function createControlledPromise<T>(onResolve?: () => void) {\n let resolveLoadPromise!: () => void\n let rejectLoadPromise!: (value: any) => void\n\n const controlledPromise = new Promise<void>((resolve, reject) => {\n resolveLoadPromise = resolve\n rejectLoadPromise = reject\n }) as ControlledPromise<T>\n\n controlledPromise.status = 'pending'\n\n controlledPromise.resolve = () => {\n controlledPromise.status = 'resolved'\n resolveLoadPromise()\n onResolve?.()\n }\n\n controlledPromise.reject = (e) => {\n controlledPromise.status = 'rejected'\n rejectLoadPromise(e)\n }\n\n return controlledPromise\n}\n\n/**\n * Taken from https://www.developerway.com/posts/implementing-advanced-use-previous-hook#part3\n */\nexport function usePrevious<T>(value: T): T | null {\n // initialise the ref with previous and current values\n const ref = React.useRef<{ value: T; prev: T | null }>({\n value: value,\n prev: null,\n })\n\n const current = ref.current.value\n\n // if the value passed into hook doesn't match what we store as \"current\"\n // move the \"current\" to the \"previous\"\n // and store the passed value as \"current\"\n if (value !== current) {\n ref.current = {\n value: value,\n prev: current,\n }\n }\n\n // return the previous value only\n return ref.current.prev\n}\n"],"names":["React"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoGO,SAAS,KAAQ,KAAe;AAC9B,SAAA,IAAI,IAAI,SAAS,CAAC;AAC3B;AAEA,SAAS,WAAW,GAAuB;AACzC,SAAO,OAAO,MAAM;AACtB;AAEgB,SAAA,iBACd,SACA,UACS;AACL,MAAA,WAAW,OAAO,GAAG;AACvB,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAEO,SAAA;AACT;AAEgB,SAAA,KACd,QACA,MACoB;AACpB,SAAO,KAAK,OAAO,CAAC,KAAU,QAAc;AACtC,QAAA,GAAG,IAAI,OAAO,GAAG;AACd,WAAA;AAAA,EACT,GAAG,CAAS,CAAA;AACd;AAQgB,SAAA,iBAAoB,MAAW,OAAa;AAC1D,MAAI,SAAS,OAAO;AACX,WAAA;AAAA,EACT;AAEA,QAAM,OAAO;AAEb,QAAM,QAAQ,aAAa,IAAI,KAAK,aAAa,IAAI;AAErD,MAAI,SAAU,cAAc,IAAI,KAAK,cAAc,IAAI,GAAI;AACzD,UAAM,YAAY,QAAQ,OAAO,OAAO,KAAK,IAAI;AACjD,UAAM,WAAW,UAAU;AAC3B,UAAM,YAAY,QAAQ,OAAO,OAAO,KAAK,IAAI;AACjD,UAAM,WAAW,UAAU;AAC3B,UAAM,OAAY,QAAQ,CAAC,IAAI;AAE/B,QAAI,aAAa;AAEjB,aAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,YAAM,MAAM,QAAQ,IAAI,UAAU,CAAC;AACnC,WACI,CAAC,SAAS,UAAU,SAAS,GAAG,KAAM,UACxC,KAAK,GAAG,MAAM,UACd,KAAK,GAAG,MAAM,QACd;AACA,aAAK,GAAG,IAAI;AACZ;AAAA,MAAA,OACK;AACA,aAAA,GAAG,IAAI,iBAAiB,KAAK,GAAG,GAAG,KAAK,GAAG,CAAC;AAC7C,YAAA,KAAK,GAAG,MAAM,KAAK,GAAG,KAAK,KAAK,GAAG,MAAM,QAAW;AACtD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO,aAAa,YAAY,eAAe,WAAW,OAAO;AAAA,EACnE;AAEO,SAAA;AACT;AAGO,SAAS,cAAc,GAAQ;AAChC,MAAA,CAAC,mBAAmB,CAAC,GAAG;AACnB,WAAA;AAAA,EACT;AAGA,QAAM,OAAO,EAAE;AACX,MAAA,OAAO,SAAS,aAAa;AACxB,WAAA;AAAA,EACT;AAGA,QAAM,OAAO,KAAK;AACd,MAAA,CAAC,mBAAmB,IAAI,GAAG;AACtB,WAAA;AAAA,EACT;AAGA,MAAI,CAAC,KAAK,eAAe,eAAe,GAAG;AAClC,WAAA;AAAA,EACT;AAGO,SAAA;AACT;AAEA,SAAS,mBAAmB,GAAQ;AAClC,SAAO,OAAO,UAAU,SAAS,KAAK,CAAC,MAAM;AAC/C;AAEO,SAAS,aAAa,OAAgB;AACpC,SAAA,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,OAAO,KAAK,KAAK,EAAE;AACrE;AAEO,SAAS,UAAU,GAAQ,GAAQ,UAAmB,OAAgB;AAC3E,MAAI,MAAM,GAAG;AACJ,WAAA;AAAA,EACT;AAEI,MAAA,OAAO,MAAM,OAAO,GAAG;AAClB,WAAA;AAAA,EACT;AAEA,MAAI,cAAc,CAAC,KAAK,cAAc,CAAC,GAAG;AAClC,UAAA,QAAQ,OAAO,KAAK,CAAC;AACrB,UAAA,QAAQ,OAAO,KAAK,CAAC;AAE3B,QAAI,CAAC,WAAW,MAAM,WAAW,MAAM,QAAQ;AACtC,aAAA;AAAA,IACT;AAEA,WAAO,CAAC,MAAM;AAAA,MACZ,CAAC,QAAQ,EAAE,OAAO,MAAM,CAAC,UAAU,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,OAAO;AAAA,IAAA;AAAA,EAE9D;AAEA,MAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,GAAG;AACxC,WAAO,CAAC,EAAE,KAAK,CAAC,MAAM,UAAU,CAAC,UAAU,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC;AAAA,EACrE;AAEO,SAAA;AACT;AAEO,SAAS,kBACd,IACG;AACG,QAAA,QAAQA,iBAAM,OAAO,EAAE;AAC7B,QAAM,UAAU;AAEV,QAAA,MAAMA,iBAAM,OAAO,IAAI,SAAqB,MAAM,QAAQ,GAAG,IAAI,CAAC;AACxE,SAAO,IAAI;AACb;AAEgB,SAAA,QAAW,MAAS,MAAS;AAC3C,MAAI,OAAO,GAAG,MAAM,IAAI,GAAG;AAClB,WAAA;AAAA,EACT;AAGE,MAAA,OAAO,SAAS,YAChB,SAAS,QACT,OAAO,SAAS,YAChB,SAAS,MACT;AACO,WAAA;AAAA,EACT;AAEM,QAAA,QAAQ,OAAO,KAAK,IAAI;AAC9B,MAAI,MAAM,WAAW,OAAO,KAAK,IAAI,EAAE,QAAQ;AACtC,WAAA;AAAA,EACT;AAEA,aAAW,QAAQ,OAAO;AACxB,QACE,CAAC,OAAO,UAAU,eAAe,KAAK,MAAM,IAAI,KAChD,CAAC,OAAO,GAAG,KAAK,IAAe,GAAG,KAAK,IAAe,CAAC,GACvD;AACO,aAAA;AAAA,IACT;AAAA,EACF;AACO,SAAA;AACT;AAqBO,MAAM,kBACX,OAAO,WAAW,cAAcA,iBAAM,kBAAkBA,iBAAM;AAMzD,SAAS,WAAW,YAAoB;AACtC,SAAA,WACJ,QAAQ,OAAO,MAAM,EACrB,QAAQ,MAAM,KAAK,EACnB,QAAQ,MAAM,KAAK;AACxB;AAQO,SAAS,wBAA2B,WAAwB;AAC7D,MAAA;AACA,MAAA;AAEJ,QAAM,oBAAoB,IAAI,QAAc,CAAC,SAAS,WAAW;AAC1C,yBAAA;AACD,wBAAA;AAAA,EAAA,CACrB;AAED,oBAAkB,SAAS;AAE3B,oBAAkB,UAAU,MAAM;AAChC,sBAAkB,SAAS;AACR;AACP;AAAA,EAAA;AAGI,oBAAA,SAAS,CAAC,MAAM;AAChC,sBAAkB,SAAS;AAC3B,sBAAkB,CAAC;AAAA,EAAA;AAGd,SAAA;AACT;AAKO,SAAS,YAAe,OAAoB;AAE3C,QAAA,MAAMA,iBAAM,OAAqC;AAAA,IACrD;AAAA,IACA,MAAM;AAAA,EAAA,CACP;AAEK,QAAA,UAAU,IAAI,QAAQ;AAK5B,MAAI,UAAU,SAAS;AACrB,QAAI,UAAU;AAAA,MACZ;AAAA,MACA,MAAM;AAAA,IAAA;AAAA,EAEV;AAGA,SAAO,IAAI,QAAQ;AACrB;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"utils.cjs","sources":["../../src/utils.ts"],"sourcesContent":["import * as React from 'react'\n\nexport type NoInfer<T> = [T][T extends any ? 0 : never]\nexport type IsAny<TValue, TYesResult, TNoResult = TValue> = 1 extends 0 & TValue\n ? TYesResult\n : TNoResult\nexport type PickAsRequired<TValue, TKey extends keyof TValue> = Omit<\n TValue,\n TKey\n> &\n Required<Pick<TValue, TKey>>\n\nexport type PickRequired<T> = {\n [K in keyof T as undefined extends T[K] ? never : K]: T[K]\n}\n\n// from https://stackoverflow.com/a/76458160\nexport type WithoutEmpty<T> = T extends any ? ({} extends T ? never : T) : never\n\n// export type Expand<T> = T\nexport type Expand<T> = T extends object\n ? T extends infer O\n ? O extends Function\n ? O\n : { [K in keyof O]: O[K] }\n : never\n : T\n\nexport type DeepPartial<T> = T extends object\n ? {\n [P in keyof T]?: DeepPartial<T[P]>\n }\n : T\n\nexport type MakeDifferenceOptional<TLeft, TRight> = Omit<\n TRight,\n keyof TLeft\n> & {\n [K in keyof TLeft & keyof TRight]?: TRight[K]\n}\n\n// from https://stackoverflow.com/a/53955431\n// eslint-disable-next-line ts/naming-convention\nexport type IsUnion<T, U extends T = T> = (\n T extends any ? (U extends T ? false : true) : never\n) extends false\n ? false\n : true\n\nexport type Assign<TLeft, TRight> = keyof TLeft extends never\n ? TRight\n : keyof TRight extends never\n ? TLeft\n : keyof TLeft & keyof TRight extends never\n ? TLeft & TRight\n : Omit<TLeft, keyof TRight> & TRight\n\nexport type Timeout = ReturnType<typeof setTimeout>\n\nexport type Updater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev?: TPrevious) => TResult)\n\nexport type NonNullableUpdater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev: TPrevious) => TResult)\n\nexport type MergeUnionObjects<TUnion> = TUnion extends MergeUnionPrimitive\n ? never\n : TUnion\n\nexport type MergeUnionObject<TUnion> =\n MergeUnionObjects<TUnion> extends infer TObj\n ? {\n [TKey in TObj extends any ? keyof TObj : never]?: TObj extends any\n ? TKey extends keyof TObj\n ? TObj[TKey]\n : never\n : never\n }\n : never\n\nexport type MergeUnionPrimitive =\n | ReadonlyArray<any>\n | number\n | string\n | bigint\n | boolean\n | symbol\n\nexport type MergeUnionPrimitives<TUnion> = TUnion extends MergeUnionPrimitive\n ? TUnion\n : TUnion extends object\n ? never\n : TUnion\n\nexport type MergeUnion<TUnion> =\n | MergeUnionPrimitives<TUnion>\n | MergeUnionObject<TUnion>\n\nexport function last<T>(arr: Array<T>) {\n return arr[arr.length - 1]\n}\n\nfunction isFunction(d: any): d is Function {\n return typeof d === 'function'\n}\n\nexport function functionalUpdate<TResult>(\n updater: Updater<TResult> | NonNullableUpdater<TResult>,\n previous: TResult,\n): TResult {\n if (isFunction(updater)) {\n return updater(previous)\n }\n\n return updater\n}\n\nexport function pick<TValue, TKey extends keyof TValue>(\n parent: TValue,\n keys: Array<TKey>,\n): Pick<TValue, TKey> {\n return keys.reduce((obj: any, key: TKey) => {\n obj[key] = parent[key]\n return obj\n }, {} as any)\n}\n\n/**\n * This function returns `prev` if `_next` is deeply equal.\n * If not, it will replace any deeply equal children of `b` with those of `a`.\n * This can be used for structural sharing between immutable JSON values for example.\n * Do not use this with signals\n */\nexport function replaceEqualDeep<T>(prev: any, _next: T): T {\n if (prev === _next) {\n return prev\n }\n\n const next = _next as any\n\n const array = isPlainArray(prev) && isPlainArray(next)\n\n if (array || (isPlainObject(prev) && isPlainObject(next))) {\n const prevItems = array ? prev : Object.keys(prev)\n const prevSize = prevItems.length\n const nextItems = array ? next : Object.keys(next)\n const nextSize = nextItems.length\n const copy: any = array ? [] : {}\n\n let equalItems = 0\n\n for (let i = 0; i < nextSize; i++) {\n const key = array ? i : (nextItems[i] as any)\n if (\n ((!array && prevItems.includes(key)) || array) &&\n prev[key] === undefined &&\n next[key] === undefined\n ) {\n copy[key] = undefined\n equalItems++\n } else {\n copy[key] = replaceEqualDeep(prev[key], next[key])\n if (copy[key] === prev[key] && prev[key] !== undefined) {\n equalItems++\n }\n }\n }\n\n return prevSize === nextSize && equalItems === prevSize ? prev : copy\n }\n\n return next\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\nexport function isPlainObject(o: any) {\n if (!hasObjectPrototype(o)) {\n return false\n }\n\n // If has modified constructor\n const ctor = o.constructor\n if (typeof ctor === 'undefined') {\n return true\n }\n\n // If has modified prototype\n const prot = ctor.prototype\n if (!hasObjectPrototype(prot)) {\n return false\n }\n\n // If constructor does not have an Object-specific method\n if (!prot.hasOwnProperty('isPrototypeOf')) {\n return false\n }\n\n // Most likely a plain Object\n return true\n}\n\nfunction hasObjectPrototype(o: any) {\n return Object.prototype.toString.call(o) === '[object Object]'\n}\n\nexport function isPlainArray(value: unknown): value is Array<unknown> {\n return Array.isArray(value) && value.length === Object.keys(value).length\n}\n\nexport function deepEqual(a: any, b: any, partial: boolean = false): boolean {\n if (a === b) {\n return true\n }\n\n if (typeof a !== typeof b) {\n return false\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n\n if (!partial && aKeys.length !== bKeys.length) {\n return false\n }\n\n return !bKeys.some(\n (key) => !(key in a) || !deepEqual(a[key], b[key], partial),\n )\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n return !a.some((item, index) => !deepEqual(item, b[index], partial))\n }\n\n return false\n}\n\nexport function useStableCallback<T extends (...args: Array<any>) => any>(\n fn: T,\n): T {\n const fnRef = React.useRef(fn)\n fnRef.current = fn\n\n const ref = React.useRef((...args: Array<any>) => fnRef.current(...args))\n return ref.current as T\n}\n\nexport function shallow<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n const keysA = Object.keys(objA)\n if (keysA.length !== Object.keys(objB).length) {\n return false\n }\n\n for (const item of keysA) {\n if (\n !Object.prototype.hasOwnProperty.call(objB, item) ||\n !Object.is(objA[item as keyof T], objB[item as keyof T])\n ) {\n return false\n }\n }\n return true\n}\n\nexport type StringLiteral<T> = T extends string\n ? string extends T\n ? string\n : T\n : never\n\nexport type StrictOrFrom<\n TFrom,\n TStrict extends boolean = true,\n> = TStrict extends false\n ? {\n from?: never\n strict: TStrict\n }\n : {\n from: StringLiteral<TFrom> | TFrom\n strict?: TStrict\n }\n\nexport const useLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\n\n/**\n *\n * @deprecated use `jsesc` instead\n */\nexport function escapeJSON(jsonString: string) {\n return jsonString\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes\n .replace(/'/g, \"\\\\'\") // Escape single quotes\n .replace(/\"/g, '\\\\\"') // Escape double quotes\n}\n\nexport type ControlledPromise<T> = Promise<T> & {\n resolve: (value: T) => void\n reject: (value: any) => void\n status: 'pending' | 'resolved' | 'rejected'\n value?: T\n}\n\nexport function createControlledPromise<T>(onResolve?: (value: T) => void) {\n let resolveLoadPromise!: (value: T) => void\n let rejectLoadPromise!: (value: any) => void\n\n const controlledPromise = new Promise<T>((resolve, reject) => {\n resolveLoadPromise = resolve\n rejectLoadPromise = reject\n }) as ControlledPromise<T>\n\n controlledPromise.status = 'pending'\n\n controlledPromise.resolve = (value: T) => {\n controlledPromise.status = 'resolved'\n controlledPromise.value = value\n resolveLoadPromise(value)\n onResolve?.(value)\n }\n\n controlledPromise.reject = (e) => {\n controlledPromise.status = 'rejected'\n rejectLoadPromise(e)\n }\n\n return controlledPromise\n}\n\n/**\n * Taken from https://www.developerway.com/posts/implementing-advanced-use-previous-hook#part3\n */\nexport function usePrevious<T>(value: T): T | null {\n // initialise the ref with previous and current values\n const ref = React.useRef<{ value: T; prev: T | null }>({\n value: value,\n prev: null,\n })\n\n const current = ref.current.value\n\n // if the value passed into hook doesn't match what we store as \"current\"\n // move the \"current\" to the \"previous\"\n // and store the passed value as \"current\"\n if (value !== current) {\n ref.current = {\n value: value,\n prev: current,\n }\n }\n\n // return the previous value only\n return ref.current.prev\n}\n"],"names":["React"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoGO,SAAS,KAAQ,KAAe;AAC9B,SAAA,IAAI,IAAI,SAAS,CAAC;AAC3B;AAEA,SAAS,WAAW,GAAuB;AACzC,SAAO,OAAO,MAAM;AACtB;AAEgB,SAAA,iBACd,SACA,UACS;AACL,MAAA,WAAW,OAAO,GAAG;AACvB,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAEO,SAAA;AACT;AAEgB,SAAA,KACd,QACA,MACoB;AACpB,SAAO,KAAK,OAAO,CAAC,KAAU,QAAc;AACtC,QAAA,GAAG,IAAI,OAAO,GAAG;AACd,WAAA;AAAA,EACT,GAAG,CAAS,CAAA;AACd;AAQgB,SAAA,iBAAoB,MAAW,OAAa;AAC1D,MAAI,SAAS,OAAO;AACX,WAAA;AAAA,EACT;AAEA,QAAM,OAAO;AAEb,QAAM,QAAQ,aAAa,IAAI,KAAK,aAAa,IAAI;AAErD,MAAI,SAAU,cAAc,IAAI,KAAK,cAAc,IAAI,GAAI;AACzD,UAAM,YAAY,QAAQ,OAAO,OAAO,KAAK,IAAI;AACjD,UAAM,WAAW,UAAU;AAC3B,UAAM,YAAY,QAAQ,OAAO,OAAO,KAAK,IAAI;AACjD,UAAM,WAAW,UAAU;AAC3B,UAAM,OAAY,QAAQ,CAAC,IAAI;AAE/B,QAAI,aAAa;AAEjB,aAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,YAAM,MAAM,QAAQ,IAAK,UAAU,CAAC;AACpC,WACI,CAAC,SAAS,UAAU,SAAS,GAAG,KAAM,UACxC,KAAK,GAAG,MAAM,UACd,KAAK,GAAG,MAAM,QACd;AACA,aAAK,GAAG,IAAI;AACZ;AAAA,MAAA,OACK;AACA,aAAA,GAAG,IAAI,iBAAiB,KAAK,GAAG,GAAG,KAAK,GAAG,CAAC;AAC7C,YAAA,KAAK,GAAG,MAAM,KAAK,GAAG,KAAK,KAAK,GAAG,MAAM,QAAW;AACtD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO,aAAa,YAAY,eAAe,WAAW,OAAO;AAAA,EACnE;AAEO,SAAA;AACT;AAGO,SAAS,cAAc,GAAQ;AAChC,MAAA,CAAC,mBAAmB,CAAC,GAAG;AACnB,WAAA;AAAA,EACT;AAGA,QAAM,OAAO,EAAE;AACX,MAAA,OAAO,SAAS,aAAa;AACxB,WAAA;AAAA,EACT;AAGA,QAAM,OAAO,KAAK;AACd,MAAA,CAAC,mBAAmB,IAAI,GAAG;AACtB,WAAA;AAAA,EACT;AAGA,MAAI,CAAC,KAAK,eAAe,eAAe,GAAG;AAClC,WAAA;AAAA,EACT;AAGO,SAAA;AACT;AAEA,SAAS,mBAAmB,GAAQ;AAClC,SAAO,OAAO,UAAU,SAAS,KAAK,CAAC,MAAM;AAC/C;AAEO,SAAS,aAAa,OAAyC;AAC7D,SAAA,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,OAAO,KAAK,KAAK,EAAE;AACrE;AAEO,SAAS,UAAU,GAAQ,GAAQ,UAAmB,OAAgB;AAC3E,MAAI,MAAM,GAAG;AACJ,WAAA;AAAA,EACT;AAEI,MAAA,OAAO,MAAM,OAAO,GAAG;AAClB,WAAA;AAAA,EACT;AAEA,MAAI,cAAc,CAAC,KAAK,cAAc,CAAC,GAAG;AAClC,UAAA,QAAQ,OAAO,KAAK,CAAC;AACrB,UAAA,QAAQ,OAAO,KAAK,CAAC;AAE3B,QAAI,CAAC,WAAW,MAAM,WAAW,MAAM,QAAQ;AACtC,aAAA;AAAA,IACT;AAEA,WAAO,CAAC,MAAM;AAAA,MACZ,CAAC,QAAQ,EAAE,OAAO,MAAM,CAAC,UAAU,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,OAAO;AAAA,IAAA;AAAA,EAE9D;AAEA,MAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,GAAG;AACxC,WAAO,CAAC,EAAE,KAAK,CAAC,MAAM,UAAU,CAAC,UAAU,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC;AAAA,EACrE;AAEO,SAAA;AACT;AAEO,SAAS,kBACd,IACG;AACG,QAAA,QAAQA,iBAAM,OAAO,EAAE;AAC7B,QAAM,UAAU;AAEV,QAAA,MAAMA,iBAAM,OAAO,IAAI,SAAqB,MAAM,QAAQ,GAAG,IAAI,CAAC;AACxE,SAAO,IAAI;AACb;AAEgB,SAAA,QAAW,MAAS,MAAS;AAC3C,MAAI,OAAO,GAAG,MAAM,IAAI,GAAG;AAClB,WAAA;AAAA,EACT;AAGE,MAAA,OAAO,SAAS,YAChB,SAAS,QACT,OAAO,SAAS,YAChB,SAAS,MACT;AACO,WAAA;AAAA,EACT;AAEM,QAAA,QAAQ,OAAO,KAAK,IAAI;AAC9B,MAAI,MAAM,WAAW,OAAO,KAAK,IAAI,EAAE,QAAQ;AACtC,WAAA;AAAA,EACT;AAEA,aAAW,QAAQ,OAAO;AACxB,QACE,CAAC,OAAO,UAAU,eAAe,KAAK,MAAM,IAAI,KAChD,CAAC,OAAO,GAAG,KAAK,IAAe,GAAG,KAAK,IAAe,CAAC,GACvD;AACO,aAAA;AAAA,IACT;AAAA,EACF;AACO,SAAA;AACT;AAqBO,MAAM,kBACX,OAAO,WAAW,cAAcA,iBAAM,kBAAkBA,iBAAM;AAMzD,SAAS,WAAW,YAAoB;AACtC,SAAA,WACJ,QAAQ,OAAO,MAAM,EACrB,QAAQ,MAAM,KAAK,EACnB,QAAQ,MAAM,KAAK;AACxB;AASO,SAAS,wBAA2B,WAAgC;AACrE,MAAA;AACA,MAAA;AAEJ,QAAM,oBAAoB,IAAI,QAAW,CAAC,SAAS,WAAW;AACvC,yBAAA;AACD,wBAAA;AAAA,EAAA,CACrB;AAED,oBAAkB,SAAS;AAET,oBAAA,UAAU,CAAC,UAAa;AACxC,sBAAkB,SAAS;AAC3B,sBAAkB,QAAQ;AAC1B,uBAAmB,KAAK;AACxB,2CAAY;AAAA,EAAK;AAGD,oBAAA,SAAS,CAAC,MAAM;AAChC,sBAAkB,SAAS;AAC3B,sBAAkB,CAAC;AAAA,EAAA;AAGd,SAAA;AACT;AAKO,SAAS,YAAe,OAAoB;AAE3C,QAAA,MAAMA,iBAAM,OAAqC;AAAA,IACrD;AAAA,IACA,MAAM;AAAA,EAAA,CACP;AAEK,QAAA,UAAU,IAAI,QAAQ;AAK5B,MAAI,UAAU,SAAS;AACrB,QAAI,UAAU;AAAA,MACZ;AAAA,MACA,MAAM;AAAA,IAAA;AAAA,EAEV;AAGA,SAAO,IAAI,QAAQ;AACrB;;;;;;;;;;;;;;"}
|
package/dist/cjs/utils.d.cts
CHANGED
|
@@ -38,7 +38,7 @@ export declare function pick<TValue, TKey extends keyof TValue>(parent: TValue,
|
|
|
38
38
|
*/
|
|
39
39
|
export declare function replaceEqualDeep<T>(prev: any, _next: T): T;
|
|
40
40
|
export declare function isPlainObject(o: any): boolean;
|
|
41
|
-
export declare function isPlainArray(value: unknown):
|
|
41
|
+
export declare function isPlainArray(value: unknown): value is Array<unknown>;
|
|
42
42
|
export declare function deepEqual(a: any, b: any, partial?: boolean): boolean;
|
|
43
43
|
export declare function useStableCallback<T extends (...args: Array<any>) => any>(fn: T): T;
|
|
44
44
|
export declare function shallow<T>(objA: T, objB: T): boolean;
|
|
@@ -60,8 +60,9 @@ export type ControlledPromise<T> = Promise<T> & {
|
|
|
60
60
|
resolve: (value: T) => void;
|
|
61
61
|
reject: (value: any) => void;
|
|
62
62
|
status: 'pending' | 'resolved' | 'rejected';
|
|
63
|
+
value?: T;
|
|
63
64
|
};
|
|
64
|
-
export declare function createControlledPromise<T>(onResolve?: () => void): ControlledPromise<T>;
|
|
65
|
+
export declare function createControlledPromise<T>(onResolve?: (value: T) => void): ControlledPromise<T>;
|
|
65
66
|
/**
|
|
66
67
|
* Taken from https://www.developerway.com/posts/implementing-advanced-use-previous-hook#part3
|
|
67
68
|
*/
|
|
@@ -6,7 +6,7 @@ export declare function CatchBoundary(props: {
|
|
|
6
6
|
children: React.ReactNode;
|
|
7
7
|
errorComponent?: ErrorRouteComponent;
|
|
8
8
|
onCatch?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
9
|
-
}):
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
10
10
|
export declare function ErrorComponent({ error }: {
|
|
11
11
|
error: any;
|
|
12
|
-
}):
|
|
12
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import invariant from "tiny-invariant";
|
|
5
|
+
import warning from "tiny-warning";
|
|
6
|
+
import { ErrorComponent, CatchBoundary } from "./CatchBoundary.js";
|
|
7
|
+
import { useRouterState } from "./useRouterState.js";
|
|
8
|
+
import { useRouter } from "./useRouter.js";
|
|
9
|
+
import { pick, createControlledPromise } from "./utils.js";
|
|
10
|
+
import { isNotFound, CatchNotFound } from "./not-found.js";
|
|
11
|
+
import { isRedirect } from "./redirects.js";
|
|
12
|
+
import { matchContext } from "./matchContext.js";
|
|
13
|
+
import { isServerSideError, defaultDeserializeError } from "./isServerSideError.js";
|
|
14
|
+
import { SafeFragment } from "./SafeFragment.js";
|
|
15
|
+
import { renderRouteNotFound } from "./renderRouteNotFound.js";
|
|
16
|
+
import { rootRouteId } from "./root.js";
|
|
17
|
+
function Match({ matchId }) {
|
|
18
|
+
var _a, _b;
|
|
19
|
+
const router = useRouter();
|
|
20
|
+
const routeId = useRouterState({
|
|
21
|
+
select: (s) => {
|
|
22
|
+
var _a2;
|
|
23
|
+
return (_a2 = s.matches.find((d) => d.id === matchId)) == null ? void 0 : _a2.routeId;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
invariant(
|
|
27
|
+
routeId,
|
|
28
|
+
`Could not find routeId for matchId "${matchId}". Please file an issue!`
|
|
29
|
+
);
|
|
30
|
+
const route = router.routesById[routeId];
|
|
31
|
+
const PendingComponent = route.options.pendingComponent ?? router.options.defaultPendingComponent;
|
|
32
|
+
const pendingElement = PendingComponent ? /* @__PURE__ */ jsx(PendingComponent, {}) : null;
|
|
33
|
+
const routeErrorComponent = route.options.errorComponent ?? router.options.defaultErrorComponent;
|
|
34
|
+
const routeOnCatch = route.options.onCatch ?? router.options.defaultOnCatch;
|
|
35
|
+
const routeNotFoundComponent = route.isRoot ? (
|
|
36
|
+
// If it's the root route, use the globalNotFound option, with fallback to the notFoundRoute's component
|
|
37
|
+
route.options.notFoundComponent ?? ((_a = router.options.notFoundRoute) == null ? void 0 : _a.options.component)
|
|
38
|
+
) : route.options.notFoundComponent;
|
|
39
|
+
const ResolvedSuspenseBoundary = (
|
|
40
|
+
// If we're on the root route, allow forcefully wrapping in suspense
|
|
41
|
+
(!route.isRoot || route.options.wrapInSuspense) && (route.options.wrapInSuspense ?? PendingComponent ?? ((_b = route.options.errorComponent) == null ? void 0 : _b.preload)) ? React.Suspense : SafeFragment
|
|
42
|
+
);
|
|
43
|
+
const ResolvedCatchBoundary = routeErrorComponent ? CatchBoundary : SafeFragment;
|
|
44
|
+
const ResolvedNotFoundBoundary = routeNotFoundComponent ? CatchNotFound : SafeFragment;
|
|
45
|
+
const resetKey = useRouterState({
|
|
46
|
+
select: (s) => s.resolvedLocation.state.key
|
|
47
|
+
});
|
|
48
|
+
return /* @__PURE__ */ jsx(matchContext.Provider, { value: matchId, children: /* @__PURE__ */ jsx(ResolvedSuspenseBoundary, { fallback: pendingElement, children: /* @__PURE__ */ jsx(
|
|
49
|
+
ResolvedCatchBoundary,
|
|
50
|
+
{
|
|
51
|
+
getResetKey: () => resetKey,
|
|
52
|
+
errorComponent: routeErrorComponent || ErrorComponent,
|
|
53
|
+
onCatch: (error, errorInfo) => {
|
|
54
|
+
if (isNotFound(error)) throw error;
|
|
55
|
+
warning(false, `Error in route match: ${matchId}`);
|
|
56
|
+
routeOnCatch == null ? void 0 : routeOnCatch(error, errorInfo);
|
|
57
|
+
},
|
|
58
|
+
children: /* @__PURE__ */ jsx(
|
|
59
|
+
ResolvedNotFoundBoundary,
|
|
60
|
+
{
|
|
61
|
+
fallback: (error) => {
|
|
62
|
+
if (!routeNotFoundComponent || error.routeId && error.routeId !== routeId || !error.routeId && !route.isRoot)
|
|
63
|
+
throw error;
|
|
64
|
+
return React.createElement(routeNotFoundComponent, error);
|
|
65
|
+
},
|
|
66
|
+
children: /* @__PURE__ */ jsx(MatchInner, { matchId })
|
|
67
|
+
}
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
) }) });
|
|
71
|
+
}
|
|
72
|
+
function MatchInner({ matchId }) {
|
|
73
|
+
var _a, _b;
|
|
74
|
+
const router = useRouter();
|
|
75
|
+
const routeId = useRouterState({
|
|
76
|
+
select: (s) => {
|
|
77
|
+
var _a2;
|
|
78
|
+
return (_a2 = s.matches.find((d) => d.id === matchId)) == null ? void 0 : _a2.routeId;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
const route = router.routesById[routeId];
|
|
82
|
+
const [match, matchIndex] = useRouterState({
|
|
83
|
+
select: (s) => {
|
|
84
|
+
const matchIndex2 = s.matches.findIndex((d) => d.id === matchId);
|
|
85
|
+
const match2 = s.matches[matchIndex2];
|
|
86
|
+
return [
|
|
87
|
+
pick(match2, [
|
|
88
|
+
"id",
|
|
89
|
+
"status",
|
|
90
|
+
"error",
|
|
91
|
+
"loadPromise",
|
|
92
|
+
"minPendingPromise"
|
|
93
|
+
]),
|
|
94
|
+
matchIndex2
|
|
95
|
+
];
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
const RouteErrorComponent = (route.options.errorComponent ?? router.options.defaultErrorComponent) || ErrorComponent;
|
|
99
|
+
if (match.status === "notFound") {
|
|
100
|
+
let error;
|
|
101
|
+
if (isServerSideError(match.error)) {
|
|
102
|
+
const deserializeError = ((_a = router.options.errorSerializer) == null ? void 0 : _a.deserialize) ?? defaultDeserializeError;
|
|
103
|
+
error = deserializeError(match.error.data);
|
|
104
|
+
} else {
|
|
105
|
+
error = match.error;
|
|
106
|
+
}
|
|
107
|
+
invariant(isNotFound(error), "Expected a notFound error");
|
|
108
|
+
return renderRouteNotFound(router, route, error);
|
|
109
|
+
}
|
|
110
|
+
if (match.status === "redirected") {
|
|
111
|
+
invariant(isRedirect(match.error), "Expected a redirect error");
|
|
112
|
+
throw match.loadPromise;
|
|
113
|
+
}
|
|
114
|
+
if (match.status === "error") {
|
|
115
|
+
if (router.isServer) {
|
|
116
|
+
return /* @__PURE__ */ jsx(
|
|
117
|
+
RouteErrorComponent,
|
|
118
|
+
{
|
|
119
|
+
error: match.error,
|
|
120
|
+
info: {
|
|
121
|
+
componentStack: ""
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
if (isServerSideError(match.error)) {
|
|
127
|
+
const deserializeError = ((_b = router.options.errorSerializer) == null ? void 0 : _b.deserialize) ?? defaultDeserializeError;
|
|
128
|
+
throw deserializeError(match.error.data);
|
|
129
|
+
} else {
|
|
130
|
+
throw match.error;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (match.status === "pending") {
|
|
134
|
+
const pendingMinMs = route.options.pendingMinMs ?? router.options.defaultPendingMinMs;
|
|
135
|
+
if (pendingMinMs && !match.minPendingPromise) {
|
|
136
|
+
match.minPendingPromise = createControlledPromise();
|
|
137
|
+
if (!router.isServer) {
|
|
138
|
+
Promise.resolve().then(() => {
|
|
139
|
+
router.__store.setState((s) => ({
|
|
140
|
+
...s,
|
|
141
|
+
matches: s.matches.map(
|
|
142
|
+
(d) => d.id === match.id ? { ...d, minPendingPromise: createControlledPromise() } : d
|
|
143
|
+
)
|
|
144
|
+
}));
|
|
145
|
+
});
|
|
146
|
+
setTimeout(() => {
|
|
147
|
+
router.__store.setState((s) => {
|
|
148
|
+
return {
|
|
149
|
+
...s,
|
|
150
|
+
matches: s.matches.map(
|
|
151
|
+
(d) => {
|
|
152
|
+
var _a2;
|
|
153
|
+
return d.id === match.id ? {
|
|
154
|
+
...d,
|
|
155
|
+
minPendingPromise: ((_a2 = d.minPendingPromise) == null ? void 0 : _a2.resolve(), void 0)
|
|
156
|
+
} : d;
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
}, pendingMinMs);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
throw match.loadPromise;
|
|
165
|
+
}
|
|
166
|
+
const Comp = route.options.component ?? router.options.defaultComponent;
|
|
167
|
+
const out = Comp ? /* @__PURE__ */ jsx(Comp, {}) : /* @__PURE__ */ jsx(Outlet, {});
|
|
168
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
169
|
+
router.AfterEachMatch ? /* @__PURE__ */ jsx(router.AfterEachMatch, { match, matchIndex }) : null,
|
|
170
|
+
out
|
|
171
|
+
] });
|
|
172
|
+
}
|
|
173
|
+
const Outlet = React.memo(function Outlet2() {
|
|
174
|
+
const router = useRouter();
|
|
175
|
+
const matchId = React.useContext(matchContext);
|
|
176
|
+
const routeId = useRouterState({
|
|
177
|
+
select: (s) => {
|
|
178
|
+
var _a;
|
|
179
|
+
return (_a = s.matches.find((d) => d.id === matchId)) == null ? void 0 : _a.routeId;
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
const route = router.routesById[routeId];
|
|
183
|
+
const { parentGlobalNotFound } = useRouterState({
|
|
184
|
+
select: (s) => {
|
|
185
|
+
const matches = s.matches;
|
|
186
|
+
const parentMatch = matches.find((d) => d.id === matchId);
|
|
187
|
+
invariant(
|
|
188
|
+
parentMatch,
|
|
189
|
+
`Could not find parent match for matchId "${matchId}"`
|
|
190
|
+
);
|
|
191
|
+
return {
|
|
192
|
+
parentGlobalNotFound: parentMatch.globalNotFound
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
const childMatchId = useRouterState({
|
|
197
|
+
select: (s) => {
|
|
198
|
+
var _a;
|
|
199
|
+
const matches = s.matches;
|
|
200
|
+
const index = matches.findIndex((d) => d.id === matchId);
|
|
201
|
+
return (_a = matches[index + 1]) == null ? void 0 : _a.id;
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
if (parentGlobalNotFound) {
|
|
205
|
+
return renderRouteNotFound(router, route, void 0);
|
|
206
|
+
}
|
|
207
|
+
if (!childMatchId) {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
const nextMatch = /* @__PURE__ */ jsx(Match, { matchId: childMatchId });
|
|
211
|
+
const pendingElement = router.options.defaultPendingComponent ? /* @__PURE__ */ jsx(router.options.defaultPendingComponent, {}) : null;
|
|
212
|
+
if (matchId === rootRouteId) {
|
|
213
|
+
return /* @__PURE__ */ jsx(React.Suspense, { fallback: pendingElement, children: nextMatch });
|
|
214
|
+
}
|
|
215
|
+
return nextMatch;
|
|
216
|
+
});
|
|
217
|
+
export {
|
|
218
|
+
Match,
|
|
219
|
+
Outlet
|
|
220
|
+
};
|
|
221
|
+
//# sourceMappingURL=Match.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Match.js","sources":["../../src/Match.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport invariant from 'tiny-invariant'\nimport warning from 'tiny-warning'\nimport { CatchBoundary, ErrorComponent } from './CatchBoundary'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport { createControlledPromise, pick } from './utils'\nimport { CatchNotFound, isNotFound } from './not-found'\nimport { isRedirect } from './redirects'\nimport { type AnyRoute } from './route'\nimport { matchContext } from './matchContext'\nimport { defaultDeserializeError, isServerSideError } from './isServerSideError'\nimport { SafeFragment } from './SafeFragment'\nimport { renderRouteNotFound } from './renderRouteNotFound'\nimport { rootRouteId } from './root'\n\nexport function Match({ matchId }: { matchId: string }) {\n const router = useRouter()\n const routeId = useRouterState({\n select: (s) => s.matches.find((d) => d.id === matchId)?.routeId as string,\n })\n\n invariant(\n routeId,\n `Could not find routeId for matchId \"${matchId}\". Please file an issue!`,\n )\n\n const route: AnyRoute = router.routesById[routeId]\n\n const PendingComponent =\n route.options.pendingComponent ?? router.options.defaultPendingComponent\n\n const pendingElement = PendingComponent ? <PendingComponent /> : null\n\n const routeErrorComponent =\n route.options.errorComponent ?? router.options.defaultErrorComponent\n\n const routeOnCatch = route.options.onCatch ?? router.options.defaultOnCatch\n\n const routeNotFoundComponent = route.isRoot\n ? // If it's the root route, use the globalNotFound option, with fallback to the notFoundRoute's component\n route.options.notFoundComponent ??\n router.options.notFoundRoute?.options.component\n : route.options.notFoundComponent\n\n const ResolvedSuspenseBoundary =\n // If we're on the root route, allow forcefully wrapping in suspense\n (!route.isRoot || route.options.wrapInSuspense) &&\n (route.options.wrapInSuspense ??\n PendingComponent ??\n (route.options.errorComponent as any)?.preload)\n ? React.Suspense\n : SafeFragment\n\n const ResolvedCatchBoundary = routeErrorComponent\n ? CatchBoundary\n : SafeFragment\n\n const ResolvedNotFoundBoundary = routeNotFoundComponent\n ? CatchNotFound\n : SafeFragment\n\n const resetKey = useRouterState({\n select: (s) => s.resolvedLocation.state.key!,\n })\n\n return (\n <matchContext.Provider value={matchId}>\n <ResolvedSuspenseBoundary fallback={pendingElement}>\n <ResolvedCatchBoundary\n getResetKey={() => resetKey}\n errorComponent={routeErrorComponent || ErrorComponent}\n onCatch={(error, errorInfo) => {\n // Forward not found errors (we don't want to show the error component for these)\n if (isNotFound(error)) throw error\n warning(false, `Error in route match: ${matchId}`)\n routeOnCatch?.(error, errorInfo)\n }}\n >\n <ResolvedNotFoundBoundary\n fallback={(error) => {\n // If the current not found handler doesn't exist or it has a\n // route ID which doesn't match the current route, rethrow the error\n if (\n !routeNotFoundComponent ||\n (error.routeId && error.routeId !== routeId) ||\n (!error.routeId && !route.isRoot)\n )\n throw error\n\n return React.createElement(routeNotFoundComponent, error as any)\n }}\n >\n <MatchInner matchId={matchId} />\n </ResolvedNotFoundBoundary>\n </ResolvedCatchBoundary>\n </ResolvedSuspenseBoundary>\n </matchContext.Provider>\n )\n}\nfunction MatchInner({ matchId }: { matchId: string }): any {\n const router = useRouter()\n const routeId = useRouterState({\n select: (s) => s.matches.find((d) => d.id === matchId)?.routeId as string,\n })\n\n const route = router.routesById[routeId]!\n\n const [match, matchIndex] = useRouterState({\n select: (s) => {\n const matchIndex = s.matches.findIndex((d) => d.id === matchId)\n const match = s.matches[matchIndex]!\n return [\n pick(match, [\n 'id',\n 'status',\n 'error',\n 'loadPromise',\n 'minPendingPromise',\n ]),\n matchIndex,\n ] as const\n },\n })\n\n const RouteErrorComponent =\n (route.options.errorComponent ?? router.options.defaultErrorComponent) ||\n ErrorComponent\n\n if (match.status === 'notFound') {\n let error: unknown\n if (isServerSideError(match.error)) {\n const deserializeError =\n router.options.errorSerializer?.deserialize ?? defaultDeserializeError\n\n error = deserializeError(match.error.data)\n } else {\n error = match.error\n }\n\n invariant(isNotFound(error), 'Expected a notFound error')\n\n return renderRouteNotFound(router, route, error)\n }\n\n if (match.status === 'redirected') {\n // Redirects should be handled by the router transition. If we happen to\n // encounter a redirect here, it's a bug. Let's warn, but render nothing.\n invariant(isRedirect(match.error), 'Expected a redirect error')\n\n // warning(\n // false,\n // 'Tried to render a redirected route match! This is a weird circumstance, please file an issue!',\n // )\n throw match.loadPromise\n }\n\n if (match.status === 'error') {\n // If we're on the server, we need to use React's new and super\n // wonky api for throwing errors from a server side render inside\n // of a suspense boundary. This is the only way to get\n // renderToPipeableStream to not hang indefinitely.\n // We'll serialize the error and rethrow it on the client.\n if (router.isServer) {\n return (\n <RouteErrorComponent\n error={match.error}\n info={{\n componentStack: '',\n }}\n />\n )\n }\n\n if (isServerSideError(match.error)) {\n const deserializeError =\n router.options.errorSerializer?.deserialize ?? defaultDeserializeError\n throw deserializeError(match.error.data)\n } else {\n throw match.error\n }\n }\n\n if (match.status === 'pending') {\n // We're pending, and if we have a minPendingMs, we need to wait for it\n const pendingMinMs =\n route.options.pendingMinMs ?? router.options.defaultPendingMinMs\n\n if (pendingMinMs && !match.minPendingPromise) {\n // Create a promise that will resolve after the minPendingMs\n match.minPendingPromise = createControlledPromise()\n\n if (!router.isServer) {\n Promise.resolve().then(() => {\n router.__store.setState((s) => ({\n ...s,\n matches: s.matches.map((d) =>\n d.id === match.id\n ? { ...d, minPendingPromise: createControlledPromise() }\n : d,\n ),\n }))\n })\n\n setTimeout(() => {\n // We've handled the minPendingPromise, so we can delete it\n router.__store.setState((s) => {\n return {\n ...s,\n matches: s.matches.map((d) =>\n d.id === match.id\n ? {\n ...d,\n minPendingPromise:\n (d.minPendingPromise?.resolve(), undefined),\n }\n : d,\n ),\n }\n })\n }, pendingMinMs)\n }\n }\n\n throw match.loadPromise\n }\n\n const Comp = route.options.component ?? router.options.defaultComponent\n\n const out = Comp ? <Comp /> : <Outlet />\n\n return (\n <>\n {router.AfterEachMatch ? (\n <router.AfterEachMatch match={match} matchIndex={matchIndex} />\n ) : null}\n {out}\n </>\n )\n}\n\nexport const Outlet = React.memo(function Outlet() {\n const router = useRouter()\n const matchId = React.useContext(matchContext)\n const routeId = useRouterState({\n select: (s) => s.matches.find((d) => d.id === matchId)?.routeId as string,\n })\n\n const route = router.routesById[routeId]!\n\n const { parentGlobalNotFound } = useRouterState({\n select: (s) => {\n const matches = s.matches\n const parentMatch = matches.find((d) => d.id === matchId)\n invariant(\n parentMatch,\n `Could not find parent match for matchId \"${matchId}\"`,\n )\n return {\n parentGlobalNotFound: parentMatch.globalNotFound,\n }\n },\n })\n\n const childMatchId = useRouterState({\n select: (s) => {\n const matches = s.matches\n const index = matches.findIndex((d) => d.id === matchId)\n return matches[index + 1]?.id\n },\n })\n\n if (parentGlobalNotFound) {\n return renderRouteNotFound(router, route, undefined)\n }\n\n if (!childMatchId) {\n return null\n }\n\n const nextMatch = <Match matchId={childMatchId} />\n\n const pendingElement = router.options.defaultPendingComponent ? (\n <router.options.defaultPendingComponent />\n ) : null\n\n if (matchId === rootRouteId) {\n return (\n <React.Suspense fallback={pendingElement}>{nextMatch}</React.Suspense>\n )\n }\n\n return nextMatch\n})\n"],"names":["matchIndex","match"],"mappings":";;;;;;;;;;;;;;;;AAkBgB;;AACd;AACA;AAA+B;;AACd;AAAyC;AAAA;AAG1D;AAAA;AACE;AAC8C;AAG1C;AAEN;AAGA;AAEA;AAGA;AAEA;AAAqC;AAAA;AAGK;AAGpC;AAAA;AAAA;AAOA;AAEA;AAIA;AAIN;AAAgC;AACU;AAIxC;AAEI;AAAC;AAAA;AACoB;AACoB;AAGjC;AACI;AACR;AAAsB;AACxB;AAEA;AAAC;AAAA;AAKK;AAIM;AAED;AAAwD;AACjE;AAE8B;AAAA;AAChC;AAAA;AAKV;AACA;;AACE;AACA;AAA+B;;AACd;AAAyC;AAAA;AAGpD;AAEN;AAA2C;AAEjCA;AACAC;AACC;AAAA;AACO;AACV;AACA;AACA;AACA;AACA;AACD;AACDD;AAAA;AAEJ;AAGF;AAII;AACE;AACA;AACF;AAGQ;AAAiC;AAEzC;AAAc;AAGN;AAEH;AAAwC;AAG7C;AAGF;AAMA;AAAY;AAGV;AAMF;AAEI;AAAA;AAAC;AAAA;AACc;AACP;AACY;AAClB;AAAA;AAAA;AAKF;AACF;AAEM;AAAiC;AAEvC;AAAY;AACd;AAGE;AAEF;AAGI;AAEF;AAEI;AACM;AACC;AAAyB;AAC3B;AACgB;AAGb;AACN;AACA;AAGJ;AAES;AACE;AAAA;AACF;AACgB;;AACjB;AACI;AACK;AAEgC;AAErC;AAAA;AACN;AAAA;AAEH;AACY;AACjB;AAGF;AAAY;AAGd;AAEA;AAEA;AAEK;AAEG;AACH;AAGP;AAEO;AACL;AACM;AACN;AAA+B;;AACd;AAAyC;AAAA;AAGpD;AAEA;AAA0C;AAE5C;AACA;AACA;AAAA;AACE;AACmD;AAE9C;AAAA;AAC6B;AAAA;AAEtC;AAGF;AAAoC;;AAEhC;AACA;AACO;AAAoB;AAC7B;AAGF;AACS;AAA4C;AAGrD;AACS;AAAA;AAGT;AAEM;AAIN;AACE;AACuD;AAIlD;AACT;;;;;"}
|
package/dist/esm/Matches.d.ts
CHANGED
|
@@ -4,10 +4,10 @@ import { ResolveRelativePath, ToOptions } from './link.js';
|
|
|
4
4
|
import { AllContext, AllLoaderData, AllParams, FullSearchSchema, ParseRoute, RouteById, RouteByPath, RouteIds, RoutePaths } from './routeInfo.js';
|
|
5
5
|
import { ControlledPromise, DeepPartial, NoInfer } from './utils.js';
|
|
6
6
|
import * as React from 'react';
|
|
7
|
-
export declare const matchContext: React.Context<string | undefined>;
|
|
8
7
|
export interface RouteMatch<TRouteId, TAllParams, TFullSearchSchema, TLoaderData, TAllContext, TRouteContext, TLoaderDeps> {
|
|
9
8
|
id: string;
|
|
10
9
|
routeId: TRouteId;
|
|
10
|
+
index: number;
|
|
11
11
|
pathname: string;
|
|
12
12
|
params: TAllParams;
|
|
13
13
|
status: 'pending' | 'success' | 'error' | 'redirected' | 'notFound';
|
|
@@ -38,11 +38,7 @@ export interface RouteMatch<TRouteId, TAllParams, TFullSearchSchema, TLoaderData
|
|
|
38
38
|
}
|
|
39
39
|
export type MakeRouteMatch<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TRouteId = ParseRoute<TRouteTree>['id'], TStrict extends boolean = true, TTypes extends AnyRoute['types'] = RouteById<TRouteTree, TRouteId>['types'], TAllParams = TStrict extends false ? AllParams<TRouteTree> : TTypes['allParams'], TFullSearchSchema = TStrict extends false ? FullSearchSchema<TRouteTree> : TTypes['fullSearchSchema'], TLoaderData = TStrict extends false ? AllLoaderData<TRouteTree> : TTypes['loaderData'], TAllContext = TStrict extends false ? AllContext<TRouteTree> : TTypes['allContext'], TRouteContext = TTypes['routeContext'], TLoaderDeps = TTypes['loaderDeps']> = RouteMatch<TRouteId, TAllParams, TFullSearchSchema, TLoaderData, TAllContext, TRouteContext, TLoaderDeps>;
|
|
40
40
|
export type AnyRouteMatch = RouteMatch<any, any, any, any, any, any, any>;
|
|
41
|
-
export declare function Matches():
|
|
42
|
-
export declare function Match({ matchId }: {
|
|
43
|
-
matchId: string;
|
|
44
|
-
}): React.JSX.Element;
|
|
45
|
-
export declare const Outlet: React.NamedExoticComponent<object>;
|
|
41
|
+
export declare function Matches(): import("react/jsx-runtime").JSX.Element;
|
|
46
42
|
export interface MatchRouteOptions {
|
|
47
43
|
pending?: boolean;
|
|
48
44
|
caseSensitive?: boolean;
|
|
@@ -64,8 +60,3 @@ export declare function useParentMatches<TRouteTree extends AnyRoute = Registere
|
|
|
64
60
|
export declare function useChildMatches<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TRouteId extends RouteIds<TRouteTree> = ParseRoute<TRouteTree>['id'], TRouteMatch = MakeRouteMatch<TRouteTree, TRouteId>, T = Array<TRouteMatch>>(opts?: {
|
|
65
61
|
select?: (matches: Array<TRouteMatch>) => T;
|
|
66
62
|
}): T;
|
|
67
|
-
export declare function isServerSideError(error: unknown): error is {
|
|
68
|
-
__isServerError: true;
|
|
69
|
-
data: Record<string, any>;
|
|
70
|
-
};
|
|
71
|
-
export declare function defaultDeserializeError(serializedData: Record<string, any>): any;
|