@solidjs/router 2.0.0-next.34 → 2.0.0-next.36
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/README.md +24 -7
- package/dist/claims.d.ts +14 -6
- package/dist/claims.js +64 -28
- package/dist/data/action.js +171 -51
- package/dist/data/events.js +2 -2
- package/dist/index.js +322 -98
- package/dist/paths.d.ts +23 -3
- package/dist/routing.d.ts +10 -2
- package/dist/routing.js +7 -17
- package/dist/utils.d.ts +29 -1
- package/dist/utils.js +48 -2
- package/package.json +1 -1
package/dist/routing.js
CHANGED
|
@@ -4,7 +4,7 @@ import { runWithOwner } from "solid-js";
|
|
|
4
4
|
import { DEV } from "solid-js";
|
|
5
5
|
import { createComponent, createContext, createMemo, createSignal, getOwner, isPending, latest, NotReadyError, untrack, useContext } from "solid-js";
|
|
6
6
|
import { clearFlashCookie, getRequestEvent, hasFlashCookie, isServer } from "@solidjs/web";
|
|
7
|
-
import { mockBase,
|
|
7
|
+
import { mockBase, createMemoObject, extractSearchParams, invariant, matchLink, resolvePath, createMatcher, joinPaths, scoreRoute, mergeSearchString, expandOptionals, validateSearch } from "./utils.js";
|
|
8
8
|
import { HREF } from "./paths.js";
|
|
9
9
|
import { serverRouteOf, serverRouteArgs, serverRouteArgsEqual } from "./serverRouteShared.js";
|
|
10
10
|
const MAX_REDIRECTS = 100;
|
|
@@ -227,22 +227,11 @@ export const useLinkState = (href, options = {}) => {
|
|
|
227
227
|
const router = useRouter();
|
|
228
228
|
const location = router.location;
|
|
229
229
|
const to = useResolvedPath(() => String(href()));
|
|
230
|
-
|
|
231
|
-
const
|
|
232
|
-
const to_ = to();
|
|
233
|
-
return to_ === undefined ? undefined : comparablePath(to_);
|
|
234
|
-
});
|
|
235
|
-
const matches = (loc) => {
|
|
236
|
-
const path_ = path();
|
|
237
|
-
if (path_ === undefined)
|
|
238
|
-
return [false, false];
|
|
239
|
-
const exact = loc === path_;
|
|
240
|
-
return [exact || (!options.end && loc.startsWith(path_ + "/")), exact];
|
|
241
|
-
};
|
|
242
|
-
const state = createMemo(() => matches(decodeURI(comparablePath(location.pathname))));
|
|
230
|
+
const base = router.base.path();
|
|
231
|
+
const state = createMemo(() => matchLink(location, to(), base, options.end));
|
|
243
232
|
return {
|
|
244
|
-
active: () => state()
|
|
245
|
-
current: () => state()
|
|
233
|
+
active: createMemo(() => state().active),
|
|
234
|
+
current: createMemo(() => state().current),
|
|
246
235
|
// match the in-flight target explicitly (rather than active-while-routing)
|
|
247
236
|
// so the answer is the same from pure reads and from effects, which
|
|
248
237
|
// observe the committed location during a transition
|
|
@@ -250,7 +239,8 @@ export const useLinkState = (href, options = {}) => {
|
|
|
250
239
|
state(); // location dependency: mid-flight target swaps recompute
|
|
251
240
|
return (router.isRouting() &&
|
|
252
241
|
!!router.pendingTarget &&
|
|
253
|
-
|
|
242
|
+
matchLink({ pathname: router.pendingTarget.value, search: "" }, to(), base, options.end)
|
|
243
|
+
.active);
|
|
254
244
|
})
|
|
255
245
|
};
|
|
256
246
|
};
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
1
|
import type { StandardSchemaV1, MatchFilters, PathMatch, RouteDescription, SearchParams, SetSearchParams } from "./types.js";
|
|
2
2
|
export declare const mockBase = "http://sr";
|
|
3
3
|
export declare function normalizePath(path: string, omitSlash?: boolean): string;
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Pathname stripped of search/hash and trailing slash, percent-encoded the
|
|
6
|
+
* way `URL` (and so `location.pathname`) reports it, lowercased — the form
|
|
7
|
+
* link matching compares. Raw and encoded spellings (`/café`, `/caf%C3%A9`)
|
|
8
|
+
* meet; escapes are never decoded, so `%2F` is not a path separator.
|
|
9
|
+
*/
|
|
5
10
|
export declare const comparablePath: (path: string) => string;
|
|
11
|
+
/**
|
|
12
|
+
* Whether a URL pathname is the router's base path or under it, on a segment
|
|
13
|
+
* boundary: base `/app` covers `/app`, `/app/` and `/app/x`, not `/apple`.
|
|
14
|
+
* Case-insensitive; no base (`""` or `/`) covers every path.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isUnderBase(pathname: string, base: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* The link-state rule shared by claimed anchors and `useLinkState`, given
|
|
19
|
+
* the location and a link's already-resolved target (path, optional query
|
|
20
|
+
* and hash):
|
|
21
|
+
*
|
|
22
|
+
* - `current` — same pathname and same query (parameter order and hash aside)
|
|
23
|
+
* - `active` — same pathname or one under it; the router's root (`base`, or
|
|
24
|
+
* `/` without one) only matches exactly, since it is a prefix of every
|
|
25
|
+
* page. `end` makes every link exact-only.
|
|
26
|
+
*/
|
|
27
|
+
export declare function matchLink(location: {
|
|
28
|
+
pathname: string;
|
|
29
|
+
search: string;
|
|
30
|
+
}, target: string | undefined, base: string, end?: boolean): {
|
|
31
|
+
active: boolean;
|
|
32
|
+
current: boolean;
|
|
33
|
+
};
|
|
6
34
|
export declare function resolvePath(base: string, path: string, from?: string): string | undefined;
|
|
7
35
|
export declare function invariant<T>(value: T | null | undefined, message: string): T;
|
|
8
36
|
export declare function joinPaths(from: string, to: string): string;
|
package/dist/utils.js
CHANGED
|
@@ -6,8 +6,54 @@ export function normalizePath(path, omitSlash = false) {
|
|
|
6
6
|
const s = path.replace(trimPathRegex, "$1");
|
|
7
7
|
return s ? (omitSlash || /^[?#]/.test(s) ? s : "/" + s) : "";
|
|
8
8
|
}
|
|
9
|
-
/**
|
|
10
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Pathname stripped of search/hash and trailing slash, percent-encoded the
|
|
11
|
+
* way `URL` (and so `location.pathname`) reports it, lowercased — the form
|
|
12
|
+
* link matching compares. Raw and encoded spellings (`/café`, `/caf%C3%A9`)
|
|
13
|
+
* meet; escapes are never decoded, so `%2F` is not a path separator.
|
|
14
|
+
*/
|
|
15
|
+
export const comparablePath = (path) => new URL(mockBase + normalizePath(path.split(/[?#]/, 1)[0])).pathname
|
|
16
|
+
.toLowerCase()
|
|
17
|
+
.replace(/\/$/, "");
|
|
18
|
+
/**
|
|
19
|
+
* Whether a URL pathname is the router's base path or under it, on a segment
|
|
20
|
+
* boundary: base `/app` covers `/app`, `/app/` and `/app/x`, not `/apple`.
|
|
21
|
+
* Case-insensitive; no base (`""` or `/`) covers every path.
|
|
22
|
+
*/
|
|
23
|
+
export function isUnderBase(pathname, base) {
|
|
24
|
+
const b = base.toLowerCase().replace(/\/+$/, "");
|
|
25
|
+
const p = pathname.toLowerCase();
|
|
26
|
+
return !b || !p || p === b || p.startsWith(b + "/");
|
|
27
|
+
}
|
|
28
|
+
/** A query string as an order-independent comparable string. */
|
|
29
|
+
const comparableQuery = (search) => {
|
|
30
|
+
const params = new URLSearchParams(search);
|
|
31
|
+
params.sort();
|
|
32
|
+
return params.toString();
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* The link-state rule shared by claimed anchors and `useLinkState`, given
|
|
36
|
+
* the location and a link's already-resolved target (path, optional query
|
|
37
|
+
* and hash):
|
|
38
|
+
*
|
|
39
|
+
* - `current` — same pathname and same query (parameter order and hash aside)
|
|
40
|
+
* - `active` — same pathname or one under it; the router's root (`base`, or
|
|
41
|
+
* `/` without one) only matches exactly, since it is a prefix of every
|
|
42
|
+
* page. `end` makes every link exact-only.
|
|
43
|
+
*/
|
|
44
|
+
export function matchLink(location, target, base, end) {
|
|
45
|
+
if (target === undefined)
|
|
46
|
+
return { active: false, current: false };
|
|
47
|
+
const loc = comparablePath(location.pathname);
|
|
48
|
+
const path = comparablePath(target);
|
|
49
|
+
const exact = loc === path;
|
|
50
|
+
const hashless = target.split("#", 1)[0];
|
|
51
|
+
const q = hashless.indexOf("?");
|
|
52
|
+
return {
|
|
53
|
+
active: exact || (!end && path !== "" && path !== comparablePath(base) && loc.startsWith(path + "/")),
|
|
54
|
+
current: exact && comparableQuery(location.search) === comparableQuery(q < 0 ? "" : hashless.slice(q))
|
|
55
|
+
};
|
|
56
|
+
}
|
|
11
57
|
export function resolvePath(base, path, from) {
|
|
12
58
|
if (hasSchemeRegex.test(path)) {
|
|
13
59
|
return undefined;
|