vite-plugin-vanjs 0.1.23 → 0.1.25
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 +14 -7
- package/meta/Head.mjs +20 -0
- package/meta/global.d.ts +6 -2
- package/meta/helpers.mjs +1 -1
- package/meta/types.d.ts +2 -1
- package/package.json +8 -8
- package/plugin/helpers.mjs +6 -6
- package/plugin/types.d.ts +2 -2
- package/router/a.mjs +2 -2
- package/router/global.d.ts +8 -8
- package/router/helpers.mjs +52 -6
- package/router/router.mjs +9 -39
- package/router/state.mjs +1 -8
- package/router/types.d.ts +8 -8
package/client/index.mjs
CHANGED
|
@@ -108,18 +108,24 @@ export function elementsMatch(el1, el2, deep) {
|
|
|
108
108
|
return false;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
// Filter empty text nodes — SSR omits them, client creates Text("")
|
|
112
|
+
// from function children returning ""
|
|
113
|
+
const cn1 = Array.from(el1.childNodes).filter((n) =>
|
|
114
|
+
n.nodeType !== 3 || /* istanbul ignore next */ n.textContent !== ""
|
|
115
|
+
);
|
|
116
|
+
const cn2 = Array.from(el2.childNodes).filter((n) =>
|
|
117
|
+
n.nodeType !== 3 || /* istanbul ignore next */ n.textContent !== ""
|
|
118
|
+
);
|
|
113
119
|
|
|
114
120
|
// istanbul ignore else
|
|
115
|
-
if (
|
|
121
|
+
if (cn1.length !== cn2.length) {
|
|
116
122
|
return false;
|
|
117
123
|
}
|
|
118
124
|
|
|
119
125
|
// Only recurse if necessary (has childNodes with data-hk)
|
|
120
|
-
const hasHydratedChildren =
|
|
121
|
-
child instanceof HTMLElement &&
|
|
122
|
-
|
|
126
|
+
const hasHydratedChildren = cn1.some((child) =>
|
|
127
|
+
child instanceof HTMLElement &&
|
|
128
|
+
(child.hasAttribute("data-hk") || child.querySelector("[data-hk]"))
|
|
123
129
|
);
|
|
124
130
|
|
|
125
131
|
// istanbul ignore next
|
|
@@ -130,7 +136,7 @@ export function elementsMatch(el1, el2, deep) {
|
|
|
130
136
|
// Only recurse if opted in
|
|
131
137
|
// istanbul ignore next
|
|
132
138
|
return deep
|
|
133
|
-
?
|
|
139
|
+
? cn1.every((child, idx) => elementsMatch(child, cn2[idx]))
|
|
134
140
|
: true;
|
|
135
141
|
}
|
|
136
142
|
|
|
@@ -279,4 +285,5 @@ export const hydrate = (target, content) => {
|
|
|
279
285
|
target.replaceChildren(...parsed);
|
|
280
286
|
}
|
|
281
287
|
}
|
|
288
|
+
return target;
|
|
282
289
|
};
|
package/meta/Head.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { getTagKey } from "./helpers.mjs";
|
|
|
6
6
|
/** @typedef {typeof import("./types.d.ts").resetHeadTags} ResetTags */
|
|
7
7
|
/** @typedef {typeof import("./types.d.ts").initializeHeadTags} InitializeTags */
|
|
8
8
|
/** @typedef {typeof import("./types.d.ts").addMeta} AddMeta */
|
|
9
|
+
/** @typedef {typeof import("./types.d.ts").removeMeta} RemoveMeta */
|
|
9
10
|
/** @typedef {typeof import("./types.d.ts").Head} HeadComp */
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -69,6 +70,25 @@ export const addMeta = (tag) => {
|
|
|
69
70
|
tags.set(key, tag);
|
|
70
71
|
};
|
|
71
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Remove a new meta tag `van.tags.script({ id })`
|
|
75
|
+
* or TAGNAME.id key.
|
|
76
|
+
* Only client side.
|
|
77
|
+
* @type {RemoveMeta}
|
|
78
|
+
*/
|
|
79
|
+
export const removeMeta = (tagOrId) => {
|
|
80
|
+
if (!tagOrId || isServer) return;
|
|
81
|
+
const tags = getHeadTags();
|
|
82
|
+
const tagIsString = typeof tagOrId === "string";
|
|
83
|
+
const key = tagIsString ? tagOrId : getTagKey(tagOrId);
|
|
84
|
+
const id = tagIsString ? tagOrId.split(".")[1] : tagOrId.id;
|
|
85
|
+
// istanbul ignore else
|
|
86
|
+
if (id) {
|
|
87
|
+
document.getElementById(id)?.remove();
|
|
88
|
+
tags.delete(key);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
72
92
|
/**
|
|
73
93
|
* Get the head tags
|
|
74
94
|
* @type {HeadComp}
|
package/meta/global.d.ts
CHANGED
|
@@ -29,7 +29,8 @@ declare module "@vanjs/meta" {
|
|
|
29
29
|
|
|
30
30
|
export type HeadTags = SupportedTags[] | TagFunc[];
|
|
31
31
|
|
|
32
|
-
export const addMeta: (tag?:
|
|
32
|
+
export const addMeta: (tag?: Partial<SupportedTags>) => void;
|
|
33
|
+
export const removeMeta = (_tag: string | Partial<SupportedTags>) => null;
|
|
33
34
|
|
|
34
35
|
export const Head: () => HeadTags;
|
|
35
36
|
|
|
@@ -39,7 +40,10 @@ declare module "@vanjs/meta" {
|
|
|
39
40
|
) => null;
|
|
40
41
|
|
|
41
42
|
export const Meta: (
|
|
42
|
-
props: PropsWithKnownKeys<HTMLMetaElement> & {
|
|
43
|
+
props: PropsWithKnownKeys<HTMLMetaElement> & {
|
|
44
|
+
charset?: string & "utf-8";
|
|
45
|
+
property?: string;
|
|
46
|
+
},
|
|
43
47
|
) => null;
|
|
44
48
|
|
|
45
49
|
export const Style: (
|
package/meta/helpers.mjs
CHANGED
|
@@ -19,6 +19,7 @@ export const parseAttributes = (attributeString) => {
|
|
|
19
19
|
/** @type {typeof import('./types.d.ts').getTagAttribute} */
|
|
20
20
|
const getTagAttribute = (tag) => {
|
|
21
21
|
const attributes = [
|
|
22
|
+
"id",
|
|
22
23
|
"name",
|
|
23
24
|
"property",
|
|
24
25
|
"charset",
|
|
@@ -28,7 +29,6 @@ const getTagAttribute = (tag) => {
|
|
|
28
29
|
"rel",
|
|
29
30
|
"src",
|
|
30
31
|
"href",
|
|
31
|
-
"id",
|
|
32
32
|
];
|
|
33
33
|
|
|
34
34
|
for (const attr of attributes) {
|
package/meta/types.d.ts
CHANGED
|
@@ -29,7 +29,8 @@ export type TagProps = SupportedTags | PropsWithKnownKeys<SupportedTags>;
|
|
|
29
29
|
|
|
30
30
|
export type HeadTags = AllHeadTags[] | TagFunc[];
|
|
31
31
|
|
|
32
|
-
export const addMeta = (_tag: string |
|
|
32
|
+
export const addMeta = (_tag: string | Partial<SupportedTags>) => null;
|
|
33
|
+
export const removeMeta = (_tag: string | Partial<SupportedTags>) => null;
|
|
33
34
|
|
|
34
35
|
export const Head: () => HeadTags;
|
|
35
36
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-vanjs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.25",
|
|
4
4
|
"author": "thednp",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "An async first mini meta-framework for VanJS powered by Vite",
|
|
@@ -88,14 +88,14 @@
|
|
|
88
88
|
"vanjs-ext": "^0.6.3"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
|
-
"@types/node": "^25.
|
|
92
|
-
"@vitest/browser": "^4.1.
|
|
93
|
-
"@vitest/coverage-istanbul": "^4.1.
|
|
94
|
-
"@vitest/ui": "^4.1.
|
|
95
|
-
"happy-dom": "^20.
|
|
91
|
+
"@types/node": "^25.9.3",
|
|
92
|
+
"@vitest/browser": "^4.1.8",
|
|
93
|
+
"@vitest/coverage-istanbul": "^4.1.8",
|
|
94
|
+
"@vitest/ui": "^4.1.8",
|
|
95
|
+
"happy-dom": "^20.10.3",
|
|
96
96
|
"typescript": "6.0.3",
|
|
97
|
-
"vite": "^8.0.
|
|
98
|
-
"vitest": "^4.1.
|
|
97
|
+
"vite": "^8.0.16",
|
|
98
|
+
"vitest": "^4.1.8"
|
|
99
99
|
},
|
|
100
100
|
"engines": {
|
|
101
101
|
"node": ">=20",
|
package/plugin/helpers.mjs
CHANGED
|
@@ -218,26 +218,26 @@ export const generateRouteProloaders = (route) => {
|
|
|
218
218
|
const layoutName = "Module";
|
|
219
219
|
|
|
220
220
|
return `{
|
|
221
|
-
preload: async () => {
|
|
221
|
+
preload: async (params) => {
|
|
222
222
|
${
|
|
223
223
|
route.layouts.map((layout) =>
|
|
224
224
|
`if (${layout.id + layoutName}?.route?.preload) await ${
|
|
225
225
|
layout.id + layoutName
|
|
226
|
-
}?.route?.preload();`
|
|
226
|
+
}?.route?.preload(params);`
|
|
227
227
|
).join("\n ")
|
|
228
228
|
}
|
|
229
|
-
if (${moduleName}?.route?.preload) await ${moduleName}?.route?.preload();
|
|
229
|
+
if (${moduleName}?.route?.preload) await ${moduleName}?.route?.preload(params);
|
|
230
230
|
},
|
|
231
|
-
load: async () => {
|
|
231
|
+
load: async (params) => {
|
|
232
232
|
let _data;
|
|
233
233
|
${
|
|
234
234
|
route.layouts.map((layout) =>
|
|
235
235
|
`if (${layout.id + layoutName}?.route?.load) await ${
|
|
236
236
|
layout.id + layoutName
|
|
237
|
-
}?.route?.load();`
|
|
237
|
+
}?.route?.load(params);`
|
|
238
238
|
).join("\n ")
|
|
239
239
|
}
|
|
240
|
-
if (${moduleName}?.route?.load) _data = await ${moduleName}?.route?.load();
|
|
240
|
+
if (${moduleName}?.route?.load) _data = await ${moduleName}?.route?.load(params);
|
|
241
241
|
return _data;
|
|
242
242
|
}
|
|
243
243
|
}`;
|
package/plugin/types.d.ts
CHANGED
|
@@ -14,8 +14,8 @@ export type VanJSPluginOptions = {
|
|
|
14
14
|
excludeRoutesProd?: string[]; // NEW — excluded in production only
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const VitePluginVanJS: (
|
|
18
18
|
config?: VanJSPluginOptions,
|
|
19
|
-
) => Plugin
|
|
19
|
+
) => Plugin<VanJSPluginOptions>;
|
|
20
20
|
|
|
21
21
|
export default VitePluginVanJS;
|
package/router/a.mjs
CHANGED
|
@@ -29,8 +29,8 @@ export const A = (
|
|
|
29
29
|
href,
|
|
30
30
|
...props,
|
|
31
31
|
onclick: async (e) => {
|
|
32
|
-
const HREF = getValue(href);
|
|
33
32
|
e.preventDefault();
|
|
33
|
+
const HREF = getValue(href);
|
|
34
34
|
/* istanbul ignore next */
|
|
35
35
|
if (isCurrentPage(HREF)) return;
|
|
36
36
|
|
|
@@ -60,7 +60,7 @@ export const A = (
|
|
|
60
60
|
newProps["aria-current"] = van.derive(() => {
|
|
61
61
|
const isPage = isCurrentPage(href);
|
|
62
62
|
const isLocation = isCurrentLocation(href);
|
|
63
|
-
return isPage ? "page" : isLocation ? "location" :
|
|
63
|
+
return isPage ? "page" : isLocation ? "location" : "";
|
|
64
64
|
});
|
|
65
65
|
|
|
66
66
|
return van.tags.a(newProps, children || otherChildren);
|
package/router/global.d.ts
CHANGED
|
@@ -139,8 +139,8 @@ declare module "@vanjs/router" {
|
|
|
139
139
|
path: string;
|
|
140
140
|
component: () => Promise<ComponentModule>;
|
|
141
141
|
params?: Record<string, string>;
|
|
142
|
-
preload?: () =>
|
|
143
|
-
load?: () =>
|
|
142
|
+
preload?: (params?: Record<string, string>) => unknown;
|
|
143
|
+
load?: (params?: Record<string, string>) => Promise<unknown>;
|
|
144
144
|
};
|
|
145
145
|
|
|
146
146
|
export type ImportFn = () => LazyComponent;
|
|
@@ -153,8 +153,8 @@ declare module "@vanjs/router" {
|
|
|
153
153
|
| VanComponent
|
|
154
154
|
| ComponentFn
|
|
155
155
|
| (() => Promise<ComponentModule>);
|
|
156
|
-
preload?: () =>
|
|
157
|
-
load?: () =>
|
|
156
|
+
preload?: (params?: Record<string, string>) => unknown;
|
|
157
|
+
load?: (params?: Record<string, string>) => Promise<unknown>;
|
|
158
158
|
};
|
|
159
159
|
|
|
160
160
|
export type RouteConfig = {
|
|
@@ -185,7 +185,7 @@ declare module "@vanjs/router" {
|
|
|
185
185
|
pathname: string;
|
|
186
186
|
searchParams: string;
|
|
187
187
|
params: Record<string, string>;
|
|
188
|
-
|
|
188
|
+
loading: boolean;
|
|
189
189
|
};
|
|
190
190
|
|
|
191
191
|
/**
|
|
@@ -196,7 +196,7 @@ declare module "@vanjs/router" {
|
|
|
196
196
|
pathname: RouterState["pathname"];
|
|
197
197
|
searchParams: RouterState["searchParams"];
|
|
198
198
|
params?: RouterState["params"];
|
|
199
|
-
|
|
199
|
+
loading: RouterState["loading"];
|
|
200
200
|
};
|
|
201
201
|
|
|
202
202
|
/**
|
|
@@ -285,8 +285,8 @@ declare module "@vanjs/router" {
|
|
|
285
285
|
*/
|
|
286
286
|
export const executeLifecycle: (
|
|
287
287
|
route: RouteEntry | {
|
|
288
|
-
preload?: () => unknown;
|
|
289
|
-
load?: () => unknown
|
|
288
|
+
preload?: (params?: Record<string, string>) => unknown;
|
|
289
|
+
load?: (params?: Record<string, string>) => Promise<unknown>;
|
|
290
290
|
} | null,
|
|
291
291
|
) => Promise<boolean>;
|
|
292
292
|
|
package/router/helpers.mjs
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import van from "vanjs-core";
|
|
1
2
|
import isServer from "../setup/isServer.mjs";
|
|
2
3
|
import { routerState, setRouterState } from "./state.mjs";
|
|
3
4
|
import { matchRoute } from "./matchRoute.mjs";
|
|
4
5
|
import { unwrap } from "./unwrap.mjs";
|
|
6
|
+
import { hydrate } from "../client/index.mjs";
|
|
7
|
+
import { Head } from "../meta/index.mjs";
|
|
8
|
+
|
|
5
9
|
import * as dataCache from "./dataCache.mjs";
|
|
6
10
|
|
|
7
11
|
/** @typedef {typeof import("./types.d.ts").navigate} Navigate */
|
|
@@ -12,6 +16,16 @@ import * as dataCache from "./dataCache.mjs";
|
|
|
12
16
|
/** @typedef {import("./types.d.ts").ComponentFn} ComponentFn */
|
|
13
17
|
/** @typedef {import("./types.d.ts").LazyComponent} LazyComponent */
|
|
14
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Update head tags
|
|
21
|
+
*/
|
|
22
|
+
const updateHead = () => {
|
|
23
|
+
// istanbul ignore else
|
|
24
|
+
if (document.head) {
|
|
25
|
+
hydrate(document.head, Head());
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
15
29
|
/**
|
|
16
30
|
* Resolve component children from a module
|
|
17
31
|
* @param {ComponentModule | Element | Element[] | any} module
|
|
@@ -51,8 +65,8 @@ export const getCacheKey = () => {
|
|
|
51
65
|
*/
|
|
52
66
|
export const isCurrentPage = (pageName) => {
|
|
53
67
|
const href = getValue(pageName);
|
|
54
|
-
|
|
55
|
-
|
|
68
|
+
const url = new URL(href, "http://localhost:5173");
|
|
69
|
+
// console.log({ href }, routerState.searchParams, url.searchParams.toString())
|
|
56
70
|
return routerState.pathname === url.pathname &&
|
|
57
71
|
routerState.searchParams === url.searchParams.toString();
|
|
58
72
|
};
|
|
@@ -63,8 +77,12 @@ export const isCurrentPage = (pageName) => {
|
|
|
63
77
|
* @returns {boolean}
|
|
64
78
|
*/
|
|
65
79
|
export const isCurrentLocation = (pageName) => {
|
|
66
|
-
const
|
|
67
|
-
|
|
80
|
+
const href = getValue(pageName);
|
|
81
|
+
const searchParams = new URLSearchParams(routerState.searchParams);
|
|
82
|
+
const pathname = routerState.pathname;
|
|
83
|
+
const url = new URL(href, "http://localhost:5173");
|
|
84
|
+
return url.pathname !== "/" && pathname.includes(url.pathname) ||
|
|
85
|
+
pathname === url.pathname && searchParams.size > 0;
|
|
68
86
|
};
|
|
69
87
|
|
|
70
88
|
/**
|
|
@@ -96,9 +114,9 @@ export const executeLifecycle = async (route) => {
|
|
|
96
114
|
const pathname = routerState.pathname;
|
|
97
115
|
const cacheKey = getCacheKey();
|
|
98
116
|
|
|
99
|
-
if (preload) await preload();
|
|
117
|
+
if (preload) await preload(route.params);
|
|
100
118
|
if (!data && load && !dataCache.has(pathname, cacheKey)) {
|
|
101
|
-
data = await load();
|
|
119
|
+
data = await load(route.params);
|
|
102
120
|
} else if (load && dataCache.has(pathname, cacheKey)) {
|
|
103
121
|
dataCache.touch(pathname);
|
|
104
122
|
}
|
|
@@ -123,6 +141,34 @@ export const executeLifecycle = async (route) => {
|
|
|
123
141
|
}
|
|
124
142
|
};
|
|
125
143
|
|
|
144
|
+
/**
|
|
145
|
+
* @param {RouteEntry} route
|
|
146
|
+
* @param {HTMLElement} wrapper
|
|
147
|
+
* @param {boolean} ssr
|
|
148
|
+
* @returns
|
|
149
|
+
*/
|
|
150
|
+
export const executeModule = async (route, wrapper, ssr) => {
|
|
151
|
+
if (routerState.loading === true) return;
|
|
152
|
+
// 0. Set Loading State
|
|
153
|
+
routerState.loading = true;
|
|
154
|
+
try {
|
|
155
|
+
// 1. Resolve the module first (to get route lifecycle hooks)
|
|
156
|
+
const module = await route.component();
|
|
157
|
+
// 2. Execute lifecycle (a complete route includes all props)
|
|
158
|
+
await executeLifecycle(Object.assign(route, module.route));
|
|
159
|
+
// 3. Resolve children
|
|
160
|
+
const children = resolveChildren(module);
|
|
161
|
+
// 4. Update <head> in the client
|
|
162
|
+
if (!isServer) updateHead();
|
|
163
|
+
// 6. Update / replace children in wrapper
|
|
164
|
+
if (ssr) return van.add(wrapper, ...children);
|
|
165
|
+
else wrapper.replaceChildren(...children);
|
|
166
|
+
} finally {
|
|
167
|
+
// 5. Set Loading State
|
|
168
|
+
routerState.loading = false;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
126
172
|
/**
|
|
127
173
|
* Convenience hook to get the current route's cached data.
|
|
128
174
|
* @returns {any | undefined}
|
package/router/router.mjs
CHANGED
|
@@ -3,9 +3,8 @@ import isServer from "../setup/isServer.mjs";
|
|
|
3
3
|
import { MODE } from "../plugin/const.mjs";
|
|
4
4
|
import { routerState, setRouterState } from "./state.mjs";
|
|
5
5
|
import { matchRoute } from "./matchRoute.mjs";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { Head, initializeHeadTags } from "../meta/index.mjs";
|
|
6
|
+
import { executeModule } from "./helpers.mjs";
|
|
7
|
+
import { initializeHeadTags } from "../meta/index.mjs";
|
|
9
8
|
import * as dataCache from "./dataCache.mjs";
|
|
10
9
|
import "virtual:@vanjs/routes";
|
|
11
10
|
|
|
@@ -15,36 +14,6 @@ const isDev = MODE === "development";
|
|
|
15
14
|
/** @typedef {import("./types.d.ts").RouteEntry} RouteEntry */
|
|
16
15
|
/** @typedef {import("./types.d.ts").VanNode} VanNode */
|
|
17
16
|
|
|
18
|
-
/**
|
|
19
|
-
* Update head tags
|
|
20
|
-
*/
|
|
21
|
-
const updateHead = () => {
|
|
22
|
-
// istanbul ignore else
|
|
23
|
-
if (document.head) {
|
|
24
|
-
hydrate(document.head, Head());
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* @param {RouteEntry} route
|
|
30
|
-
* @param {HTMLElement} wrapper
|
|
31
|
-
* @param {boolean} ssr
|
|
32
|
-
* @returns
|
|
33
|
-
*/
|
|
34
|
-
const executeModule = async (route, wrapper, ssr) => {
|
|
35
|
-
// 1. Resolve the module first (to get route lifecycle hooks)
|
|
36
|
-
const module = await route.component();
|
|
37
|
-
// 2. Execute lifecycle
|
|
38
|
-
await executeLifecycle(module.route);
|
|
39
|
-
// 3. Resolve children
|
|
40
|
-
const children = resolveChildren(module);
|
|
41
|
-
// 4. Update <head> in the client
|
|
42
|
-
if (!isServer) updateHead();
|
|
43
|
-
// 5. Update / replace children in wrapper
|
|
44
|
-
if (ssr) return van.add(wrapper, ...children);
|
|
45
|
-
else wrapper.replaceChildren(...children);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
17
|
/**
|
|
49
18
|
* Initialize client-side router (Head + popstate listener)
|
|
50
19
|
*/
|
|
@@ -83,7 +52,7 @@ export const Router = (initialProps = /* istanbul ignore next */ {}) => {
|
|
|
83
52
|
/* istanbul ignore else */
|
|
84
53
|
if (!route) return van.add(wrapper, div("No Route Found"));
|
|
85
54
|
// It's important to READ the params
|
|
86
|
-
Object.assign(routerState.params, route.params
|
|
55
|
+
Object.assign(routerState.params, route.params);
|
|
87
56
|
|
|
88
57
|
// Server-side rendering
|
|
89
58
|
if (isServer) {
|
|
@@ -105,6 +74,7 @@ export const Router = (initialProps = /* istanbul ignore next */ {}) => {
|
|
|
105
74
|
|
|
106
75
|
// Client-side: hydrate data cache from SSR output
|
|
107
76
|
// This must happen BEFORE any component renders so useRouteData() works
|
|
77
|
+
// Skip in dev mode: we manually clear dataCache on mutations for instant updates
|
|
108
78
|
if (globalThis.__DATA_CACHE && !isDev) {
|
|
109
79
|
dataCache.hydrateFromJSON(globalThis.__DATA_CACHE);
|
|
110
80
|
}
|
|
@@ -114,7 +84,6 @@ export const Router = (initialProps = /* istanbul ignore next */ {}) => {
|
|
|
114
84
|
|
|
115
85
|
if (root) {
|
|
116
86
|
van.derive(() => {
|
|
117
|
-
_searchParams = routerState.searchParams;
|
|
118
87
|
if (!initialized) return;
|
|
119
88
|
const matchedRoute = matchRoute(routerState.pathname);
|
|
120
89
|
if (!matchedRoute) {
|
|
@@ -122,26 +91,27 @@ export const Router = (initialProps = /* istanbul ignore next */ {}) => {
|
|
|
122
91
|
return;
|
|
123
92
|
}
|
|
124
93
|
(async () => {
|
|
125
|
-
|
|
94
|
+
_searchParams = routerState.searchParams;
|
|
126
95
|
await executeModule(matchedRoute, wrapper);
|
|
127
96
|
})();
|
|
128
97
|
});
|
|
129
98
|
return async () => {
|
|
130
|
-
|
|
99
|
+
const result = await executeModule(route, wrapper, true);
|
|
100
|
+
initialized = true;
|
|
101
|
+
return result;
|
|
131
102
|
};
|
|
132
103
|
}
|
|
133
104
|
|
|
134
105
|
// Pure SPA path - reactive routing
|
|
135
106
|
van.derive(() => {
|
|
136
107
|
const matchedRoute = matchRoute(routerState.pathname);
|
|
137
|
-
_searchParams = routerState.searchParams;
|
|
138
|
-
// routerState.searchParams;
|
|
139
108
|
if (!matchedRoute) {
|
|
140
109
|
wrapper.replaceChildren(div("No Route Found"));
|
|
141
110
|
return;
|
|
142
111
|
}
|
|
143
112
|
|
|
144
113
|
(async () => {
|
|
114
|
+
_searchParams = routerState.searchParams;
|
|
145
115
|
await executeModule(matchedRoute, wrapper);
|
|
146
116
|
})();
|
|
147
117
|
});
|
package/router/state.mjs
CHANGED
|
@@ -92,18 +92,11 @@ export function microStore(init) {
|
|
|
92
92
|
return target;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
/**
|
|
96
|
-
* @type {typeof import("./types.d.ts").routerState}
|
|
97
|
-
*/
|
|
98
|
-
const initialStatus = isServer
|
|
99
|
-
? "success"
|
|
100
|
-
: (globalThis.__DATA_CACHE ? "success" : "idle");
|
|
101
|
-
|
|
102
95
|
export const routerState = microStore({
|
|
103
96
|
pathname: initialPath,
|
|
104
97
|
searchParams: normalizeSearch(initialSearch),
|
|
105
98
|
params: {},
|
|
106
|
-
|
|
99
|
+
loading: false,
|
|
107
100
|
});
|
|
108
101
|
|
|
109
102
|
/**
|
package/router/types.d.ts
CHANGED
|
@@ -83,8 +83,8 @@ export const isLazyComponent: (component: unknown) => boolean;
|
|
|
83
83
|
|
|
84
84
|
export const executeLifecycle: (
|
|
85
85
|
route: RouteEntry | {
|
|
86
|
-
preload?: () => unknown;
|
|
87
|
-
load?: () => unknown
|
|
86
|
+
preload?: (params?: Record<string, unknown>) => unknown;
|
|
87
|
+
load?: (params?: Record<string, string>) => Promise<unknown>;
|
|
88
88
|
} | null,
|
|
89
89
|
) => Promise<boolean>;
|
|
90
90
|
|
|
@@ -103,8 +103,8 @@ export type RouteEntry = {
|
|
|
103
103
|
path: string;
|
|
104
104
|
component: () => Promise<ComponentModule>;
|
|
105
105
|
params?: Record<string, string>;
|
|
106
|
-
preload?: () =>
|
|
107
|
-
load?: () =>
|
|
106
|
+
preload?: (params?: Record<string, string>) => unknown;
|
|
107
|
+
load?: (params?: Record<string, string>) => Promise<unknown>;
|
|
108
108
|
};
|
|
109
109
|
|
|
110
110
|
export type ImportFn = () => LazyComponent;
|
|
@@ -119,8 +119,8 @@ export type RouteProps = {
|
|
|
119
119
|
| VanComponent
|
|
120
120
|
| ComponentFn
|
|
121
121
|
| (() => Promise<ComponentModule>);
|
|
122
|
-
preload?: () =>
|
|
123
|
-
load?: () =>
|
|
122
|
+
preload?: (params?: Record<string, string>) => unknown;
|
|
123
|
+
load?: (params?: Record<string, string>) => Promise<unknown>;
|
|
124
124
|
};
|
|
125
125
|
|
|
126
126
|
export type RouteConfig = {
|
|
@@ -138,14 +138,14 @@ export type RouterState = {
|
|
|
138
138
|
pathname: string;
|
|
139
139
|
searchParams: string;
|
|
140
140
|
params: Record<string, string>;
|
|
141
|
-
|
|
141
|
+
loading: boolean;
|
|
142
142
|
};
|
|
143
143
|
|
|
144
144
|
export const routerState: {
|
|
145
145
|
pathname: RouterState["pathname"];
|
|
146
146
|
searchParams: RouterState["searchParams"];
|
|
147
147
|
params?: RouterState["params"];
|
|
148
|
-
|
|
148
|
+
loading: RouterState["loading"];
|
|
149
149
|
};
|
|
150
150
|
|
|
151
151
|
export const setRouterState: (
|