vike-lite 1.15.14 → 1.15.16
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/__internal/client.d.mts +37 -2
- package/dist/__internal/client.mjs +50 -6
- package/dist/__internal/server.d.mts +1 -10
- package/dist/store-9UNcAe5D.d.mts +11 -0
- package/dist/vite.mjs +13 -9
- package/package.json +2 -2
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { t as VikeState } from "../store-9UNcAe5D.mjs";
|
|
1
2
|
//#region src/__internal/client.d.ts
|
|
2
3
|
declare function createLinkClickHandler(onNavigate: (url: URL) => void): (e: MouseEvent) => void;
|
|
3
4
|
declare function createLinkPrefetchHandler(onPrefetch: (url: URL) => void): (e: Event) => void;
|
|
4
|
-
declare function finalizeNavigation(
|
|
5
|
+
declare function finalizeNavigation(shouldScrollToTop: {
|
|
6
|
+
current: boolean;
|
|
7
|
+
}): void;
|
|
5
8
|
interface ViewComponents {
|
|
6
9
|
Page: any | null;
|
|
7
10
|
Layout: any | null;
|
|
@@ -49,5 +52,37 @@ declare function createRoutePrefetcher(): (route: PrefetchableRoute) => void;
|
|
|
49
52
|
* Returns true if a reload was triggered — the caller should stop further error handling.
|
|
50
53
|
*/
|
|
51
54
|
declare function tryRecoverFromStaleModuleGraph(message: string, urlToReload: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Stamp the client-only flags that every `PageContextClient` requires (`isClientSide`,
|
|
57
|
+
* `isHydration`) onto the raw context blob the server injected via `window.__PAGE_CONTEXT__`.
|
|
58
|
+
* Centralized so every adapter sets these consistently instead of some silently omitting them.
|
|
59
|
+
*/
|
|
60
|
+
declare function buildInitialClientContext<T extends Record<string, any>>(rawContext: T | undefined, isHydration: boolean): T & {
|
|
61
|
+
isClientSide: true;
|
|
62
|
+
isHydration: boolean;
|
|
63
|
+
};
|
|
64
|
+
interface HydrationInitialContext {
|
|
65
|
+
urlPathname?: string;
|
|
66
|
+
is404?: boolean;
|
|
67
|
+
is500?: boolean;
|
|
68
|
+
errorMessage?: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Resolve the Page/Layout/Head modules to hydrate with, matching what the server
|
|
72
|
+
* actually rendered into the HTML: the error route's modules when the server
|
|
73
|
+
* reported a 404/500/error, otherwise the modules of the route matching the
|
|
74
|
+
* initial pathname. Returns a null view when hydration isn't happening (client
|
|
75
|
+
* takeover) — the router's own first-load effect performs the initial load instead.
|
|
76
|
+
*/
|
|
77
|
+
declare function resolveHydrationView(initialContext: HydrationInitialContext, isHydration: boolean, routes: VikeState['routes'], errorRoute: VikeState['errorRoute']): Promise<ViewComponents>;
|
|
78
|
+
/**
|
|
79
|
+
* Consume the server-injected initial context if it still matches the given pathname
|
|
80
|
+
* (i.e. this is the very first client-side route load, right after SSR hydration/render).
|
|
81
|
+
* Clears the global reference so a later remount at the same pathname (e.g. React
|
|
82
|
+
* StrictMode double-invoke in dev) triggers a real fetch instead of being mistaken
|
|
83
|
+
* for the original initial load. Returns true if consumed — the caller should skip
|
|
84
|
+
* loading for this run.
|
|
85
|
+
*/
|
|
86
|
+
declare function consumeMatchingInitialContext(pathname: string): boolean;
|
|
52
87
|
//#endregion
|
|
53
|
-
export { ViewComponents, buildPageContextJsonUrl, createLinkClickHandler, createLinkPrefetchHandler, createRoutePrefetcher, fetchPageContextJson, finalizeNavigation, loadViewModules, tryRecoverFromStaleModuleGraph };
|
|
88
|
+
export { ViewComponents, buildInitialClientContext, buildPageContextJsonUrl, consumeMatchingInitialContext, createLinkClickHandler, createLinkPrefetchHandler, createRoutePrefetcher, fetchPageContextJson, finalizeNavigation, loadViewModules, resolveHydrationView, tryRecoverFromStaleModuleGraph };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BASE_URL } from "./shared.mjs";
|
|
1
|
+
import { BASE_URL, matchRoute } from "./shared.mjs";
|
|
2
2
|
//#region src/__internal/client.ts
|
|
3
3
|
function getClientSideUrl(target) {
|
|
4
4
|
if (!target?.href || target.target && target.target !== "_self" || target.hasAttribute("download") || target.hasAttribute("data-native") || target.getAttribute("rel")?.includes("external")) return null;
|
|
@@ -15,7 +15,7 @@ function isSamePage(url) {
|
|
|
15
15
|
}
|
|
16
16
|
function createLinkClickHandler(onNavigate) {
|
|
17
17
|
return (e) => {
|
|
18
|
-
if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
18
|
+
if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || !(e.target instanceof Element)) return;
|
|
19
19
|
const url = getClientSideUrl(e.target.closest("a"));
|
|
20
20
|
if (!url || isSamePage(url)) return;
|
|
21
21
|
e.preventDefault();
|
|
@@ -25,15 +25,16 @@ function createLinkClickHandler(onNavigate) {
|
|
|
25
25
|
}
|
|
26
26
|
function createLinkPrefetchHandler(onPrefetch) {
|
|
27
27
|
return (e) => {
|
|
28
|
+
if (!(e.target instanceof Element)) return;
|
|
28
29
|
const url = getClientSideUrl(e.target.closest("a"));
|
|
29
30
|
if (!url || isSamePage(url)) return;
|
|
30
31
|
onPrefetch(url);
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
|
-
function finalizeNavigation(
|
|
34
|
-
if (
|
|
34
|
+
function finalizeNavigation(shouldScrollToTop) {
|
|
35
|
+
if (shouldScrollToTop.current) {
|
|
35
36
|
globalThis.scrollTo(0, 0);
|
|
36
|
-
|
|
37
|
+
shouldScrollToTop.current = false;
|
|
37
38
|
} else if (globalThis.location.hash) requestAnimationFrame(() => {
|
|
38
39
|
try {
|
|
39
40
|
document.querySelector(decodeURIComponent(globalThis.location.hash))?.scrollIntoView();
|
|
@@ -111,5 +112,48 @@ function tryRecoverFromStaleModuleGraph(message, urlToReload) {
|
|
|
111
112
|
globalThis.location.assign(urlToReload);
|
|
112
113
|
return true;
|
|
113
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Stamp the client-only flags that every `PageContextClient` requires (`isClientSide`,
|
|
117
|
+
* `isHydration`) onto the raw context blob the server injected via `window.__PAGE_CONTEXT__`.
|
|
118
|
+
* Centralized so every adapter sets these consistently instead of some silently omitting them.
|
|
119
|
+
*/
|
|
120
|
+
function buildInitialClientContext(rawContext, isHydration) {
|
|
121
|
+
return {
|
|
122
|
+
...rawContext ?? {},
|
|
123
|
+
isClientSide: true,
|
|
124
|
+
isHydration
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Resolve the Page/Layout/Head modules to hydrate with, matching what the server
|
|
129
|
+
* actually rendered into the HTML: the error route's modules when the server
|
|
130
|
+
* reported a 404/500/error, otherwise the modules of the route matching the
|
|
131
|
+
* initial pathname. Returns a null view when hydration isn't happening (client
|
|
132
|
+
* takeover) — the router's own first-load effect performs the initial load instead.
|
|
133
|
+
*/
|
|
134
|
+
async function resolveHydrationView(initialContext, isHydration, routes, errorRoute) {
|
|
135
|
+
const emptyView = {
|
|
136
|
+
Page: null,
|
|
137
|
+
Layout: null,
|
|
138
|
+
Head: null
|
|
139
|
+
};
|
|
140
|
+
if (!isHydration) return emptyView;
|
|
141
|
+
if (errorRoute && (initialContext.is404 || initialContext.is500 || initialContext.errorMessage)) return loadViewModules(errorRoute);
|
|
142
|
+
const matched = matchRoute(initialContext.urlPathname ?? globalThis.location.pathname, routes);
|
|
143
|
+
return matched ? loadViewModules(matched.route) : emptyView;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Consume the server-injected initial context if it still matches the given pathname
|
|
147
|
+
* (i.e. this is the very first client-side route load, right after SSR hydration/render).
|
|
148
|
+
* Clears the global reference so a later remount at the same pathname (e.g. React
|
|
149
|
+
* StrictMode double-invoke in dev) triggers a real fetch instead of being mistaken
|
|
150
|
+
* for the original initial load. Returns true if consumed — the caller should skip
|
|
151
|
+
* loading for this run.
|
|
152
|
+
*/
|
|
153
|
+
function consumeMatchingInitialContext(pathname) {
|
|
154
|
+
if (globalThis.__PAGE_CONTEXT__?.urlPathname !== pathname) return false;
|
|
155
|
+
globalThis.__PAGE_CONTEXT__ = void 0;
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
114
158
|
//#endregion
|
|
115
|
-
export { buildPageContextJsonUrl, createLinkClickHandler, createLinkPrefetchHandler, createRoutePrefetcher, fetchPageContextJson, finalizeNavigation, loadViewModules, tryRecoverFromStaleModuleGraph };
|
|
159
|
+
export { buildInitialClientContext, buildPageContextJsonUrl, consumeMatchingInitialContext, createLinkClickHandler, createLinkPrefetchHandler, createRoutePrefetcher, fetchPageContextJson, finalizeNavigation, loadViewModules, resolveHydrationView, tryRecoverFromStaleModuleGraph };
|
|
@@ -1,11 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
interface VikeState {
|
|
3
|
-
routes: typeof import('virtual:vike-lite/routes')['routes'] | [];
|
|
4
|
-
errorRoute: typeof import('virtual:vike-lite/routes')['errorRoute'] | null;
|
|
5
|
-
config: typeof import('virtual:vike-lite/routes')['config'] | null;
|
|
6
|
-
manifest: typeof import('virtual:vike-lite/client-manifest')['default'] | null;
|
|
7
|
-
}
|
|
8
|
-
declare const store: VikeState;
|
|
9
|
-
declare function setVikeState(newState: Partial<VikeState>): void;
|
|
10
|
-
//#endregion
|
|
1
|
+
import { n as setVikeState, r as store, t as VikeState } from "../store-9UNcAe5D.mjs";
|
|
11
2
|
export { VikeState, setVikeState, store };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/server/store.d.ts
|
|
2
|
+
interface VikeState {
|
|
3
|
+
routes: typeof import('virtual:vike-lite/routes')['routes'] | [];
|
|
4
|
+
errorRoute: typeof import('virtual:vike-lite/routes')['errorRoute'] | null;
|
|
5
|
+
config: typeof import('virtual:vike-lite/routes')['config'] | null;
|
|
6
|
+
manifest: typeof import('virtual:vike-lite/client-manifest')['default'] | null;
|
|
7
|
+
}
|
|
8
|
+
declare const store: VikeState;
|
|
9
|
+
declare function setVikeState(newState: Partial<VikeState>): void;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { setVikeState as n, store as r, VikeState as t };
|
package/dist/vite.mjs
CHANGED
|
@@ -209,7 +209,7 @@ function vikeLite({ pagesDir = "pages", apiPrefix = "/api", prerender = false, s
|
|
|
209
209
|
} : VIRTUAL.entryServer,
|
|
210
210
|
output: {
|
|
211
211
|
format: "esm",
|
|
212
|
-
entryFileNames: "
|
|
212
|
+
entryFileNames: "[name].mjs",
|
|
213
213
|
chunkFileNames: (chunkInfo) => {
|
|
214
214
|
if (chunkInfo.facadeModuleId?.includes(`/${pagesDir}/`)) return "assets/pages/[name].[hash].mjs";
|
|
215
215
|
return "assets/chunks/[name].[hash].mjs";
|
|
@@ -221,7 +221,7 @@ function vikeLite({ pagesDir = "pages", apiPrefix = "/api", prerender = false, s
|
|
|
221
221
|
};
|
|
222
222
|
},
|
|
223
223
|
configResolved(config) {
|
|
224
|
-
if (!config.plugins.some((plugin) => plugin.name?.startsWith("vike-lite-") && SUPPORTED_RENDERERS.includes(plugin.name.replace("vike-lite-", "")))) throw new Error(
|
|
224
|
+
if (!config.plugins.some((plugin) => plugin.name?.startsWith("vike-lite-") && SUPPORTED_RENDERERS.includes(plugin.name.replace("vike-lite-", "")))) throw new Error(`❌ No UI adapter plugin found in 'vite.config': please install and configure one of ${SUPPORTED_RENDERERS.map((r) => `vike-lite-${r}`).join(", ")}`);
|
|
225
225
|
},
|
|
226
226
|
resolveId(id) {
|
|
227
227
|
if (VIRTUAL_VALUES.has(id)) return "\0" + id;
|
|
@@ -283,7 +283,7 @@ function vikeLite({ pagesDir = "pages", apiPrefix = "/api", prerender = false, s
|
|
|
283
283
|
break;
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
|
-
if (!serverEntryPath) throw new Error(
|
|
286
|
+
if (!serverEntryPath) throw new Error(`❌ serverEntry ${serverEntry} file not found`);
|
|
287
287
|
serverEntryPath = serverEntryPath.replaceAll("\\", "/");
|
|
288
288
|
return importSetup + `export*from'${serverEntryPath}';export{default}from'${serverEntryPath}';`;
|
|
289
289
|
}
|
|
@@ -314,7 +314,7 @@ function vikeLite({ pagesDir = "pages", apiPrefix = "/api", prerender = false, s
|
|
|
314
314
|
}
|
|
315
315
|
if (shouldPrerender) {
|
|
316
316
|
if (route.path.includes(":") && dynamicUrls.length === 0) {
|
|
317
|
-
console.warn(
|
|
317
|
+
console.warn(`⚠️ Skipping dynamic route ${route.path}: no URLs provided by +prerender. Return an array of URLs to prerender it.`);
|
|
318
318
|
continue;
|
|
319
319
|
}
|
|
320
320
|
if (!route.path.includes(":")) urlsToPrerender.add(route.path);
|
|
@@ -322,7 +322,7 @@ function vikeLite({ pagesDir = "pages", apiPrefix = "/api", prerender = false, s
|
|
|
322
322
|
}
|
|
323
323
|
}
|
|
324
324
|
if (urlsToPrerender.size === 0) return;
|
|
325
|
-
console.log("
|
|
325
|
+
console.log("📦 Starting Static Site Generation (SSG)…");
|
|
326
326
|
let generatedCount = 0;
|
|
327
327
|
const clientDir = path.join(viteConfigRoot, outDir, "client");
|
|
328
328
|
for (const urlPath of urlsToPrerender) {
|
|
@@ -331,18 +331,22 @@ function vikeLite({ pagesDir = "pages", apiPrefix = "/api", prerender = false, s
|
|
|
331
331
|
const outDirRoute = path.join(clientDir, urlPath === "/" ? "" : urlPath);
|
|
332
332
|
fs.mkdirSync(outDirRoute, { recursive: true });
|
|
333
333
|
fs.writeFileSync(path.join(outDirRoute, "index.html"), await htmlRes.text());
|
|
334
|
-
} else throw new Error(
|
|
334
|
+
} else throw new Error(`❌ SSG HTML Error for "${urlPath}"`);
|
|
335
335
|
const jsonTarget = urlPath === "/" ? "/index" : urlPath;
|
|
336
336
|
const jsonRes = await renderPage(new Request(`http://localhost${baseUrl}${jsonTarget}.pageContext.json`));
|
|
337
337
|
if (jsonRes?.ok) {
|
|
338
338
|
const jsonOutPath = path.join(clientDir, `${jsonTarget}.pageContext.json`);
|
|
339
339
|
fs.mkdirSync(path.dirname(jsonOutPath), { recursive: true });
|
|
340
340
|
fs.writeFileSync(jsonOutPath, await jsonRes.text());
|
|
341
|
-
} else throw new Error(
|
|
342
|
-
console.log(` → ${urlPath}`);
|
|
341
|
+
} else throw new Error(`❌ SSG JSON Error for "${jsonTarget}"`);
|
|
342
|
+
console.log(` route → ${urlPath}`);
|
|
343
343
|
generatedCount++;
|
|
344
344
|
}
|
|
345
|
-
|
|
345
|
+
if (urlsToPrerender.size === 0) {
|
|
346
|
+
console.warn("ℹ️ No static routes to generate. If you don't want to use SSG, in the 'vite.config', set \"prerender\" option as \"false\" or remove.");
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
console.log(`✨ SSG Completed! Generated ${generatedCount} static routes`);
|
|
346
350
|
},
|
|
347
351
|
configureServer(server) {
|
|
348
352
|
return () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vike-lite",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.16",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
84
|
"@types/node": "^26.1.1",
|
|
85
|
-
"tsdown": "^0.22.
|
|
85
|
+
"tsdown": "^0.22.11",
|
|
86
86
|
"vite": "^8.1.5",
|
|
87
87
|
"vitest": "^4.1.10"
|
|
88
88
|
},
|