@tanstack/react-router 0.0.1-beta.204 → 0.0.1-beta.206

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.
Files changed (73) hide show
  1. package/build/cjs/RouterProvider.js +963 -0
  2. package/build/cjs/RouterProvider.js.map +1 -0
  3. package/build/cjs/fileRoute.js +29 -0
  4. package/build/cjs/fileRoute.js.map +1 -0
  5. package/build/cjs/index.js +69 -21
  6. package/build/cjs/index.js.map +1 -1
  7. package/build/cjs/path.js +211 -0
  8. package/build/cjs/path.js.map +1 -0
  9. package/build/cjs/qss.js +65 -0
  10. package/build/cjs/qss.js.map +1 -0
  11. package/build/cjs/react.js +148 -190
  12. package/build/cjs/react.js.map +1 -1
  13. package/build/cjs/redirects.js +27 -0
  14. package/build/cjs/redirects.js.map +1 -0
  15. package/build/cjs/route.js +136 -0
  16. package/build/cjs/route.js.map +1 -0
  17. package/build/cjs/router.js +203 -0
  18. package/build/cjs/router.js.map +1 -0
  19. package/build/cjs/searchParams.js +83 -0
  20. package/build/cjs/searchParams.js.map +1 -0
  21. package/build/cjs/utils.js +196 -0
  22. package/build/cjs/utils.js.map +1 -0
  23. package/build/esm/index.js +1801 -211
  24. package/build/esm/index.js.map +1 -1
  25. package/build/stats-html.html +1 -1
  26. package/build/stats-react.json +385 -164
  27. package/build/types/RouteMatch.d.ts +23 -0
  28. package/build/types/RouterProvider.d.ts +54 -0
  29. package/build/types/awaited.d.ts +0 -8
  30. package/build/types/defer.d.ts +0 -0
  31. package/build/types/fileRoute.d.ts +17 -0
  32. package/build/types/history.d.ts +7 -0
  33. package/build/types/index.d.ts +17 -4
  34. package/build/types/link.d.ts +98 -0
  35. package/build/types/location.d.ts +14 -0
  36. package/build/types/path.d.ts +16 -0
  37. package/build/types/qss.d.ts +2 -0
  38. package/build/types/react.d.ts +23 -83
  39. package/build/types/redirects.d.ts +10 -0
  40. package/build/types/route.d.ts +222 -0
  41. package/build/types/routeInfo.d.ts +22 -0
  42. package/build/types/router.d.ts +115 -0
  43. package/build/types/scroll-restoration.d.ts +0 -3
  44. package/build/types/searchParams.d.ts +7 -0
  45. package/build/types/utils.d.ts +48 -0
  46. package/build/umd/index.development.js +1118 -1540
  47. package/build/umd/index.development.js.map +1 -1
  48. package/build/umd/index.production.js +2 -33
  49. package/build/umd/index.production.js.map +1 -1
  50. package/package.json +2 -4
  51. package/src/RouteMatch.ts +28 -0
  52. package/src/RouterProvider.tsx +1390 -0
  53. package/src/awaited.tsx +40 -40
  54. package/src/defer.ts +55 -0
  55. package/src/fileRoute.ts +143 -0
  56. package/src/history.ts +8 -0
  57. package/src/index.tsx +18 -5
  58. package/src/link.ts +347 -0
  59. package/src/location.ts +14 -0
  60. package/src/path.ts +256 -0
  61. package/src/qss.ts +53 -0
  62. package/src/react.tsx +174 -422
  63. package/src/redirects.ts +31 -0
  64. package/src/route.ts +710 -0
  65. package/src/routeInfo.ts +68 -0
  66. package/src/router.ts +373 -0
  67. package/src/scroll-restoration.tsx +205 -27
  68. package/src/searchParams.ts +78 -0
  69. package/src/utils.ts +257 -0
  70. package/build/cjs/awaited.js +0 -45
  71. package/build/cjs/awaited.js.map +0 -1
  72. package/build/cjs/scroll-restoration.js +0 -56
  73. package/build/cjs/scroll-restoration.js.map +0 -1
@@ -0,0 +1,78 @@
1
+ import { decode, encode } from './qss'
2
+ import { AnySearchSchema } from './route'
3
+
4
+ export const defaultParseSearch = parseSearchWith(JSON.parse)
5
+ export const defaultStringifySearch = stringifySearchWith(
6
+ JSON.stringify,
7
+ JSON.parse,
8
+ )
9
+
10
+ export function parseSearchWith(parser: (str: string) => any) {
11
+ return (searchStr: string): AnySearchSchema => {
12
+ if (searchStr.substring(0, 1) === '?') {
13
+ searchStr = searchStr.substring(1)
14
+ }
15
+
16
+ let query: Record<string, unknown> = decode(searchStr)
17
+
18
+ // Try to parse any query params that might be json
19
+ for (let key in query) {
20
+ const value = query[key]
21
+ if (typeof value === 'string') {
22
+ try {
23
+ query[key] = parser(value)
24
+ } catch (err) {
25
+ //
26
+ }
27
+ }
28
+ }
29
+
30
+ return query
31
+ }
32
+ }
33
+
34
+ export function stringifySearchWith(
35
+ stringify: (search: any) => string,
36
+ parser?: (str: string) => any,
37
+ ) {
38
+ function stringifyValue(val: any) {
39
+ if (typeof val === 'object' && val !== null) {
40
+ try {
41
+ return stringify(val)
42
+ } catch (err) {
43
+ // silent
44
+ }
45
+ } else if (typeof val === 'string' && typeof parser === 'function') {
46
+ try {
47
+ // Check if it's a valid parseable string.
48
+ // If it is, then stringify it again.
49
+ parser(val)
50
+ return stringify(val)
51
+ } catch (err) {
52
+ // silent
53
+ }
54
+ }
55
+ return val
56
+ }
57
+
58
+ return (search: Record<string, any>) => {
59
+ search = { ...search }
60
+
61
+ if (search) {
62
+ Object.keys(search).forEach((key) => {
63
+ const val = search[key]
64
+ if (typeof val === 'undefined' || val === undefined) {
65
+ delete search[key]
66
+ } else {
67
+ search[key] = stringifyValue(val)
68
+ }
69
+ })
70
+ }
71
+
72
+ const searchStr = encode(search as Record<string, string>).toString()
73
+
74
+ return searchStr ? `?${searchStr}` : ''
75
+ }
76
+ }
77
+ export type SearchSerializer = (searchObj: Record<string, any>) => string
78
+ export type SearchParser = (searchStr: string) => Record<string, any>
package/src/utils.ts ADDED
@@ -0,0 +1,257 @@
1
+ import * as React from 'react'
2
+ export type NoInfer<T> = [T][T extends any ? 0 : never]
3
+ export type IsAny<T, Y, N = T> = 1 extends 0 & T ? Y : N
4
+ export type IsAnyBoolean<T> = 1 extends 0 & T ? true : false
5
+ export type IsKnown<T, Y, N> = unknown extends T ? N : Y
6
+ export type PickAsRequired<T, K extends keyof T> = Omit<T, K> &
7
+ Required<Pick<T, K>>
8
+ export type PickAsPartial<T, K extends keyof T> = Omit<T, K> &
9
+ Partial<Pick<T, K>>
10
+ export type PickUnsafe<T, K> = K extends keyof T ? Pick<T, K> : never
11
+ export type PickExtra<T, K> = {
12
+ [TKey in keyof K as string extends TKey
13
+ ? never
14
+ : TKey extends keyof T
15
+ ? never
16
+ : TKey]: K[TKey]
17
+ }
18
+
19
+ export type PickRequired<T> = {
20
+ [K in keyof T as undefined extends T[K] ? never : K]: T[K]
21
+ }
22
+
23
+ // export type Expand<T> = T
24
+ export type Expand<T> = T extends object
25
+ ? T extends infer O
26
+ ? { [K in keyof O]: O[K] }
27
+ : never
28
+ : T
29
+
30
+ export type UnionToIntersection<U> = (
31
+ U extends any ? (k: U) => void : never
32
+ ) extends (k: infer I) => any
33
+ ? I
34
+ : never
35
+
36
+ // type Compute<T> = { [K in keyof T]: T[K] } | never
37
+
38
+ // type AllKeys<T> = T extends any ? keyof T : never
39
+
40
+ // export type MergeUnion<T, Keys extends keyof T = keyof T> = Compute<
41
+ // {
42
+ // [K in Keys]: T[Keys]
43
+ // } & {
44
+ // [K in AllKeys<T>]?: T extends any
45
+ // ? K extends keyof T
46
+ // ? T[K]
47
+ // : never
48
+ // : never
49
+ // }
50
+ // >
51
+
52
+ export type Assign<Left, Right> = Omit<Left, keyof Right> & Right
53
+
54
+ export type AssignAll<T extends any[]> = T extends [infer Left, ...infer Right]
55
+ ? Right extends any[]
56
+ ? Assign<Left, AssignAll<Right>>
57
+ : Left
58
+ : {}
59
+
60
+ // // Sample types to merge
61
+ // type TypeA = {
62
+ // shared: string
63
+ // onlyInA: string
64
+ // nested: {
65
+ // shared: string
66
+ // aProp: string
67
+ // }
68
+ // array: string[]
69
+ // }
70
+
71
+ // type TypeB = {
72
+ // shared: number
73
+ // onlyInB: number
74
+ // nested: {
75
+ // shared: number
76
+ // bProp: number
77
+ // }
78
+ // array: number[]
79
+ // }
80
+
81
+ // type TypeC = {
82
+ // shared: boolean
83
+ // onlyInC: boolean
84
+ // nested: {
85
+ // shared: boolean
86
+ // cProp: boolean
87
+ // }
88
+ // array: boolean[]
89
+ // }
90
+
91
+ // type Test = Expand<Assign<TypeA, TypeB>>
92
+
93
+ // // Using DeepMerge to merge TypeA and TypeB
94
+ // type MergedType = Expand<AssignAll<[TypeA, TypeB, TypeC]>>
95
+
96
+ export type Values<O> = O[ValueKeys<O>]
97
+ export type ValueKeys<O> = Extract<keyof O, PropertyKey>
98
+
99
+ export type DeepAwaited<T> = T extends Promise<infer A>
100
+ ? DeepAwaited<A>
101
+ : T extends Record<infer A, Promise<infer B>>
102
+ ? { [K in A]: DeepAwaited<B> }
103
+ : T
104
+
105
+ export type PathParamMask<TRoutePath extends string> =
106
+ TRoutePath extends `${infer L}/$${infer C}/${infer R}`
107
+ ? PathParamMask<`${L}/${string}/${R}`>
108
+ : TRoutePath extends `${infer L}/$${infer C}`
109
+ ? PathParamMask<`${L}/${string}`>
110
+ : TRoutePath
111
+
112
+ export type Timeout = ReturnType<typeof setTimeout>
113
+
114
+ export type Updater<TPrevious, TResult = TPrevious> =
115
+ | TResult
116
+ | ((prev?: TPrevious) => TResult)
117
+
118
+ export type NonNullableUpdater<TPrevious, TResult = TPrevious> =
119
+ | TResult
120
+ | ((prev: TPrevious) => TResult)
121
+
122
+ export type PickExtract<T, U> = {
123
+ [K in keyof T as T[K] extends U ? K : never]: T[K]
124
+ }
125
+
126
+ export type PickExclude<T, U> = {
127
+ [K in keyof T as T[K] extends U ? never : K]: T[K]
128
+ }
129
+
130
+ //
131
+
132
+ export const isServer = typeof document === 'undefined'
133
+
134
+ export function last<T>(arr: T[]) {
135
+ return arr[arr.length - 1]
136
+ }
137
+
138
+ function isFunction(d: any): d is Function {
139
+ return typeof d === 'function'
140
+ }
141
+
142
+ export function functionalUpdate<TResult>(
143
+ updater: Updater<TResult> | NonNullableUpdater<TResult>,
144
+ previous: TResult,
145
+ ): TResult {
146
+ if (isFunction(updater)) {
147
+ return updater(previous as TResult)
148
+ }
149
+
150
+ return updater
151
+ }
152
+
153
+ export function pick<T, K extends keyof T>(parent: T, keys: K[]): Pick<T, K> {
154
+ return keys.reduce((obj: any, key: K) => {
155
+ obj[key] = parent[key]
156
+ return obj
157
+ }, {} as any)
158
+ }
159
+
160
+ /**
161
+ * This function returns `a` if `b` is deeply equal.
162
+ * If not, it will replace any deeply equal children of `b` with those of `a`.
163
+ * This can be used for structural sharing between immutable JSON values for example.
164
+ * Do not use this with signals
165
+ */
166
+ export function replaceEqualDeep<T>(prev: any, _next: T): T {
167
+ if (prev === _next) {
168
+ return prev
169
+ }
170
+
171
+ const next = _next as any
172
+
173
+ const array = Array.isArray(prev) && Array.isArray(next)
174
+
175
+ if (array || (isPlainObject(prev) && isPlainObject(next))) {
176
+ const prevSize = array ? prev.length : Object.keys(prev).length
177
+ const nextItems = array ? next : Object.keys(next)
178
+ const nextSize = nextItems.length
179
+ const copy: any = array ? [] : {}
180
+
181
+ let equalItems = 0
182
+
183
+ for (let i = 0; i < nextSize; i++) {
184
+ const key = array ? i : nextItems[i]
185
+ copy[key] = replaceEqualDeep(prev[key], next[key])
186
+ if (copy[key] === prev[key]) {
187
+ equalItems++
188
+ }
189
+ }
190
+
191
+ return prevSize === nextSize && equalItems === prevSize ? prev : copy
192
+ }
193
+
194
+ return next
195
+ }
196
+
197
+ // Copied from: https://github.com/jonschlinkert/is-plain-object
198
+ export function isPlainObject(o: any) {
199
+ if (!hasObjectPrototype(o)) {
200
+ return false
201
+ }
202
+
203
+ // If has modified constructor
204
+ const ctor = o.constructor
205
+ if (typeof ctor === 'undefined') {
206
+ return true
207
+ }
208
+
209
+ // If has modified prototype
210
+ const prot = ctor.prototype
211
+ if (!hasObjectPrototype(prot)) {
212
+ return false
213
+ }
214
+
215
+ // If constructor does not have an Object-specific method
216
+ if (!prot.hasOwnProperty('isPrototypeOf')) {
217
+ return false
218
+ }
219
+
220
+ // Most likely a plain Object
221
+ return true
222
+ }
223
+
224
+ function hasObjectPrototype(o: any) {
225
+ return Object.prototype.toString.call(o) === '[object Object]'
226
+ }
227
+
228
+ export function partialDeepEqual(a: any, b: any): boolean {
229
+ if (a === b) {
230
+ return true
231
+ }
232
+
233
+ if (typeof a !== typeof b) {
234
+ return false
235
+ }
236
+
237
+ if (isPlainObject(a) && isPlainObject(b)) {
238
+ return !Object.keys(b).some((key) => !partialDeepEqual(a[key], b[key]))
239
+ }
240
+
241
+ if (Array.isArray(a) && Array.isArray(b)) {
242
+ return (
243
+ a.length === b.length &&
244
+ a.every((item, index) => partialDeepEqual(item, b[index]))
245
+ )
246
+ }
247
+
248
+ return false
249
+ }
250
+
251
+ export function useStableCallback<T extends (...args: any[]) => any>(fn: T): T {
252
+ const fnRef = React.useRef(fn)
253
+ fnRef.current = fn
254
+
255
+ const ref = React.useRef((...args: any[]) => fnRef.current(...args))
256
+ return ref.current as T
257
+ }
@@ -1,45 +0,0 @@
1
- /**
2
- * @tanstack/react-router/src/index.tsx
3
- *
4
- * Copyright (c) TanStack
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE.md file in the root directory of this source tree.
8
- *
9
- * @license MIT
10
- */
11
- 'use strict';
12
-
13
- Object.defineProperty(exports, '__esModule', { value: true });
14
-
15
- var routerCore = require('@tanstack/router-core');
16
- var react = require('./react.js');
17
-
18
- function useAwaited({
19
- promise
20
- }) {
21
- const router = react.useRouter();
22
- let state = promise.__deferredState;
23
- const key = `__TSR__DEFERRED__${state.uid}`;
24
- if (routerCore.isDehydratedDeferred(promise)) {
25
- state = router.hydrateData(key);
26
- promise = Promise.resolve(state.data);
27
- promise.__deferredState = state;
28
- }
29
- if (state.status === 'pending') {
30
- throw promise;
31
- }
32
- if (state.status === 'error') {
33
- throw state.error;
34
- }
35
- router.dehydrateData(key, state);
36
- return [state.data];
37
- }
38
- function Await(props) {
39
- const awaited = useAwaited(props);
40
- return props.children(...awaited);
41
- }
42
-
43
- exports.Await = Await;
44
- exports.useAwaited = useAwaited;
45
- //# sourceMappingURL=awaited.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"awaited.js","sources":["../../src/awaited.tsx"],"sourcesContent":["import { DeferredPromise, isDehydratedDeferred } from '@tanstack/router-core'\nimport { useRouter } from './react'\n\nexport type AwaitOptions<T> = {\n promise: DeferredPromise<T>\n}\n\nexport function useAwaited<T>({ promise }: AwaitOptions<T>): [T] {\n const router = useRouter()\n\n let state = promise.__deferredState\n const key = `__TSR__DEFERRED__${state.uid}`\n\n if (isDehydratedDeferred(promise)) {\n state = router.hydrateData(key)!\n promise = Promise.resolve(state.data) as DeferredPromise<any>\n promise.__deferredState = state\n }\n\n if (state.status === 'pending') {\n throw promise\n }\n\n if (state.status === 'error') {\n throw state.error\n }\n\n router.dehydrateData(key, state)\n\n return [state.data]\n}\n\nexport function Await<T>(\n props: AwaitOptions<T> & {\n children: (result: T) => JSX.Element\n },\n) {\n const awaited = useAwaited(props)\n return props.children(...awaited)\n}\n"],"names":["useAwaited","promise","router","useRouter","state","__deferredState","key","uid","isDehydratedDeferred","hydrateData","Promise","resolve","data","status","error","dehydrateData","Await","props","awaited","children"],"mappings":";;;;;;;;;;;;;;;;;AAOO,SAASA,UAAUA,CAAI;AAAEC,EAAAA,OAAAA;AAAyB,CAAC,EAAO;AAC/D,EAAA,MAAMC,MAAM,GAAGC,eAAS,EAAE,CAAA;AAE1B,EAAA,IAAIC,KAAK,GAAGH,OAAO,CAACI,eAAe,CAAA;AACnC,EAAA,MAAMC,GAAG,GAAI,CAAA,iBAAA,EAAmBF,KAAK,CAACG,GAAI,CAAC,CAAA,CAAA;AAE3C,EAAA,IAAIC,+BAAoB,CAACP,OAAO,CAAC,EAAE;AACjCG,IAAAA,KAAK,GAAGF,MAAM,CAACO,WAAW,CAACH,GAAG,CAAE,CAAA;IAChCL,OAAO,GAAGS,OAAO,CAACC,OAAO,CAACP,KAAK,CAACQ,IAAI,CAAyB,CAAA;IAC7DX,OAAO,CAACI,eAAe,GAAGD,KAAK,CAAA;AACjC,GAAA;AAEA,EAAA,IAAIA,KAAK,CAACS,MAAM,KAAK,SAAS,EAAE;AAC9B,IAAA,MAAMZ,OAAO,CAAA;AACf,GAAA;AAEA,EAAA,IAAIG,KAAK,CAACS,MAAM,KAAK,OAAO,EAAE;IAC5B,MAAMT,KAAK,CAACU,KAAK,CAAA;AACnB,GAAA;AAEAZ,EAAAA,MAAM,CAACa,aAAa,CAACT,GAAG,EAAEF,KAAK,CAAC,CAAA;AAEhC,EAAA,OAAO,CAACA,KAAK,CAACQ,IAAI,CAAC,CAAA;AACrB,CAAA;AAEO,SAASI,KAAKA,CACnBC,KAEC,EACD;AACA,EAAA,MAAMC,OAAO,GAAGlB,UAAU,CAACiB,KAAK,CAAC,CAAA;AACjC,EAAA,OAAOA,KAAK,CAACE,QAAQ,CAAC,GAAGD,OAAO,CAAC,CAAA;AACnC;;;;;"}
@@ -1,56 +0,0 @@
1
- /**
2
- * @tanstack/react-router/src/index.tsx
3
- *
4
- * Copyright (c) TanStack
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE.md file in the root directory of this source tree.
8
- *
9
- * @license MIT
10
- */
11
- 'use strict';
12
-
13
- Object.defineProperty(exports, '__esModule', { value: true });
14
-
15
- var React = require('react');
16
- var routerCore = require('@tanstack/router-core');
17
- var react = require('./react.js');
18
-
19
- function _interopNamespace(e) {
20
- if (e && e.__esModule) return e;
21
- var n = Object.create(null);
22
- if (e) {
23
- Object.keys(e).forEach(function (k) {
24
- if (k !== 'default') {
25
- var d = Object.getOwnPropertyDescriptor(e, k);
26
- Object.defineProperty(n, k, d.get ? d : {
27
- enumerable: true,
28
- get: function () { return e[k]; }
29
- });
30
- }
31
- });
32
- }
33
- n["default"] = e;
34
- return Object.freeze(n);
35
- }
36
-
37
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
38
-
39
- const useLayoutEffect = typeof window !== 'undefined' ? React__namespace.useLayoutEffect : React__namespace.useEffect;
40
- function useScrollRestoration(options) {
41
- const router = react.useRouter();
42
- useLayoutEffect(() => {
43
- return routerCore.watchScrollPositions(router, options);
44
- }, []);
45
- useLayoutEffect(() => {
46
- routerCore.restoreScrollPositions(router, options);
47
- });
48
- }
49
- function ScrollRestoration(props) {
50
- useScrollRestoration(props);
51
- return null;
52
- }
53
-
54
- exports.ScrollRestoration = ScrollRestoration;
55
- exports.useScrollRestoration = useScrollRestoration;
56
- //# sourceMappingURL=scroll-restoration.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scroll-restoration.js","sources":["../../src/scroll-restoration.tsx"],"sourcesContent":["import * as React from 'react'\nimport {\n ScrollRestorationOptions,\n restoreScrollPositions,\n watchScrollPositions,\n} from '@tanstack/router-core'\nimport { useRouter } from './react'\n\nconst useLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\n\nexport function useScrollRestoration(options?: ScrollRestorationOptions) {\n const router = useRouter()\n\n useLayoutEffect(() => {\n return watchScrollPositions(router, options)\n }, [])\n\n useLayoutEffect(() => {\n restoreScrollPositions(router, options)\n })\n}\n\nexport function ScrollRestoration(props: ScrollRestorationOptions) {\n useScrollRestoration(props)\n return null\n}\n"],"names":["useLayoutEffect","window","React","useEffect","useScrollRestoration","options","router","useRouter","watchScrollPositions","restoreScrollPositions","ScrollRestoration","props"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,MAAMA,eAAe,GACnB,OAAOC,MAAM,KAAK,WAAW,GAAGC,gBAAK,CAACF,eAAe,GAAGE,gBAAK,CAACC,SAAS,CAAA;AAElE,SAASC,oBAAoBA,CAACC,OAAkC,EAAE;AACvE,EAAA,MAAMC,MAAM,GAAGC,eAAS,EAAE,CAAA;AAE1BP,EAAAA,eAAe,CAAC,MAAM;AACpB,IAAA,OAAOQ,+BAAoB,CAACF,MAAM,EAAED,OAAO,CAAC,CAAA;GAC7C,EAAE,EAAE,CAAC,CAAA;AAENL,EAAAA,eAAe,CAAC,MAAM;AACpBS,IAAAA,iCAAsB,CAACH,MAAM,EAAED,OAAO,CAAC,CAAA;AACzC,GAAC,CAAC,CAAA;AACJ,CAAA;AAEO,SAASK,iBAAiBA,CAACC,KAA+B,EAAE;EACjEP,oBAAoB,CAACO,KAAK,CAAC,CAAA;AAC3B,EAAA,OAAO,IAAI,CAAA;AACb;;;;;"}