Skip to content

Commit

Permalink
refactor: simplify router resolve
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Dec 23, 2024
1 parent 42c9849 commit 4d2c23b
Show file tree
Hide file tree
Showing 8 changed files with 359 additions and 259 deletions.
309 changes: 143 additions & 166 deletions packages/router/src/experimental/router.ts

Large diffs are not rendered by default.

15 changes: 1 addition & 14 deletions packages/router/src/new-route-resolver/matcher-pattern.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
import { decode, MatcherName, MatcherQueryParams } from './matcher'
import { decode, MatcherQueryParams } from './matcher'
import { EmptyParams, MatcherParamsFormatted } from './matcher-location'
import { miss } from './matchers/errors'

export interface MatcherPattern {
/**
* Name of the matcher. Unique across all matchers.
*/
name: MatcherName

path: MatcherPatternPath
query?: MatcherPatternQuery
hash?: MatcherPatternHash

parent?: MatcherPattern
}

export interface MatcherPatternParams_Base<
TIn = string,
TOut extends MatcherParamsFormatted = MatcherParamsFormatted
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { mockWarn } from '../../__tests__/vitest-mock-warn'
import {
createCompiledMatcher,
MatcherLocationRaw,
MatcherRecordRaw,
NEW_MatcherRecordRaw,
NEW_LocationResolved,
} from './matcher'
import { PathParams, tokensToParser } from '../matcher/pathParserRanker'
Expand All @@ -24,7 +24,7 @@ const components = { default: component }
function compileRouteRecord(
record: RouteRecordRaw,
parentRecord?: RouteRecordRaw
): MatcherRecordRaw {
): NEW_MatcherRecordRaw {
// we adapt the path to ensure they are absolute
// TODO: aliases? they could be handled directly in the path matcher
const path = record.path.startsWith('/')
Expand Down Expand Up @@ -100,7 +100,7 @@ describe('RouterMatcher.resolve', () => {
| `/${string}` = START_LOCATION
) {
const records = (Array.isArray(record) ? record : [record]).map(
(record): MatcherRecordRaw => compileRouteRecord(record)
(record): NEW_MatcherRecordRaw => compileRouteRecord(record)
)
const matcher = createCompiledMatcher()
for (const record of records) {
Expand Down
57 changes: 54 additions & 3 deletions packages/router/src/new-route-resolver/matcher.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import {
} from './matcher'
import {
MatcherPatternParams_Base,
MatcherPattern,
MatcherPatternPath,
MatcherPatternQuery,
MatcherPatternPathStatic,
MatcherPatternPathDynamic,
} from './matcher-pattern'
import { NEW_MatcherRecord } from './matcher'
import { miss } from './matchers/errors'
import { EmptyParams } from './matcher-location'

Expand Down Expand Up @@ -72,12 +72,17 @@ const ANY_HASH_PATTERN_MATCHER: MatcherPatternParams_Base<
const EMPTY_PATH_ROUTE = {
name: 'no params',
path: EMPTY_PATH_PATTERN_MATCHER,
} satisfies MatcherPattern
} satisfies NEW_MatcherRecord

const ANY_PATH_ROUTE = {
name: 'any path',
path: ANY_PATH_PATTERN_MATCHER,
} satisfies NEW_MatcherRecord

const USER_ID_ROUTE = {
name: 'user-id',
path: USER_ID_PATH_PATTERN_MATCHER,
} satisfies MatcherPattern
} satisfies NEW_MatcherRecord

describe('RouterMatcher', () => {
describe('new matchers', () => {
Expand Down Expand Up @@ -135,6 +140,20 @@ describe('RouterMatcher', () => {
const matcher = createCompiledMatcher()
matcher.addRoute(USER_ID_ROUTE)
})

it('removes static path', () => {
const matcher = createCompiledMatcher()
matcher.addRoute(EMPTY_PATH_ROUTE)
matcher.removeRoute(EMPTY_PATH_ROUTE)
// Add assertions to verify the route was removed
})

it('removes dynamic path', () => {
const matcher = createCompiledMatcher()
matcher.addRoute(USER_ID_ROUTE)
matcher.removeRoute(USER_ID_ROUTE)
// Add assertions to verify the route was removed
})
})

describe('resolve()', () => {
Expand Down Expand Up @@ -293,5 +312,37 @@ describe('RouterMatcher', () => {
})
})
})

describe('encoding', () => {
it('handles encoded string path', () => {
const matcher = createCompiledMatcher([ANY_PATH_ROUTE])
console.log(matcher.resolve('/%23%2F%3F'))
expect(matcher.resolve('/%23%2F%3F')).toMatchObject({
fullPath: '/%23%2F%3F',
path: '/%23%2F%3F',
query: {},
params: {},
hash: '',
})
})

it('decodes query from a string', () => {
const matcher = createCompiledMatcher([ANY_PATH_ROUTE])
expect(matcher.resolve('/foo?foo=%23%2F%3F')).toMatchObject({
path: '/foo',
fullPath: '/foo?foo=%23%2F%3F',
query: { foo: '#/?' },
})
})

it('decodes hash from a string', () => {
const matcher = createCompiledMatcher([ANY_PATH_ROUTE])
expect(matcher.resolve('/foo#h-%23%2F%3F')).toMatchObject({
path: '/foo',
fullPath: '/foo#h-%23%2F%3F',
hash: '#h-#/?',
})
})
})
})
})
36 changes: 24 additions & 12 deletions packages/router/src/new-route-resolver/matcher.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import { describe, expectTypeOf, it } from 'vitest'
import { NEW_LocationResolved, RouteResolver } from './matcher'
import {
NEW_LocationResolved,
NEW_MatcherRecordRaw,
NEW_RouterMatcher,
} from './matcher'
import { EXPERIMENTAL_RouteRecordNormalized } from '../experimental/router'

describe('Matcher', () => {
const matcher: RouteResolver<unknown, unknown> = {} as any
type TMatcherRecordRaw = NEW_MatcherRecordRaw
type TMatcherRecord = EXPERIMENTAL_RouteRecordNormalized

const matcher: NEW_RouterMatcher<TMatcherRecordRaw, TMatcherRecord> =
{} as any

describe('matcher.resolve()', () => {
it('resolves absolute string locations', () => {
expectTypeOf(
matcher.resolve('/foo')
).toEqualTypeOf<NEW_LocationResolved>()
expectTypeOf(matcher.resolve('/foo')).toEqualTypeOf<
NEW_LocationResolved<TMatcherRecord>
>()
})

it('fails on non absolute location without a currentLocation', () => {
Expand All @@ -18,14 +27,14 @@ describe('Matcher', () => {

it('resolves relative locations', () => {
expectTypeOf(
matcher.resolve('foo', {} as NEW_LocationResolved)
).toEqualTypeOf<NEW_LocationResolved>()
matcher.resolve('foo', {} as NEW_LocationResolved<TMatcherRecord>)
).toEqualTypeOf<NEW_LocationResolved<TMatcherRecord>>()
})

it('resolved named locations', () => {
expectTypeOf(
matcher.resolve({ name: 'foo', params: {} })
).toEqualTypeOf<NEW_LocationResolved>()
expectTypeOf(matcher.resolve({ name: 'foo', params: {} })).toEqualTypeOf<
NEW_LocationResolved<TMatcherRecord>
>()
})

it('fails on object relative location without a currentLocation', () => {
Expand All @@ -35,8 +44,11 @@ describe('Matcher', () => {

it('resolves object relative locations with a currentLocation', () => {
expectTypeOf(
matcher.resolve({ params: { id: 1 } }, {} as NEW_LocationResolved)
).toEqualTypeOf<NEW_LocationResolved>()
matcher.resolve(
{ params: { id: 1 } },
{} as NEW_LocationResolved<TMatcherRecord>
)
).toEqualTypeOf<NEW_LocationResolved<TMatcherRecord>>()
})
})

Expand Down
Loading

0 comments on commit 4d2c23b

Please sign in to comment.