Skip to content

Commit

Permalink
refactor: add methods needed by router
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Dec 10, 2024
1 parent b8eba1a commit 65a0940
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 5 deletions.
20 changes: 18 additions & 2 deletions packages/router/src/new-route-resolver/matcher-location.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,41 @@ export interface MatcherLocationAsNamed {
hash?: string

/**
* A path is ignored if `name` is provided.
* @deprecated This is ignored when `name` is provided
*/
path?: undefined
}

export interface MatcherLocationAsPath {
export interface MatcherLocationAsPathRelative {
path: string
query?: LocationQueryRaw
hash?: string

/**
* @deprecated This is ignored when `path` is provided
*/
name?: undefined
/**
* @deprecated This is ignored when `path` (instead of `name`) is provided
*/
params?: undefined
}
export interface MatcherLocationAsPathAbsolute
extends MatcherLocationAsPathRelative {
path: `/${string}`
}

export interface MatcherLocationAsRelative {
params?: MatcherParamsFormatted
query?: LocationQueryRaw
hash?: string

/**
* @deprecated This location is relative to the next parameter. This `name` will be ignored.
*/
name?: undefined
/**
* @deprecated This location is relative to the next parameter. This `path` will be ignored.
*/
path?: undefined
}
14 changes: 14 additions & 0 deletions packages/router/src/new-route-resolver/matcher.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,20 @@ describe('Matcher', () => {
})
})

describe('absolute locations as objects', () => {
it('resolves an object location', () => {
const matcher = createCompiledMatcher()
matcher.addRoute(EMPTY_PATH_ROUTE)
expect(matcher.resolve({ path: '/' })).toMatchObject({
fullPath: '/',
path: '/',
params: {},
query: {},
hash: '',
})
})
})

describe('named locations', () => {
it('resolves named locations with no params', () => {
const matcher = createCompiledMatcher()
Expand Down
12 changes: 12 additions & 0 deletions packages/router/src/new-route-resolver/matcher.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,16 @@ describe('Matcher', () => {
).toEqualTypeOf<NEW_LocationResolved>()
})
})

it('does not allow a name + path', () => {
matcher.resolve({
// ...({} as NEW_LocationResolved),
name: 'foo',
params: {},
// @ts-expect-error: name + path
path: '/e',
})
// @ts-expect-error: name + currentLocation
matcher.resolve({ name: 'a', params: {} }, {} as NEW_LocationResolved)
})
})
43 changes: 40 additions & 3 deletions packages/router/src/new-route-resolver/matcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { encodeQueryValue as _encodeQueryValue } from '../encoding'
import { parseURL, stringifyURL } from '../location'
import type {
MatcherLocationAsNamed,
MatcherLocationAsPathAbsolute,
MatcherLocationAsPathRelative,
MatcherLocationAsRelative,
MatcherParamsFormatted,
} from './matcher-location'
Expand Down Expand Up @@ -48,10 +50,16 @@ export interface RouteResolver<Matcher, MatcherNormalized> {
resolve(location: MatcherLocationAsNamed): NEW_LocationResolved

/**
* Resolves a location by its path. Any required query must be passed.
* Resolves a location by its absolute path (starts with `/`). Any required query must be passed.
* @param location - The location to resolve.
*/
// resolve(location: MatcherLocationAsPath): NEW_MatcherLocationResolved
resolve(location: MatcherLocationAsPathAbsolute): NEW_LocationResolved

resolve(
location: MatcherLocationAsPathRelative,
currentLocation: NEW_LocationResolved
): NEW_LocationResolved

// NOTE: in practice, this overload can cause bugs. It's better to use named locations

/**
Expand All @@ -66,11 +74,28 @@ export interface RouteResolver<Matcher, MatcherNormalized> {
addRoute(matcher: Matcher, parent?: MatcherNormalized): MatcherNormalized
removeRoute(matcher: MatcherNormalized): void
clearRoutes(): void

/**
* Get a list of all matchers.
* Previously named `getRoutes()`
*/
getMatchers(): MatcherNormalized[]

/**
* Get a matcher by its name.
* Previously named `getRecordMatcher()`
*/
getMatcher(name: MatcherName): MatcherNormalized | undefined
}

type MatcherResolveArgs =
| [absoluteLocation: `/${string}`]
| [relativeLocation: string, currentLocation: NEW_LocationResolved]
| [absoluteLocation: MatcherLocationAsPathAbsolute]
| [
relativeLocation: MatcherLocationAsPathRelative,
currentLocation: NEW_LocationResolved
]
| [location: MatcherLocationAsNamed]
| [
relativeLocation: MatcherLocationAsRelative,
Expand Down Expand Up @@ -224,6 +249,7 @@ export function createCompiledMatcher(): RouteResolver<
MatcherRecordRaw,
MatcherPattern
> {
// TODO: we also need an array that has the correct order
const matchers = new Map<MatcherName, MatcherPattern>()

// TODO: allow custom encode/decode functions
Expand All @@ -241,6 +267,7 @@ export function createCompiledMatcher(): RouteResolver<

// string location, e.g. '/foo', '../bar', 'baz', '?page=1'
if (typeof location === 'string') {
// parseURL handles relative paths
const url = parseURL(parseQuery, location, currentLocation?.path)

let matcher: MatcherPattern | undefined
Expand All @@ -266,7 +293,6 @@ export function createCompiledMatcher(): RouteResolver<
// }

parsedParams = { ...pathParams, ...queryParams, ...hashParams }
// console.log('parsedParams', parsedParams)

if (parsedParams) break
} catch (e) {
Expand Down Expand Up @@ -296,6 +322,7 @@ export function createCompiledMatcher(): RouteResolver<
hash: url.hash,
matched,
}
// TODO: handle object location { path, query, hash }
} else {
// relative location or by name
if (__DEV__ && location.name == null && currentLocation == null) {
Expand Down Expand Up @@ -368,11 +395,21 @@ export function createCompiledMatcher(): RouteResolver<
matchers.clear()
}

function getMatchers() {
return Array.from(matchers.values())
}

function getMatcher(name: MatcherName) {
return matchers.get(name)
}

return {
resolve,

addRoute,
removeRoute,
clearRoutes,
getMatcher,
getMatchers,
}
}

0 comments on commit 65a0940

Please sign in to comment.