space-router 0.8.4 → 0.8.5
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/CHANGELOG.md +5 -0
- package/dist/cjs/history.js +15 -13
- package/dist/cjs/router.js +10 -12
- package/dist/esm/history.js +13 -14
- package/dist/esm/router.js +8 -10
- package/docs/content/_index.md +30 -6
- package/package.json +6 -6
- package/src/history.js +13 -13
- package/src/router.js +8 -8
- package/test/router.test.js +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## 0.8.5
|
|
2
|
+
|
|
3
|
+
- fix redirects - the history was not ready by the time initial transition was kicked off by redirecting
|
|
4
|
+
- remove the possibility to pass the current route via the `merge` option directly, instead set `merge: true` (truthy value works now), and instead optionally pass the current route as the second argument to `navigate(to, curr)` or `href(to, curr)`, this is a breaking change, but also an undocumented API as it it's still being refined and is used for correctly merging urls during async navigations.
|
|
5
|
+
|
|
1
6
|
## 0.8.4
|
|
2
7
|
|
|
3
8
|
- fix the `navigate(url: string)` implementation where `"".replace` was being tested instead of `to.replace`
|
package/dist/cjs/history.js
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.createHistory = createHistory;
|
|
5
5
|
|
|
6
|
-
function createHistory(
|
|
6
|
+
function createHistory(options) {
|
|
7
7
|
var sync = options.sync;
|
|
8
8
|
var mode = options.mode;
|
|
9
9
|
var raf;
|
|
10
|
+
var onPop;
|
|
10
11
|
var memory = [];
|
|
11
12
|
var off;
|
|
12
13
|
var destroyed = false;
|
|
@@ -26,29 +27,30 @@ function createHistory(onChange, options) {
|
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
function listen(onChange) {
|
|
31
|
+
onPop = function onPop() {
|
|
32
|
+
return onChange(getUrl());
|
|
33
|
+
};
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
if (mode !== 'memory') {
|
|
36
|
+
off = on(window, mode === 'history' ? 'popstate' : 'hashchange', onPop);
|
|
37
|
+
raf(onPop);
|
|
38
|
+
}
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
return function () {
|
|
41
|
+
destroyed = true;
|
|
42
|
+
off && off();
|
|
43
|
+
};
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
return {
|
|
47
|
+
listen: listen,
|
|
42
48
|
getUrl: getUrl,
|
|
43
49
|
push: function push(url) {
|
|
44
50
|
go(url);
|
|
45
51
|
},
|
|
46
52
|
replace: function replace(url) {
|
|
47
53
|
go(url, true);
|
|
48
|
-
},
|
|
49
|
-
destroy: function destroy() {
|
|
50
|
-
destroyed = true;
|
|
51
|
-
off && off();
|
|
52
54
|
}
|
|
53
55
|
};
|
|
54
56
|
|
package/dist/cjs/router.js
CHANGED
|
@@ -40,29 +40,27 @@ function createRouter(options) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
routes = flatten(routeMap);
|
|
43
|
-
|
|
44
|
-
var onHistoryChange = function onHistoryChange(url) {
|
|
45
|
-
return transition(router, url, cb);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
history = (0, _history.createHistory)(onHistoryChange, {
|
|
43
|
+
history = (0, _history.createHistory)({
|
|
49
44
|
mode: mode,
|
|
50
45
|
sync: sync
|
|
51
46
|
});
|
|
47
|
+
var dispose = history.listen(function (url) {
|
|
48
|
+
return transition(router, url, cb);
|
|
49
|
+
});
|
|
52
50
|
return function () {
|
|
53
|
-
|
|
51
|
+
dispose();
|
|
54
52
|
history = null;
|
|
55
53
|
routes = [];
|
|
56
54
|
};
|
|
57
55
|
},
|
|
58
|
-
navigate: function navigate(to) {
|
|
56
|
+
navigate: function navigate(to, curr) {
|
|
59
57
|
if (typeof to === 'string') {
|
|
60
58
|
to = {
|
|
61
59
|
url: to
|
|
62
60
|
};
|
|
63
61
|
}
|
|
64
62
|
|
|
65
|
-
var url = router.href(to);
|
|
63
|
+
var url = router.href(to, curr);
|
|
66
64
|
|
|
67
65
|
if (to.replace) {
|
|
68
66
|
history.replace(url);
|
|
@@ -70,7 +68,7 @@ function createRouter(options) {
|
|
|
70
68
|
history.push(url);
|
|
71
69
|
}
|
|
72
70
|
},
|
|
73
|
-
href: function href(to) {
|
|
71
|
+
href: function href(to, curr) {
|
|
74
72
|
// already a url
|
|
75
73
|
if (typeof to === 'string') {
|
|
76
74
|
return to;
|
|
@@ -82,7 +80,7 @@ function createRouter(options) {
|
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
if (to.merge) {
|
|
85
|
-
|
|
83
|
+
curr = curr || router.match(router.getUrl());
|
|
86
84
|
to = merge(curr, to);
|
|
87
85
|
}
|
|
88
86
|
|
|
@@ -195,7 +193,7 @@ function merge(curr, to) {
|
|
|
195
193
|
curr = {};
|
|
196
194
|
}
|
|
197
195
|
|
|
198
|
-
var pathname = to.pathname || curr.pattern;
|
|
196
|
+
var pathname = to.pathname || curr.pattern || curr.pathname;
|
|
199
197
|
var params = Object.assign({}, curr.params, to.params);
|
|
200
198
|
var query = to.query === null ? null : Object.assign({}, curr.query, to.query);
|
|
201
199
|
var hash = to.hash === null ? null : to.hash || curr.hash || '';
|
package/dist/esm/history.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export function createHistory(
|
|
1
|
+
export function createHistory(options) {
|
|
2
2
|
const sync = options.sync;
|
|
3
3
|
let mode = options.mode;
|
|
4
4
|
let raf;
|
|
5
|
+
let onPop;
|
|
5
6
|
const memory = [];
|
|
6
7
|
let off;
|
|
7
8
|
let destroyed = false;
|
|
@@ -17,19 +18,22 @@ export function createHistory(onChange, options) {
|
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
21
|
+
function listen(onChange) {
|
|
22
|
+
onPop = () => onChange(getUrl());
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
if (mode !== 'memory') {
|
|
25
|
+
off = on(window, mode === 'history' ? 'popstate' : 'hashchange', onPop);
|
|
26
|
+
raf(onPop);
|
|
27
|
+
}
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
return () => {
|
|
30
|
+
destroyed = true;
|
|
31
|
+
off && off();
|
|
32
|
+
};
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
return {
|
|
36
|
+
listen,
|
|
33
37
|
getUrl,
|
|
34
38
|
|
|
35
39
|
push(url) {
|
|
@@ -38,11 +42,6 @@ export function createHistory(onChange, options) {
|
|
|
38
42
|
|
|
39
43
|
replace(url) {
|
|
40
44
|
go(url, true);
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
destroy() {
|
|
44
|
-
destroyed = true;
|
|
45
|
-
off && off();
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
};
|
package/dist/esm/router.js
CHANGED
|
@@ -14,28 +14,26 @@ export function createRouter(options = {}) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
routes = flatten(routeMap);
|
|
17
|
-
|
|
18
|
-
const onHistoryChange = url => transition(router, url, cb);
|
|
19
|
-
|
|
20
|
-
history = createHistory(onHistoryChange, {
|
|
17
|
+
history = createHistory({
|
|
21
18
|
mode,
|
|
22
19
|
sync
|
|
23
20
|
});
|
|
21
|
+
const dispose = history.listen(url => transition(router, url, cb));
|
|
24
22
|
return () => {
|
|
25
|
-
|
|
23
|
+
dispose();
|
|
26
24
|
history = null;
|
|
27
25
|
routes = [];
|
|
28
26
|
};
|
|
29
27
|
},
|
|
30
28
|
|
|
31
|
-
navigate(to) {
|
|
29
|
+
navigate(to, curr) {
|
|
32
30
|
if (typeof to === 'string') {
|
|
33
31
|
to = {
|
|
34
32
|
url: to
|
|
35
33
|
};
|
|
36
34
|
}
|
|
37
35
|
|
|
38
|
-
const url = router.href(to);
|
|
36
|
+
const url = router.href(to, curr);
|
|
39
37
|
|
|
40
38
|
if (to.replace) {
|
|
41
39
|
history.replace(url);
|
|
@@ -44,7 +42,7 @@ export function createRouter(options = {}) {
|
|
|
44
42
|
}
|
|
45
43
|
},
|
|
46
44
|
|
|
47
|
-
href(to) {
|
|
45
|
+
href(to, curr) {
|
|
48
46
|
// already a url
|
|
49
47
|
if (typeof to === 'string') {
|
|
50
48
|
return to;
|
|
@@ -56,7 +54,7 @@ export function createRouter(options = {}) {
|
|
|
56
54
|
}
|
|
57
55
|
|
|
58
56
|
if (to.merge) {
|
|
59
|
-
|
|
57
|
+
curr = curr || router.match(router.getUrl());
|
|
60
58
|
to = merge(curr, to);
|
|
61
59
|
}
|
|
62
60
|
|
|
@@ -164,7 +162,7 @@ function data(routes, matchingRoute) {
|
|
|
164
162
|
}
|
|
165
163
|
|
|
166
164
|
export function merge(curr = {}, to) {
|
|
167
|
-
const pathname = to.pathname || curr.pattern;
|
|
165
|
+
const pathname = to.pathname || curr.pattern || curr.pathname;
|
|
168
166
|
const params = Object.assign({}, curr.params, to.params);
|
|
169
167
|
const query = to.query === null ? null : Object.assign({}, curr.query, to.query);
|
|
170
168
|
const hash = to.hash === null ? null : to.hash || curr.hash || '';
|
package/docs/content/_index.md
CHANGED
|
@@ -107,9 +107,18 @@ Note, calling listen will immediately call `onChange` based on the current url w
|
|
|
107
107
|
- `redirect` can be a string or a function that redirects upon entering that route
|
|
108
108
|
- `routes` is a nested object of nested route definitions
|
|
109
109
|
- `...metadata` all other other keys can be chosen by you
|
|
110
|
-
- `onChange` is called with `
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
- `onChange` is called with the `route` object
|
|
111
|
+
|
|
112
|
+
`route` is an object of shape `{ url, pathname, params, query, search, hash, pattern, data }`:
|
|
113
|
+
|
|
114
|
+
- `url` full relative url string including query string and hash if any
|
|
115
|
+
- `pathname` the pathname portion of the target url, which can include named segments
|
|
116
|
+
- `params` params extracted from the named pathname segments
|
|
117
|
+
- `query` query object that was parsed with `qs.parse`
|
|
118
|
+
- `search` full unparsed query string
|
|
119
|
+
- `hash` hash fragment
|
|
120
|
+
- `pattern` the matched route pattern as defined in the route config
|
|
121
|
+
- `data` an array of nested matched route objects with any metadata found in the route config
|
|
113
122
|
|
|
114
123
|
Listen returns a `dispose` function that stops listening to url changes.
|
|
115
124
|
|
|
@@ -117,9 +126,17 @@ Listen returns a `dispose` function that stops listening to url changes.
|
|
|
117
126
|
|
|
118
127
|
```js
|
|
119
128
|
router.navigate(to)
|
|
129
|
+
|
|
130
|
+
// examples
|
|
131
|
+
router.navigate('/shows')
|
|
132
|
+
router.navigate({ url: '/show/1' })
|
|
133
|
+
router.navigate({ url: '/show/2', replace: true })
|
|
134
|
+
router.navigate({ pathname: '/shows', query: { 'most-recent': 1 } })
|
|
135
|
+
router.navigate({ query: { 'top-rated': 1 }, merge: true })
|
|
136
|
+
router.navigate({ query: { 'top-rated': undefined }, merge: true })
|
|
120
137
|
```
|
|
121
138
|
|
|
122
|
-
Navigate to a url. Navigating will update the browser's location bar
|
|
139
|
+
Navigate to a url. Navigating will update the browser's location bar (unless in `memory` mode) and will call the router listener callback with the newly matched route.
|
|
123
140
|
|
|
124
141
|
- `to` - a `string` url or an `object` with the following properties
|
|
125
142
|
- `url` a relative url string or a route pattern
|
|
@@ -140,19 +157,26 @@ Note, be careful when using `merge` as this reads the location's current url whi
|
|
|
140
157
|
const route = router.match(url)
|
|
141
158
|
```
|
|
142
159
|
|
|
143
|
-
Match the url string against the routes and return the matching route object.
|
|
160
|
+
Match the url string against the routes and return the matching route object.
|
|
144
161
|
|
|
145
162
|
### `href`
|
|
146
163
|
|
|
147
164
|
```js
|
|
148
165
|
const url = router.href(to)
|
|
166
|
+
|
|
167
|
+
// examples
|
|
168
|
+
router.href('/shows')
|
|
169
|
+
router.href({ url: '/show/1' })
|
|
170
|
+
router.href({ pathname: '/shows', query: { 'most-recent': 1 } })
|
|
171
|
+
router.href({ query: { 'top-rated': 1 }, merge: true })
|
|
172
|
+
router.href({ query: { 'top-rated': undefined }, merge: true })
|
|
149
173
|
```
|
|
150
174
|
|
|
151
175
|
Create a relative url string to use in `<a href>` attribute.
|
|
152
176
|
|
|
153
177
|
- `to` object of shape `{ pathname, params, query, hash }`. The `params` will be interpolated into the pathname if the pathname contains any parametrised segments. The `query` is an object that will be passed through `qs.stringify`.
|
|
154
178
|
|
|
155
|
-
Note: `to` can
|
|
179
|
+
Note: `to` can be a string, in which case `href` simply returns the input. Similarly, the to can contain `{ url }` key in which case `href` returns that url. This is to align the function signature with that of `navigate` so the two can be used interchangeably.
|
|
156
180
|
|
|
157
181
|
### `getUrl`
|
|
158
182
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "space-router",
|
|
3
3
|
"description": "All the routing essentials.",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.5",
|
|
5
5
|
"main": "dist/cjs",
|
|
6
6
|
"module": "dist/esm",
|
|
7
7
|
"license": "ICS",
|
|
@@ -32,16 +32,16 @@
|
|
|
32
32
|
"release:docs": "hugo -s docs && gh-pages -d docs/public"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@babel/cli": "^7.
|
|
36
|
-
"@babel/preset-env": "^7.16.
|
|
35
|
+
"@babel/cli": "^7.17.6",
|
|
36
|
+
"@babel/preset-env": "^7.16.11",
|
|
37
37
|
"ava": "^3.15.0",
|
|
38
38
|
"esm": "^3.2.25",
|
|
39
39
|
"execa": "^5.1.1",
|
|
40
40
|
"gh-pages": "^3.2.3",
|
|
41
|
-
"healthier": "^
|
|
42
|
-
"np": "^7.
|
|
41
|
+
"healthier": "^5.0.1",
|
|
42
|
+
"np": "^7.6.1",
|
|
43
43
|
"nyc": "^15.1.0",
|
|
44
|
-
"prettier": "^2.
|
|
44
|
+
"prettier": "^2.6.2"
|
|
45
45
|
},
|
|
46
46
|
"healthier": {
|
|
47
47
|
"global": [
|
package/src/history.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export function createHistory(
|
|
1
|
+
export function createHistory(options) {
|
|
2
2
|
const sync = options.sync
|
|
3
3
|
let mode = options.mode
|
|
4
4
|
let raf
|
|
5
|
+
let onPop
|
|
5
6
|
|
|
6
7
|
const memory = []
|
|
7
8
|
let off
|
|
@@ -17,19 +18,22 @@ export function createHistory(onChange, options) {
|
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
21
|
+
function listen(onChange) {
|
|
22
|
+
onPop = () => onChange(getUrl())
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
if (mode !== 'memory') {
|
|
25
|
+
off = on(window, mode === 'history' ? 'popstate' : 'hashchange', onPop)
|
|
26
|
+
raf(onPop)
|
|
27
|
+
}
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
return () => {
|
|
30
|
+
destroyed = true
|
|
31
|
+
off && off()
|
|
32
|
+
}
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
return {
|
|
36
|
+
listen,
|
|
33
37
|
getUrl,
|
|
34
38
|
push(url) {
|
|
35
39
|
go(url)
|
|
@@ -37,10 +41,6 @@ export function createHistory(onChange, options) {
|
|
|
37
41
|
replace(url) {
|
|
38
42
|
go(url, true)
|
|
39
43
|
},
|
|
40
|
-
destroy() {
|
|
41
|
-
destroyed = true
|
|
42
|
-
off && off()
|
|
43
|
-
},
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
function go(url, replace) {
|
package/src/router.js
CHANGED
|
@@ -16,21 +16,21 @@ export function createRouter(options = {}) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
routes = flatten(routeMap)
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
history = createHistory({ mode, sync })
|
|
20
|
+
const dispose = history.listen((url) => transition(router, url, cb))
|
|
21
21
|
|
|
22
22
|
return () => {
|
|
23
|
-
|
|
23
|
+
dispose()
|
|
24
24
|
history = null
|
|
25
25
|
routes = []
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
|
|
29
|
-
navigate(to) {
|
|
29
|
+
navigate(to, curr) {
|
|
30
30
|
if (typeof to === 'string') {
|
|
31
31
|
to = { url: to }
|
|
32
32
|
}
|
|
33
|
-
const url = router.href(to)
|
|
33
|
+
const url = router.href(to, curr)
|
|
34
34
|
if (to.replace) {
|
|
35
35
|
history.replace(url)
|
|
36
36
|
} else {
|
|
@@ -38,7 +38,7 @@ export function createRouter(options = {}) {
|
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
40
|
|
|
41
|
-
href(to) {
|
|
41
|
+
href(to, curr) {
|
|
42
42
|
// already a url
|
|
43
43
|
if (typeof to === 'string') {
|
|
44
44
|
return to
|
|
@@ -50,7 +50,7 @@ export function createRouter(options = {}) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
if (to.merge) {
|
|
53
|
-
|
|
53
|
+
curr = curr || router.match(router.getUrl())
|
|
54
54
|
to = merge(curr, to)
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -139,7 +139,7 @@ function data(routes, matchingRoute) {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
export function merge(curr = {}, to) {
|
|
142
|
-
const pathname = to.pathname || curr.pattern
|
|
142
|
+
const pathname = to.pathname || curr.pattern || curr.pathname
|
|
143
143
|
const params = Object.assign({}, curr.params, to.params)
|
|
144
144
|
const query = to.query === null ? null : Object.assign({}, curr.query, to.query)
|
|
145
145
|
const hash = to.hash === null ? null : to.hash || curr.hash || ''
|
package/test/router.test.js
CHANGED
|
@@ -20,6 +20,7 @@ test('createRouter, listen, navigate and dispose', (t) => {
|
|
|
20
20
|
router.navigate({ query: { a: 11, b: 22 }, merge: true })
|
|
21
21
|
router.navigate({ query: { b: undefined, c: 'bla' }, hash: 'test', merge: true })
|
|
22
22
|
router.navigate({ params: { id: 3 }, merge: true })
|
|
23
|
+
router.navigate({ query: { curr: 'test' }, merge: true }, { pathname: '/user/curr' })
|
|
23
24
|
|
|
24
25
|
t.deepEqual(
|
|
25
26
|
[
|
|
@@ -35,6 +36,7 @@ test('createRouter, listen, navigate and dispose', (t) => {
|
|
|
35
36
|
'user=2?a=11&b=22',
|
|
36
37
|
'user=2?a=11&c=bla#test',
|
|
37
38
|
'user=3?a=11&c=bla#test',
|
|
39
|
+
'user=curr?curr=test',
|
|
38
40
|
],
|
|
39
41
|
calls
|
|
40
42
|
)
|
|
@@ -42,7 +44,7 @@ test('createRouter, listen, navigate and dispose', (t) => {
|
|
|
42
44
|
dispose()
|
|
43
45
|
})
|
|
44
46
|
|
|
45
|
-
test('.href(
|
|
47
|
+
test('.href(to)', (t) => {
|
|
46
48
|
const { router, dispose } = createTestRouter()
|
|
47
49
|
|
|
48
50
|
t.deepEqual('/user/7/friends?a=1&b=2', router.href({ pathname: '/user/7/friends', query: { a: 1, b: 2 } }))
|