@pauloevpr/solid-router 0.16.2-vt.1

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.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1097 -0
  3. package/dist/components.d.ts +31 -0
  4. package/dist/components.jsx +40 -0
  5. package/dist/data/action.d.ts +17 -0
  6. package/dist/data/action.js +166 -0
  7. package/dist/data/createAsync.d.ts +32 -0
  8. package/dist/data/createAsync.js +96 -0
  9. package/dist/data/events.d.ts +9 -0
  10. package/dist/data/events.js +123 -0
  11. package/dist/data/index.d.ts +4 -0
  12. package/dist/data/index.js +4 -0
  13. package/dist/data/query.d.ts +23 -0
  14. package/dist/data/query.js +232 -0
  15. package/dist/data/response.d.ts +4 -0
  16. package/dist/data/response.js +42 -0
  17. package/dist/index.d.ts +8 -0
  18. package/dist/index.js +2055 -0
  19. package/dist/index.jsx +7 -0
  20. package/dist/lifecycle.d.ts +5 -0
  21. package/dist/lifecycle.js +76 -0
  22. package/dist/routers/HashRouter.d.ts +9 -0
  23. package/dist/routers/HashRouter.js +41 -0
  24. package/dist/routers/MemoryRouter.d.ts +24 -0
  25. package/dist/routers/MemoryRouter.js +57 -0
  26. package/dist/routers/Router.d.ts +9 -0
  27. package/dist/routers/Router.js +45 -0
  28. package/dist/routers/StaticRouter.d.ts +6 -0
  29. package/dist/routers/StaticRouter.js +15 -0
  30. package/dist/routers/components.d.ts +29 -0
  31. package/dist/routers/components.jsx +122 -0
  32. package/dist/routers/createRouter.d.ts +10 -0
  33. package/dist/routers/createRouter.js +41 -0
  34. package/dist/routers/index.d.ts +11 -0
  35. package/dist/routers/index.js +6 -0
  36. package/dist/routing.d.ts +176 -0
  37. package/dist/routing.js +608 -0
  38. package/dist/types.d.ts +203 -0
  39. package/dist/types.js +1 -0
  40. package/dist/utils.d.ts +13 -0
  41. package/dist/utils.js +193 -0
  42. package/dist/viewTransitions.d.ts +20 -0
  43. package/dist/viewTransitions.js +118 -0
  44. package/package.json +71 -0
@@ -0,0 +1,232 @@
1
+ import { createSignal, getListener, getOwner, onCleanup, sharedConfig, startTransition } from "solid-js";
2
+ import { getRequestEvent, isServer } from "solid-js/web";
3
+ import { useNavigate, getIntent, getInPreloadFn } from "../routing.js";
4
+ const LocationHeader = "Location";
5
+ const PRELOAD_TIMEOUT = 5000;
6
+ const CACHE_TIMEOUT = 180000;
7
+ let cacheMap = new Map();
8
+ // cleanup forward/back cache
9
+ if (!isServer) {
10
+ setInterval(() => {
11
+ const now = Date.now();
12
+ for (let [k, v] of cacheMap.entries()) {
13
+ if (!v[4].count && now - v[0] > CACHE_TIMEOUT) {
14
+ cacheMap.delete(k);
15
+ }
16
+ }
17
+ }, 300000);
18
+ }
19
+ function getCache() {
20
+ if (!isServer)
21
+ return cacheMap;
22
+ const req = getRequestEvent();
23
+ if (!req)
24
+ throw new Error("Cannot find cache context");
25
+ return (req.router || (req.router = {})).cache || (req.router.cache = new Map());
26
+ }
27
+ /**
28
+ * Revalidates the given cache entry/entries.
29
+ */
30
+ export function revalidate(key, force = true) {
31
+ const now = Date.now();
32
+ // force the cache miss synchronously so a `refetch` in the same tick sees it —
33
+ // startTransition defers its callback to a microtask (#497)
34
+ force && cacheKeyOp(key, entry => (entry[0] = 0));
35
+ return startTransition(() => {
36
+ cacheKeyOp(key, entry => entry[4][1](now)); // retrigger live signals
37
+ });
38
+ }
39
+ export function cacheKeyOp(key, fn) {
40
+ key && !Array.isArray(key) && (key = [key]);
41
+ for (let k of cacheMap.keys()) {
42
+ if (key === undefined || matchKey(k, key))
43
+ fn(cacheMap.get(k));
44
+ }
45
+ }
46
+ export function query(fn, name) {
47
+ // prioritize GET for server functions
48
+ if (fn.GET)
49
+ fn = fn.GET;
50
+ const cachedFn = ((...args) => {
51
+ const cache = getCache();
52
+ const intent = getIntent();
53
+ const inPreloadFn = getInPreloadFn();
54
+ const owner = getOwner();
55
+ const navigate = owner ? useNavigate() : undefined;
56
+ const now = Date.now();
57
+ const key = name + hashKey(args);
58
+ let cached = cache.get(key);
59
+ let tracking;
60
+ if (isServer) {
61
+ const e = getRequestEvent();
62
+ if (e) {
63
+ const dataOnly = (e.router || (e.router = {})).dataOnly;
64
+ if (dataOnly) {
65
+ const data = e && (e.router.data || (e.router.data = {}));
66
+ if (data && key in data)
67
+ return data[key];
68
+ if (Array.isArray(dataOnly) && !matchKey(key, dataOnly)) {
69
+ data[key] = undefined;
70
+ return Promise.resolve();
71
+ }
72
+ }
73
+ }
74
+ }
75
+ if (getListener() && !isServer) {
76
+ tracking = true;
77
+ onCleanup(() => cached[4].count--);
78
+ }
79
+ if (cached &&
80
+ cached[0] &&
81
+ (isServer ||
82
+ intent === "native" ||
83
+ cached[4].count ||
84
+ Date.now() - cached[0] < PRELOAD_TIMEOUT)) {
85
+ if (tracking) {
86
+ cached[4].count++;
87
+ cached[4][0](); // track
88
+ }
89
+ if (cached[3] === "preload" && intent !== "preload") {
90
+ cached[0] = now;
91
+ }
92
+ let res = cached[1];
93
+ if (intent !== "preload") {
94
+ res =
95
+ "then" in cached[1]
96
+ ? cached[1].then(handleResponse(false), handleResponse(true))
97
+ : handleResponse(false)(cached[1]);
98
+ !isServer && intent === "navigate" && startTransition(() => cached[4][1](cached[0])); // update version
99
+ }
100
+ inPreloadFn && "then" in res && res.catch(() => { });
101
+ return res;
102
+ }
103
+ let res;
104
+ if (!isServer && sharedConfig.has && sharedConfig.has(key)) {
105
+ res = sharedConfig.load(key); // hydrating
106
+ // @ts-ignore at least until we add a delete method to sharedConfig
107
+ delete globalThis._$HY.r[key];
108
+ }
109
+ else
110
+ res = fn(...args);
111
+ if (cached) {
112
+ cached[0] = now;
113
+ cached[1] = res;
114
+ cached[3] = intent;
115
+ !isServer && intent === "navigate" && startTransition(() => cached[4][1](cached[0])); // update version
116
+ }
117
+ else {
118
+ cache.set(key, (cached = [now, res, , intent, createSignal(now)]));
119
+ cached[4].count = 0;
120
+ }
121
+ if (tracking) {
122
+ cached[4].count++;
123
+ cached[4][0](); // track
124
+ }
125
+ if (isServer) {
126
+ const e = getRequestEvent();
127
+ if (e && e.router.dataOnly)
128
+ return (e.router.data[key] = res);
129
+ }
130
+ if (intent !== "preload") {
131
+ res =
132
+ "then" in res
133
+ ? res.then(handleResponse(false), handleResponse(true))
134
+ : handleResponse(false)(res);
135
+ }
136
+ inPreloadFn && "then" in res && res.catch(() => { });
137
+ // serialize on server
138
+ if (isServer &&
139
+ sharedConfig.context &&
140
+ sharedConfig.context.async &&
141
+ !sharedConfig.context.noHydrate) {
142
+ const e = getRequestEvent();
143
+ (!e || !e.serverOnly) && sharedConfig.context.serialize(key, res);
144
+ }
145
+ return res;
146
+ function handleResponse(error) {
147
+ return async (v) => {
148
+ if (v instanceof Response) {
149
+ const e = getRequestEvent();
150
+ if (e) {
151
+ for (const [key, value] of v.headers) {
152
+ if (key == "set-cookie")
153
+ e.response.headers.append("set-cookie", value);
154
+ else
155
+ e.response.headers.set(key, value);
156
+ }
157
+ }
158
+ const url = v.headers.get(LocationHeader);
159
+ if (url !== null) {
160
+ // client + server relative redirect
161
+ if (navigate && url.startsWith("/"))
162
+ startTransition(() => {
163
+ navigate(url, { replace: true });
164
+ });
165
+ else if (!isServer)
166
+ window.location.href = url;
167
+ else if (e)
168
+ e.response.status = 302;
169
+ return;
170
+ }
171
+ if (v.customBody)
172
+ v = await v.customBody();
173
+ }
174
+ if (error)
175
+ throw v;
176
+ cached[2] = v;
177
+ return v;
178
+ };
179
+ }
180
+ });
181
+ cachedFn.keyFor = (...args) => name + hashKey(args);
182
+ cachedFn.key = name;
183
+ return cachedFn;
184
+ }
185
+ query.get = (key) => {
186
+ const cached = getCache().get(key);
187
+ return cached[2];
188
+ };
189
+ query.set = (key, value) => {
190
+ const cache = getCache();
191
+ const now = Date.now();
192
+ let cached = cache.get(key);
193
+ if (cached) {
194
+ cached[0] = now;
195
+ cached[1] = Promise.resolve(value);
196
+ cached[2] = value;
197
+ cached[3] = "preload";
198
+ }
199
+ else {
200
+ cache.set(key, (cached = [now, Promise.resolve(value), value, "preload", createSignal(now)]));
201
+ cached[4].count = 0;
202
+ }
203
+ };
204
+ query.delete = (key) => getCache().delete(key);
205
+ query.clear = () => getCache().clear();
206
+ /** @deprecated use query instead */
207
+ export const cache = query;
208
+ function matchKey(key, keys) {
209
+ for (let k of keys) {
210
+ if (k && key.startsWith(k))
211
+ return true;
212
+ }
213
+ return false;
214
+ }
215
+ // Modified from the amazing Tanstack Query library (MIT)
216
+ // https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L168
217
+ export function hashKey(args) {
218
+ return JSON.stringify(args, (_, val) => isPlainObject(val)
219
+ ? Object.keys(val)
220
+ .sort()
221
+ .reduce((result, key) => {
222
+ result[key] = val[key];
223
+ return result;
224
+ }, {})
225
+ : val);
226
+ }
227
+ function isPlainObject(obj) {
228
+ let proto;
229
+ return (obj != null &&
230
+ typeof obj === "object" &&
231
+ (!(proto = Object.getPrototypeOf(obj)) || proto === Object.prototype));
232
+ }
@@ -0,0 +1,4 @@
1
+ import type { RouterResponseInit, CustomResponse } from "../types.js";
2
+ export declare function redirect(url: string, init?: number | RouterResponseInit): CustomResponse<never>;
3
+ export declare function reload(init?: RouterResponseInit): CustomResponse<never>;
4
+ export declare function json<T>(data: T, init?: RouterResponseInit): CustomResponse<T>;
@@ -0,0 +1,42 @@
1
+ export function redirect(url, init = 302) {
2
+ let responseInit;
3
+ let revalidate;
4
+ if (typeof init === "number") {
5
+ responseInit = { status: init };
6
+ }
7
+ else {
8
+ ({ revalidate, ...responseInit } = init);
9
+ if (typeof responseInit.status === "undefined") {
10
+ responseInit.status = 302;
11
+ }
12
+ }
13
+ const headers = new Headers(responseInit.headers);
14
+ headers.set("Location", url);
15
+ revalidate !== undefined && headers.set("X-Revalidate", revalidate.toString());
16
+ const response = new Response(null, {
17
+ ...responseInit,
18
+ headers: headers
19
+ });
20
+ return response;
21
+ }
22
+ export function reload(init = {}) {
23
+ const { revalidate, ...responseInit } = init;
24
+ const headers = new Headers(responseInit.headers);
25
+ revalidate !== undefined && headers.set("X-Revalidate", revalidate.toString());
26
+ return new Response(null, {
27
+ ...responseInit,
28
+ headers
29
+ });
30
+ }
31
+ export function json(data, init = {}) {
32
+ const { revalidate, ...responseInit } = init;
33
+ const headers = new Headers(responseInit.headers);
34
+ revalidate !== undefined && headers.set("X-Revalidate", revalidate.toString());
35
+ headers.set("Content-Type", "application/json");
36
+ const response = new Response(JSON.stringify(data), {
37
+ ...responseInit,
38
+ headers
39
+ });
40
+ response.customBody = () => data;
41
+ return response;
42
+ }
@@ -0,0 +1,8 @@
1
+ export * from "./routers/index.js";
2
+ export * from "./components.jsx";
3
+ export * from "./lifecycle.js";
4
+ export { useHref, useIsRouting, useLocation, useMatch, useCurrentMatches, useNavigate, useParams, useResolvedPath, useSearchParams, useBeforeLeave, usePreloadRoute, RouterContextObj as RouterContext } from "./routing.js";
5
+ export { mergeSearchString as _mergeSearchString } from "./utils.js";
6
+ export * from "./data/index.js";
7
+ export { viewTransitionSource, viewTransitionTarget, type ViewTransitionAnimation, type ViewTransitionOptions, type ViewTransitionSourceOptions, type ViewTransitionTargetOptions } from "./viewTransitions.js";
8
+ export type { Location, LocationChange, SearchParams, MatchFilter, MatchFilters, NavigateOptions, Navigator, OutputMatch, Params, PathMatch, RouteSectionProps, RoutePreloadFunc, RoutePreloadFuncArgs, RouteDefinition, RouteDescription, RouteMatch, RouterIntegration, RouterUtils, SetParams, Submission, BeforeLeaveEventArgs, RouteLoadFunc, RouteLoadFuncArgs, RouterResponseInit, CustomResponse } from "./types.js";