vike-lite 1.15.13 → 1.15.15
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/__internal/vite.d.mts +21 -1
- package/dist/__internal/vite.mjs +30 -1
- package/dist/store-9UNcAe5D.d.mts +11 -0
- package/dist/vite.mjs +5 -3
- package/package.json +3 -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 ((initialContext.is404 || initialContext.is500 || initialContext.errorMessage) && errorRoute) 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 };
|
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
import { Plugin } from "vite";
|
|
2
2
|
//#region src/__internal/vite.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Creates the Vite plugin that configures dev-server pre-bundling and SSR externalization
|
|
5
|
+
* for framework adapters (e.g. vike-lite-solid, vike-lite-vue) that export raw, uncompiled
|
|
6
|
+
* source files (.tsx/.vue) instead of a pre-built dist. Those adapters need:
|
|
7
|
+
* - `optimizeDeps.include`: eagerly pre-bundle the framework runtime (e.g. `solid-js`, `vue`)
|
|
8
|
+
* so the dev server doesn't re-bundle it on every page navigation.
|
|
9
|
+
* - `optimizeDeps.exclude` + `ssr.noExternal`: prevent Vite from treating the adapter package
|
|
10
|
+
* as an opaque, externalizable dependency, so its raw JSX/SFC source is instead processed
|
|
11
|
+
* by the framework's own Vite plugin (e.g. vite-plugin-solid, @vitejs/plugin-vue) both in
|
|
12
|
+
* dev and during the SSR build.
|
|
13
|
+
*
|
|
14
|
+
* This centralizes logic that is otherwise identical across every `vike-lite-*` package
|
|
15
|
+
* that ships raw source files.
|
|
16
|
+
*/
|
|
17
|
+
declare function createDepsConfigPlugin({ packageName, optimizeDepsInclude }: {
|
|
18
|
+
/** The framework adapter's package name, e.g. 'vike-lite-solid'. */
|
|
19
|
+
packageName: string;
|
|
20
|
+
/** Framework runtime packages to eagerly pre-bundle, e.g. ['solid-js']. */
|
|
21
|
+
optimizeDepsInclude: string[];
|
|
22
|
+
}): Plugin;
|
|
3
23
|
/**
|
|
4
24
|
* Creates the Vite plugin that wires a UI framework adapter (react/vue/solid) into vike-lite,
|
|
5
25
|
* by providing the virtual `virtual:vike-lite/client` and `virtual:vike-lite/server` modules
|
|
@@ -16,4 +36,4 @@ declare function createFrameworkAdapterPlugin({ packageName, hydration, wrapServ
|
|
|
16
36
|
wrapServerHydration?: boolean;
|
|
17
37
|
}): Plugin;
|
|
18
38
|
//#endregion
|
|
19
|
-
export { createFrameworkAdapterPlugin };
|
|
39
|
+
export { createDepsConfigPlugin, createFrameworkAdapterPlugin };
|
package/dist/__internal/vite.mjs
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
//#region src/__internal/vite.ts
|
|
2
2
|
/**
|
|
3
|
+
* Creates the Vite plugin that configures dev-server pre-bundling and SSR externalization
|
|
4
|
+
* for framework adapters (e.g. vike-lite-solid, vike-lite-vue) that export raw, uncompiled
|
|
5
|
+
* source files (.tsx/.vue) instead of a pre-built dist. Those adapters need:
|
|
6
|
+
* - `optimizeDeps.include`: eagerly pre-bundle the framework runtime (e.g. `solid-js`, `vue`)
|
|
7
|
+
* so the dev server doesn't re-bundle it on every page navigation.
|
|
8
|
+
* - `optimizeDeps.exclude` + `ssr.noExternal`: prevent Vite from treating the adapter package
|
|
9
|
+
* as an opaque, externalizable dependency, so its raw JSX/SFC source is instead processed
|
|
10
|
+
* by the framework's own Vite plugin (e.g. vite-plugin-solid, @vitejs/plugin-vue) both in
|
|
11
|
+
* dev and during the SSR build.
|
|
12
|
+
*
|
|
13
|
+
* This centralizes logic that is otherwise identical across every `vike-lite-*` package
|
|
14
|
+
* that ships raw source files.
|
|
15
|
+
*/
|
|
16
|
+
function createDepsConfigPlugin({ packageName, optimizeDepsInclude }) {
|
|
17
|
+
return {
|
|
18
|
+
name: `${packageName}-config`,
|
|
19
|
+
enforce: "pre",
|
|
20
|
+
config() {
|
|
21
|
+
return {
|
|
22
|
+
optimizeDeps: {
|
|
23
|
+
include: optimizeDepsInclude,
|
|
24
|
+
exclude: [packageName]
|
|
25
|
+
},
|
|
26
|
+
ssr: { noExternal: [packageName] }
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
3
32
|
* Creates the Vite plugin that wires a UI framework adapter (react/vue/solid) into vike-lite,
|
|
4
33
|
* by providing the virtual `virtual:vike-lite/client` and `virtual:vike-lite/server` modules
|
|
5
34
|
* that vike-lite's core plugin reads to discover the framework's onRenderClient/onRenderHtml hooks.
|
|
@@ -25,4 +54,4 @@ function createFrameworkAdapterPlugin({ packageName, hydration = true, wrapServe
|
|
|
25
54
|
};
|
|
26
55
|
}
|
|
27
56
|
//#endregion
|
|
28
|
-
export { createFrameworkAdapterPlugin };
|
|
57
|
+
export { createDepsConfigPlugin, createFrameworkAdapterPlugin };
|
|
@@ -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
|
@@ -19,7 +19,8 @@ function generateRoutes(viteRoot, pagesDir) {
|
|
|
19
19
|
const routes = [];
|
|
20
20
|
let errorRoute;
|
|
21
21
|
function walk(dir, routePath, parentLayout, parentHead) {
|
|
22
|
-
const
|
|
22
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
23
|
+
const files = entries.map((entry) => entry.name);
|
|
23
24
|
const importPath = path.relative(viteRoot, dir).replaceAll("\\", "/");
|
|
24
25
|
const layoutFile = findFile(files, "+Layout", pageExtensions);
|
|
25
26
|
const currentLayout = layoutFile ? `${importPath}/${layoutFile}` : parentLayout;
|
|
@@ -41,9 +42,10 @@ function generateRoutes(viteRoot, pagesDir) {
|
|
|
41
42
|
if (currentHead) route.head = currentHead;
|
|
42
43
|
routes.push(route);
|
|
43
44
|
}
|
|
44
|
-
for (const
|
|
45
|
+
for (const entry of entries) {
|
|
46
|
+
if (!entry.isDirectory()) continue;
|
|
47
|
+
const file = entry.name;
|
|
45
48
|
const fullPath = path.join(dir, file);
|
|
46
|
-
if (!fs.statSync(fullPath).isDirectory()) continue;
|
|
47
49
|
if (file === "_error") {
|
|
48
50
|
const errorPageFile = findFile(fs.readdirSync(fullPath), "+Page", pageExtensions);
|
|
49
51
|
if (errorPageFile) errorRoute = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vike-lite",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.15",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -83,7 +83,8 @@
|
|
|
83
83
|
"devDependencies": {
|
|
84
84
|
"@types/node": "^26.1.1",
|
|
85
85
|
"tsdown": "^0.22.9",
|
|
86
|
-
"vite": "^8.1.5"
|
|
86
|
+
"vite": "^8.1.5",
|
|
87
|
+
"vitest": "^4.1.10"
|
|
87
88
|
},
|
|
88
89
|
"peerDependencies": {
|
|
89
90
|
"vite": ">=8"
|