vite-plugin-vanjs 0.1.16 → 0.1.18
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/client/index.mjs +21 -15
- package/package.json +3 -2
- package/plugin/helpers.mjs +13 -11
- package/plugin/index.mjs +4 -2
- package/plugin/types.d.ts +1 -1
- package/router/a.mjs +28 -16
- package/router/dataCache.mjs +168 -0
- package/router/global.d.ts +108 -53
- package/router/helpers.mjs +61 -14
- package/router/index.mjs +2 -1
- package/router/lazy.mjs +15 -53
- package/router/route.mjs +6 -6
- package/router/{cache.mjs → routeCache.mjs} +2 -2
- package/router/router.mjs +42 -27
- package/router/state.mjs +21 -15
- package/router/types.d.ts +64 -133
- package/server/global.d.ts +22 -0
- package/server/index.mjs +26 -10
- package/tsconfig.json +0 -3
package/client/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import van from "vanjs-core";
|
|
1
2
|
import { unwrap } from "../router/unwrap.mjs";
|
|
2
3
|
import { getTagKey } from "../meta/helpers.mjs";
|
|
3
4
|
|
|
@@ -225,20 +226,16 @@ function createHydrationContext() {
|
|
|
225
226
|
export const hydrate = (target, content) => {
|
|
226
227
|
if (content instanceof Promise) {
|
|
227
228
|
content.then((res) => {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
...(Array.from(wrapper.children)),
|
|
236
|
-
);
|
|
237
|
-
}
|
|
229
|
+
hydrate(target, res);
|
|
230
|
+
});
|
|
231
|
+
return target;
|
|
232
|
+
}
|
|
233
|
+
if (typeof content === "function") {
|
|
234
|
+
van.derive(() => {
|
|
235
|
+
hydrate(target, content());
|
|
238
236
|
});
|
|
239
237
|
return target;
|
|
240
238
|
}
|
|
241
|
-
|
|
242
239
|
const wrapper = unwrap(content);
|
|
243
240
|
const currentChildren = Array.from(target.children);
|
|
244
241
|
const newChildren = Array.from(wrapper.children);
|
|
@@ -257,7 +254,9 @@ export const hydrate = (target, content) => {
|
|
|
257
254
|
getTagKey(child) === key
|
|
258
255
|
);
|
|
259
256
|
if (existing) {
|
|
260
|
-
existing.
|
|
257
|
+
if (existing.outerHTML !== newChild.outerHTML) {
|
|
258
|
+
existing.replaceWith(newChild);
|
|
259
|
+
}
|
|
261
260
|
} else {
|
|
262
261
|
target.appendChild(newChild);
|
|
263
262
|
}
|
|
@@ -268,9 +267,16 @@ export const hydrate = (target, content) => {
|
|
|
268
267
|
diffAndHydrate(target, content);
|
|
269
268
|
target.setAttribute("data-h", "");
|
|
270
269
|
} else {
|
|
271
|
-
target.replaceChildren(...newChildren);
|
|
270
|
+
// target.replaceChildren(...newChildren);
|
|
271
|
+
const parsed = [];
|
|
272
|
+
for (const child of newChildren) {
|
|
273
|
+
parsed.push(
|
|
274
|
+
child instanceof Element
|
|
275
|
+
? child
|
|
276
|
+
: /* istanbul ignore next */ String(child),
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
target.replaceChildren(...parsed);
|
|
272
280
|
}
|
|
273
281
|
}
|
|
274
|
-
|
|
275
|
-
return target;
|
|
276
282
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-vanjs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"author": "thednp",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "A mini meta-framework for VanJS powered by Vite",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"setup",
|
|
16
16
|
"router",
|
|
17
17
|
"meta",
|
|
18
|
+
"data",
|
|
18
19
|
"client",
|
|
19
20
|
"server",
|
|
20
21
|
"jsx",
|
|
@@ -93,7 +94,7 @@
|
|
|
93
94
|
"@vitest/ui": "^4.1.5",
|
|
94
95
|
"happy-dom": "^20.9.0",
|
|
95
96
|
"typescript": "6.0.3",
|
|
96
|
-
"vite": "^8.0.
|
|
97
|
+
"vite": "^8.0.10",
|
|
97
98
|
"vitest": "^4.1.5"
|
|
98
99
|
},
|
|
99
100
|
"engines": {
|
package/plugin/helpers.mjs
CHANGED
|
@@ -206,27 +206,29 @@ export const generateRouteProloaders = (route) => {
|
|
|
206
206
|
const layoutName = "Module";
|
|
207
207
|
|
|
208
208
|
return `{
|
|
209
|
-
|
|
210
|
-
|
|
209
|
+
preload: async (params) => {
|
|
210
|
+
${
|
|
211
211
|
route.layouts.map((layout) =>
|
|
212
212
|
`if (${layout.id + layoutName}?.route?.preload) await ${
|
|
213
213
|
layout.id + layoutName
|
|
214
214
|
}?.route?.preload(params);`
|
|
215
|
-
).join("\n
|
|
215
|
+
).join("\n ")
|
|
216
216
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
217
|
+
if (${moduleName}?.route?.preload) await ${moduleName}?.route?.preload(params);
|
|
218
|
+
},
|
|
219
|
+
load: async (params) => {
|
|
220
|
+
let _data;
|
|
221
|
+
${
|
|
221
222
|
route.layouts.map((layout) =>
|
|
222
223
|
`if (${layout.id + layoutName}?.route?.load) await ${
|
|
223
224
|
layout.id + layoutName
|
|
224
225
|
}?.route?.load(params);`
|
|
225
|
-
).join("\n
|
|
226
|
+
).join("\n ")
|
|
226
227
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
228
|
+
if (${moduleName}?.route?.load) _data = await ${moduleName}?.route?.load(params);
|
|
229
|
+
return _data;
|
|
230
|
+
}
|
|
231
|
+
}`;
|
|
230
232
|
};
|
|
231
233
|
|
|
232
234
|
/** @type {(route: RouteFile) => string} */
|
package/plugin/index.mjs
CHANGED
|
@@ -87,6 +87,7 @@ export default function VitePluginVanJS(options = {}) {
|
|
|
87
87
|
],
|
|
88
88
|
},
|
|
89
89
|
ssr: {
|
|
90
|
+
// external: ["virtual:@vanjs/routes"],
|
|
90
91
|
noExternal: ["vanjs-*", "*-vanjs", "@vanjs/*"],
|
|
91
92
|
},
|
|
92
93
|
resolve: {
|
|
@@ -235,8 +236,9 @@ routes.length = 0;
|
|
|
235
236
|
// Register routes
|
|
236
237
|
${currentRoutes.map(generateRoute).join("\n")}
|
|
237
238
|
${
|
|
238
|
-
(ops
|
|
239
|
-
|
|
239
|
+
(ops?.ssr && currentRoutes.length)
|
|
240
|
+
? `console.log(\`🍦 @vanjs/router registered ${currentRoutes.length} routes.\`)`
|
|
241
|
+
: /* istanbul ignore next */ ""
|
|
240
242
|
}
|
|
241
243
|
`;
|
|
242
244
|
|
package/plugin/types.d.ts
CHANGED
package/router/a.mjs
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
// router/a.mjs
|
|
2
2
|
import van from "vanjs-core";
|
|
3
3
|
import { matchRoute } from "./matchRoute.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
getValue,
|
|
6
|
+
isCurrentLocation,
|
|
7
|
+
isCurrentPage,
|
|
8
|
+
navigate,
|
|
9
|
+
} from "./helpers.mjs";
|
|
5
10
|
|
|
6
11
|
/** @typedef {typeof import("./types").A} A */
|
|
7
12
|
|
|
@@ -9,46 +14,53 @@ import { executeLifecycle, isCurrentPage, navigate } from "./helpers.mjs";
|
|
|
9
14
|
* @type {A}
|
|
10
15
|
*/
|
|
11
16
|
export const A = (
|
|
12
|
-
/* istanbul ignore next */
|
|
17
|
+
/* istanbul ignore next */
|
|
18
|
+
{ href, children, ...rest } = {},
|
|
13
19
|
...otherChildren
|
|
14
20
|
) => {
|
|
15
21
|
/* istanbul ignore next - try again later */
|
|
16
22
|
const props = Object.fromEntries(
|
|
17
23
|
Object.entries(rest || {}).filter(([_, val]) => val !== undefined),
|
|
18
24
|
);
|
|
25
|
+
|
|
26
|
+
const preloaded = van.state(false);
|
|
27
|
+
|
|
19
28
|
const newProps = {
|
|
20
29
|
href,
|
|
21
30
|
...props,
|
|
22
31
|
onclick: async (e) => {
|
|
32
|
+
const HREF = getValue(href);
|
|
23
33
|
e.preventDefault();
|
|
24
34
|
/* istanbul ignore next */
|
|
25
|
-
if (isCurrentPage(
|
|
35
|
+
if (isCurrentPage(HREF)) return;
|
|
26
36
|
|
|
27
37
|
// istanbul ignore else
|
|
28
|
-
if (props.onclick) {
|
|
38
|
+
if (typeof props.onclick === "function") {
|
|
29
39
|
await props.onclick(e);
|
|
30
40
|
}
|
|
31
41
|
|
|
32
|
-
|
|
33
|
-
const module = await route.component();
|
|
34
|
-
await executeLifecycle(module, route.params);
|
|
35
|
-
|
|
36
|
-
navigate(href);
|
|
42
|
+
navigate(HREF);
|
|
37
43
|
},
|
|
38
|
-
onmouseenter: () => {
|
|
39
|
-
const
|
|
44
|
+
onmouseenter: async () => {
|
|
45
|
+
const HREF = getValue(href);
|
|
46
|
+
const route = matchRoute(HREF);
|
|
40
47
|
|
|
48
|
+
// istanbul ignore else
|
|
49
|
+
if (typeof props.onmouseenter === "function") {
|
|
50
|
+
await props.onmouseenter(e);
|
|
51
|
+
}
|
|
41
52
|
/* istanbul ignore else */
|
|
42
|
-
if (route?.component) {
|
|
53
|
+
if (route?.component && !preloaded.val) {
|
|
43
54
|
route.component();
|
|
55
|
+
preloaded.val = true;
|
|
44
56
|
}
|
|
45
57
|
},
|
|
46
58
|
};
|
|
47
59
|
|
|
48
|
-
van.derive(() => {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
60
|
+
newProps["aria-current"] = van.derive(() => {
|
|
61
|
+
const isPage = isCurrentPage(href);
|
|
62
|
+
const isLocation = isCurrentLocation(href);
|
|
63
|
+
return isPage ? "page" : isLocation ? "location" : null;
|
|
52
64
|
});
|
|
53
65
|
|
|
54
66
|
return van.tags.a(newProps, children || otherChildren);
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/** @typedef {{ data: unknown; error: Error | null; status: "idle" | "pending" | "success" | "error"; timestamp: number }} CacheEntry */
|
|
2
|
+
/** @typedef {CacheEntry["status"]} DataStatus */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @param {string} pathname
|
|
6
|
+
* @returns {string}
|
|
7
|
+
*/
|
|
8
|
+
export const normalizePath = (pathname) => {
|
|
9
|
+
if (!pathname || pathname === "/") return "/";
|
|
10
|
+
return pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** @type {Map<string, Map<string, CacheEntry>>} */
|
|
14
|
+
const dataCacheMap = new Map();
|
|
15
|
+
|
|
16
|
+
const DEFAULT_MAX_ROUTES = 20;
|
|
17
|
+
let maxRoutes = DEFAULT_MAX_ROUTES;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {number} n
|
|
21
|
+
*/
|
|
22
|
+
export const setMaxRoutes = (n) => {
|
|
23
|
+
maxRoutes = n;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const evictIfNeeded = () => {
|
|
27
|
+
if (maxRoutes <= 0) return;
|
|
28
|
+
while (dataCacheMap.size > maxRoutes) {
|
|
29
|
+
const firstKey = dataCacheMap.keys().next().value;
|
|
30
|
+
if (firstKey !== undefined) {
|
|
31
|
+
dataCacheMap.delete(firstKey);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {string} pathname
|
|
38
|
+
* @param {string} key
|
|
39
|
+
* @returns {CacheEntry | undefined}
|
|
40
|
+
*/
|
|
41
|
+
export const get = (pathname, key) => {
|
|
42
|
+
const path = normalizePath(pathname);
|
|
43
|
+
const routeMap = dataCacheMap.get(path);
|
|
44
|
+
if (!routeMap) return undefined;
|
|
45
|
+
return routeMap.get(key);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {string} pathname
|
|
50
|
+
* @param {string} key
|
|
51
|
+
* @param {Partial<CacheEntry>} entry
|
|
52
|
+
*/
|
|
53
|
+
export const set = (pathname, key, entry) => {
|
|
54
|
+
const path = normalizePath(pathname);
|
|
55
|
+
let routeMap = dataCacheMap.get(path);
|
|
56
|
+
if (!routeMap) {
|
|
57
|
+
routeMap = new Map();
|
|
58
|
+
dataCacheMap.set(path, routeMap);
|
|
59
|
+
evictIfNeeded();
|
|
60
|
+
}
|
|
61
|
+
routeMap.set(key, {
|
|
62
|
+
...entry,
|
|
63
|
+
timestamp: entry?.timestamp || Date.now(),
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @param {string} pathname
|
|
69
|
+
* @param {string} [key]
|
|
70
|
+
* @returns {boolean}
|
|
71
|
+
*/
|
|
72
|
+
export const has = (pathname, key) => {
|
|
73
|
+
const path = normalizePath(pathname);
|
|
74
|
+
const routeMap = dataCacheMap.get(path);
|
|
75
|
+
if (!routeMap) return false;
|
|
76
|
+
if (key === undefined) return routeMap.size > 0;
|
|
77
|
+
return routeMap.has(key);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @param {string} pathname
|
|
82
|
+
* @returns {Record<string, CacheEntry> | undefined}
|
|
83
|
+
*/
|
|
84
|
+
export const getRoute = (pathname) => {
|
|
85
|
+
const path = normalizePath(pathname);
|
|
86
|
+
const routeMap = dataCacheMap.get(path);
|
|
87
|
+
if (!routeMap) return undefined;
|
|
88
|
+
return Object.fromEntries(routeMap.entries());
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param {string} pathname
|
|
93
|
+
* @param {string} [key]
|
|
94
|
+
* @returns {boolean}
|
|
95
|
+
*/
|
|
96
|
+
export const del = (pathname, key) => {
|
|
97
|
+
const path = normalizePath(pathname);
|
|
98
|
+
if (key === undefined) {
|
|
99
|
+
const deleted = dataCacheMap.delete(path);
|
|
100
|
+
return deleted;
|
|
101
|
+
}
|
|
102
|
+
const routeMap = dataCacheMap.get(path);
|
|
103
|
+
if (!routeMap) return false;
|
|
104
|
+
const deleted = routeMap.delete(key);
|
|
105
|
+
if (routeMap.size === 0) {
|
|
106
|
+
dataCacheMap.delete(path);
|
|
107
|
+
}
|
|
108
|
+
return deleted;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const clear = () => {
|
|
112
|
+
dataCacheMap.clear();
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @param {string} pathname
|
|
117
|
+
*/
|
|
118
|
+
export const touch = (pathname) => {
|
|
119
|
+
const path = normalizePath(pathname);
|
|
120
|
+
const routeMap = dataCacheMap.get(path);
|
|
121
|
+
if (!routeMap) return;
|
|
122
|
+
dataCacheMap.delete(path);
|
|
123
|
+
dataCacheMap.set(path, routeMap);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* @returns {Record<string, Record<string, { data: unknown; status: string; timestamp: number; error: { message: string } | null }>>}
|
|
128
|
+
*/
|
|
129
|
+
export const toJSON = () => {
|
|
130
|
+
/** @type {Record<string, Record<string, { data: unknown; status: string; timestamp: number; error: { message: string } | null }>>} */
|
|
131
|
+
const result = {};
|
|
132
|
+
for (const [path, routeMap] of dataCacheMap.entries()) {
|
|
133
|
+
result[path] = {};
|
|
134
|
+
for (const [key, entry] of routeMap.entries()) {
|
|
135
|
+
result[path][key] = {
|
|
136
|
+
data: entry.data,
|
|
137
|
+
timestamp: entry.timestamp,
|
|
138
|
+
error: entry.error ? { message: entry.error.message } : null,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @param {Record<string, Record<string, { data: unknown; status?: string; timestamp?: number; error?: { message: string } | null }>>} json
|
|
147
|
+
*/
|
|
148
|
+
export const hydrateFromJSON = (json) => {
|
|
149
|
+
if (!json || typeof json !== "object") return;
|
|
150
|
+
for (const [path, routeEntries] of Object.entries(json)) {
|
|
151
|
+
const normalized = normalizePath(path);
|
|
152
|
+
let routeMap = dataCacheMap.get(normalized);
|
|
153
|
+
if (!routeMap) {
|
|
154
|
+
routeMap = new Map();
|
|
155
|
+
dataCacheMap.set(normalized, routeMap);
|
|
156
|
+
}
|
|
157
|
+
for (const [key, entry] of Object.entries(routeEntries)) {
|
|
158
|
+
routeMap.set(key, {
|
|
159
|
+
data: entry.data,
|
|
160
|
+
timestamp: entry.timestamp || Date.now(),
|
|
161
|
+
error: entry.error ? new Error(entry.error.message) : null,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/** @returns {number} */
|
|
168
|
+
export const size = () => dataCacheMap.size;
|
package/router/global.d.ts
CHANGED
|
@@ -12,9 +12,8 @@ declare module "@vanjs/router" {
|
|
|
12
12
|
PropValueOrDerived,
|
|
13
13
|
State,
|
|
14
14
|
} from "vanjs-core";
|
|
15
|
+
import type { LayoutFile } from "../plugin/types.d.ts";
|
|
15
16
|
|
|
16
|
-
// type VanElement = VElement | Exclude<Primitive, boolean | undefined>;
|
|
17
|
-
// type DOMElement = globalThis.Element;
|
|
18
17
|
type PrimitiveChild = Primitive | State<Primitive | undefined | null>;
|
|
19
18
|
|
|
20
19
|
type DOMElement<T extends keyof HTMLElementTagNameMap = "div"> =
|
|
@@ -27,13 +26,6 @@ declare module "@vanjs/router" {
|
|
|
27
26
|
| DOMElement
|
|
28
27
|
| VElement
|
|
29
28
|
| PrimitiveChild;
|
|
30
|
-
// type VanElement =
|
|
31
|
-
// | SVGElement
|
|
32
|
-
// | HTMLElement
|
|
33
|
-
// | DOMElement
|
|
34
|
-
// | Node
|
|
35
|
-
// | VElement
|
|
36
|
-
// | PrimitiveChild;
|
|
37
29
|
export type VanNode =
|
|
38
30
|
| VanElement
|
|
39
31
|
| VanElement[]
|
|
@@ -41,9 +33,7 @@ declare module "@vanjs/router" {
|
|
|
41
33
|
| null
|
|
42
34
|
| undefined;
|
|
43
35
|
|
|
44
|
-
type ComponentProps1<T> =
|
|
45
|
-
& Props
|
|
46
|
-
& PropsWithKnownKeys<T>;
|
|
36
|
+
type ComponentProps1<T> = Props & PropsWithKnownKeys<T>;
|
|
47
37
|
|
|
48
38
|
type ComponentProps<K extends keyof HTMLElementTagNameMap> =
|
|
49
39
|
& Props
|
|
@@ -69,7 +59,7 @@ declare module "@vanjs/router" {
|
|
|
69
59
|
* import { Router } from '@vanjs/router';
|
|
70
60
|
*
|
|
71
61
|
* export const App = () => {
|
|
72
|
-
*
|
|
62
|
+
* return Router(); // or <Router /> for JSX
|
|
73
63
|
* }
|
|
74
64
|
*/
|
|
75
65
|
export const Router:
|
|
@@ -89,12 +79,11 @@ declare module "@vanjs/router" {
|
|
|
89
79
|
* import van from 'vanjs-core';
|
|
90
80
|
*
|
|
91
81
|
* export const Navigation = () => {
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* );
|
|
82
|
+
* const { nav } = van.tags
|
|
83
|
+
* return nav(
|
|
84
|
+
* A({ href="/" }, "Home"),
|
|
85
|
+
* A({ href="/about" }, "About"),
|
|
86
|
+
* );
|
|
98
87
|
* }
|
|
99
88
|
*/
|
|
100
89
|
export const A:
|
|
@@ -114,23 +103,41 @@ declare module "@vanjs/router" {
|
|
|
114
103
|
options?: { replace?: boolean },
|
|
115
104
|
) => void;
|
|
116
105
|
|
|
117
|
-
/**
|
|
118
|
-
* A client only helper function that reloads the current page.
|
|
119
|
-
*/
|
|
106
|
+
/** A client only helper function that reloads the current page. */
|
|
120
107
|
export const reload: () => void;
|
|
121
108
|
|
|
122
109
|
/**
|
|
123
110
|
* A helper function that redirects the user to the specified href.
|
|
124
111
|
* When called in the server, it will return a function that will redirect the user
|
|
125
112
|
* to the specified href when called.
|
|
126
|
-
* @param
|
|
113
|
+
* @param href the URL to redirect to
|
|
127
114
|
*/
|
|
128
115
|
export const redirect: (href?: string) => void | (() => void);
|
|
129
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Returns the string value of a State or primitive
|
|
119
|
+
*/
|
|
120
|
+
export const getValue: (v: unknown) => string;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Check if selected page is the current page
|
|
124
|
+
*/
|
|
125
|
+
export const isCurrentPage: (pageName: string) => boolean;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Check if selected page is related to the current page
|
|
129
|
+
*/
|
|
130
|
+
export const isCurrentLocation: (pageName: string) => boolean;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Check if component is a lazy component
|
|
134
|
+
*/
|
|
135
|
+
export const isLazyComponent: (component: unknown) => boolean;
|
|
136
|
+
|
|
130
137
|
// routes.mjs
|
|
131
138
|
export type RouteEntry = {
|
|
132
139
|
path: string;
|
|
133
|
-
component: Promise<ComponentModule>;
|
|
140
|
+
component: () => Promise<ComponentModule>;
|
|
134
141
|
params?: Record<string, string>;
|
|
135
142
|
preload?: (
|
|
136
143
|
params?: Record<string, string>,
|
|
@@ -140,17 +147,16 @@ declare module "@vanjs/router" {
|
|
|
140
147
|
) => boolean | void | Promise<boolean | void>;
|
|
141
148
|
};
|
|
142
149
|
|
|
150
|
+
export type ImportFn = () => LazyComponent;
|
|
151
|
+
|
|
143
152
|
export type RouteProps = {
|
|
144
153
|
path: string;
|
|
154
|
+
params?: Record<string, string>;
|
|
145
155
|
component:
|
|
146
|
-
| (() =>
|
|
147
|
-
| HTMLElementTagNameMap[unknown]
|
|
148
|
-
| HTMLElementTagNameMap[unknown][])
|
|
156
|
+
| (() => DOMElement)
|
|
149
157
|
| VanComponent
|
|
150
158
|
| ComponentFn
|
|
151
|
-
| (() => Promise<
|
|
152
|
-
// | ComponentModule["component"];
|
|
153
|
-
// component: ComponentFn | (() => Promise<ComponentModule>);
|
|
159
|
+
| (() => Promise<ComponentModule>);
|
|
154
160
|
preload?: (
|
|
155
161
|
params?: Record<string, string>,
|
|
156
162
|
) => boolean | void | Promise<boolean | void>;
|
|
@@ -158,6 +164,13 @@ declare module "@vanjs/router" {
|
|
|
158
164
|
params?: Record<string, string>,
|
|
159
165
|
) => boolean | void | Promise<boolean | void>;
|
|
160
166
|
};
|
|
167
|
+
|
|
168
|
+
export type RouteConfig = {
|
|
169
|
+
routePath: string;
|
|
170
|
+
path: string;
|
|
171
|
+
layouts?: LayoutFile[];
|
|
172
|
+
};
|
|
173
|
+
|
|
161
174
|
export const routes: RouteEntry[];
|
|
162
175
|
|
|
163
176
|
/**
|
|
@@ -180,20 +193,18 @@ declare module "@vanjs/router" {
|
|
|
180
193
|
pathname: string;
|
|
181
194
|
searchParams: URLSearchParams;
|
|
182
195
|
params: Record<string, string>;
|
|
196
|
+
status: "idle" | "pending" | "success" | "error";
|
|
183
197
|
};
|
|
198
|
+
|
|
184
199
|
/**
|
|
185
200
|
* A reactive object that holds the current router state.
|
|
186
201
|
* This state is maintained by both server and client.
|
|
187
202
|
*/
|
|
188
|
-
// export const routerState: {
|
|
189
|
-
// pathname: State<RouterState.pathname>;
|
|
190
|
-
// searchParams: State<RouterState.searchParams>;
|
|
191
|
-
// params?: State<RouterState.params>;
|
|
192
|
-
// };
|
|
193
203
|
export const routerState: {
|
|
194
204
|
pathname: RouterState["pathname"];
|
|
195
205
|
searchParams: RouterState["searchParams"];
|
|
196
206
|
params?: RouterState["params"];
|
|
207
|
+
status: RouterState["status"];
|
|
197
208
|
};
|
|
198
209
|
|
|
199
210
|
/**
|
|
@@ -208,12 +219,24 @@ declare module "@vanjs/router" {
|
|
|
208
219
|
params?: Record<string, string>,
|
|
209
220
|
) => void;
|
|
210
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Creates a reactive micro store from an initial object
|
|
224
|
+
*/
|
|
225
|
+
export const microStore: <T extends Record<string, unknown>>(init: T) => T;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Fixes the URL of a route.
|
|
229
|
+
* @param url
|
|
230
|
+
*/
|
|
231
|
+
export const fixRouteUrl: (url: string) => string;
|
|
232
|
+
|
|
233
|
+
// unwrap.mjs
|
|
211
234
|
/**
|
|
212
235
|
* Merge the children of an Element or an array of elements with an optional array of children
|
|
213
|
-
* into the
|
|
214
|
-
* @param source
|
|
215
|
-
* @param children
|
|
236
|
+
* into the children property of a simple object.
|
|
216
237
|
*/
|
|
238
|
+
export type UnwrapResult = { children: VanNode[] };
|
|
239
|
+
|
|
217
240
|
export const unwrap: (
|
|
218
241
|
source:
|
|
219
242
|
| VanNode
|
|
@@ -228,8 +251,8 @@ declare module "@vanjs/router" {
|
|
|
228
251
|
| ReturnType<IsoTagFunc>[]
|
|
229
252
|
| VanNode
|
|
230
253
|
| VanNode[]),
|
|
231
|
-
...children:
|
|
232
|
-
) =>
|
|
254
|
+
...children: VanNode[]
|
|
255
|
+
) => UnwrapResult;
|
|
233
256
|
|
|
234
257
|
export type JSXComponentFn = () => JSX.Element;
|
|
235
258
|
export type FragmentFn = () => ChildDom | ChildDom[];
|
|
@@ -240,15 +263,11 @@ declare module "@vanjs/router" {
|
|
|
240
263
|
route?: Pick<RouteEntry, "load" | "preload">;
|
|
241
264
|
};
|
|
242
265
|
|
|
243
|
-
export type
|
|
244
|
-
Page: ComponentFn;
|
|
266
|
+
export type LazyComponent = Promise<{
|
|
245
267
|
default?: ComponentFn;
|
|
268
|
+
Page?: ComponentFn;
|
|
246
269
|
route?: Pick<RouteEntry, "load" | "preload">;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
export type LazyComponent = Promise<DynamicModule>;
|
|
250
|
-
|
|
251
|
-
export type ImportFn = () => LazyComponent;
|
|
270
|
+
}>;
|
|
252
271
|
|
|
253
272
|
/**
|
|
254
273
|
* Registers a lazy component.
|
|
@@ -257,21 +276,57 @@ declare module "@vanjs/router" {
|
|
|
257
276
|
export const lazy: (importFn: ImportFn) => () => Promise<ComponentModule>;
|
|
258
277
|
|
|
259
278
|
/**
|
|
260
|
-
*
|
|
261
|
-
* @param
|
|
279
|
+
* Cache a route.
|
|
280
|
+
* @param key the cache route key
|
|
281
|
+
* @param value the cache route
|
|
262
282
|
*/
|
|
263
|
-
export const
|
|
283
|
+
export const cacheRoute: (key: ImportFn, value: ComponentModule) => void;
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Return a route cache.
|
|
287
|
+
* @param key the cache route key
|
|
288
|
+
*/
|
|
289
|
+
export const getCachedRoute: (key: ImportFn) => ComponentModule | undefined;
|
|
264
290
|
|
|
265
291
|
/**
|
|
266
292
|
* Execute lifecycle methods preload and / or load
|
|
267
293
|
*/
|
|
268
294
|
export const executeLifecycle: (
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
295
|
+
route: RouteEntry | {
|
|
296
|
+
preload?: (params?: Record<string, string>) => unknown;
|
|
297
|
+
load?: (params?: Record<string, string>) => unknown;
|
|
298
|
+
} | null,
|
|
299
|
+
params: Record<string, string> | undefined,
|
|
300
|
+
) => Promise<boolean>;
|
|
272
301
|
|
|
273
302
|
/**
|
|
274
303
|
* Find a registered route that matches the given path
|
|
275
304
|
*/
|
|
276
305
|
export const matchRoute: (path: string) => RouteEntry | null;
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Convenience hook to get the current route's cached data.
|
|
309
|
+
*/
|
|
310
|
+
export const useRouteData: <T>() => T | undefined;
|
|
311
|
+
|
|
312
|
+
// dataCache.mjs
|
|
313
|
+
export type CacheEntry<T = unknown> = {
|
|
314
|
+
data: T;
|
|
315
|
+
error: Error | null;
|
|
316
|
+
timestamp: number;
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
export const dataCache: {
|
|
320
|
+
get<T>(pathname: string, key: string): CacheEntry<T> | undefined;
|
|
321
|
+
set<T>(pathname: string, key: string, entry: Partial<CacheEntry<T>>): void;
|
|
322
|
+
has(pathname: string, key?: string): boolean;
|
|
323
|
+
getRoute(pathname: string): Record<string, CacheEntry> | undefined;
|
|
324
|
+
del(pathname: string, key?: string): boolean;
|
|
325
|
+
clear(): void;
|
|
326
|
+
touch(pathname: string): void;
|
|
327
|
+
toJSON(): Record<string, Record<string, CacheEntry>>;
|
|
328
|
+
hydrateFromJSON(json: Record<string, Record<string, CacheEntry>>): void;
|
|
329
|
+
size(): number;
|
|
330
|
+
setMaxRoutes(n: number): void;
|
|
331
|
+
};
|
|
277
332
|
}
|