@solidjs/router 0.4.2
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/LICENSE +21 -0
- package/README.md +557 -0
- package/dist/components.d.ts +65 -0
- package/dist/components.jsx +111 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +936 -0
- package/dist/index.jsx +4 -0
- package/dist/integration.d.ts +6 -0
- package/dist/integration.js +105 -0
- package/dist/routing.d.ts +24 -0
- package/dist/routing.js +377 -0
- package/dist/types.d.ts +115 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +11 -0
- package/dist/utils.js +132 -0
- package/package.json +62 -0
package/dist/utils.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { createMemo, getOwner, runWithOwner } from "solid-js";
|
|
2
|
+
const hasSchemeRegex = /^(?:[a-z0-9]+:)?\/\//i;
|
|
3
|
+
const trimPathRegex = /^\/+|\/+$/g;
|
|
4
|
+
function normalize(path, omitSlash = false) {
|
|
5
|
+
const s = path.replace(trimPathRegex, "");
|
|
6
|
+
return s ? (omitSlash || /^[?#]/.test(s) ? s : "/" + s) : "";
|
|
7
|
+
}
|
|
8
|
+
export function resolvePath(base, path, from) {
|
|
9
|
+
if (hasSchemeRegex.test(path)) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
const basePath = normalize(base);
|
|
13
|
+
const fromPath = from && normalize(from);
|
|
14
|
+
let result = "";
|
|
15
|
+
if (!fromPath || path.startsWith("/")) {
|
|
16
|
+
result = basePath;
|
|
17
|
+
}
|
|
18
|
+
else if (fromPath.toLowerCase().indexOf(basePath.toLowerCase()) !== 0) {
|
|
19
|
+
result = basePath + fromPath;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
result = fromPath;
|
|
23
|
+
}
|
|
24
|
+
return (result || "/") + normalize(path, !result);
|
|
25
|
+
}
|
|
26
|
+
export function invariant(value, message) {
|
|
27
|
+
if (value == null) {
|
|
28
|
+
throw new Error(message);
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
export function joinPaths(from, to) {
|
|
33
|
+
return normalize(from).replace(/\/*(\*.*)?$/g, "") + normalize(to);
|
|
34
|
+
}
|
|
35
|
+
export function extractSearchParams(url) {
|
|
36
|
+
const params = {};
|
|
37
|
+
url.searchParams.forEach((value, key) => {
|
|
38
|
+
params[key] = value;
|
|
39
|
+
});
|
|
40
|
+
return params;
|
|
41
|
+
}
|
|
42
|
+
export function urlDecode(str, isQuery) {
|
|
43
|
+
return decodeURIComponent(isQuery ? str.replace(/\+/g, " ") : str);
|
|
44
|
+
}
|
|
45
|
+
export function createMatcher(path, partial) {
|
|
46
|
+
const [pattern, splat] = path.split("/*", 2);
|
|
47
|
+
const segments = pattern.split("/").filter(Boolean);
|
|
48
|
+
const len = segments.length;
|
|
49
|
+
return (location) => {
|
|
50
|
+
const locSegments = location.split("/").filter(Boolean);
|
|
51
|
+
const lenDiff = locSegments.length - len;
|
|
52
|
+
if (lenDiff < 0 || (lenDiff > 0 && splat === undefined && !partial)) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
const match = {
|
|
56
|
+
path: len ? "" : "/",
|
|
57
|
+
params: {}
|
|
58
|
+
};
|
|
59
|
+
for (let i = 0; i < len; i++) {
|
|
60
|
+
const segment = segments[i];
|
|
61
|
+
const locSegment = locSegments[i];
|
|
62
|
+
if (segment[0] === ":") {
|
|
63
|
+
match.params[segment.slice(1)] = locSegment;
|
|
64
|
+
}
|
|
65
|
+
else if (segment.localeCompare(locSegment, undefined, { sensitivity: "base" }) !== 0) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
match.path += `/${locSegment}`;
|
|
69
|
+
}
|
|
70
|
+
if (splat) {
|
|
71
|
+
match.params[splat] = lenDiff ? locSegments.slice(-lenDiff).join("/") : "";
|
|
72
|
+
}
|
|
73
|
+
return match;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export function scoreRoute(route) {
|
|
77
|
+
const [pattern, splat] = route.pattern.split("/*", 2);
|
|
78
|
+
const segments = pattern.split("/").filter(Boolean);
|
|
79
|
+
return segments.reduce((score, segment) => score + (segment.startsWith(":") ? 2 : 3), segments.length - (splat === undefined ? 0 : 1));
|
|
80
|
+
}
|
|
81
|
+
export function createMemoObject(fn) {
|
|
82
|
+
const map = new Map();
|
|
83
|
+
const owner = getOwner();
|
|
84
|
+
return new Proxy({}, {
|
|
85
|
+
get(_, property) {
|
|
86
|
+
if (!map.has(property)) {
|
|
87
|
+
runWithOwner(owner, () => map.set(property, createMemo(() => fn()[property])));
|
|
88
|
+
}
|
|
89
|
+
return map.get(property)();
|
|
90
|
+
},
|
|
91
|
+
getOwnPropertyDescriptor() {
|
|
92
|
+
return {
|
|
93
|
+
enumerable: true,
|
|
94
|
+
configurable: true
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
ownKeys() {
|
|
98
|
+
return Reflect.ownKeys(fn());
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
export function mergeSearchString(search, params) {
|
|
103
|
+
const merged = new URLSearchParams(search);
|
|
104
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
105
|
+
if (value == null || value === "") {
|
|
106
|
+
merged.delete(key);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
merged.set(key, String(value));
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
const s = merged.toString();
|
|
113
|
+
return s ? `?${s}` : "";
|
|
114
|
+
}
|
|
115
|
+
export function expandOptionals(pattern) {
|
|
116
|
+
let match = /(\/?\:[^\/]+)\?/.exec(pattern);
|
|
117
|
+
if (!match)
|
|
118
|
+
return [pattern];
|
|
119
|
+
let prefix = pattern.slice(0, match.index);
|
|
120
|
+
let suffix = pattern.slice(match.index + match[0].length);
|
|
121
|
+
const prefixes = [prefix, (prefix += match[1])];
|
|
122
|
+
// This section handles adjacent optional params. We don't actually want all permuations since
|
|
123
|
+
// that will lead to equivalent routes which have the same number of params. For example
|
|
124
|
+
// `/:a?/:b?/:c`? only has the unique expansion: `/`, `/:a`, `/:a/:b`, `/:a/:b/:c` and we can
|
|
125
|
+
// discard `/:b`, `/:c`, `/:b/:c` by building them up in order and not recursing. This also helps
|
|
126
|
+
// ensure predictability where earlier params have precidence.
|
|
127
|
+
while ((match = /^(\/\:[^\/]+)\?/.exec(suffix))) {
|
|
128
|
+
prefixes.push((prefix += match[1]));
|
|
129
|
+
suffix = suffix.slice(match[0].length);
|
|
130
|
+
}
|
|
131
|
+
return expandOptionals(suffix).reduce((results, expansion) => [...results, ...prefixes.map(p => p + expansion)], []);
|
|
132
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@solidjs/router",
|
|
3
|
+
"description": "Universal router for SolidJS",
|
|
4
|
+
"author": "Ryan Carniato",
|
|
5
|
+
"contributors": [
|
|
6
|
+
"Ryan Turnquist"
|
|
7
|
+
],
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"version": "0.4.2",
|
|
10
|
+
"homepage": "https://github.com/solidjs/solid-router#readme",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/solidjs/solid-router"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"main": "dist/index.js",
|
|
20
|
+
"types": "dist/index.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"solid": "./dist/index.jsx",
|
|
24
|
+
"default": "./dist/index.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"sideEffects": false,
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc && rollup -c",
|
|
33
|
+
"prepublishOnly": "npm run build",
|
|
34
|
+
"test": "jest && npm run test:types",
|
|
35
|
+
"test:watch": "jest --watch",
|
|
36
|
+
"test:coverage": "jest --coverage && npm run test:types",
|
|
37
|
+
"test:types": "tsc --project tsconfig.test.json",
|
|
38
|
+
"pretty": "prettier --write \"{src,test}/**/*.{ts,tsx}\""
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@babel/core": "^7.15.8",
|
|
42
|
+
"@babel/preset-typescript": "^7.15.0",
|
|
43
|
+
"@rollup/plugin-babel": "5.3.0",
|
|
44
|
+
"@rollup/plugin-node-resolve": "13.0.5",
|
|
45
|
+
"@types/jest": "^27.0.2",
|
|
46
|
+
"@types/node": "^16.10.3",
|
|
47
|
+
"babel-preset-solid": "^1.4.4",
|
|
48
|
+
"jest": "^27.2.5",
|
|
49
|
+
"prettier": "^2.5.1",
|
|
50
|
+
"rollup": "^2.52.1",
|
|
51
|
+
"rollup-plugin-terser": "^7.0.2",
|
|
52
|
+
"solid-jest": "^0.2.0",
|
|
53
|
+
"solid-js": "^1.4.4",
|
|
54
|
+
"typescript": "^4.5.4"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"solid-js": "^1.3.5"
|
|
58
|
+
},
|
|
59
|
+
"jest": {
|
|
60
|
+
"preset": "solid-jest/preset/browser"
|
|
61
|
+
}
|
|
62
|
+
}
|