@tanstack/react-router 1.97.20 → 1.97.21
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/Match.cjs +4 -5
- package/dist/cjs/Match.cjs.map +1 -1
- package/dist/cjs/Matches.cjs +0 -10
- package/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/Matches.d.cts +3 -30
- package/dist/cjs/RouterProvider.cjs.map +1 -1
- package/dist/cjs/RouterProvider.d.cts +2 -2
- package/dist/cjs/Transitioner.cjs +2 -2
- package/dist/cjs/Transitioner.cjs.map +1 -1
- package/dist/cjs/awaited.cjs +6 -6
- package/dist/cjs/awaited.cjs.map +1 -1
- package/dist/cjs/awaited.d.cts +1 -1
- package/dist/cjs/fileRoute.cjs.map +1 -1
- package/dist/cjs/fileRoute.d.cts +2 -3
- package/dist/cjs/index.cjs +136 -42
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +12 -26
- package/dist/cjs/link.cjs +8 -9
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/link.d.cts +2 -49
- package/dist/cjs/redirects.cjs.map +1 -1
- package/dist/cjs/redirects.d.cts +1 -1
- package/dist/cjs/route.cjs +14 -15
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +2 -149
- package/dist/cjs/routeInfo.d.cts +2 -3
- package/dist/cjs/router.cjs +51 -70
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +4 -19
- package/dist/cjs/routerContext.d.cts +1 -1
- package/dist/cjs/scroll-restoration.cjs +2 -2
- package/dist/cjs/scroll-restoration.cjs.map +1 -1
- package/dist/cjs/scroll-restoration.d.cts +1 -1
- package/dist/cjs/structuralSharing.d.cts +1 -4
- package/dist/cjs/typePrimitives.d.cts +1 -1
- package/dist/cjs/useLoaderData.cjs.map +1 -1
- package/dist/cjs/useLoaderData.d.cts +2 -1
- package/dist/cjs/useLoaderDeps.cjs.map +1 -1
- package/dist/cjs/useLoaderDeps.d.cts +2 -1
- package/dist/cjs/useMatch.cjs.map +1 -1
- package/dist/cjs/useMatch.d.cts +2 -1
- package/dist/cjs/useParams.cjs.map +1 -1
- package/dist/cjs/useParams.d.cts +2 -1
- package/dist/cjs/useRouteContext.cjs.map +1 -1
- package/dist/cjs/useRouteContext.d.cts +2 -1
- package/dist/cjs/useRouterState.cjs +2 -2
- package/dist/cjs/useRouterState.cjs.map +1 -1
- package/dist/cjs/useSearch.cjs.map +1 -1
- package/dist/cjs/useSearch.d.cts +2 -1
- package/dist/cjs/utils.cjs +0 -152
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +1 -81
- package/dist/esm/Match.js +1 -2
- package/dist/esm/Match.js.map +1 -1
- package/dist/esm/Matches.d.ts +3 -30
- package/dist/esm/Matches.js +0 -10
- 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/Transitioner.js +1 -1
- package/dist/esm/Transitioner.js.map +1 -1
- package/dist/esm/awaited.d.ts +1 -1
- package/dist/esm/awaited.js +1 -1
- package/dist/esm/awaited.js.map +1 -1
- package/dist/esm/fileRoute.d.ts +2 -3
- package/dist/esm/fileRoute.js.map +1 -1
- package/dist/esm/index.d.ts +12 -26
- package/dist/esm/index.js +5 -10
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/link.d.ts +2 -49
- package/dist/esm/link.js +2 -3
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/redirects.d.ts +1 -1
- package/dist/esm/redirects.js.map +1 -1
- package/dist/esm/route.d.ts +2 -149
- package/dist/esm/route.js +1 -2
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/routeInfo.d.ts +2 -3
- package/dist/esm/router.d.ts +4 -19
- package/dist/esm/router.js +1 -20
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/routerContext.d.ts +1 -1
- package/dist/esm/scroll-restoration.d.ts +1 -1
- package/dist/esm/scroll-restoration.js +1 -1
- package/dist/esm/scroll-restoration.js.map +1 -1
- package/dist/esm/structuralSharing.d.ts +1 -4
- package/dist/esm/typePrimitives.d.ts +1 -1
- package/dist/esm/useLoaderData.d.ts +2 -1
- package/dist/esm/useLoaderData.js.map +1 -1
- package/dist/esm/useLoaderDeps.d.ts +2 -1
- package/dist/esm/useLoaderDeps.js.map +1 -1
- package/dist/esm/useMatch.d.ts +2 -1
- package/dist/esm/useMatch.js.map +1 -1
- package/dist/esm/useParams.d.ts +2 -1
- package/dist/esm/useParams.js.map +1 -1
- package/dist/esm/useRouteContext.d.ts +2 -1
- package/dist/esm/useRouteContext.js.map +1 -1
- package/dist/esm/useRouterState.js +1 -1
- package/dist/esm/useRouterState.js.map +1 -1
- package/dist/esm/useSearch.d.ts +2 -1
- package/dist/esm/useSearch.js.map +1 -1
- package/dist/esm/utils.d.ts +1 -81
- package/dist/esm/utils.js +0 -152
- package/dist/esm/utils.js.map +1 -1
- package/package.json +3 -2
- package/src/Match.tsx +5 -2
- package/src/Matches.tsx +8 -101
- package/src/RouterProvider.tsx +4 -2
- package/src/Transitioner.tsx +1 -1
- package/src/awaited.tsx +2 -2
- package/src/fileRoute.ts +6 -3
- package/src/index.tsx +128 -128
- package/src/link.tsx +27 -155
- package/src/redirects.ts +1 -1
- package/src/route.ts +41 -315
- package/src/routeInfo.ts +7 -3
- package/src/router.ts +32 -52
- package/src/scroll-restoration.tsx +2 -3
- package/src/structuralSharing.ts +5 -7
- package/src/typePrimitives.ts +1 -1
- package/src/useLoaderData.tsx +2 -1
- package/src/useLoaderDeps.tsx +2 -1
- package/src/useMatch.tsx +2 -1
- package/src/useParams.tsx +2 -1
- package/src/useRouteContext.ts +2 -1
- package/src/useRouterState.tsx +1 -1
- package/src/useSearch.tsx +2 -1
- package/src/utils.ts +1 -405
- package/dist/cjs/defer.cjs +0 -25
- package/dist/cjs/defer.cjs.map +0 -1
- package/dist/cjs/defer.d.cts +0 -20
- package/dist/cjs/location.d.cts +0 -12
- package/dist/cjs/manifest.d.cts +0 -24
- package/dist/cjs/path.cjs +0 -289
- package/dist/cjs/path.cjs.map +0 -1
- package/dist/cjs/path.d.cts +0 -34
- package/dist/cjs/qss.cjs +0 -51
- package/dist/cjs/qss.cjs.map +0 -1
- package/dist/cjs/qss.d.cts +0 -27
- package/dist/cjs/root.cjs +0 -5
- package/dist/cjs/root.cjs.map +0 -1
- package/dist/cjs/root.d.cts +0 -2
- package/dist/cjs/searchMiddleware.cjs +0 -42
- package/dist/cjs/searchMiddleware.cjs.map +0 -1
- package/dist/cjs/searchMiddleware.d.cts +0 -5
- package/dist/cjs/searchParams.cjs +0 -61
- package/dist/cjs/searchParams.cjs.map +0 -1
- package/dist/cjs/searchParams.d.cts +0 -7
- package/dist/cjs/serializer.d.cts +0 -15
- package/dist/cjs/validators.d.cts +0 -51
- package/dist/esm/defer.d.ts +0 -20
- package/dist/esm/defer.js +0 -25
- package/dist/esm/defer.js.map +0 -1
- package/dist/esm/location.d.ts +0 -12
- package/dist/esm/manifest.d.ts +0 -24
- package/dist/esm/path.d.ts +0 -34
- package/dist/esm/path.js +0 -289
- package/dist/esm/path.js.map +0 -1
- package/dist/esm/qss.d.ts +0 -27
- package/dist/esm/qss.js +0 -51
- package/dist/esm/qss.js.map +0 -1
- package/dist/esm/root.d.ts +0 -2
- package/dist/esm/root.js +0 -5
- package/dist/esm/root.js.map +0 -1
- package/dist/esm/searchMiddleware.d.ts +0 -5
- package/dist/esm/searchMiddleware.js +0 -42
- package/dist/esm/searchMiddleware.js.map +0 -1
- package/dist/esm/searchParams.d.ts +0 -7
- package/dist/esm/searchParams.js +0 -61
- package/dist/esm/searchParams.js.map +0 -1
- package/dist/esm/serializer.d.ts +0 -15
- package/dist/esm/validators.d.ts +0 -51
- package/src/defer.ts +0 -52
- package/src/location.ts +0 -13
- package/src/manifest.ts +0 -32
- package/src/path.ts +0 -427
- package/src/qss.ts +0 -91
- package/src/root.ts +0 -2
- package/src/searchMiddleware.ts +0 -54
- package/src/searchParams.ts +0 -77
- package/src/serializer.ts +0 -24
- package/src/validators.ts +0 -121
package/dist/esm/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import * as React from 'react'\nimport type { RouteIds } from './routeInfo'\nimport type { AnyRouter } from './router'\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\n\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\nexport type PickOptional<T> = {\n [K in keyof T as undefined extends T[K] ? K : never]: 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 IsNonEmptyObject<T> = T extends object\n ? keyof T extends never\n ? false\n : true\n : false\n\nexport type Assign<TLeft, TRight> = TLeft extends any\n ? TRight extends any\n ? IsNonEmptyObject<TLeft> extends false\n ? TRight\n : IsNonEmptyObject<TRight> extends false\n ? TLeft\n : keyof TLeft & keyof TRight extends never\n ? TLeft & TRight\n : Omit<TLeft, keyof TRight> & TRight\n : never\n : never\n\nexport type IntersectAssign<TLeft, TRight> = TLeft extends any\n ? TRight extends any\n ? IsNonEmptyObject<TLeft> extends false\n ? TRight\n : IsNonEmptyObject<TRight> extends false\n ? TLeft\n : TRight & TLeft\n : never\n : never\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 ExtractObjects<TUnion> = TUnion extends MergeAllPrimitive\n ? never\n : TUnion\n\nexport type PartialMergeAllObject<TUnion> =\n ExtractObjects<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 MergeAllPrimitive =\n | ReadonlyArray<any>\n | number\n | string\n | bigint\n | boolean\n | symbol\n | undefined\n | null\n\nexport type ExtractPrimitives<TUnion> = TUnion extends MergeAllPrimitive\n ? TUnion\n : TUnion extends object\n ? never\n : TUnion\n\nexport type PartialMergeAll<TUnion> =\n | ExtractPrimitives<TUnion>\n | PartialMergeAllObject<TUnion>\n\nexport type Constrain<T, TConstraint, TDefault = TConstraint> =\n | (T extends TConstraint ? T : never)\n | TDefault\n\nexport type ConstrainLiteral<T, TConstraint, TDefault = TConstraint> =\n | (T & TConstraint)\n | TDefault\n\n/**\n * To be added to router types\n */\nexport type UnionToIntersection<T> = (\n T extends any ? (arg: T) => any : never\n) extends (arg: infer T) => any\n ? T\n : never\n\n/**\n * Merges everything in a union into one object.\n * This mapped type is homomorphic which means it preserves stuff! :)\n */\nexport type MergeAllObjects<\n TUnion,\n TIntersected = UnionToIntersection<ExtractObjects<TUnion>>,\n> = [keyof TIntersected] extends [never]\n ? never\n : {\n [TKey in keyof TIntersected]: TUnion extends any\n ? TUnion[TKey & keyof TUnion]\n : never\n }\n\nexport type MergeAll<TUnion> =\n | MergeAllObjects<TUnion>\n | ExtractPrimitives<TUnion>\n\nexport type ValidateJSON<T> = ((...args: Array<any>) => any) extends T\n ? unknown extends T\n ? never\n : 'Function is not serializable'\n : { [K in keyof T]: ValidateJSON<T[K]> }\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<TPrevious, TResult = TPrevious>(\n updater: Updater<TPrevious, TResult> | NonNullableUpdater<TPrevious, TResult>,\n previous: TPrevious,\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\nfunction getObjectKeys(obj: any, ignoreUndefined: boolean) {\n let keys = Object.keys(obj)\n if (ignoreUndefined) {\n keys = keys.filter((key) => obj[key] !== undefined)\n }\n return keys\n}\n\nexport function deepEqual(\n a: any,\n b: any,\n opts?: { partial?: boolean; ignoreUndefined?: boolean },\n): 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 ignoreUndefined = opts?.ignoreUndefined ?? true\n const aKeys = getObjectKeys(a, ignoreUndefined)\n const bKeys = getObjectKeys(b, ignoreUndefined)\n\n if (!opts?.partial && aKeys.length !== bKeys.length) {\n return false\n }\n\n return bKeys.every((key) => deepEqual(a[key], b[key], opts))\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false\n }\n return !a.some((item, index) => !deepEqual(item, b[index], opts))\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 TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean = true,\n> = TStrict extends false\n ? {\n from?: never\n strict: TStrict\n }\n : {\n from: ConstrainLiteral<TFrom, RouteIds<TRouter['routeTree']>>\n strict?: TStrict\n }\n\nexport type ThrowOrOptional<T, TThrow extends boolean> = TThrow extends true\n ? T\n : T | undefined\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\n/**\n * React hook to wrap `IntersectionObserver`.\n *\n * This hook will create an `IntersectionObserver` and observe the ref passed to it.\n *\n * When the intersection changes, the callback will be called with the `IntersectionObserverEntry`.\n *\n * @param ref - The ref to observe\n * @param intersectionObserverOptions - The options to pass to the IntersectionObserver\n * @param options - The options to pass to the hook\n * @param callback - The callback to call when the intersection changes\n * @returns The IntersectionObserver instance\n * @example\n * ```tsx\n * const MyComponent = () => {\n * const ref = React.useRef<HTMLDivElement>(null)\n * useIntersectionObserver(\n * ref,\n * (entry) => { doSomething(entry) },\n * { rootMargin: '10px' },\n * { disabled: false }\n * )\n * return <div ref={ref} />\n * ```\n */\nexport function useIntersectionObserver<T extends Element>(\n ref: React.RefObject<T | null>,\n callback: (entry: IntersectionObserverEntry | undefined) => void,\n intersectionObserverOptions: IntersectionObserverInit = {},\n options: { disabled?: boolean } = {},\n): IntersectionObserver | null {\n const isIntersectionObserverAvailable = React.useRef(\n typeof IntersectionObserver === 'function',\n )\n\n const observerRef = React.useRef<IntersectionObserver | null>(null)\n\n React.useEffect(() => {\n if (\n !ref.current ||\n !isIntersectionObserverAvailable.current ||\n options.disabled\n ) {\n return\n }\n\n observerRef.current = new IntersectionObserver(([entry]) => {\n callback(entry)\n }, intersectionObserverOptions)\n\n observerRef.current.observe(ref.current)\n\n return () => {\n observerRef.current?.disconnect()\n }\n }, [callback, intersectionObserverOptions, options.disabled, ref])\n\n return observerRef.current\n}\n\n/**\n * React hook to take a `React.ForwardedRef` and returns a `ref` that can be used on a DOM element.\n *\n * @param ref - The forwarded ref\n * @returns The inner ref returned by `useRef`\n * @example\n * ```tsx\n * const MyComponent = React.forwardRef((props, ref) => {\n * const innerRef = useForwardedRef(ref)\n * return <div ref={innerRef} />\n * })\n * ```\n */\nexport function useForwardedRef<T>(ref?: React.ForwardedRef<T>) {\n const innerRef = React.useRef<T>(null)\n\n React.useEffect(() => {\n if (!ref) return\n if (typeof ref === 'function') {\n ref(innerRef.current)\n } else {\n ref.current = innerRef.current\n }\n })\n\n return innerRef\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import * as React from 'react'\nimport type { RouteIds } from './routeInfo'\nimport type { AnyRouter } from './router'\nimport type { ConstrainLiteral } from '@tanstack/router-core'\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 type StrictOrFrom<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean = true,\n> = TStrict extends false\n ? {\n from?: never\n strict: TStrict\n }\n : {\n from: ConstrainLiteral<TFrom, RouteIds<TRouter['routeTree']>>\n strict?: TStrict\n }\n\nexport const useLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\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\n/**\n * React hook to wrap `IntersectionObserver`.\n *\n * This hook will create an `IntersectionObserver` and observe the ref passed to it.\n *\n * When the intersection changes, the callback will be called with the `IntersectionObserverEntry`.\n *\n * @param ref - The ref to observe\n * @param intersectionObserverOptions - The options to pass to the IntersectionObserver\n * @param options - The options to pass to the hook\n * @param callback - The callback to call when the intersection changes\n * @returns The IntersectionObserver instance\n * @example\n * ```tsx\n * const MyComponent = () => {\n * const ref = React.useRef<HTMLDivElement>(null)\n * useIntersectionObserver(\n * ref,\n * (entry) => { doSomething(entry) },\n * { rootMargin: '10px' },\n * { disabled: false }\n * )\n * return <div ref={ref} />\n * ```\n */\nexport function useIntersectionObserver<T extends Element>(\n ref: React.RefObject<T | null>,\n callback: (entry: IntersectionObserverEntry | undefined) => void,\n intersectionObserverOptions: IntersectionObserverInit = {},\n options: { disabled?: boolean } = {},\n): IntersectionObserver | null {\n const isIntersectionObserverAvailable = React.useRef(\n typeof IntersectionObserver === 'function',\n )\n\n const observerRef = React.useRef<IntersectionObserver | null>(null)\n\n React.useEffect(() => {\n if (\n !ref.current ||\n !isIntersectionObserverAvailable.current ||\n options.disabled\n ) {\n return\n }\n\n observerRef.current = new IntersectionObserver(([entry]) => {\n callback(entry)\n }, intersectionObserverOptions)\n\n observerRef.current.observe(ref.current)\n\n return () => {\n observerRef.current?.disconnect()\n }\n }, [callback, intersectionObserverOptions, options.disabled, ref])\n\n return observerRef.current\n}\n\n/**\n * React hook to take a `React.ForwardedRef` and returns a `ref` that can be used on a DOM element.\n *\n * @param ref - The forwarded ref\n * @returns The inner ref returned by `useRef`\n * @example\n * ```tsx\n * const MyComponent = React.forwardRef((props, ref) => {\n * const innerRef = useForwardedRef(ref)\n * return <div ref={innerRef} />\n * })\n * ```\n */\nexport function useForwardedRef<T>(ref?: React.ForwardedRef<T>) {\n const innerRef = React.useRef<T>(null)\n\n React.useEffect(() => {\n if (!ref) return\n if (typeof ref === 'function') {\n ref(innerRef.current)\n } else {\n ref.current = innerRef.current\n }\n })\n\n return innerRef\n}\n"],"names":[],"mappings":";AAKO,SAAS,kBACd,IACG;AACG,QAAA,QAAQ,MAAM,OAAO,EAAE;AAC7B,QAAM,UAAU;AAEV,QAAA,MAAM,MAAM,OAAO,IAAI,SAAqB,MAAM,QAAQ,GAAG,IAAI,CAAC;AACxE,SAAO,IAAI;AACb;AAgBO,MAAM,kBACX,OAAO,WAAW,cAAc,MAAM,kBAAkB,MAAM;AAKzD,SAAS,YAAe,OAAoB;AAE3C,QAAA,MAAM,MAAM,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,IACR;AAAA,EAAA;AAIF,SAAO,IAAI,QAAQ;AACrB;AA2BgB,SAAA,wBACd,KACA,UACA,8BAAwD,CACxD,GAAA,UAAkC,IACL;AAC7B,QAAM,kCAAkC,MAAM;AAAA,IAC5C,OAAO,yBAAyB;AAAA,EAClC;AAEM,QAAA,cAAc,MAAM,OAAoC,IAAI;AAElE,QAAM,UAAU,MAAM;AACpB,QACE,CAAC,IAAI,WACL,CAAC,gCAAgC,WACjC,QAAQ,UACR;AACA;AAAA,IAAA;AAGF,gBAAY,UAAU,IAAI,qBAAqB,CAAC,CAAC,KAAK,MAAM;AAC1D,eAAS,KAAK;AAAA,OACb,2BAA2B;AAElB,gBAAA,QAAQ,QAAQ,IAAI,OAAO;AAEvC,WAAO,MAAM;;AACX,wBAAY,YAAZ,mBAAqB;AAAA,IACvB;AAAA,EAAA,GACC,CAAC,UAAU,6BAA6B,QAAQ,UAAU,GAAG,CAAC;AAEjE,SAAO,YAAY;AACrB;AAeO,SAAS,gBAAmB,KAA6B;AACxD,QAAA,WAAW,MAAM,OAAU,IAAI;AAErC,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,IAAK;AACN,QAAA,OAAO,QAAQ,YAAY;AAC7B,UAAI,SAAS,OAAO;AAAA,IAAA,OACf;AACL,UAAI,UAAU,SAAS;AAAA,IAAA;AAAA,EACzB,CACD;AAEM,SAAA;AACT;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/react-router",
|
|
3
|
-
"version": "1.97.
|
|
3
|
+
"version": "1.97.21",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -53,7 +53,8 @@
|
|
|
53
53
|
"jsesc": "^3.1.0",
|
|
54
54
|
"tiny-invariant": "^1.3.3",
|
|
55
55
|
"tiny-warning": "^1.0.3",
|
|
56
|
-
"@tanstack/history": "1.97.8"
|
|
56
|
+
"@tanstack/history": "1.97.8",
|
|
57
|
+
"@tanstack/router-core": "^1.97.21"
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
59
60
|
"@testing-library/jest-dom": "^6.6.3",
|
package/src/Match.tsx
CHANGED
|
@@ -3,16 +3,19 @@
|
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
import invariant from 'tiny-invariant'
|
|
5
5
|
import warning from 'tiny-warning'
|
|
6
|
+
import {
|
|
7
|
+
createControlledPromise,
|
|
8
|
+
pick,
|
|
9
|
+
rootRouteId,
|
|
10
|
+
} from '@tanstack/router-core'
|
|
6
11
|
import { CatchBoundary, ErrorComponent } from './CatchBoundary'
|
|
7
12
|
import { useRouterState } from './useRouterState'
|
|
8
13
|
import { useRouter } from './useRouter'
|
|
9
|
-
import { createControlledPromise, pick } from './utils'
|
|
10
14
|
import { CatchNotFound, isNotFound } from './not-found'
|
|
11
15
|
import { isRedirect } from './redirects'
|
|
12
16
|
import { matchContext } from './matchContext'
|
|
13
17
|
import { SafeFragment } from './SafeFragment'
|
|
14
18
|
import { renderRouteNotFound } from './renderRouteNotFound'
|
|
15
|
-
import { rootRouteId } from './root'
|
|
16
19
|
import type { AnyRoute } from './route'
|
|
17
20
|
|
|
18
21
|
export const Match = React.memo(function MatchImpl({
|
package/src/Matches.tsx
CHANGED
|
@@ -11,13 +11,19 @@ import type {
|
|
|
11
11
|
StructuralSharingOption,
|
|
12
12
|
ValidateSelected,
|
|
13
13
|
} from './structuralSharing'
|
|
14
|
-
import type { AnyRoute, ReactNode
|
|
14
|
+
import type { AnyRoute, ReactNode } from './route'
|
|
15
|
+
import type {
|
|
16
|
+
ControlledPromise,
|
|
17
|
+
DeepPartial,
|
|
18
|
+
NoInfer,
|
|
19
|
+
ResolveRelativePath,
|
|
20
|
+
StaticDataRouteOption,
|
|
21
|
+
} from '@tanstack/router-core'
|
|
15
22
|
import type { AnyRouter, RegisteredRouter, RouterState } from './router'
|
|
16
23
|
import type {
|
|
17
24
|
MakeOptionalPathParams,
|
|
18
25
|
MakeOptionalSearchParams,
|
|
19
26
|
MaskOptions,
|
|
20
|
-
ResolveRelativePath,
|
|
21
27
|
ResolveRoute,
|
|
22
28
|
ToSubOptionsProps,
|
|
23
29
|
} from './link'
|
|
@@ -31,105 +37,6 @@ import type {
|
|
|
31
37
|
RouteByPath,
|
|
32
38
|
RouteIds,
|
|
33
39
|
} from './routeInfo'
|
|
34
|
-
import type {
|
|
35
|
-
Constrain,
|
|
36
|
-
ControlledPromise,
|
|
37
|
-
DeepPartial,
|
|
38
|
-
NoInfer,
|
|
39
|
-
} from './utils'
|
|
40
|
-
|
|
41
|
-
export type AnyMatchAndValue = { match: any; value: any }
|
|
42
|
-
|
|
43
|
-
export type FindValueByIndex<
|
|
44
|
-
TKey,
|
|
45
|
-
TValue extends ReadonlyArray<any>,
|
|
46
|
-
> = TKey extends `${infer TIndex extends number}` ? TValue[TIndex] : never
|
|
47
|
-
|
|
48
|
-
export type FindValueByKey<TKey, TValue> =
|
|
49
|
-
TValue extends ReadonlyArray<any>
|
|
50
|
-
? FindValueByIndex<TKey, TValue>
|
|
51
|
-
: TValue[TKey & keyof TValue]
|
|
52
|
-
|
|
53
|
-
export type CreateMatchAndValue<TMatch, TValue> = TValue extends any
|
|
54
|
-
? {
|
|
55
|
-
match: TMatch
|
|
56
|
-
value: TValue
|
|
57
|
-
}
|
|
58
|
-
: never
|
|
59
|
-
|
|
60
|
-
export type NextMatchAndValue<
|
|
61
|
-
TKey,
|
|
62
|
-
TMatchAndValue extends AnyMatchAndValue,
|
|
63
|
-
> = TMatchAndValue extends any
|
|
64
|
-
? CreateMatchAndValue<
|
|
65
|
-
TMatchAndValue['match'],
|
|
66
|
-
FindValueByKey<TKey, TMatchAndValue['value']>
|
|
67
|
-
>
|
|
68
|
-
: never
|
|
69
|
-
|
|
70
|
-
export type IsMatchKeyOf<TValue> =
|
|
71
|
-
TValue extends ReadonlyArray<any>
|
|
72
|
-
? number extends TValue['length']
|
|
73
|
-
? `${number}`
|
|
74
|
-
: keyof TValue & `${number}`
|
|
75
|
-
: TValue extends object
|
|
76
|
-
? keyof TValue & string
|
|
77
|
-
: never
|
|
78
|
-
|
|
79
|
-
export type IsMatchPath<
|
|
80
|
-
TParentPath extends string,
|
|
81
|
-
TMatchAndValue extends AnyMatchAndValue,
|
|
82
|
-
> = `${TParentPath}${IsMatchKeyOf<TMatchAndValue['value']>}`
|
|
83
|
-
|
|
84
|
-
export type IsMatchResult<
|
|
85
|
-
TKey,
|
|
86
|
-
TMatchAndValue extends AnyMatchAndValue,
|
|
87
|
-
> = TMatchAndValue extends any
|
|
88
|
-
? TKey extends keyof TMatchAndValue['value']
|
|
89
|
-
? TMatchAndValue['match']
|
|
90
|
-
: never
|
|
91
|
-
: never
|
|
92
|
-
|
|
93
|
-
export type IsMatchParse<
|
|
94
|
-
TPath,
|
|
95
|
-
TMatchAndValue extends AnyMatchAndValue,
|
|
96
|
-
TParentPath extends string = '',
|
|
97
|
-
> = TPath extends `${string}.${string}`
|
|
98
|
-
? TPath extends `${infer TFirst}.${infer TRest}`
|
|
99
|
-
? IsMatchParse<
|
|
100
|
-
TRest,
|
|
101
|
-
NextMatchAndValue<TFirst, TMatchAndValue>,
|
|
102
|
-
`${TParentPath}${TFirst}.`
|
|
103
|
-
>
|
|
104
|
-
: never
|
|
105
|
-
: {
|
|
106
|
-
path: IsMatchPath<TParentPath, TMatchAndValue>
|
|
107
|
-
result: IsMatchResult<TPath, TMatchAndValue>
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export type IsMatch<TMatch, TPath> = IsMatchParse<
|
|
111
|
-
TPath,
|
|
112
|
-
TMatch extends any ? { match: TMatch; value: TMatch } : never
|
|
113
|
-
>
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Narrows matches based on a path
|
|
117
|
-
* @experimental
|
|
118
|
-
*/
|
|
119
|
-
export const isMatch = <TMatch, TPath extends string>(
|
|
120
|
-
match: TMatch,
|
|
121
|
-
path: Constrain<TPath, IsMatch<TMatch, TPath>['path']>,
|
|
122
|
-
): match is IsMatch<TMatch, TPath>['result'] => {
|
|
123
|
-
const parts = (path as string).split('.')
|
|
124
|
-
let part
|
|
125
|
-
let value: any = match
|
|
126
|
-
|
|
127
|
-
while ((part = parts.shift()) != null && value != null) {
|
|
128
|
-
value = value[part]
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return value != null
|
|
132
|
-
}
|
|
133
40
|
|
|
134
41
|
export type MakeRouteMatchFromRoute<TRoute extends AnyRoute> = RouteMatch<
|
|
135
42
|
TRoute['types']['id'],
|
package/src/RouterProvider.tsx
CHANGED
|
@@ -2,14 +2,16 @@ import * as React from 'react'
|
|
|
2
2
|
import { Matches } from './Matches'
|
|
3
3
|
import { getRouterContext } from './routerContext'
|
|
4
4
|
import type { NavigateOptions, ToOptions } from './link'
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
ParsedLocation,
|
|
7
|
+
ViewTransitionOptions,
|
|
8
|
+
} from '@tanstack/router-core'
|
|
6
9
|
import type { RoutePaths } from './routeInfo'
|
|
7
10
|
import type {
|
|
8
11
|
AnyRouter,
|
|
9
12
|
RegisteredRouter,
|
|
10
13
|
Router,
|
|
11
14
|
RouterOptions,
|
|
12
|
-
ViewTransitionOptions,
|
|
13
15
|
} from './router'
|
|
14
16
|
|
|
15
17
|
export interface CommitLocationOptions {
|
package/src/Transitioner.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
|
+
import { trimPathRight } from '@tanstack/router-core'
|
|
2
3
|
import { useLayoutEffect, usePrevious } from './utils'
|
|
3
4
|
import { useRouter } from './useRouter'
|
|
4
5
|
import { useRouterState } from './useRouterState'
|
|
5
|
-
import { trimPathRight } from './path'
|
|
6
6
|
|
|
7
7
|
export function Transitioner() {
|
|
8
8
|
const router = useRouter()
|
package/src/awaited.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
2
|
|
|
3
|
-
import { TSR_DEFERRED_PROMISE, defer } from '
|
|
4
|
-
import type { DeferredPromise } from '
|
|
3
|
+
import { TSR_DEFERRED_PROMISE, defer } from '@tanstack/router-core'
|
|
4
|
+
import type { DeferredPromise } from '@tanstack/router-core'
|
|
5
5
|
|
|
6
6
|
export type AwaitOptions<T> = {
|
|
7
7
|
promise: Promise<T>
|
package/src/fileRoute.ts
CHANGED
|
@@ -10,13 +10,17 @@ import { useNavigate } from './useNavigate'
|
|
|
10
10
|
import type { UseParamsRoute } from './useParams'
|
|
11
11
|
import type { UseMatchRoute } from './useMatch'
|
|
12
12
|
import type { UseSearchRoute } from './useSearch'
|
|
13
|
-
import type { Constrain } from './utils'
|
|
14
13
|
import type {
|
|
15
14
|
AnyContext,
|
|
16
15
|
AnyPathParams,
|
|
16
|
+
AnyValidator,
|
|
17
|
+
Constrain,
|
|
18
|
+
ResolveParams,
|
|
19
|
+
} from '@tanstack/router-core'
|
|
20
|
+
|
|
21
|
+
import type {
|
|
17
22
|
AnyRoute,
|
|
18
23
|
FileBaseRouteOptions,
|
|
19
|
-
ResolveParams,
|
|
20
24
|
RootRoute,
|
|
21
25
|
Route,
|
|
22
26
|
RouteConstraints,
|
|
@@ -25,7 +29,6 @@ import type {
|
|
|
25
29
|
} from './route'
|
|
26
30
|
import type { RegisteredRouter } from './router'
|
|
27
31
|
import type { RouteById, RouteIds } from './routeInfo'
|
|
28
|
-
import type { AnyValidator } from './validators'
|
|
29
32
|
import type { UseLoaderDepsRoute } from './useLoaderDeps'
|
|
30
33
|
import type { UseLoaderDataRoute } from './useLoaderData'
|
|
31
34
|
import type { UseRouteContextRoute } from './useRouteContext'
|
package/src/index.tsx
CHANGED
|
@@ -1,9 +1,134 @@
|
|
|
1
|
+
export { default as invariant } from 'tiny-invariant'
|
|
2
|
+
export { default as warning } from 'tiny-warning'
|
|
3
|
+
|
|
4
|
+
export {
|
|
5
|
+
defer,
|
|
6
|
+
TSR_DEFERRED_PROMISE,
|
|
7
|
+
isMatch,
|
|
8
|
+
joinPaths,
|
|
9
|
+
cleanPath,
|
|
10
|
+
trimPathLeft,
|
|
11
|
+
trimPathRight,
|
|
12
|
+
trimPath,
|
|
13
|
+
resolvePath,
|
|
14
|
+
parsePathname,
|
|
15
|
+
interpolatePath,
|
|
16
|
+
matchPathname,
|
|
17
|
+
removeBasepath,
|
|
18
|
+
matchByPath,
|
|
19
|
+
encode,
|
|
20
|
+
decode,
|
|
21
|
+
rootRouteId,
|
|
22
|
+
defaultSerializeError,
|
|
23
|
+
defaultParseSearch,
|
|
24
|
+
defaultStringifySearch,
|
|
25
|
+
parseSearchWith,
|
|
26
|
+
stringifySearchWith,
|
|
27
|
+
escapeJSON, // SSR
|
|
28
|
+
pick,
|
|
29
|
+
functionalUpdate,
|
|
30
|
+
replaceEqualDeep,
|
|
31
|
+
isPlainObject,
|
|
32
|
+
isPlainArray,
|
|
33
|
+
deepEqual,
|
|
34
|
+
shallow,
|
|
35
|
+
createControlledPromise,
|
|
36
|
+
retainSearchParams,
|
|
37
|
+
stripSearchParams,
|
|
38
|
+
} from '@tanstack/router-core'
|
|
39
|
+
|
|
40
|
+
export type {
|
|
41
|
+
StartSerializer,
|
|
42
|
+
Serializable,
|
|
43
|
+
SerializerParse,
|
|
44
|
+
SerializerParseBy,
|
|
45
|
+
SerializerStringify,
|
|
46
|
+
SerializerStringifyBy,
|
|
47
|
+
DeferredPromiseState,
|
|
48
|
+
DeferredPromise,
|
|
49
|
+
ParsedLocation,
|
|
50
|
+
ParsePathParams,
|
|
51
|
+
RemoveTrailingSlashes,
|
|
52
|
+
RemoveLeadingSlashes,
|
|
53
|
+
ActiveOptions,
|
|
54
|
+
Segment,
|
|
55
|
+
ResolveRelativePath,
|
|
56
|
+
RootRouteId,
|
|
57
|
+
AnyPathParams,
|
|
58
|
+
ResolveParams,
|
|
59
|
+
SearchSchemaInput,
|
|
60
|
+
AnyContext,
|
|
61
|
+
RouteContext,
|
|
62
|
+
PreloadableObj,
|
|
63
|
+
RoutePathOptions,
|
|
64
|
+
StaticDataRouteOption,
|
|
65
|
+
RoutePathOptionsIntersection,
|
|
66
|
+
UpdatableStaticRouteOption,
|
|
67
|
+
MetaDescriptor,
|
|
68
|
+
RouteLinkEntry,
|
|
69
|
+
ParseParamsFn,
|
|
70
|
+
SearchFilter,
|
|
71
|
+
ResolveId,
|
|
72
|
+
InferFullSearchSchema,
|
|
73
|
+
InferFullSearchSchemaInput,
|
|
74
|
+
ErrorRouteProps,
|
|
75
|
+
ErrorComponentProps,
|
|
76
|
+
NotFoundRouteProps,
|
|
77
|
+
TrimPath,
|
|
78
|
+
TrimPathLeft,
|
|
79
|
+
TrimPathRight,
|
|
80
|
+
ParseSplatParams,
|
|
81
|
+
SplatParams,
|
|
82
|
+
StringifyParamsFn,
|
|
83
|
+
ParamsOptions,
|
|
84
|
+
InferAllParams,
|
|
85
|
+
InferAllContext,
|
|
86
|
+
LooseReturnType,
|
|
87
|
+
LooseAsyncReturnType,
|
|
88
|
+
ContextReturnType,
|
|
89
|
+
ContextAsyncReturnType,
|
|
90
|
+
ResolveLoaderData,
|
|
91
|
+
ResolveRouteContext,
|
|
92
|
+
SearchSerializer,
|
|
93
|
+
SearchParser,
|
|
94
|
+
TrailingSlashOption,
|
|
95
|
+
ExtractedEntry,
|
|
96
|
+
ExtractedStream,
|
|
97
|
+
ExtractedPromise,
|
|
98
|
+
StreamState,
|
|
99
|
+
Manifest,
|
|
100
|
+
RouterManagedTag,
|
|
101
|
+
ControlledPromise,
|
|
102
|
+
Constrain,
|
|
103
|
+
Expand,
|
|
104
|
+
MergeAll,
|
|
105
|
+
Assign,
|
|
106
|
+
IntersectAssign,
|
|
107
|
+
ResolveValidatorInput,
|
|
108
|
+
ResolveValidatorOutput,
|
|
109
|
+
AnyValidator,
|
|
110
|
+
DefaultValidator,
|
|
111
|
+
ValidatorFn,
|
|
112
|
+
AnySchema,
|
|
113
|
+
AnyValidatorAdapter,
|
|
114
|
+
AnyValidatorFn,
|
|
115
|
+
AnyValidatorObj,
|
|
116
|
+
ResolveValidatorInputFn,
|
|
117
|
+
ResolveValidatorOutputFn,
|
|
118
|
+
ResolveSearchValidatorInput,
|
|
119
|
+
ResolveSearchValidatorInputFn,
|
|
120
|
+
Validator,
|
|
121
|
+
ValidatorAdapter,
|
|
122
|
+
ValidatorObj,
|
|
123
|
+
} from '@tanstack/router-core'
|
|
124
|
+
|
|
1
125
|
export {
|
|
2
126
|
createHistory,
|
|
3
127
|
createBrowserHistory,
|
|
4
128
|
createHashHistory,
|
|
5
129
|
createMemoryHistory,
|
|
6
130
|
} from '@tanstack/history'
|
|
131
|
+
|
|
7
132
|
export type {
|
|
8
133
|
BlockerFn,
|
|
9
134
|
HistoryLocation,
|
|
@@ -11,15 +136,10 @@ export type {
|
|
|
11
136
|
ParsedPath,
|
|
12
137
|
HistoryState,
|
|
13
138
|
} from '@tanstack/history'
|
|
14
|
-
export { default as invariant } from 'tiny-invariant'
|
|
15
|
-
export { default as warning } from 'tiny-warning'
|
|
16
139
|
|
|
17
140
|
export { useAwaited, Await } from './awaited'
|
|
18
141
|
export type { AwaitOptions } from './awaited'
|
|
19
142
|
|
|
20
|
-
export { defer, TSR_DEFERRED_PROMISE } from './defer'
|
|
21
|
-
export type { DeferredPromiseState, DeferredPromise } from './defer'
|
|
22
|
-
|
|
23
143
|
export { CatchBoundary, ErrorComponent } from './CatchBoundary'
|
|
24
144
|
|
|
25
145
|
export {
|
|
@@ -42,9 +162,6 @@ export { lazyRouteComponent } from './lazyRouteComponent'
|
|
|
42
162
|
|
|
43
163
|
export { useLinkProps, createLink, Link, linkOptions } from './link'
|
|
44
164
|
export type {
|
|
45
|
-
ParsePathParams,
|
|
46
|
-
RemoveTrailingSlashes,
|
|
47
|
-
RemoveLeadingSlashes,
|
|
48
165
|
InferDescendantToPaths,
|
|
49
166
|
RelativeToPath,
|
|
50
167
|
RelativeToParentPath,
|
|
@@ -59,9 +176,7 @@ export type {
|
|
|
59
176
|
SearchParamOptions,
|
|
60
177
|
PathParamOptions,
|
|
61
178
|
ToPathOption,
|
|
62
|
-
ActiveOptions,
|
|
63
179
|
LinkOptions,
|
|
64
|
-
ResolveRelativePath,
|
|
65
180
|
UseLinkPropsOptions,
|
|
66
181
|
ActiveLinkOptions,
|
|
67
182
|
LinkProps,
|
|
@@ -71,8 +186,6 @@ export type {
|
|
|
71
186
|
MakeOptionalPathParams,
|
|
72
187
|
} from './link'
|
|
73
188
|
|
|
74
|
-
export type { ParsedLocation } from './location'
|
|
75
|
-
|
|
76
189
|
export {
|
|
77
190
|
Matches,
|
|
78
191
|
useMatchRoute,
|
|
@@ -80,8 +193,8 @@ export {
|
|
|
80
193
|
useMatches,
|
|
81
194
|
useParentMatches,
|
|
82
195
|
useChildMatches,
|
|
83
|
-
isMatch,
|
|
84
196
|
} from './Matches'
|
|
197
|
+
|
|
85
198
|
export type {
|
|
86
199
|
RouteMatch,
|
|
87
200
|
AnyRouteMatch,
|
|
@@ -94,33 +207,14 @@ export type {
|
|
|
94
207
|
|
|
95
208
|
export { matchContext } from './matchContext'
|
|
96
209
|
export { Match, Outlet } from './Match'
|
|
210
|
+
|
|
97
211
|
export { useMatch } from './useMatch'
|
|
98
212
|
export { useLoaderDeps } from './useLoaderDeps'
|
|
99
213
|
export { useLoaderData } from './useLoaderData'
|
|
100
214
|
|
|
101
|
-
export {
|
|
102
|
-
joinPaths,
|
|
103
|
-
cleanPath,
|
|
104
|
-
trimPathLeft,
|
|
105
|
-
trimPathRight,
|
|
106
|
-
trimPath,
|
|
107
|
-
resolvePath,
|
|
108
|
-
parsePathname,
|
|
109
|
-
interpolatePath,
|
|
110
|
-
matchPathname,
|
|
111
|
-
removeBasepath,
|
|
112
|
-
matchByPath,
|
|
113
|
-
} from './path'
|
|
114
|
-
export type { Segment } from './path'
|
|
115
|
-
|
|
116
|
-
export { encode, decode } from './qss'
|
|
117
|
-
|
|
118
215
|
export { redirect, isRedirect } from './redirects'
|
|
119
216
|
export type { AnyRedirect, Redirect, ResolvedRedirect } from './redirects'
|
|
120
217
|
|
|
121
|
-
export { rootRouteId } from './root'
|
|
122
|
-
export type { RootRouteId } from './root'
|
|
123
|
-
|
|
124
218
|
export {
|
|
125
219
|
RouteApi,
|
|
126
220
|
getRouteApi,
|
|
@@ -134,29 +228,12 @@ export {
|
|
|
134
228
|
NotFoundRoute,
|
|
135
229
|
} from './route'
|
|
136
230
|
export type {
|
|
137
|
-
AnyPathParams,
|
|
138
|
-
ResolveParams,
|
|
139
|
-
SearchSchemaInput,
|
|
140
|
-
AnyContext,
|
|
141
|
-
RouteContext,
|
|
142
|
-
PreloadableObj,
|
|
143
|
-
RoutePathOptions,
|
|
144
|
-
StaticDataRouteOption,
|
|
145
|
-
RoutePathOptionsIntersection,
|
|
146
231
|
RouteOptions,
|
|
147
232
|
FileBaseRouteOptions,
|
|
148
233
|
BaseRouteOptions,
|
|
149
234
|
UpdatableRouteOptions,
|
|
150
|
-
UpdatableStaticRouteOption,
|
|
151
|
-
MetaDescriptor,
|
|
152
|
-
RouteLinkEntry,
|
|
153
|
-
ParseParamsFn,
|
|
154
235
|
RouteLoaderFn,
|
|
155
236
|
LoaderFnContext,
|
|
156
|
-
SearchFilter,
|
|
157
|
-
ResolveId,
|
|
158
|
-
InferFullSearchSchema,
|
|
159
|
-
InferFullSearchSchemaInput,
|
|
160
237
|
ResolveFullSearchSchema,
|
|
161
238
|
ResolveFullSearchSchemaInput,
|
|
162
239
|
AnyRoute,
|
|
@@ -164,42 +241,24 @@ export type {
|
|
|
164
241
|
AnyRootRoute,
|
|
165
242
|
ResolveFullPath,
|
|
166
243
|
RouteMask,
|
|
167
|
-
ErrorRouteProps,
|
|
168
|
-
ErrorComponentProps,
|
|
169
|
-
NotFoundRouteProps,
|
|
170
244
|
ReactNode,
|
|
171
245
|
SyncRouteComponent,
|
|
172
246
|
AsyncRouteComponent,
|
|
173
247
|
RouteComponent,
|
|
174
248
|
ErrorRouteComponent,
|
|
175
249
|
NotFoundRouteComponent,
|
|
176
|
-
TrimPath,
|
|
177
|
-
TrimPathLeft,
|
|
178
|
-
TrimPathRight,
|
|
179
250
|
RootRouteOptions,
|
|
180
251
|
AnyRouteWithContext,
|
|
181
|
-
ParseSplatParams,
|
|
182
|
-
SplatParams,
|
|
183
|
-
StringifyParamsFn,
|
|
184
|
-
ParamsOptions,
|
|
185
252
|
FullSearchSchemaOption,
|
|
186
253
|
RouteContextFn,
|
|
187
254
|
RouteContextOptions,
|
|
188
255
|
BeforeLoadFn,
|
|
189
256
|
BeforeLoadContextOptions,
|
|
190
257
|
ContextOptions,
|
|
191
|
-
InferAllParams,
|
|
192
|
-
InferAllContext,
|
|
193
|
-
LooseReturnType,
|
|
194
|
-
LooseAsyncReturnType,
|
|
195
|
-
ContextReturnType,
|
|
196
|
-
ContextAsyncReturnType,
|
|
197
258
|
RouteContextParameter,
|
|
198
259
|
BeforeLoadContextParameter,
|
|
199
260
|
ResolveAllContext,
|
|
200
|
-
ResolveLoaderData,
|
|
201
261
|
ResolveAllParamsFromParent,
|
|
202
|
-
ResolveRouteContext,
|
|
203
262
|
} from './route'
|
|
204
263
|
|
|
205
264
|
export type {
|
|
@@ -225,14 +284,13 @@ export {
|
|
|
225
284
|
SearchParamError,
|
|
226
285
|
PathParamError,
|
|
227
286
|
getInitialRouterState,
|
|
228
|
-
defaultSerializeError,
|
|
229
287
|
} from './router'
|
|
288
|
+
|
|
230
289
|
export type {
|
|
231
290
|
Register,
|
|
232
291
|
AnyRouter,
|
|
233
292
|
RegisteredRouter,
|
|
234
293
|
RouterContextOptions,
|
|
235
|
-
TrailingSlashOption,
|
|
236
294
|
RouterOptions,
|
|
237
295
|
RouterErrorSerializer,
|
|
238
296
|
RouterState,
|
|
@@ -247,15 +305,6 @@ export type {
|
|
|
247
305
|
InjectedHtmlEntry,
|
|
248
306
|
} from './router'
|
|
249
307
|
|
|
250
|
-
export type {
|
|
251
|
-
StartSerializer,
|
|
252
|
-
Serializable,
|
|
253
|
-
SerializerParse,
|
|
254
|
-
SerializerParseBy,
|
|
255
|
-
SerializerStringify,
|
|
256
|
-
SerializerStringifyBy,
|
|
257
|
-
} from './serializer'
|
|
258
|
-
|
|
259
308
|
export { RouterProvider, RouterContextProvider } from './RouterProvider'
|
|
260
309
|
export type {
|
|
261
310
|
RouterProps,
|
|
@@ -272,14 +321,6 @@ export {
|
|
|
272
321
|
} from './scroll-restoration'
|
|
273
322
|
export type { ScrollRestorationOptions } from './scroll-restoration'
|
|
274
323
|
|
|
275
|
-
export {
|
|
276
|
-
defaultParseSearch,
|
|
277
|
-
defaultStringifySearch,
|
|
278
|
-
parseSearchWith,
|
|
279
|
-
stringifySearchWith,
|
|
280
|
-
} from './searchParams'
|
|
281
|
-
export type { SearchSerializer, SearchParser } from './searchParams'
|
|
282
|
-
|
|
283
324
|
export type { UseBlockerOpts, ShouldBlockFn } from './useBlocker'
|
|
284
325
|
export { useBlocker, Block } from './useBlocker'
|
|
285
326
|
|
|
@@ -300,16 +341,8 @@ export { useLocation } from './useLocation'
|
|
|
300
341
|
export { useCanGoBack } from './useCanGoBack'
|
|
301
342
|
|
|
302
343
|
export {
|
|
303
|
-
escapeJSON, // SSR
|
|
304
344
|
useLayoutEffect, // SSR
|
|
305
|
-
pick,
|
|
306
|
-
functionalUpdate,
|
|
307
|
-
replaceEqualDeep,
|
|
308
|
-
isPlainObject,
|
|
309
|
-
isPlainArray,
|
|
310
|
-
deepEqual,
|
|
311
345
|
useStableCallback,
|
|
312
|
-
shallow,
|
|
313
346
|
} from './utils'
|
|
314
347
|
|
|
315
348
|
export {
|
|
@@ -320,39 +353,6 @@ export {
|
|
|
320
353
|
} from './not-found'
|
|
321
354
|
export type { NotFoundError } from './not-found'
|
|
322
355
|
|
|
323
|
-
export type { Manifest, RouterManagedTag } from './manifest'
|
|
324
|
-
|
|
325
|
-
export { createControlledPromise } from './utils'
|
|
326
|
-
export type {
|
|
327
|
-
ControlledPromise,
|
|
328
|
-
Constrain,
|
|
329
|
-
Expand,
|
|
330
|
-
MergeAll,
|
|
331
|
-
Assign,
|
|
332
|
-
IntersectAssign,
|
|
333
|
-
} from './utils'
|
|
334
|
-
|
|
335
|
-
export type {
|
|
336
|
-
ResolveValidatorInput,
|
|
337
|
-
ResolveValidatorOutput,
|
|
338
|
-
AnyValidator,
|
|
339
|
-
DefaultValidator,
|
|
340
|
-
ValidatorFn,
|
|
341
|
-
AnySchema,
|
|
342
|
-
AnyValidatorAdapter,
|
|
343
|
-
AnyValidatorFn,
|
|
344
|
-
AnyValidatorObj,
|
|
345
|
-
ResolveValidatorInputFn,
|
|
346
|
-
ResolveValidatorOutputFn,
|
|
347
|
-
ResolveSearchValidatorInput,
|
|
348
|
-
ResolveSearchValidatorInputFn,
|
|
349
|
-
Validator,
|
|
350
|
-
ValidatorAdapter,
|
|
351
|
-
ValidatorObj,
|
|
352
|
-
} from './validators'
|
|
353
|
-
|
|
354
|
-
export { retainSearchParams, stripSearchParams } from './searchMiddleware'
|
|
355
|
-
|
|
356
356
|
export * from './typePrimitives'
|
|
357
357
|
|
|
358
358
|
export { ScriptOnce } from './ScriptOnce'
|