vike-lite 1.7.0 → 1.8.0
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/client/router.d.mts +11 -0
- package/dist/client/router.mjs +17 -0
- package/dist/server/abort.d.mts +29 -0
- package/dist/server/abort.mjs +43 -0
- package/dist/server.mjs +19 -13
- package/dist/shared-DEpJkq09.mjs +4 -0
- package/dist/vite.mjs +4 -4
- package/package.json +9 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/client/router.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Change page programmatically on the client without reloading the browser.
|
|
4
|
+
*
|
|
5
|
+
* @example navigate('/dashboard')
|
|
6
|
+
*/
|
|
7
|
+
declare function navigate(url: string, options?: {
|
|
8
|
+
keepScrollPosition?: boolean;
|
|
9
|
+
}): void;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { navigate };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { t as BASE_URL } from "../shared-DEpJkq09.mjs";
|
|
2
|
+
//#region src/client/router.ts
|
|
3
|
+
/**
|
|
4
|
+
* Change page programmatically on the client without reloading the browser.
|
|
5
|
+
*
|
|
6
|
+
* @example navigate('/dashboard')
|
|
7
|
+
*/
|
|
8
|
+
function navigate(url, options) {
|
|
9
|
+
if (typeof globalThis === "undefined") throw new Error("navigate() can only be called on the client side.");
|
|
10
|
+
let finalUrl = url;
|
|
11
|
+
if (finalUrl.startsWith("/")) finalUrl = (BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL) + (finalUrl === "/" ? "" : finalUrl);
|
|
12
|
+
globalThis.history.pushState(null, "", finalUrl);
|
|
13
|
+
globalThis.dispatchEvent(new Event("popstate"));
|
|
14
|
+
if (!options?.keepScrollPosition) globalThis.scrollTo(0, 0);
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { navigate };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/server/abort.d.ts
|
|
2
|
+
declare class AbortRedirect extends Error {
|
|
3
|
+
url: string;
|
|
4
|
+
statusCode: number;
|
|
5
|
+
constructor(url: string, statusCode?: number);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Interrupt the current rendering and redirect the user to a new URL.
|
|
9
|
+
* Use with 'throw' inside +data.ts or in middleware.
|
|
10
|
+
* @param url The URL to redirect to
|
|
11
|
+
* @param statusCode Optional: the HTTP status code for the redirect (default is 302)
|
|
12
|
+
* @example throw redirect('/login')
|
|
13
|
+
*/
|
|
14
|
+
declare function redirect(url: string, statusCode?: number): AbortRedirect;
|
|
15
|
+
declare class AbortRender extends Error {
|
|
16
|
+
statusCode: number;
|
|
17
|
+
reason?: unknown;
|
|
18
|
+
constructor(statusCode: number, reason?: unknown);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Interrupt the current rendering and display the error page.
|
|
22
|
+
* Always use with 'throw': throw render(404, 'Not Found')
|
|
23
|
+
*
|
|
24
|
+
* @param statusCode The HTTP status code (e.g. 404, 401, 500)
|
|
25
|
+
* @param reason Optional: the reason for the error to display in the UI
|
|
26
|
+
*/
|
|
27
|
+
declare function render(statusCode: number, reason?: unknown): AbortRender;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { AbortRedirect, AbortRender, redirect, render };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
//#region src/server/abort.ts
|
|
2
|
+
var AbortRedirect = class AbortRedirect extends Error {
|
|
3
|
+
url;
|
|
4
|
+
statusCode;
|
|
5
|
+
constructor(url, statusCode = 302) {
|
|
6
|
+
super(`Redirecting to ${url}`);
|
|
7
|
+
this.url = url;
|
|
8
|
+
this.statusCode = statusCode;
|
|
9
|
+
Object.setPrototypeOf(this, AbortRedirect.prototype);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Interrupt the current rendering and redirect the user to a new URL.
|
|
14
|
+
* Use with 'throw' inside +data.ts or in middleware.
|
|
15
|
+
* @param url The URL to redirect to
|
|
16
|
+
* @param statusCode Optional: the HTTP status code for the redirect (default is 302)
|
|
17
|
+
* @example throw redirect('/login')
|
|
18
|
+
*/
|
|
19
|
+
function redirect(url, statusCode = 302) {
|
|
20
|
+
return new AbortRedirect(url, statusCode);
|
|
21
|
+
}
|
|
22
|
+
var AbortRender = class AbortRender extends Error {
|
|
23
|
+
statusCode;
|
|
24
|
+
reason;
|
|
25
|
+
constructor(statusCode, reason) {
|
|
26
|
+
super(`Render aborted with status ${statusCode}${reason && typeof reason === "string" ? `: ${reason}` : ""}`);
|
|
27
|
+
this.statusCode = statusCode;
|
|
28
|
+
this.reason = reason;
|
|
29
|
+
Object.setPrototypeOf(this, AbortRender.prototype);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Interrupt the current rendering and display the error page.
|
|
34
|
+
* Always use with 'throw': throw render(404, 'Not Found')
|
|
35
|
+
*
|
|
36
|
+
* @param statusCode The HTTP status code (e.g. 404, 401, 500)
|
|
37
|
+
* @param reason Optional: the reason for the error to display in the UI
|
|
38
|
+
*/
|
|
39
|
+
function render(statusCode, reason) {
|
|
40
|
+
return new AbortRender(statusCode, reason);
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { AbortRedirect, AbortRender, redirect, render };
|
package/dist/server.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { t as BASE_URL } from "./shared-DEpJkq09.mjs";
|
|
1
2
|
import { t as matchRoute } from "./matchRoute-nTNPxoMq.mjs";
|
|
3
|
+
import { AbortRedirect, AbortRender } from "./server/abort.mjs";
|
|
2
4
|
import { n as store } from "./store-CfUB1COP.mjs";
|
|
3
5
|
//#region src/utils/serializeContext.ts
|
|
4
6
|
const ESCAPE_LOOKUP = {
|
|
@@ -13,20 +15,8 @@ function serializeContext(data) {
|
|
|
13
15
|
return JSON.stringify(data).replaceAll(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
|
|
14
16
|
}
|
|
15
17
|
//#endregion
|
|
16
|
-
//#region src/server/abort.ts
|
|
17
|
-
var AbortRender = class extends Error {
|
|
18
|
-
statusCode;
|
|
19
|
-
reason;
|
|
20
|
-
constructor(statusCode, reason) {
|
|
21
|
-
super(`Render aborted with status ${statusCode}: ${reason || ""}`);
|
|
22
|
-
this.statusCode = statusCode;
|
|
23
|
-
this.reason = reason;
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
//#endregion
|
|
27
18
|
//#region src/server/renderPage.ts
|
|
28
19
|
const isProd = process.env.NODE_ENV === "production";
|
|
29
|
-
const { BASE_URL } = import.meta.env;
|
|
30
20
|
function withBase(file) {
|
|
31
21
|
return `${BASE_URL.replace(/\/$/, "")}/${file.replace(/^\//, "")}`;
|
|
32
22
|
}
|
|
@@ -172,7 +162,23 @@ async function renderPage(req) {
|
|
|
172
162
|
headers: { "Content-Type": "text/html" }
|
|
173
163
|
});
|
|
174
164
|
} catch (error) {
|
|
175
|
-
if (error instanceof
|
|
165
|
+
if (error instanceof AbortRedirect) {
|
|
166
|
+
let redirectUrl = error.url;
|
|
167
|
+
if (redirectUrl.startsWith("/")) redirectUrl = (BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL) + (redirectUrl === "/" ? "" : redirectUrl);
|
|
168
|
+
if (isJsonRequest) return Response.json({ _redirect: redirectUrl }, { status: 200 });
|
|
169
|
+
return new Response(null, {
|
|
170
|
+
status: error.statusCode,
|
|
171
|
+
headers: { Location: redirectUrl }
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
if (error instanceof AbortRender) {
|
|
175
|
+
if (isJsonRequest) return Response.json({
|
|
176
|
+
is404: error.statusCode === 404,
|
|
177
|
+
isError: true,
|
|
178
|
+
reason: error.reason
|
|
179
|
+
}, { status: error.statusCode });
|
|
180
|
+
return renderErrorPage(req, error.statusCode, targetPathname, error.reason);
|
|
181
|
+
}
|
|
176
182
|
console.error("Render Error:", error);
|
|
177
183
|
if (isJsonRequest) return Response.json({ is500: true }, { status: 500 });
|
|
178
184
|
return renderErrorPage(req, 500, targetPathname, error);
|
package/dist/vite.mjs
CHANGED
|
@@ -271,13 +271,13 @@ if (process.env.NODE_ENV === 'production') {
|
|
|
271
271
|
'.woff2': 'font/woff2',
|
|
272
272
|
'.wasm': 'application/wasm'
|
|
273
273
|
};
|
|
274
|
-
const
|
|
274
|
+
const { BASE_URL } = import.meta.env;
|
|
275
275
|
const server = createServer(async (req, res) => {
|
|
276
276
|
try {
|
|
277
277
|
const urlObj = new URL(req.url || '/', 'http://' + (req.headers.host || 'localhost'));
|
|
278
278
|
const pathname = urlObj.pathname;
|
|
279
279
|
let fileUrl = pathname;
|
|
280
|
-
if (
|
|
280
|
+
if (BASE_URL !== '/' && pathname.startsWith(BASE_URL)) fileUrl = '/' + pathname.slice(BASE_URL.length);
|
|
281
281
|
if (fileUrl !== '/') {
|
|
282
282
|
const filePath = path.resolve(clientDir, '.' + fileUrl)
|
|
283
283
|
if (!filePath.startsWith(clientDir + path.sep)) {
|
|
@@ -362,8 +362,8 @@ if (process.env.NODE_ENV === 'production') {
|
|
|
362
362
|
}
|
|
363
363
|
if (urlsToPrerender.size === 0) return;
|
|
364
364
|
console.log("\n\x1B[36m📦 Starting Static Site Generation (SSG)...\x1B[0m");
|
|
365
|
-
const
|
|
366
|
-
const baseNoSlash =
|
|
365
|
+
const { BASE_URL } = import.meta.env;
|
|
366
|
+
const baseNoSlash = BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL;
|
|
367
367
|
let generatedCount = 0;
|
|
368
368
|
const clientDir = path.resolve(viteConfigRoot, outDir, "client");
|
|
369
369
|
for (const urlPath of urlsToPrerender) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vike-lite",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -13,10 +13,18 @@
|
|
|
13
13
|
"types": "./dist/vite.d.mts",
|
|
14
14
|
"import": "./dist/vite.mjs"
|
|
15
15
|
},
|
|
16
|
+
"./client/router": {
|
|
17
|
+
"import": "./dist/client/router.mjs",
|
|
18
|
+
"types": "./dist/client/router.d.mts"
|
|
19
|
+
},
|
|
16
20
|
"./server": {
|
|
17
21
|
"types": "./dist/server.d.mts",
|
|
18
22
|
"import": "./dist/server.mjs"
|
|
19
23
|
},
|
|
24
|
+
"./server/abort": {
|
|
25
|
+
"import": "./dist/server/abort.mjs",
|
|
26
|
+
"types": "./dist/server/abort.d.mts"
|
|
27
|
+
},
|
|
20
28
|
"./__internal/shared": {
|
|
21
29
|
"types": "./dist/__internal/shared.d.mts",
|
|
22
30
|
"import": "./dist/__internal/shared.mjs"
|