vike-lite 1.7.1 → 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.
@@ -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 AbortRender) return new Response(error.reason || "Not Found", { status: error.statusCode });
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);
@@ -0,0 +1,4 @@
1
+ //#region src/shared/index.ts
2
+ const { BASE_URL } = import.meta.env;
3
+ //#endregion
4
+ export { BASE_URL as t };
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 base = import.meta.env.BASE_URL;
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 (base !== '/' && pathname.startsWith(base)) fileUrl = '/' + pathname.slice(base.length);
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 base = process.env.BASE_URL || "/";
366
- const baseNoSlash = base.endsWith("/") ? base.slice(0, -1) : base;
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.7.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"