@tanstack/router-core 0.0.1-beta.36 → 0.0.1-beta.39
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/build/cjs/index.js +2 -1
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/path.js +5 -7
- package/build/cjs/path.js.map +1 -1
- package/build/cjs/route.js +112 -95
- package/build/cjs/route.js.map +1 -1
- package/build/cjs/routeConfig.js +2 -2
- package/build/cjs/routeConfig.js.map +1 -1
- package/build/cjs/routeMatch.js +107 -65
- package/build/cjs/routeMatch.js.map +1 -1
- package/build/cjs/router.js +320 -351
- package/build/cjs/router.js.map +1 -1
- package/build/cjs/searchParams.js +4 -3
- package/build/cjs/searchParams.js.map +1 -1
- package/build/cjs/sharedClone.js +122 -0
- package/build/cjs/sharedClone.js.map +1 -0
- package/build/cjs/utils.js +1 -59
- package/build/cjs/utils.js.map +1 -1
- package/build/esm/index.js +654 -592
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +183 -158
- package/build/types/index.d.ts +54 -68
- package/build/umd/index.development.js +1000 -595
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -1
- package/src/index.ts +1 -0
- package/src/link.ts +20 -12
- package/src/route.ts +160 -139
- package/src/routeMatch.ts +144 -99
- package/src/router.ts +402 -491
- package/src/sharedClone.ts +118 -0
- package/src/utils.ts +0 -65
- package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -31
- package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/router-core",
|
|
3
3
|
"author": "Tanner Linsley",
|
|
4
|
-
"version": "0.0.1-beta.
|
|
4
|
+
"version": "0.0.1-beta.39",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "tanstack/router",
|
|
7
7
|
"homepage": "https://tanstack.com/router",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@babel/runtime": "^7.16.7",
|
|
43
|
+
"@solidjs/reactivity": "^0.0.6",
|
|
43
44
|
"history": "^5.2.0",
|
|
44
45
|
"tiny-invariant": "^1.3.1"
|
|
45
46
|
},
|
package/src/index.ts
CHANGED
package/src/link.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AnyPathParams } from './routeConfig'
|
|
2
1
|
import {
|
|
3
2
|
AnyAllRouteInfo,
|
|
4
3
|
DefaultAllRouteInfo,
|
|
@@ -112,11 +111,20 @@ export type RelativeToPathAutoComplete<
|
|
|
112
111
|
]
|
|
113
112
|
? `${TTo}${Join<RestPath>}`
|
|
114
113
|
: never
|
|
115
|
-
:
|
|
114
|
+
:
|
|
115
|
+
| (TFrom extends `/`
|
|
116
|
+
? never
|
|
117
|
+
: SplitPaths extends [...Split<TFrom, false>, ...infer RestPath]
|
|
118
|
+
? Join<RestPath> extends { length: 0 }
|
|
119
|
+
? never
|
|
120
|
+
: './'
|
|
121
|
+
: never)
|
|
122
|
+
| (TFrom extends `/` ? never : '../')
|
|
123
|
+
| AllPaths
|
|
116
124
|
|
|
117
|
-
export type
|
|
125
|
+
export type NavigateOptions<
|
|
118
126
|
TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
|
|
119
|
-
TFrom extends
|
|
127
|
+
TFrom extends TAllRouteInfo['routePaths'] = '/',
|
|
120
128
|
TTo extends string = '.',
|
|
121
129
|
> = ToOptions<TAllRouteInfo, TFrom, TTo> & {
|
|
122
130
|
// Whether to replace the current history stack instead of pushing a new one
|
|
@@ -125,7 +133,7 @@ export type NavigateOptionsAbsolute<
|
|
|
125
133
|
|
|
126
134
|
export type ToOptions<
|
|
127
135
|
TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
|
|
128
|
-
TFrom extends
|
|
136
|
+
TFrom extends TAllRouteInfo['routePaths'] = '/',
|
|
129
137
|
TTo extends string = '.',
|
|
130
138
|
TResolvedTo = ResolveRelativePath<TFrom, NoInfer<TTo>>,
|
|
131
139
|
> = {
|
|
@@ -142,7 +150,7 @@ export type ToOptions<
|
|
|
142
150
|
SearchParamOptions<TAllRouteInfo, TFrom, TResolvedTo> &
|
|
143
151
|
PathParamOptions<TAllRouteInfo, TFrom, TResolvedTo>
|
|
144
152
|
|
|
145
|
-
type SearchParamOptions<
|
|
153
|
+
export type SearchParamOptions<
|
|
146
154
|
TAllRouteInfo extends AnyAllRouteInfo,
|
|
147
155
|
TFrom,
|
|
148
156
|
TTo,
|
|
@@ -183,7 +191,7 @@ type SearchReducer<TFrom, TTo> =
|
|
|
183
191
|
| { [TKey in keyof TTo]: TTo[TKey] }
|
|
184
192
|
| ((current: TFrom) => TTo)
|
|
185
193
|
|
|
186
|
-
type PathParamOptions<
|
|
194
|
+
export type PathParamOptions<
|
|
187
195
|
TAllRouteInfo extends AnyAllRouteInfo,
|
|
188
196
|
TFrom,
|
|
189
197
|
TTo,
|
|
@@ -219,7 +227,7 @@ type ParamsReducer<TFrom, TTo> = TTo | ((current: TFrom) => TTo)
|
|
|
219
227
|
|
|
220
228
|
export type ToPathOption<
|
|
221
229
|
TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
|
|
222
|
-
TFrom extends
|
|
230
|
+
TFrom extends TAllRouteInfo['routePaths'] = '/',
|
|
223
231
|
TTo extends string = '.',
|
|
224
232
|
> =
|
|
225
233
|
| TTo
|
|
@@ -231,7 +239,7 @@ export type ToPathOption<
|
|
|
231
239
|
|
|
232
240
|
export type ToIdOption<
|
|
233
241
|
TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
|
|
234
|
-
TFrom extends
|
|
242
|
+
TFrom extends TAllRouteInfo['routePaths'] = '/',
|
|
235
243
|
TTo extends string = '.',
|
|
236
244
|
> =
|
|
237
245
|
| TTo
|
|
@@ -241,16 +249,16 @@ export type ToIdOption<
|
|
|
241
249
|
NoInfer<TTo> & string
|
|
242
250
|
>
|
|
243
251
|
|
|
244
|
-
interface ActiveOptions {
|
|
252
|
+
export interface ActiveOptions {
|
|
245
253
|
exact?: boolean
|
|
246
254
|
includeHash?: boolean
|
|
247
255
|
}
|
|
248
256
|
|
|
249
257
|
export type LinkOptions<
|
|
250
258
|
TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
|
|
251
|
-
TFrom extends
|
|
259
|
+
TFrom extends TAllRouteInfo['routePaths'] = '/',
|
|
252
260
|
TTo extends string = '.',
|
|
253
|
-
> =
|
|
261
|
+
> = NavigateOptions<TAllRouteInfo, TFrom, TTo> & {
|
|
254
262
|
// The standard anchor tag target attribute
|
|
255
263
|
target?: HTMLAnchorElement['target']
|
|
256
264
|
// Defaults to `{ exact: false, includeHash: false }`
|
package/src/route.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
Router,
|
|
23
23
|
} from './router'
|
|
24
24
|
import { NoInfer } from './utils'
|
|
25
|
+
import { createStore } from '@solidjs/reactivity'
|
|
25
26
|
|
|
26
27
|
export interface AnyRoute extends Route<any, any, any> {}
|
|
27
28
|
|
|
@@ -38,31 +39,8 @@ export interface Route<
|
|
|
38
39
|
parentRoute?: AnyRoute
|
|
39
40
|
childRoutes?: AnyRoute[]
|
|
40
41
|
options: RouteOptions
|
|
42
|
+
originalIndex: number
|
|
41
43
|
router: Router<TAllRouteInfo['routeConfig'], TAllRouteInfo, TRouterContext>
|
|
42
|
-
buildLink: <TTo extends string = '.'>(
|
|
43
|
-
options: Omit<
|
|
44
|
-
LinkOptions<TAllRouteInfo, TRouteInfo['fullPath'], TTo>,
|
|
45
|
-
'from'
|
|
46
|
-
>,
|
|
47
|
-
) => LinkInfo
|
|
48
|
-
matchRoute: <
|
|
49
|
-
TTo extends string = '.',
|
|
50
|
-
TResolved extends string = ResolveRelativePath<TRouteInfo['id'], TTo>,
|
|
51
|
-
>(
|
|
52
|
-
matchLocation: CheckRelativePath<
|
|
53
|
-
TAllRouteInfo,
|
|
54
|
-
TRouteInfo['fullPath'],
|
|
55
|
-
NoInfer<TTo>
|
|
56
|
-
> &
|
|
57
|
-
Omit<ToOptions<TAllRouteInfo, TRouteInfo['fullPath'], TTo>, 'from'>,
|
|
58
|
-
opts?: MatchRouteOptions,
|
|
59
|
-
) => RouteInfoByPath<TAllRouteInfo, TResolved>['allParams']
|
|
60
|
-
navigate: <TTo extends string = '.'>(
|
|
61
|
-
options: Omit<
|
|
62
|
-
LinkOptions<TAllRouteInfo, TRouteInfo['fullPath'], TTo>,
|
|
63
|
-
'from'
|
|
64
|
-
>,
|
|
65
|
-
) => Promise<void>
|
|
66
44
|
action: unknown extends TRouteInfo['actionResponse']
|
|
67
45
|
?
|
|
68
46
|
| Action<TRouteInfo['actionPayload'], TRouteInfo['actionResponse']>
|
|
@@ -83,6 +61,30 @@ export interface Route<
|
|
|
83
61
|
TRouteInfo['allParams'],
|
|
84
62
|
TRouteInfo['routeLoaderData']
|
|
85
63
|
>
|
|
64
|
+
// buildLink: <TTo extends string = '.'>(
|
|
65
|
+
// options: Omit<
|
|
66
|
+
// LinkOptions<TAllRouteInfo, TRouteInfo['fullPath'], TTo>,
|
|
67
|
+
// 'from'
|
|
68
|
+
// >,
|
|
69
|
+
// ) => LinkInfo
|
|
70
|
+
// matchRoute: <
|
|
71
|
+
// TTo extends string = '.',
|
|
72
|
+
// TResolved extends string = ResolveRelativePath<TRouteInfo['id'], TTo>,
|
|
73
|
+
// >(
|
|
74
|
+
// matchLocation: CheckRelativePath<
|
|
75
|
+
// TAllRouteInfo,
|
|
76
|
+
// TRouteInfo['fullPath'],
|
|
77
|
+
// NoInfer<TTo>
|
|
78
|
+
// > &
|
|
79
|
+
// Omit<ToOptions<TAllRouteInfo, TRouteInfo['fullPath'], TTo>, 'from'>,
|
|
80
|
+
// opts?: MatchRouteOptions,
|
|
81
|
+
// ) => RouteInfoByPath<TAllRouteInfo, TResolved>['allParams']
|
|
82
|
+
// navigate: <TTo extends string = '.'>(
|
|
83
|
+
// options: Omit<
|
|
84
|
+
// LinkOptions<TAllRouteInfo, TRouteInfo['fullPath'], TTo>,
|
|
85
|
+
// 'from'
|
|
86
|
+
// >,
|
|
87
|
+
// ) => Promise<void>
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
export function createRoute<
|
|
@@ -92,140 +94,159 @@ export function createRoute<
|
|
|
92
94
|
>(
|
|
93
95
|
routeConfig: RouteConfig,
|
|
94
96
|
options: TRouteInfo['options'],
|
|
97
|
+
originalIndex: number,
|
|
95
98
|
parent: undefined | Route<TAllRouteInfo, any>,
|
|
96
99
|
router: Router<TAllRouteInfo['routeConfig'], TAllRouteInfo, TRouterContext>,
|
|
97
100
|
): Route<TAllRouteInfo, TRouteInfo, TRouterContext> {
|
|
98
101
|
const { id, routeId, path: routePath, fullPath } = routeConfig
|
|
99
102
|
|
|
100
|
-
const action =
|
|
101
|
-
router.state.actions[id] ||
|
|
102
|
-
(() => {
|
|
103
|
-
router.state.actions[id] = {
|
|
104
|
-
submissions: [],
|
|
105
|
-
submit: async <T, U>(
|
|
106
|
-
submission: T,
|
|
107
|
-
actionOpts?: { invalidate?: boolean; multi?: boolean },
|
|
108
|
-
) => {
|
|
109
|
-
if (!route) {
|
|
110
|
-
return
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const invalidate = actionOpts?.invalidate ?? true
|
|
114
|
-
|
|
115
|
-
if (!actionOpts?.multi) {
|
|
116
|
-
action.submissions = action.submissions.filter((d) => d.isMulti)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const actionState: ActionState<T, U> = {
|
|
120
|
-
submittedAt: Date.now(),
|
|
121
|
-
status: 'pending',
|
|
122
|
-
submission,
|
|
123
|
-
isMulti: !!actionOpts?.multi,
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
action.current = actionState
|
|
127
|
-
action.latest = actionState
|
|
128
|
-
action.submissions.push(actionState)
|
|
129
|
-
|
|
130
|
-
router.notify()
|
|
131
|
-
|
|
132
|
-
try {
|
|
133
|
-
const res = await route.options.action?.(submission)
|
|
134
|
-
actionState.data = res as U
|
|
135
|
-
|
|
136
|
-
if (invalidate) {
|
|
137
|
-
router.invalidateRoute({ to: '.', fromCurrent: true })
|
|
138
|
-
await router.reload()
|
|
139
|
-
}
|
|
140
|
-
actionState.status = 'success'
|
|
141
|
-
return res
|
|
142
|
-
} catch (err) {
|
|
143
|
-
console.error(err)
|
|
144
|
-
actionState.error = err
|
|
145
|
-
actionState.status = 'error'
|
|
146
|
-
} finally {
|
|
147
|
-
router.notify()
|
|
148
|
-
}
|
|
149
|
-
},
|
|
150
|
-
}
|
|
151
|
-
return router.state.actions[id]!
|
|
152
|
-
})()
|
|
153
|
-
|
|
154
|
-
const loader =
|
|
155
|
-
router.state.loaders[id] ||
|
|
156
|
-
(() => {
|
|
157
|
-
router.state.loaders[id] = {
|
|
158
|
-
pending: [],
|
|
159
|
-
fetch: (async (loaderContext: LoaderContext<any, any>) => {
|
|
160
|
-
if (!route) {
|
|
161
|
-
return
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const loaderState: LoaderState<any, any> = {
|
|
165
|
-
loadedAt: Date.now(),
|
|
166
|
-
loaderContext,
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
loader.current = loaderState
|
|
170
|
-
loader.latest = loaderState
|
|
171
|
-
loader.pending.push(loaderState)
|
|
172
|
-
|
|
173
|
-
// router.state = {
|
|
174
|
-
// ...router.state,
|
|
175
|
-
// currentAction: loaderState,
|
|
176
|
-
// latestAction: loaderState,
|
|
177
|
-
// }
|
|
178
|
-
|
|
179
|
-
router.notify()
|
|
180
|
-
|
|
181
|
-
try {
|
|
182
|
-
return await route.options.loader?.(loaderContext)
|
|
183
|
-
} finally {
|
|
184
|
-
loader.pending = loader.pending.filter((d) => d !== loaderState)
|
|
185
|
-
// router.removeActionQueue.push({ loader, loaderState })
|
|
186
|
-
router.notify()
|
|
187
|
-
}
|
|
188
|
-
}) as any,
|
|
189
|
-
}
|
|
190
|
-
return router.state.loaders[id]!
|
|
191
|
-
})()
|
|
192
|
-
|
|
193
103
|
let route: Route<TAllRouteInfo, TRouteInfo, TRouterContext> = {
|
|
194
104
|
routeInfo: undefined!,
|
|
195
105
|
routeId: id,
|
|
196
106
|
routeRouteId: routeId,
|
|
107
|
+
originalIndex,
|
|
197
108
|
routePath,
|
|
198
109
|
fullPath,
|
|
199
110
|
options,
|
|
200
111
|
router,
|
|
201
112
|
childRoutes: undefined!,
|
|
202
113
|
parentRoute: parent,
|
|
203
|
-
action
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
114
|
+
get action() {
|
|
115
|
+
let action =
|
|
116
|
+
router.store.actions[id] ||
|
|
117
|
+
(() => {
|
|
118
|
+
router.setStore((s) => {
|
|
119
|
+
s.actions[id] = {
|
|
120
|
+
submissions: [],
|
|
121
|
+
submit: async <T, U>(
|
|
122
|
+
submission: T,
|
|
123
|
+
actionOpts?: { invalidate?: boolean; multi?: boolean },
|
|
124
|
+
) => {
|
|
125
|
+
if (!route) {
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const invalidate = actionOpts?.invalidate ?? true
|
|
130
|
+
|
|
131
|
+
const [actionStore, setActionStore] = createStore<
|
|
132
|
+
ActionState<T, U>
|
|
133
|
+
>({
|
|
134
|
+
submittedAt: Date.now(),
|
|
135
|
+
status: 'pending',
|
|
136
|
+
submission,
|
|
137
|
+
isMulti: !!actionOpts?.multi,
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
router.setStore((s) => {
|
|
141
|
+
if (!actionOpts?.multi) {
|
|
142
|
+
s.actions[id]!.submissions = action.submissions.filter(
|
|
143
|
+
(d) => d.isMulti,
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
s.actions[id]!.current = actionStore
|
|
148
|
+
s.actions[id]!.latest = actionStore
|
|
149
|
+
s.actions[id]!.submissions.push(actionStore)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
const res = await route.options.action?.(submission)
|
|
154
|
+
|
|
155
|
+
setActionStore((s) => {
|
|
156
|
+
s.data = res as U
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
if (invalidate) {
|
|
160
|
+
router.invalidateRoute({ to: '.', fromCurrent: true })
|
|
161
|
+
await router.reload()
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
setActionStore((s) => {
|
|
165
|
+
s.status = 'success'
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
return res
|
|
169
|
+
} catch (err) {
|
|
170
|
+
console.error(err)
|
|
171
|
+
setActionStore((s) => {
|
|
172
|
+
s.error = err
|
|
173
|
+
s.status = 'error'
|
|
174
|
+
})
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
}
|
|
178
|
+
})
|
|
212
179
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
} as any) as any
|
|
180
|
+
return router.store.actions[id]!
|
|
181
|
+
})()
|
|
182
|
+
|
|
183
|
+
return action
|
|
218
184
|
},
|
|
185
|
+
get loader() {
|
|
186
|
+
let loader =
|
|
187
|
+
router.store.loaders[id] ||
|
|
188
|
+
(() => {
|
|
189
|
+
router.setStore((s) => {
|
|
190
|
+
s.loaders[id] = {
|
|
191
|
+
pending: [],
|
|
192
|
+
fetch: (async (loaderContext: LoaderContext<any, any>) => {
|
|
193
|
+
if (!route) {
|
|
194
|
+
return
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const loaderState: LoaderState<any, any> = {
|
|
198
|
+
loadedAt: Date.now(),
|
|
199
|
+
loaderContext,
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
router.setStore((s) => {
|
|
203
|
+
s.loaders[id]!.current = loaderState
|
|
204
|
+
s.loaders[id]!.latest = loaderState
|
|
205
|
+
s.loaders[id]!.pending.push(loaderState)
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
try {
|
|
209
|
+
return await route.options.loader?.(loaderContext)
|
|
210
|
+
} finally {
|
|
211
|
+
router.setStore((s) => {
|
|
212
|
+
s.loaders[id]!.pending = s.loaders[id]!.pending.filter(
|
|
213
|
+
(d) => d !== loaderState,
|
|
214
|
+
)
|
|
215
|
+
})
|
|
216
|
+
}
|
|
217
|
+
}) as any,
|
|
218
|
+
}
|
|
219
|
+
})
|
|
219
220
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
from: fullPath,
|
|
225
|
-
} as any,
|
|
226
|
-
opts,
|
|
227
|
-
) as any
|
|
221
|
+
return router.store.loaders[id]!
|
|
222
|
+
})()
|
|
223
|
+
|
|
224
|
+
return loader as any
|
|
228
225
|
},
|
|
226
|
+
|
|
227
|
+
// buildLink: (options) => {
|
|
228
|
+
// return router.buildLink({
|
|
229
|
+
// ...options,
|
|
230
|
+
// from: fullPath,
|
|
231
|
+
// } as any) as any
|
|
232
|
+
// },
|
|
233
|
+
|
|
234
|
+
// navigate: (options) => {
|
|
235
|
+
// return router.navigate({
|
|
236
|
+
// ...options,
|
|
237
|
+
// from: fullPath,
|
|
238
|
+
// } as any) as any
|
|
239
|
+
// },
|
|
240
|
+
|
|
241
|
+
// matchRoute: (matchLocation, opts) => {
|
|
242
|
+
// return router.matchRoute(
|
|
243
|
+
// {
|
|
244
|
+
// ...matchLocation,
|
|
245
|
+
// from: fullPath,
|
|
246
|
+
// } as any,
|
|
247
|
+
// opts,
|
|
248
|
+
// ) as any
|
|
249
|
+
// },
|
|
229
250
|
}
|
|
230
251
|
|
|
231
252
|
router.options.createRoute?.({ router, route })
|