@tanstack/router-core 0.0.1-beta.15 → 0.0.1-beta.151

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 (64) hide show
  1. package/LICENSE +21 -0
  2. package/build/cjs/fileRoute.js +29 -0
  3. package/build/cjs/fileRoute.js.map +1 -0
  4. package/build/cjs/history.js +226 -0
  5. package/build/cjs/history.js.map +1 -0
  6. package/build/cjs/index.js +78 -0
  7. package/build/cjs/{packages/router-core/src/index.js.map → index.js.map} +1 -1
  8. package/build/cjs/{packages/router-core/src/path.js → path.js} +45 -56
  9. package/build/cjs/path.js.map +1 -0
  10. package/build/cjs/{packages/router-core/src/qss.js → qss.js} +10 -16
  11. package/build/cjs/qss.js.map +1 -0
  12. package/build/cjs/route.js +103 -0
  13. package/build/cjs/route.js.map +1 -0
  14. package/build/cjs/router.js +1113 -0
  15. package/build/cjs/router.js.map +1 -0
  16. package/build/cjs/{packages/router-core/src/searchParams.js → searchParams.js} +11 -13
  17. package/build/cjs/searchParams.js.map +1 -0
  18. package/build/cjs/{packages/router-core/src/utils.js → utils.js} +54 -64
  19. package/build/cjs/utils.js.map +1 -0
  20. package/build/esm/index.js +1417 -2105
  21. package/build/esm/index.js.map +1 -1
  22. package/build/stats-html.html +59 -49
  23. package/build/stats-react.json +203 -234
  24. package/build/types/index.d.ts +604 -426
  25. package/build/umd/index.development.js +1640 -2224
  26. package/build/umd/index.development.js.map +1 -1
  27. package/build/umd/index.production.js +13 -2
  28. package/build/umd/index.production.js.map +1 -1
  29. package/package.json +11 -7
  30. package/src/fileRoute.ts +120 -0
  31. package/src/history.ts +292 -0
  32. package/src/index.ts +3 -10
  33. package/src/link.ts +118 -113
  34. package/src/path.ts +37 -17
  35. package/src/qss.ts +1 -2
  36. package/src/route.ts +891 -218
  37. package/src/routeInfo.ts +121 -204
  38. package/src/router.ts +1494 -1017
  39. package/src/searchParams.ts +1 -1
  40. package/src/utils.ts +80 -49
  41. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -33
  42. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
  43. package/build/cjs/node_modules/@babel/runtime/helpers/esm/extends.js +0 -33
  44. package/build/cjs/node_modules/@babel/runtime/helpers/esm/extends.js.map +0 -1
  45. package/build/cjs/node_modules/history/index.js +0 -815
  46. package/build/cjs/node_modules/history/index.js.map +0 -1
  47. package/build/cjs/node_modules/tiny-invariant/dist/esm/tiny-invariant.js +0 -30
  48. package/build/cjs/node_modules/tiny-invariant/dist/esm/tiny-invariant.js.map +0 -1
  49. package/build/cjs/packages/router-core/src/index.js +0 -58
  50. package/build/cjs/packages/router-core/src/path.js.map +0 -1
  51. package/build/cjs/packages/router-core/src/qss.js.map +0 -1
  52. package/build/cjs/packages/router-core/src/route.js +0 -147
  53. package/build/cjs/packages/router-core/src/route.js.map +0 -1
  54. package/build/cjs/packages/router-core/src/routeConfig.js +0 -69
  55. package/build/cjs/packages/router-core/src/routeConfig.js.map +0 -1
  56. package/build/cjs/packages/router-core/src/routeMatch.js +0 -231
  57. package/build/cjs/packages/router-core/src/routeMatch.js.map +0 -1
  58. package/build/cjs/packages/router-core/src/router.js +0 -833
  59. package/build/cjs/packages/router-core/src/router.js.map +0 -1
  60. package/build/cjs/packages/router-core/src/searchParams.js.map +0 -1
  61. package/build/cjs/packages/router-core/src/utils.js.map +0 -1
  62. package/src/frameworks.ts +0 -11
  63. package/src/routeConfig.ts +0 -514
  64. package/src/routeMatch.ts +0 -319
package/src/link.ts CHANGED
@@ -1,11 +1,6 @@
1
- import { AnyPathParams } from './routeConfig'
2
- import {
3
- AnyAllRouteInfo,
4
- DefaultAllRouteInfo,
5
- RouteInfoByPath,
6
- } from './routeInfo'
7
- import { Location } from './router'
8
- import { Expand, NoInfer, PickAsRequired, PickRequired, Updater } from './utils'
1
+ import { AnyRoutesInfo, RouteByPath } from './routeInfo'
2
+ import { ParsedLocation, LocationState, RegisteredRoutesInfo } from './router'
3
+ import { NoInfer, PickRequired, UnionToIntersection, Updater } from './utils'
9
4
 
10
5
  export type LinkInfo =
11
6
  | {
@@ -14,19 +9,16 @@ export type LinkInfo =
14
9
  }
15
10
  | {
16
11
  type: 'internal'
17
- next: Location
12
+ next: ParsedLocation
18
13
  handleFocus: (e: any) => void
19
14
  handleClick: (e: any) => void
20
15
  handleEnter: (e: any) => void
21
16
  handleLeave: (e: any) => void
17
+ handleTouchStart: (e: any) => void
22
18
  isActive: boolean
23
19
  disabled?: boolean
24
20
  }
25
21
 
26
- type StartsWith<A, B> = A extends `${B extends string ? B : never}${infer _}`
27
- ? true
28
- : false
29
-
30
22
  type CleanPath<T extends string> = T extends `${infer L}//${infer R}`
31
23
  ? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`>
32
24
  : T extends `${infer L}//`
@@ -58,19 +50,21 @@ export type Split<S, TIncludeTrailingSlash = true> = S extends unknown
58
50
  : never
59
51
 
60
52
  export type ParsePathParams<T extends string> = Split<T>[number] extends infer U
61
- ? U extends `:${infer V}`
53
+ ? U extends `$${infer V}`
62
54
  ? V
63
55
  : never
64
56
  : never
65
57
 
66
- type Join<T> = T extends []
58
+ export type Join<T, Delimiter extends string = '/'> = T extends []
67
59
  ? ''
68
60
  : T extends [infer L extends string]
69
61
  ? L
70
62
  : T extends [infer L extends string, ...infer Tail extends [...string[]]]
71
- ? CleanPath<`${L}/${Join<Tail>}`>
63
+ ? CleanPath<`${L}${Delimiter}${Join<Tail>}`>
72
64
  : never
73
65
 
66
+ export type Last<T extends any[]> = T extends [...infer _, infer L] ? L : never
67
+
74
68
  export type RelativeToPathAutoComplete<
75
69
  AllPaths extends string,
76
70
  TFrom extends string,
@@ -106,126 +100,155 @@ export type RelativeToPathAutoComplete<
106
100
  ]
107
101
  ? `${TTo}${Join<RestPath>}`
108
102
  : never
109
- : './' | '../' | AllPaths
103
+ :
104
+ | (TFrom extends `/`
105
+ ? never
106
+ : SplitPaths extends [...Split<TFrom, false>, ...infer RestPath]
107
+ ? Join<RestPath> extends { length: 0 }
108
+ ? never
109
+ : './'
110
+ : never)
111
+ | (TFrom extends `/` ? never : '../')
112
+ | AllPaths
110
113
 
111
- export type NavigateOptionsAbsolute<
112
- TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
113
- TFrom extends ValidFromPath<TAllRouteInfo> = '/',
114
- TTo extends string = '.',
115
- > = ToOptions<TAllRouteInfo, TFrom, TTo> & {
116
- // Whether to replace the current history stack instead of pushing a new one
114
+ export type NavigateOptions<
115
+ TRoutesInfo extends AnyRoutesInfo = RegisteredRoutesInfo,
116
+ TFrom extends TRoutesInfo['routePaths'] = '/',
117
+ TTo extends string = '',
118
+ > = ToOptions<TRoutesInfo, TFrom, TTo> & {
119
+ // `replace` is a boolean that determines whether the navigation should replace the current history entry or push a new one.
117
120
  replace?: boolean
118
121
  }
119
122
 
120
123
  export type ToOptions<
121
- TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
122
- TFrom extends ValidFromPath<TAllRouteInfo> = '/',
123
- TTo extends string = '.',
124
+ TRoutesInfo extends AnyRoutesInfo = RegisteredRoutesInfo,
125
+ TFrom extends TRoutesInfo['routePaths'] = '/',
126
+ TTo extends string = '',
124
127
  TResolvedTo = ResolveRelativePath<TFrom, NoInfer<TTo>>,
125
128
  > = {
126
- to?: ToPathOption<TAllRouteInfo, TFrom, TTo>
129
+ to?: ToPathOption<TRoutesInfo, TFrom, TTo>
127
130
  // The new has string or a function to update it
128
131
  hash?: Updater<string>
132
+ // State to pass to the history stack
133
+ state?: LocationState
129
134
  // The source route path. This is automatically set when using route-level APIs, but for type-safe relative routing on the router itself, this is required
130
135
  from?: TFrom
131
136
  // // When using relative route paths, this option forces resolution from the current path, instead of the route API's path or `from` path
132
137
  // fromCurrent?: boolean
133
- } & CheckPath<TAllRouteInfo, NoInfer<TResolvedTo>, {}> &
134
- SearchParamOptions<TAllRouteInfo, TFrom, TResolvedTo> &
135
- PathParamOptions<TAllRouteInfo, TFrom, TResolvedTo>
138
+ } & CheckPath<TRoutesInfo, NoInfer<TResolvedTo>, {}> &
139
+ SearchParamOptions<TRoutesInfo, TFrom, TResolvedTo> &
140
+ PathParamOptions<TRoutesInfo, TFrom, TResolvedTo>
136
141
 
137
- type SearchParamOptions<
138
- TAllRouteInfo extends AnyAllRouteInfo,
142
+ export type SearchParamOptions<
143
+ TRoutesInfo extends AnyRoutesInfo,
139
144
  TFrom,
140
145
  TTo,
141
- TFromSchema = RouteInfoByPath<TAllRouteInfo, TFrom>['fullSearchSchema'],
142
- TToSchema = RouteInfoByPath<TAllRouteInfo, TTo>['fullSearchSchema'],
143
- > = StartsWith<TFrom, TTo> extends true // If the next route search extend or cover the from route, params will be optional
144
- ? {
145
- search?: SearchReducer<TFromSchema, TToSchema>
146
- }
147
- : // Optional search params? Allow it
148
- keyof PickRequired<TToSchema> extends never
146
+ TFromSchema = UnionToIntersection<
147
+ TRoutesInfo['fullSearchSchema'] &
148
+ RouteByPath<TRoutesInfo, TFrom> extends never
149
+ ? {}
150
+ : RouteByPath<TRoutesInfo, TFrom>['__types']['fullSearchSchema']
151
+ >,
152
+ // Find the schema for the new path, and make optional any keys
153
+ // that are already defined in the current schema
154
+ TToSchema = Partial<
155
+ RouteByPath<TRoutesInfo, TFrom>['__types']['fullSearchSchema']
156
+ > &
157
+ Omit<
158
+ RouteByPath<TRoutesInfo, TTo>['__types']['fullSearchSchema'],
159
+ keyof PickRequired<
160
+ RouteByPath<TRoutesInfo, TFrom>['__types']['fullSearchSchema']
161
+ >
162
+ >,
163
+ TFromFullSchema = UnionToIntersection<
164
+ TRoutesInfo['fullSearchSchema'] & TFromSchema
165
+ >,
166
+ TToFullSchema = UnionToIntersection<
167
+ TRoutesInfo['fullSearchSchema'] & TToSchema
168
+ >,
169
+ > = keyof PickRequired<TToSchema> extends never
149
170
  ? {
150
- search?: SearchReducer<TFromSchema, TToSchema>
171
+ search?: true | SearchReducer<TFromFullSchema, TToFullSchema>
151
172
  }
152
173
  : {
153
- // Must have required search params, enforce it
154
- search: SearchReducer<TFromSchema, TToSchema>
174
+ search: SearchReducer<TFromFullSchema, TToFullSchema>
155
175
  }
156
176
 
157
177
  type SearchReducer<TFrom, TTo> =
158
178
  | { [TKey in keyof TTo]: TTo[TKey] }
159
179
  | ((current: TFrom) => TTo)
160
180
 
161
- type PathParamOptions<
162
- TAllRouteInfo extends AnyAllRouteInfo,
181
+ export type PathParamOptions<
182
+ TRoutesInfo extends AnyRoutesInfo,
163
183
  TFrom,
164
184
  TTo,
165
- TFromParams = RouteInfoByPath<TAllRouteInfo, TFrom>['allParams'],
166
- TToParams = RouteInfoByPath<TAllRouteInfo, TTo>['allParams'],
167
- > =
168
- // If the next routes params extend or cover the from route, params will be optional
169
- StartsWith<TFrom, TTo> extends true
170
- ? {
171
- params?: ParamsReducer<TFromParams, TToParams>
172
- }
173
- : // If the next route doesn't have params, warn if any have been passed
174
- AnyPathParams extends TToParams
175
- ? {
176
- params?: ParamsReducer<TFromParams, Record<string, never>>
177
- }
178
- : // If the next route has params, enforce them
179
- {
180
- params: ParamsReducer<TFromParams, TToParams>
181
- }
185
+ TFromSchema = UnionToIntersection<
186
+ RouteByPath<TRoutesInfo, TFrom> extends never
187
+ ? {}
188
+ : RouteByPath<TRoutesInfo, TFrom>['__types']['allParams']
189
+ >,
190
+ // Find the schema for the new path, and make optional any keys
191
+ // that are already defined in the current schema
192
+ TToSchema = Partial<RouteByPath<TRoutesInfo, TFrom>['__types']['allParams']> &
193
+ Omit<
194
+ RouteByPath<TRoutesInfo, TTo>['__types']['allParams'],
195
+ keyof PickRequired<
196
+ RouteByPath<TRoutesInfo, TFrom>['__types']['allParams']
197
+ >
198
+ >,
199
+ TFromFullParams = UnionToIntersection<TRoutesInfo['allParams'] & TFromSchema>,
200
+ TToFullParams = UnionToIntersection<TRoutesInfo['allParams'] & TToSchema>,
201
+ > = keyof PickRequired<TToSchema> extends never
202
+ ? {
203
+ params?: ParamsReducer<TFromFullParams, TToFullParams>
204
+ }
205
+ : {
206
+ params: ParamsReducer<TFromFullParams, TToFullParams>
207
+ }
182
208
 
183
209
  type ParamsReducer<TFrom, TTo> = TTo | ((current: TFrom) => TTo)
184
210
 
185
211
  export type ToPathOption<
186
- TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
187
- TFrom extends ValidFromPath<TAllRouteInfo> = '/',
188
- TTo extends string = '.',
212
+ TRoutesInfo extends AnyRoutesInfo = RegisteredRoutesInfo,
213
+ TFrom extends TRoutesInfo['routePaths'] = '/',
214
+ TTo extends string = '',
189
215
  > =
190
216
  | TTo
191
217
  | RelativeToPathAutoComplete<
192
- TAllRouteInfo['routePaths'],
218
+ TRoutesInfo['routePaths'],
193
219
  NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',
194
220
  NoInfer<TTo> & string
195
221
  >
196
222
 
197
223
  export type ToIdOption<
198
- TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
199
- TFrom extends ValidFromPath<TAllRouteInfo> = '/',
200
- TTo extends string = '.',
224
+ TRoutesInfo extends AnyRoutesInfo = RegisteredRoutesInfo,
225
+ TFrom extends TRoutesInfo['routePaths'] = '/',
226
+ TTo extends string = '',
201
227
  > =
202
228
  | TTo
203
229
  | RelativeToPathAutoComplete<
204
- TAllRouteInfo['routeIds'],
230
+ TRoutesInfo['routeIds'],
205
231
  NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',
206
232
  NoInfer<TTo> & string
207
233
  >
208
234
 
209
- interface ActiveOptions {
235
+ export interface ActiveOptions {
210
236
  exact?: boolean
211
237
  includeHash?: boolean
238
+ includeSearch?: boolean
212
239
  }
213
240
 
214
241
  export type LinkOptions<
215
- TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
216
- TFrom extends ValidFromPath<TAllRouteInfo> = '/',
217
- TTo extends string = '.',
218
- > = NavigateOptionsAbsolute<TAllRouteInfo, TFrom, TTo> & {
242
+ TRoutesInfo extends AnyRoutesInfo = RegisteredRoutesInfo,
243
+ TFrom extends TRoutesInfo['routePaths'] = '/',
244
+ TTo extends string = '',
245
+ > = NavigateOptions<TRoutesInfo, TFrom, TTo> & {
219
246
  // The standard anchor tag target attribute
220
247
  target?: HTMLAnchorElement['target']
221
248
  // Defaults to `{ exact: false, includeHash: false }`
222
249
  activeOptions?: ActiveOptions
223
250
  // If set, will preload the linked route on hover and cache it for this many milliseconds in hopes that the user will eventually navigate there.
224
251
  preload?: false | 'intent'
225
- // When preloaded, the preloaded result will be considered "fresh" for this duration in milliseconds
226
- preloadMaxAge?: number
227
- // When preloaded and subsequently inactive, the preloaded result will remain in memory for this duration in milliseconds
228
- preloadGcMaxAge?: number
229
252
  // Delay intent preloading by this many milliseconds. If the intent exits before this delay, the preload will be cancelled.
230
253
  preloadDelay?: number
231
254
  // If true, will render the link without the href attribute
@@ -233,58 +256,48 @@ export type LinkOptions<
233
256
  }
234
257
 
235
258
  export type CheckRelativePath<
236
- TAllRouteInfo extends AnyAllRouteInfo,
259
+ TRoutesInfo extends AnyRoutesInfo,
237
260
  TFrom,
238
261
  TTo,
239
262
  > = TTo extends string
240
263
  ? TFrom extends string
241
- ? ResolveRelativePath<TFrom, TTo> extends TAllRouteInfo['routePaths']
264
+ ? ResolveRelativePath<TFrom, TTo> extends TRoutesInfo['routePaths']
242
265
  ? {}
243
266
  : {
244
267
  Error: `${TFrom} + ${TTo} resolves to ${ResolveRelativePath<
245
268
  TFrom,
246
269
  TTo
247
270
  >}, which is not a valid route path.`
248
- 'Valid Route Paths': TAllRouteInfo['routePaths']
271
+ 'Valid Route Paths': TRoutesInfo['routePaths']
249
272
  }
250
273
  : {}
251
274
  : {}
252
275
 
253
276
  export type CheckPath<
254
- TAllRouteInfo extends AnyAllRouteInfo,
277
+ TRoutesInfo extends AnyRoutesInfo,
255
278
  TPath,
256
279
  TPass,
257
- > = Exclude<TPath, TAllRouteInfo['routePaths']> extends never
280
+ > = Exclude<TPath, TRoutesInfo['routePaths']> extends never
258
281
  ? TPass
259
- : CheckPathError<TAllRouteInfo, Exclude<TPath, TAllRouteInfo['routePaths']>>
282
+ : CheckPathError<TRoutesInfo, Exclude<TPath, TRoutesInfo['routePaths']>>
260
283
 
261
- export type CheckPathError<
262
- TAllRouteInfo extends AnyAllRouteInfo,
263
- TInvalids,
264
- > = Expand<{
265
- Error: `${TInvalids extends string
266
- ? TInvalids
267
- : never} is not a valid route path.`
268
- 'Valid Route Paths': TAllRouteInfo['routePaths']
269
- }>
284
+ export type CheckPathError<TRoutesInfo extends AnyRoutesInfo, TInvalids> = {
285
+ to: TRoutesInfo['routePaths']
286
+ }
270
287
 
271
- export type CheckId<
272
- TAllRouteInfo extends AnyAllRouteInfo,
288
+ export type CheckId<TRoutesInfo extends AnyRoutesInfo, TPath, TPass> = Exclude<
273
289
  TPath,
274
- TPass,
275
- > = Exclude<TPath, TAllRouteInfo['routeIds']> extends never
290
+ TRoutesInfo['routeIds']
291
+ > extends never
276
292
  ? TPass
277
- : CheckIdError<TAllRouteInfo, Exclude<TPath, TAllRouteInfo['routeIds']>>
293
+ : CheckIdError<TRoutesInfo, Exclude<TPath, TRoutesInfo['routeIds']>>
278
294
 
279
- export type CheckIdError<
280
- TAllRouteInfo extends AnyAllRouteInfo,
281
- TInvalids,
282
- > = Expand<{
295
+ export type CheckIdError<TRoutesInfo extends AnyRoutesInfo, TInvalids> = {
283
296
  Error: `${TInvalids extends string
284
297
  ? TInvalids
285
298
  : never} is not a valid route ID.`
286
- 'Valid Route IDs': TAllRouteInfo['routeIds']
287
- }>
299
+ 'Valid Route IDs': TRoutesInfo['routeIds']
300
+ }
288
301
 
289
302
  export type ResolveRelativePath<TFrom, TTo = '.'> = TFrom extends string
290
303
  ? TTo extends string
@@ -309,11 +322,3 @@ export type ResolveRelativePath<TFrom, TTo = '.'> = TFrom extends string
309
322
  : CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>>
310
323
  : never
311
324
  : never
312
-
313
- export type ValidFromPath<
314
- TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
315
- > =
316
- | undefined
317
- | (string extends TAllRouteInfo['routePaths']
318
- ? string
319
- : TAllRouteInfo['routePaths'])
package/src/path.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AnyPathParams } from './routeConfig'
1
+ import { AnyPathParams } from './route'
2
2
  import { MatchLocation } from './router'
3
3
  import { last } from './utils'
4
4
 
@@ -90,14 +90,14 @@ export function parsePathname(pathname?: string): Segment[] {
90
90
 
91
91
  segments.push(
92
92
  ...split.map((part): Segment => {
93
- if (part.startsWith('*')) {
93
+ if (part === '$' || part === '*') {
94
94
  return {
95
95
  type: 'wildcard',
96
96
  value: part,
97
97
  }
98
98
  }
99
99
 
100
- if (part.charAt(0) === ':') {
100
+ if (part.charAt(0) === '$') {
101
101
  return {
102
102
  type: 'param',
103
103
  value: part,
@@ -125,14 +125,16 @@ export function parsePathname(pathname?: string): Segment[] {
125
125
  export function interpolatePath(
126
126
  path: string | undefined,
127
127
  params: any,
128
- leaveWildcard?: boolean,
128
+ leaveWildcards: boolean = false,
129
129
  ) {
130
130
  const interpolatedPathSegments = parsePathname(path)
131
131
 
132
132
  return joinPaths(
133
133
  interpolatedPathSegments.map((segment) => {
134
- if (segment.value === '*' && !leaveWildcard) {
135
- return ''
134
+ if (segment.type === 'wildcard') {
135
+ const value = params[segment.value]
136
+ if (leaveWildcards) return `${segment.value}${value ?? ''}`
137
+ return value
136
138
  }
137
139
 
138
140
  if (segment.type === 'param') {
@@ -145,29 +147,46 @@ export function interpolatePath(
145
147
  }
146
148
 
147
149
  export function matchPathname(
150
+ basepath: string,
148
151
  currentPathname: string,
149
152
  matchLocation: Pick<MatchLocation, 'to' | 'fuzzy' | 'caseSensitive'>,
150
153
  ): AnyPathParams | undefined {
151
- const pathParams = matchByPath(currentPathname, matchLocation)
152
- // const searchMatched = matchBySearch(currentLocation.search, matchLocation)
154
+ const pathParams = matchByPath(basepath, currentPathname, matchLocation)
155
+ // const searchMatched = matchBySearch(location.search, matchLocation)
153
156
 
154
157
  if (matchLocation.to && !pathParams) {
155
158
  return
156
159
  }
157
160
 
158
- // if (matchLocation.search && !searchMatched) {
159
- // return
160
- // }
161
-
162
161
  return pathParams ?? {}
163
162
  }
164
163
 
165
164
  export function matchByPath(
165
+ basepath: string,
166
166
  from: string,
167
167
  matchLocation: Pick<MatchLocation, 'to' | 'caseSensitive' | 'fuzzy'>,
168
168
  ): Record<string, string> | undefined {
169
+ // Remove the base path from the pathname
170
+ from = basepath != '/' ? from.substring(basepath.length) : from
171
+ // Default to to $ (wildcard)
172
+ const to = `${matchLocation.to ?? '$'}`
173
+ // Parse the from and to
169
174
  const baseSegments = parsePathname(from)
170
- const routeSegments = parsePathname(`${matchLocation.to ?? '*'}`)
175
+ const routeSegments = parsePathname(to)
176
+
177
+ if (!from.startsWith('/')) {
178
+ baseSegments.unshift({
179
+ type: 'pathname',
180
+ value: '/',
181
+ })
182
+ }
183
+
184
+ if (!to.startsWith('/')) {
185
+ routeSegments.unshift({
186
+ type: 'pathname',
187
+ value: '/',
188
+ })
189
+ }
171
190
 
172
191
  const params: Record<string, string> = {}
173
192
 
@@ -180,8 +199,8 @@ export function matchByPath(
180
199
  const baseSegment = baseSegments[i]
181
200
  const routeSegment = routeSegments[i]
182
201
 
183
- const isLastRouteSegment = i === routeSegments.length - 1
184
- const isLastBaseSegment = i === baseSegments.length - 1
202
+ const isLastBaseSegment = i >= baseSegments.length - 1
203
+ const isLastRouteSegment = i >= routeSegments.length - 1
185
204
 
186
205
  if (routeSegment) {
187
206
  if (routeSegment.type === 'wildcard') {
@@ -219,16 +238,17 @@ export function matchByPath(
219
238
  if (baseSegment?.value === '/') {
220
239
  return false
221
240
  }
222
- if (!baseSegment.value.startsWith(':')) {
241
+ if (baseSegment.value.charAt(0) !== '$') {
223
242
  params[routeSegment.value.substring(1)] = baseSegment.value
224
243
  }
225
244
  }
226
245
  }
227
246
 
228
- if (isLastRouteSegment && !isLastBaseSegment) {
247
+ if (!isLastBaseSegment && isLastRouteSegment) {
229
248
  return !!matchLocation.fuzzy
230
249
  }
231
250
  }
251
+
232
252
  return true
233
253
  })()
234
254
 
package/src/qss.ts CHANGED
@@ -30,8 +30,7 @@ function toValue(mix) {
30
30
  var str = decodeURIComponent(mix)
31
31
  if (str === 'false') return false
32
32
  if (str === 'true') return true
33
- if (str.charAt(0) === '0') return str
34
- return +str * 0 === 0 ? +str : str
33
+ return +str * 0 === 0 && +str + '' === str ? +str : str
35
34
  }
36
35
 
37
36
  export function decode(str) {