@solidjs/router 0.10.8 → 0.10.10
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/dist/data/action.js +2 -2
- package/dist/data/cache.js +25 -16
- package/dist/data/events.js +6 -4
- package/dist/data/index.d.ts +1 -1
- package/dist/data/index.js +1 -1
- package/dist/data/response.d.ts +3 -2
- package/dist/data/response.js +13 -1
- package/dist/index.js +41 -21
- package/dist/routing.js +6 -3
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +1 -0
- package/package.json +1 -1
package/dist/data/action.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { $TRACK, createMemo, createSignal, onCleanup, getOwner } from "solid-js";
|
|
2
2
|
import { isServer } from "solid-js/web";
|
|
3
3
|
import { useRouter } from "../routing";
|
|
4
|
-
import { redirectStatusCodes } from "../utils";
|
|
4
|
+
import { redirectStatusCodes, mockBase } from "../utils";
|
|
5
5
|
import { cacheKeyOp, hashKey, revalidate } from "./cache";
|
|
6
6
|
export const actions = /* #__PURE__ */ new Map();
|
|
7
7
|
export function useSubmissions(fn, filter) {
|
|
@@ -80,7 +80,7 @@ function toAction(fn, url) {
|
|
|
80
80
|
const newFn = function (...passedArgs) {
|
|
81
81
|
return fn.call(this, ...args, ...passedArgs);
|
|
82
82
|
};
|
|
83
|
-
const uri = new URL(url,
|
|
83
|
+
const uri = new URL(url, mockBase);
|
|
84
84
|
uri.searchParams.set("args", hashKey(args));
|
|
85
85
|
return toAction(newFn, (uri.origin === "https://action" ? uri.origin : "") + uri.pathname + uri.search);
|
|
86
86
|
};
|
package/dist/data/cache.js
CHANGED
|
@@ -48,6 +48,9 @@ function revalidateSignals(set, time) {
|
|
|
48
48
|
}
|
|
49
49
|
export function cache(fn, name, options) {
|
|
50
50
|
const [store, setStore] = createStore({});
|
|
51
|
+
// prioritize GET for server functions
|
|
52
|
+
if (fn.GET)
|
|
53
|
+
fn = fn.GET;
|
|
51
54
|
const cachedFn = ((...args) => {
|
|
52
55
|
const cache = getCache();
|
|
53
56
|
const intent = getIntent();
|
|
@@ -75,7 +78,9 @@ export function cache(fn, name, options) {
|
|
|
75
78
|
"then" in cached[1]
|
|
76
79
|
? cached[1].then(handleResponse(false), handleResponse(true))
|
|
77
80
|
: handleResponse(false)(cached[1]);
|
|
78
|
-
!isServer &&
|
|
81
|
+
!isServer &&
|
|
82
|
+
intent === "navigate" &&
|
|
83
|
+
startTransition(() => revalidateSignals(cached[3], cached[0])); // update version
|
|
79
84
|
}
|
|
80
85
|
return res;
|
|
81
86
|
}
|
|
@@ -106,22 +111,26 @@ export function cache(fn, name, options) {
|
|
|
106
111
|
}
|
|
107
112
|
return res;
|
|
108
113
|
function handleResponse(error) {
|
|
109
|
-
return (v) => {
|
|
110
|
-
if (v instanceof Response
|
|
111
|
-
if (
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
114
|
+
return async (v) => {
|
|
115
|
+
if (v instanceof Response) {
|
|
116
|
+
if (redirectStatusCodes.has(v.status)) {
|
|
117
|
+
if (navigate) {
|
|
118
|
+
startTransition(() => {
|
|
119
|
+
let url = v.headers.get(LocationHeader);
|
|
120
|
+
if (url && url.startsWith("/")) {
|
|
121
|
+
navigate(url, {
|
|
122
|
+
replace: true
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
else if (!isServer && url) {
|
|
126
|
+
window.location.href = url;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return;
|
|
123
131
|
}
|
|
124
|
-
|
|
132
|
+
if (v.customBody)
|
|
133
|
+
v = await v.customBody();
|
|
125
134
|
}
|
|
126
135
|
if (error)
|
|
127
136
|
throw v;
|
package/dist/data/events.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { delegateEvents } from "solid-js/web";
|
|
2
2
|
import { onCleanup } from "solid-js";
|
|
3
3
|
import { actions } from "./action";
|
|
4
|
+
import { mockBase } from "../utils";
|
|
4
5
|
export function setupNativeEvents(preload = true, explicitLinks = false, actionBase = "/_server") {
|
|
5
6
|
return (router) => {
|
|
6
7
|
const basePath = router.base.path();
|
|
@@ -20,7 +21,7 @@ export function setupNativeEvents(preload = true, explicitLinks = false, actionB
|
|
|
20
21
|
const a = evt
|
|
21
22
|
.composedPath()
|
|
22
23
|
.find(el => el instanceof Node && el.nodeName.toUpperCase() === "A");
|
|
23
|
-
if (!a || (explicitLinks && !a.
|
|
24
|
+
if (!a || (explicitLinks && !a.hasAttribute("link")))
|
|
24
25
|
return;
|
|
25
26
|
const svg = isSvg(a);
|
|
26
27
|
const href = svg ? a.href.baseVal : a.href;
|
|
@@ -83,12 +84,13 @@ export function setupNativeEvents(preload = true, explicitLinks = false, actionB
|
|
|
83
84
|
}
|
|
84
85
|
function handleFormSubmit(evt) {
|
|
85
86
|
let actionRef = evt.submitter && evt.submitter.hasAttribute("formaction")
|
|
86
|
-
? evt.submitter.
|
|
87
|
-
: evt.target.action;
|
|
87
|
+
? evt.submitter.getAttribute("formaction")
|
|
88
|
+
: evt.target.getAttribute("action");
|
|
88
89
|
if (!actionRef)
|
|
89
90
|
return;
|
|
90
91
|
if (!actionRef.startsWith("https://action/")) {
|
|
91
|
-
|
|
92
|
+
// normalize server actions
|
|
93
|
+
const url = new URL(actionRef, mockBase);
|
|
92
94
|
actionRef = router.parsePath(url.pathname + url.search);
|
|
93
95
|
if (!actionRef.startsWith(actionBase))
|
|
94
96
|
return;
|
package/dist/data/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { createAsync } from "./createAsync";
|
|
2
2
|
export { action, useSubmission, useSubmissions, useAction, type Action } from "./action";
|
|
3
3
|
export { cache, revalidate, type CachedFunction } from "./cache";
|
|
4
|
-
export { redirect, reload } from "./response";
|
|
4
|
+
export { redirect, reload, json } from "./response";
|
package/dist/data/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { createAsync } from "./createAsync";
|
|
2
2
|
export { action, useSubmission, useSubmissions, useAction } from "./action";
|
|
3
3
|
export { cache, revalidate } from "./cache";
|
|
4
|
-
export { redirect, reload } from "./response";
|
|
4
|
+
export { redirect, reload, json } from "./response";
|
package/dist/data/response.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type RouterResponseInit = ResponseInit & {
|
|
2
2
|
revalidate?: string | string[];
|
|
3
3
|
};
|
|
4
|
-
export declare function redirect(url: string, init?: number | RouterResponseInit):
|
|
5
|
-
export declare function reload(init: RouterResponseInit):
|
|
4
|
+
export declare function redirect(url: string, init?: number | RouterResponseInit): never;
|
|
5
|
+
export declare function reload(init: RouterResponseInit): never;
|
|
6
|
+
export declare function json<T>(data: T, init?: Omit<ResponseInit, "body">): T;
|
package/dist/data/response.js
CHANGED
|
@@ -23,6 +23,18 @@ export function reload(init) {
|
|
|
23
23
|
const { revalidate, ...responseInit } = init;
|
|
24
24
|
return new Response(null, {
|
|
25
25
|
...responseInit,
|
|
26
|
-
...(revalidate
|
|
26
|
+
...(revalidate
|
|
27
|
+
? { headers: new Headers(responseInit.headers).set("X-Revalidate", revalidate.toString()) }
|
|
28
|
+
: {})
|
|
27
29
|
});
|
|
28
30
|
}
|
|
31
|
+
export function json(data, init) {
|
|
32
|
+
const headers = new Headers((init || {}).headers);
|
|
33
|
+
headers.set("Content-Type", "application/json");
|
|
34
|
+
const response = new Response(JSON.stringify(data), {
|
|
35
|
+
...init,
|
|
36
|
+
headers
|
|
37
|
+
});
|
|
38
|
+
response.customBody = () => data;
|
|
39
|
+
return response;
|
|
40
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -38,6 +38,7 @@ function createBeforeLeave() {
|
|
|
38
38
|
|
|
39
39
|
const hasSchemeRegex = /^(?:[a-z0-9]+:)?\/\//i;
|
|
40
40
|
const trimPathRegex = /^\/+|(\/)\/+$/g;
|
|
41
|
+
const mockBase = "http://sr";
|
|
41
42
|
const redirectStatusCodes = new Set([204, 301, 302, 303, 307, 308]);
|
|
42
43
|
function normalizePath(path, omitSlash = false) {
|
|
43
44
|
const s = path.replace(trimPathRegex, "$1");
|
|
@@ -255,7 +256,10 @@ function createRoutes(routeDef, base = "") {
|
|
|
255
256
|
return asArray(routeDef.path).reduce((acc, path) => {
|
|
256
257
|
for (const originalPath of expandOptionals(path)) {
|
|
257
258
|
const path = joinPaths(base, originalPath);
|
|
258
|
-
|
|
259
|
+
let pattern = isLeaf ? path : path.split("/*", 1)[0];
|
|
260
|
+
pattern = pattern.split("/").map(s => {
|
|
261
|
+
return s.startsWith(':') || s.startsWith('*') ? s : encodeURIComponent(s);
|
|
262
|
+
}).join("/");
|
|
259
263
|
acc.push({
|
|
260
264
|
...shared,
|
|
261
265
|
originalPath,
|
|
@@ -324,7 +328,7 @@ function getRouteMatches(branches, location) {
|
|
|
324
328
|
return [];
|
|
325
329
|
}
|
|
326
330
|
function createLocation(path, state) {
|
|
327
|
-
const origin = new URL(
|
|
331
|
+
const origin = new URL(mockBase);
|
|
328
332
|
const url = createMemo(prev => {
|
|
329
333
|
const path_ = path();
|
|
330
334
|
try {
|
|
@@ -809,6 +813,8 @@ function revalidateSignals(set, time) {
|
|
|
809
813
|
}
|
|
810
814
|
function cache(fn, name, options) {
|
|
811
815
|
const [store, setStore] = createStore({});
|
|
816
|
+
// prioritize GET for server functions
|
|
817
|
+
if (fn.GET) fn = fn.GET;
|
|
812
818
|
const cachedFn = (...args) => {
|
|
813
819
|
const cache = getCache();
|
|
814
820
|
const intent = getIntent();
|
|
@@ -862,21 +868,24 @@ function cache(fn, name, options) {
|
|
|
862
868
|
}
|
|
863
869
|
return res;
|
|
864
870
|
function handleResponse(error) {
|
|
865
|
-
return v => {
|
|
866
|
-
if (v instanceof Response
|
|
867
|
-
if (
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
871
|
+
return async v => {
|
|
872
|
+
if (v instanceof Response) {
|
|
873
|
+
if (redirectStatusCodes.has(v.status)) {
|
|
874
|
+
if (navigate) {
|
|
875
|
+
startTransition(() => {
|
|
876
|
+
let url = v.headers.get(LocationHeader);
|
|
877
|
+
if (url && url.startsWith("/")) {
|
|
878
|
+
navigate(url, {
|
|
879
|
+
replace: true
|
|
880
|
+
});
|
|
881
|
+
} else if (!isServer && url) {
|
|
882
|
+
window.location.href = url;
|
|
883
|
+
}
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
return;
|
|
878
887
|
}
|
|
879
|
-
|
|
888
|
+
if (v.customBody) v = await v.customBody();
|
|
880
889
|
}
|
|
881
890
|
if (error) throw v;
|
|
882
891
|
if (isServer) return v;
|
|
@@ -1000,7 +1009,7 @@ function toAction(fn, url) {
|
|
|
1000
1009
|
const newFn = function (...passedArgs) {
|
|
1001
1010
|
return fn.call(this, ...args, ...passedArgs);
|
|
1002
1011
|
};
|
|
1003
|
-
const uri = new URL(url,
|
|
1012
|
+
const uri = new URL(url, mockBase);
|
|
1004
1013
|
uri.searchParams.set("args", hashKey(args));
|
|
1005
1014
|
return toAction(newFn, (uri.origin === "https://action" ? uri.origin : "") + uri.pathname + uri.search);
|
|
1006
1015
|
};
|
|
@@ -1045,7 +1054,7 @@ function setupNativeEvents(preload = true, explicitLinks = false, actionBase = "
|
|
|
1045
1054
|
function handleAnchor(evt) {
|
|
1046
1055
|
if (evt.defaultPrevented || evt.button !== 0 || evt.metaKey || evt.altKey || evt.ctrlKey || evt.shiftKey) return;
|
|
1047
1056
|
const a = evt.composedPath().find(el => el instanceof Node && el.nodeName.toUpperCase() === "A");
|
|
1048
|
-
if (!a || explicitLinks && !a.
|
|
1057
|
+
if (!a || explicitLinks && !a.hasAttribute("link")) return;
|
|
1049
1058
|
const svg = isSvg(a);
|
|
1050
1059
|
const href = svg ? a.href.baseVal : a.href;
|
|
1051
1060
|
const target = svg ? a.target.baseVal : a.target;
|
|
@@ -1096,10 +1105,11 @@ function setupNativeEvents(preload = true, explicitLinks = false, actionBase = "
|
|
|
1096
1105
|
}
|
|
1097
1106
|
}
|
|
1098
1107
|
function handleFormSubmit(evt) {
|
|
1099
|
-
let actionRef = evt.submitter && evt.submitter.hasAttribute("formaction") ? evt.submitter.
|
|
1108
|
+
let actionRef = evt.submitter && evt.submitter.hasAttribute("formaction") ? evt.submitter.getAttribute("formaction") : evt.target.getAttribute("action");
|
|
1100
1109
|
if (!actionRef) return;
|
|
1101
1110
|
if (!actionRef.startsWith("https://action/")) {
|
|
1102
|
-
|
|
1111
|
+
// normalize server actions
|
|
1112
|
+
const url = new URL(actionRef, mockBase);
|
|
1103
1113
|
actionRef = router.parsePath(url.pathname + url.search);
|
|
1104
1114
|
if (!actionRef.startsWith(actionBase)) return;
|
|
1105
1115
|
}
|
|
@@ -1409,5 +1419,15 @@ function reload(init) {
|
|
|
1409
1419
|
} : {})
|
|
1410
1420
|
});
|
|
1411
1421
|
}
|
|
1422
|
+
function json(data, init) {
|
|
1423
|
+
const headers = new Headers((init || {}).headers);
|
|
1424
|
+
headers.set("Content-Type", "application/json");
|
|
1425
|
+
const response = new Response(JSON.stringify(data), {
|
|
1426
|
+
...init,
|
|
1427
|
+
headers
|
|
1428
|
+
});
|
|
1429
|
+
response.customBody = () => data;
|
|
1430
|
+
return response;
|
|
1431
|
+
}
|
|
1412
1432
|
|
|
1413
|
-
export { A, HashRouter, MemoryRouter, Navigate, Route, Router, StaticRouter, mergeSearchString as _mergeSearchString, action, cache, createAsync, createBeforeLeave, createMemoryHistory, createRouter, redirect, reload, revalidate, useAction, useBeforeLeave, useHref, useIsRouting, useLocation, useMatch, useNavigate, useParams, useResolvedPath, useSearchParams, useSubmission, useSubmissions };
|
|
1433
|
+
export { A, HashRouter, MemoryRouter, Navigate, Route, Router, StaticRouter, mergeSearchString as _mergeSearchString, action, cache, createAsync, createBeforeLeave, createMemoryHistory, createRouter, json, redirect, reload, revalidate, useAction, useBeforeLeave, useHref, useIsRouting, useLocation, useMatch, useNavigate, useParams, useResolvedPath, useSearchParams, useSubmission, useSubmissions };
|
package/dist/routing.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createComponent, createContext, createMemo, createRenderEffect, createSignal, on, onCleanup, untrack, useContext, startTransition, resetErrorBoundaries } from "solid-js";
|
|
2
2
|
import { isServer, getRequestEvent } from "solid-js/web";
|
|
3
3
|
import { createBeforeLeave } from "./lifecycle";
|
|
4
|
-
import { createMemoObject, extractSearchParams, invariant, resolvePath, createMatcher, joinPaths, scoreRoute, mergeSearchString, expandOptionals } from "./utils";
|
|
4
|
+
import { mockBase, createMemoObject, extractSearchParams, invariant, resolvePath, createMatcher, joinPaths, scoreRoute, mergeSearchString, expandOptionals } from "./utils";
|
|
5
5
|
const MAX_REDIRECTS = 100;
|
|
6
6
|
export const RouterContextObj = createContext();
|
|
7
7
|
export const RouteContextObj = createContext();
|
|
@@ -67,7 +67,10 @@ export function createRoutes(routeDef, base = "") {
|
|
|
67
67
|
return asArray(routeDef.path).reduce((acc, path) => {
|
|
68
68
|
for (const originalPath of expandOptionals(path)) {
|
|
69
69
|
const path = joinPaths(base, originalPath);
|
|
70
|
-
|
|
70
|
+
let pattern = isLeaf ? path : path.split("/*", 1)[0];
|
|
71
|
+
pattern = pattern.split("/").map((s) => {
|
|
72
|
+
return (s.startsWith(':') || s.startsWith('*')) ? s : encodeURIComponent(s);
|
|
73
|
+
}).join("/");
|
|
71
74
|
acc.push({
|
|
72
75
|
...shared,
|
|
73
76
|
originalPath,
|
|
@@ -137,7 +140,7 @@ export function getRouteMatches(branches, location) {
|
|
|
137
140
|
return [];
|
|
138
141
|
}
|
|
139
142
|
export function createLocation(path, state) {
|
|
140
|
-
const origin = new URL(
|
|
143
|
+
const origin = new URL(mockBase);
|
|
141
144
|
const url = createMemo(prev => {
|
|
142
145
|
const path_ = path();
|
|
143
146
|
try {
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { MatchFilters, Params, PathMatch, Route, SetParams } from "./types";
|
|
2
|
+
export declare const mockBase = "http://sr";
|
|
2
3
|
export declare const redirectStatusCodes: Set<number>;
|
|
3
4
|
export declare function normalizePath(path: string, omitSlash?: boolean): string;
|
|
4
5
|
export declare function resolvePath(base: string, path: string, from?: string): string | undefined;
|
package/dist/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createMemo, getOwner, runWithOwner } from "solid-js";
|
|
2
2
|
const hasSchemeRegex = /^(?:[a-z0-9]+:)?\/\//i;
|
|
3
3
|
const trimPathRegex = /^\/+|(\/)\/+$/g;
|
|
4
|
+
export const mockBase = "http://sr";
|
|
4
5
|
export const redirectStatusCodes = new Set([204, 301, 302, 303, 307, 308]);
|
|
5
6
|
export function normalizePath(path, omitSlash = false) {
|
|
6
7
|
const s = path.replace(trimPathRegex, "$1");
|