Skip to content

Commit 75e2647

Browse files
author
Ryan
authored
Merge pull request #3 from pynnl/rewrite-matching-algorithm
Rewrite matching algorithm
2 parents e0e29da + 85f7c55 commit 75e2647

File tree

8 files changed

+64
-17
lines changed

8 files changed

+64
-17
lines changed

cypress/integration/main.spec.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,16 @@ it('matches', () => {
205205
cy.visit('#/matches/route2/route3')
206206
checkProp(arr, '/', 'matches', '/route2', '/route3')
207207
})
208+
209+
it('stringify', () => {
210+
cy.visit('#/stringify')
211+
212+
cy.get('button:contains(123)').click()
213+
cy.get('.property').should('contain', 'John')
214+
215+
cy.get('button:contains(456)').click()
216+
cy.get('.property').should('contain', 'Anne')
217+
218+
cy.get('button:contains(789)').click()
219+
cy.get('.property').should('contain', 'Rose')
220+
})

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"lint:style": "stylelint .",
2323
"test": "run-s lint test:build test:start",
2424
"test:dev": "npm run test:build -- -w",
25-
"test:build": "rollup -c test.config.js",
25+
"test:build": "rollup -c",
2626
"test:server": "browser-sync test --no-ui --no-open",
2727
"test:start": "server-test test:server 3000 test:cy",
2828
"test:cy": "cypress run --spec cypress/integration/main.spec.js"
File renamed without changes.

src/utils/match.js

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,10 @@ import { derived } from 'svelte/store'
33
import { routes } from './routes'
44
import { pathname } from './path'
55

6-
function map (routes, matches = []) {
7-
return Object.values(routes).reverse().map(e => [e, matches])
8-
}
9-
106
// Search for matching route
11-
function parse (routes, pathname) {
12-
let stack = map(routes)
13-
14-
while (stack.length) {
15-
let [active, matches] = stack.pop()
7+
function parse (active, pathname, notRoot, matches = []) {
8+
if (notRoot) {
169
let params = active.$$pattern.match(pathname)
17-
matches = [...matches, active]
18-
1910
if (params) {
2011
return !active.$$redirect
2112
? { active, params, matches }
@@ -25,8 +16,11 @@ function parse (routes, pathname) {
2516
window.dispatchEvent(new Event('hashchange'))
2617
})
2718
}
19+
}
2820

29-
stack = stack.concat(map(active, matches))
21+
for (let e of Object.values(active)) {
22+
let result = parse(e, pathname, true, [...matches, e])
23+
if (result) return result
3024
}
3125
}
3226

src/utils/path.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ let path = readable(parse(), set => {
1717

1818
let pathname = derived(path, $ => $.pathname) // current pathname without query
1919
let querystring = derived(path, $ => $.querystring)
20-
let query = derived(querystring, $ => Object.fromEntries(new URLSearchParams($)))
20+
let query = derived(querystring, $ => {
21+
return Array.from(new URLSearchParams($))
22+
.reduce((a, [i, e]) => { a[i] = e; return a }, {})
23+
})
2124

2225
export { pathname, query }

src/utils/routes.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ function parse (schema = {}, notRoot, pathname, href = '#') {
1515
let type = typeof schema
1616
schema = type === 'function' ? { $$component: schema }
1717
: type === 'string' ? { $$redirect: schema }
18-
: type !== 'object' ? {}
19-
: schema === null ? {} : schema
18+
: (type !== 'object' || schema === null) ? {} : schema
2019

2120
let c = schema.$$component
2221
if (typeof c !== 'function' && c !== undefined && c !== null)

test/src/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Params, { schema as _Params } from './tests/Params.svelte'
1010
import Query from './tests/Query.svelte'
1111
import Active, { schema as _Active } from './tests/Active.svelte'
1212
import Matches, { schema as _Matches } from './tests/Matches.svelte'
13+
import Stringify, { schema as _Stringify } from './tests/Stringify.svelte'
1314

1415
routes.set({
1516
'/': {
@@ -23,7 +24,8 @@ routes.set({
2324
'params': { $$component: Params, ..._Params },
2425
'query': Query,
2526
'active': { $$component: Active, ..._Active },
26-
'matches': { $$component: Matches, ..._Matches }
27+
'matches': { $$component: Matches, ..._Matches },
28+
'stringify': { $$component: Stringify, ..._Stringify }
2729
}
2830
})
2931

test/src/tests/Stringify.svelte

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<script context='module'>
2+
import { routes, params } from '../../../src'
3+
import Navigator from '../components/Navigator.svelte'
4+
import Property from '../components/Property.svelte'
5+
6+
export let schema = {
7+
'/:id/:name': null
8+
}
9+
</script>
10+
11+
<script>
12+
let current = 0
13+
let values = [
14+
{ id: '123', name: 'John' },
15+
{ id: '456', name: 'Anne' },
16+
{ id: '789', name: 'Rose' }
17+
]
18+
19+
$: route = $routes[`/`][`stringify`]
20+
</script>
21+
22+
<Navigator route='{$routes[`/`][`stringify`]}'/>
23+
<div>
24+
{#each values as e, i}
25+
<button on:click='{()=>current=i}'>{e.id} - {e.name}</button>
26+
{/each}
27+
<Property value={values[current].name}/>
28+
</div>
29+
30+
<style>
31+
button {
32+
display: block;
33+
margin: 10px 20px;
34+
padding: 5px;
35+
}
36+
</style>

0 commit comments

Comments
 (0)