vike-lite 1.13.0 → 1.13.2

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/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/index.d.ts
2
- type PageContextBase = {
2
+ type PageContextBase<Data = unknown> = {
3
3
  routeParams: Record<string, string>;
4
4
  urlOriginal: string;
5
5
  urlPathname: string;
@@ -8,19 +8,19 @@ type PageContextBase = {
8
8
  is404?: boolean;
9
9
  is500?: boolean;
10
10
  errorMessage?: string;
11
- };
12
- type PageContext<Data = unknown> = PageContextBase & (unknown extends Data ? {
11
+ } & (unknown extends Data ? {
13
12
  data?: Data;
14
13
  } : {
15
14
  data: Data;
16
15
  });
17
- type PageContextServer<Data = unknown> = PageContext<Data> & {
16
+ type PageContextServer<Data = unknown> = PageContextBase<Data> & {
18
17
  isClientSide: false;
19
18
  nonce?: string;
20
19
  };
21
- type PageContextClient = PageContextBase & {
20
+ type PageContextClient<Data = unknown> = PageContextBase<Data> & {
22
21
  isClientSide: true;
23
22
  isHydration?: boolean;
24
23
  };
24
+ type PageContext<Data = unknown> = PageContextServer<Data> | PageContextClient<Data>;
25
25
  //#endregion
26
26
  export { PageContext, PageContextClient, PageContextServer };
@@ -122,7 +122,6 @@ async function renderErrorPage(req, status, urlPathname, error, nonce) {
122
122
  } else is500 = false;
123
123
  if (!store.errorRoute) return new Response(status === 404 ? "Not Found" : "Internal Server Error", { status });
124
124
  try {
125
- const { default: onRenderHtml } = await store.config.onRenderHtml();
126
125
  const [PageModule, HeadModule, LayoutModule] = await Promise.all([
127
126
  store.errorRoute.Page(),
128
127
  store.errorRoute.Head?.() ?? null,
@@ -136,7 +135,7 @@ async function renderErrorPage(req, status, urlPathname, error, nonce) {
136
135
  is500,
137
136
  errorMessage
138
137
  };
139
- const html = await onRenderHtml({
138
+ const html = await store.config.onRenderHtml({
140
139
  pageContext,
141
140
  Page: PageModule.Page ?? PageModule.default,
142
141
  Layout: LayoutModule ? LayoutModule.Layout ?? LayoutModule.default : void 0,
@@ -177,8 +176,7 @@ async function renderPage(req, { nonce } = {}) {
177
176
  }
178
177
  const { pageContext, route, PageModule, HeadModule, LayoutModule } = resolved;
179
178
  if (isJsonRequest) return Response.json(pageContext);
180
- const { default: onRenderHtml } = await store.config.onRenderHtml();
181
- const html = await onRenderHtml({
179
+ const html = await store.config.onRenderHtml({
182
180
  pageContext,
183
181
  Page: PageModule.Page ?? PageModule.default,
184
182
  Head: HeadModule ? HeadModule.Head ?? HeadModule.default : void 0,
package/dist/server.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { t as renderPage } from "./server-Cm1ZA_Dp.mjs";
1
+ import { t as renderPage } from "./server-GrGbl23a.mjs";
2
2
  export { renderPage };
package/dist/vite.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Plugin } from "vite";
2
- //#region src/vite-plugin.d.ts
2
+ //#region src/vite/index.d.ts
3
3
  declare function routerPlugin({ pagesDir, serverEntry, apiPrefix, prerender }?: {
4
4
  /**
5
5
  * The directory where your page components are located.
package/dist/vite.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as renderPage } from "./server-Cm1ZA_Dp.mjs";
1
+ import { t as renderPage } from "./server-GrGbl23a.mjs";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { Readable } from "node:stream";
@@ -98,7 +98,7 @@ async function injectFOUCStyles(server, html) {
98
98
  //#region src/config.ts
99
99
  const SUPPORTED_RENDERERS = ["solid"];
100
100
  //#endregion
101
- //#region src/vite-plugin.ts
101
+ //#region src/vite/index.ts
102
102
  function routerPlugin({ pagesDir = "pages", serverEntry = "server/index", apiPrefix = "/api", prerender = false } = {}) {
103
103
  const isProd = process.env.NODE_ENV === "production";
104
104
  let viteConfigRoot;
@@ -107,7 +107,8 @@ function routerPlugin({ pagesDir = "pages", serverEntry = "server/index", apiPre
107
107
  const VIRTUAL = {
108
108
  routes: "virtual:routes",
109
109
  manifest: "virtual:client-manifest",
110
- renderer: "virtual:vike-lite/renderer",
110
+ client: "virtual:vike-lite/client",
111
+ server: "virtual:vike-lite/server",
111
112
  entryClient: "virtual:entry-client",
112
113
  setup: "virtual:vike-lite/setup",
113
114
  entryServer: "virtual:entry-server",
@@ -207,7 +208,7 @@ function routerPlugin({ pagesDir = "pages", serverEntry = "server/index", apiPre
207
208
  };
208
209
  },
209
210
  configResolved(config) {
210
- if (!config.plugins.some((plugin) => plugin.name?.startsWith("vike-lite-") && SUPPORTED_RENDERERS.includes(plugin.name.replace("vike-lite-", "")))) throw new Error(`No UI renderer plugin found in 'vite.config': please install and configure one of ${SUPPORTED_RENDERERS.map((r) => `vike-lite-${r}`).join(", ")}`);
211
+ if (!config.plugins.some((plugin) => plugin.name?.startsWith("vike-lite-") && SUPPORTED_RENDERERS.includes(plugin.name.replace("vike-lite-", "")))) throw new Error(`[vike-lite] No UI renderer plugin found in 'vite.config': please install and configure one of ${SUPPORTED_RENDERERS.map((r) => `vike-lite-${r}`).join(", ")}`);
211
212
  },
212
213
  resolveId(id) {
213
214
  if (VIRTUAL_VALUES.has(id)) return "\0" + id;
@@ -216,7 +217,7 @@ function routerPlugin({ pagesDir = "pages", serverEntry = "server/index", apiPre
216
217
  if (id === RESOLVED.routes) {
217
218
  const { routes, errorRoute } = generateRoutes(viteConfigRoot, pagesDir);
218
219
  const isSSR = options.ssr;
219
- let code = `import { onRenderHtml } from '${VIRTUAL.renderer}';\nexport const config = { onRenderHtml };\nexport const routes = [\n`;
220
+ let code = `import { onRenderHtml } from '${VIRTUAL.server}';\nexport const config = { onRenderHtml };\nexport const routes = [\n`;
220
221
  for (const r of routes) {
221
222
  code += `{path:'${r.path}',page:'${r.page}',Page:()=>import('/${r.page}'),`;
222
223
  if (r.head) code += `head:'${r.head}',Head:()=>import('/${r.head}'),`;
@@ -246,7 +247,7 @@ function routerPlugin({ pagesDir = "pages", serverEntry = "server/index", apiPre
246
247
  const manifestPath = path.join(viteConfigRoot, outDir, "client/.vite/manifest.json");
247
248
  return `export default ${fs.readFileSync(manifestPath, "utf8")}`;
248
249
  }
249
- if (id === RESOLVED.entryClient) return `import{routes,errorRoute}from'${VIRTUAL.routes}';import{onRenderClient}from'${VIRTUAL.renderer}';const{default:render}=await onRenderClient();await render({routes,errorRoute});`;
250
+ if (id === RESOLVED.entryClient) return `import{routes,errorRoute}from'${VIRTUAL.routes}';import{onRenderClient}from'${VIRTUAL.client}';await (await onRenderClient()).default({routes,errorRoute});`;
250
251
  if (id === RESOLVED.setup) return `import{routes,errorRoute,config}from'${VIRTUAL.routes}';import{setVikeState}from'vike-lite/__internal/server';const manifest=process.env.NODE_ENV==='production'?(await import('${VIRTUAL.manifest}')).default:null;setVikeState({routes,errorRoute,config,manifest});`;
251
252
  if (id === RESOLVED.entryServer) {
252
253
  if (serverEntry) {
@@ -260,97 +261,11 @@ function routerPlugin({ pagesDir = "pages", serverEntry = "server/index", apiPre
260
261
  serverEntryPath = (basePath + ext).replaceAll("\\", "/");
261
262
  break;
262
263
  }
263
- if (!serverEntryPath) throw new Error(`[vike-lite] serverEntry ${serverEntry} file not found!`);
264
+ if (!serverEntryPath) throw new Error(`[vike-lite] serverEntry ${serverEntry} file not found`);
264
265
  return `import '${VIRTUAL.setup}';export * from'${serverEntryPath}';export{default}from'${serverEntryPath}';`;
265
266
  }
266
- return `import '${VIRTUAL.setup}';import{renderPage}from'vike-lite/server';
267
- export default{async fetch(request){return renderPage(request);}};
268
- if (process.env.NODE_ENV === 'production') {
269
- const { createServer } = await import('node:http');
270
- const { Readable } = await import('node:stream');
271
- const { pipeline } = await import('node:stream/promises');
272
- const fs = await import('node:fs');
273
- const path = await import('node:path');
274
- const { fileURLToPath } = await import('node:url');
275
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
276
- const clientDir = path.resolve(__dirname, '../client');
277
- const MIME_TYPES = {
278
- '.html': 'text/html; charset=utf-8',
279
- '.js': 'text/javascript; charset=utf-8',
280
- '.mjs': 'text/javascript; charset=utf-8',
281
- '.css': 'text/css; charset=utf-8',
282
- '.json': 'application/json; charset=utf-8',
283
- '.xml': 'application/xml',
284
- '.txt': 'text/plain; charset=utf-8',
285
- '.map': 'application/json; charset=utf-8',
286
- '.png': 'image/png',
287
- '.jpg': 'image/jpeg',
288
- '.jpeg': 'image/jpeg',
289
- '.gif': 'image/gif',
290
- '.svg': 'image/svg+xml',
291
- '.ico': 'image/x-icon',
292
- '.webp': 'image/webp',
293
- '.avif': 'image/avif',
294
- '.woff': 'font/woff',
295
- '.woff2': 'font/woff2',
296
- '.ttf': 'font/ttf',
297
- '.otf': 'font/otf',
298
- '.mp4': 'video/mp4',
299
- '.webm': 'video/webm',
300
- '.mp3': 'audio/mpeg',
301
- '.pdf': 'application/pdf',
302
- '.wasm': 'application/wasm',
303
- '.webmanifest': 'application/manifest+json'
304
- };
305
- const { BASE_URL } = import.meta.env;
306
- const server = createServer(async (req, res) => {
307
- try {
308
- const urlObj = new URL(req.url || '/', 'http://' + (req.headers.host || 'localhost'));
309
- const pathname = urlObj.pathname;
310
- let fileUrl = pathname;
311
- if (BASE_URL !== '/' && pathname.startsWith(BASE_URL)) fileUrl = '/' + pathname.slice(BASE_URL.length);
312
- if (fileUrl !== '/') {
313
- const filePath = path.resolve(clientDir, '.' + fileUrl)
314
- if (!filePath.startsWith(clientDir + path.sep)) {
315
- res.statusCode = 403
316
- res.end('Forbidden')
317
- return
318
- }
319
- if (filePath.startsWith(clientDir) && fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
320
- const ext = path.extname(filePath).toLowerCase();
321
- const mimeType = MIME_TYPES[ext] || 'application/octet-stream';
322
- res.setHeader('Content-Type', mimeType);
323
- res.setHeader('Cache-Control', fileUrl.startsWith('/assets/') ? 'public, max-age=31536000, immutable' : 'public, max-age=0, must-revalidate')
324
- fs.createReadStream(filePath).pipe(res);
325
- return;
326
- }
327
- }
328
- const headers = new Headers();
329
- for (const [key, val] of Object.entries(req.headers)) {
330
- if (Array.isArray(val)) val.forEach(v => headers.append(key, v));
331
- else if (val) headers.set(key, val);
332
- }
333
- const { method } = req;
334
- const init = { method, headers };
335
- if (method !== 'GET' && method !== 'HEAD') { init.body = Readable.toWeb(req); init.duplex = 'half'; }
336
- const request = new Request(urlObj.href, init);
337
- const response = await renderPage(request);
338
- res.statusCode = response.status;
339
- for (const [key, val] of response.headers) res.setHeader(key, val);
340
- if (method === 'HEAD' || !response.body) { await response.body?.cancel(); res.end(); return; }
341
- try { await pipeline(Readable.fromWeb(response.body), res); } catch {}
342
- } catch (e) {
343
- console.error(e);
344
- res.statusCode = 500;
345
- res.end('Internal Server Error');
346
- }
347
- });
348
- const { PORT } = process.env;
349
- const port = PORT ? Number.parseInt(PORT) : 3000;
350
- server.listen(port, () => {
351
- console.log('\n\u{1B}[32m🚀 Server is running at http://localhost:' + port + '\u{1B}[0m\n');
352
- });
353
- }`;
267
+ const defaultServerEntry = fs.readFileSync(path.resolve(viteConfigRoot, "defaultServerEntry.mjs"), "utf8");
268
+ return `import '${VIRTUAL.setup}';` + defaultServerEntry;
354
269
  }
355
270
  if (id === RESOLVED.entryPrerender) return `import'${VIRTUAL.setup}';export{routes}from'${VIRTUAL.routes}';`;
356
271
  },
@@ -386,29 +301,29 @@ if (process.env.NODE_ENV === 'production') {
386
301
  }
387
302
  }
388
303
  if (urlsToPrerender.size === 0) return;
389
- console.log("\n\x1B[36m📦 Starting Static Site Generation (SSG)...\x1B[0m");
304
+ console.log("[vike-lite] 📦 Starting Static Site Generation (SSG)");
390
305
  const { BASE_URL } = import.meta.env;
391
306
  const baseNoSlash = BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL;
392
307
  let generatedCount = 0;
393
308
  const clientDir = path.resolve(viteConfigRoot, outDir, "client");
394
309
  for (const urlPath of urlsToPrerender) {
395
310
  const htmlRes = await renderPage(new Request(`http://localhost${baseNoSlash}${urlPath}`));
396
- if (htmlRes && htmlRes.ok && htmlRes.headers.get("content-type")?.includes("text/html")) {
311
+ if (htmlRes?.ok && htmlRes.headers.get("content-type")?.includes("text/html")) {
397
312
  const outDirRoute = path.join(clientDir, urlPath === "/" ? "" : urlPath);
398
313
  fs.mkdirSync(outDirRoute, { recursive: true });
399
314
  fs.writeFileSync(path.join(outDirRoute, "index.html"), await htmlRes.text());
400
- } else throw new Error(`\u{1B}[31m✖ SSG HTML Error for ${urlPath}\u{1B}[0m`);
315
+ } else throw new Error(`[vike-lite] SSG HTML Error for "${urlPath}"`);
401
316
  const jsonTarget = urlPath === "/" ? "/index" : urlPath;
402
317
  const jsonRes = await renderPage(new Request(`http://localhost${baseNoSlash}${jsonTarget}.pageContext.json`));
403
- if (jsonRes && jsonRes.ok) {
318
+ if (jsonRes?.ok) {
404
319
  const jsonOutPath = path.join(clientDir, `${jsonTarget}.pageContext.json`);
405
320
  fs.mkdirSync(path.dirname(jsonOutPath), { recursive: true });
406
321
  fs.writeFileSync(jsonOutPath, await jsonRes.text());
407
- } else throw new Error(`\u{1B}[31m✖ SSG JSON Error for ${jsonTarget}\u{1B}[0m`);
408
- console.log(`\u{1B}[32m✓\u{1B}[0m Pre-rendered: ${urlPath}`);
322
+ } else throw new Error(`[vike-lite] SSG JSON Error for "${jsonTarget}"`);
323
+ console.log(` └─ ${urlPath}`);
409
324
  generatedCount++;
410
325
  }
411
- console.log(`\n\u{1B}[32m✨ SSG Completed! Generated ${generatedCount} static routes.\u{1B}[0m\n`);
326
+ console.log(`[vike-lite] ✨ SSG Completed! Generated ${generatedCount} static routes`);
412
327
  },
413
328
  configureServer(server) {
414
329
  return () => {
@@ -435,14 +350,14 @@ if (process.env.NODE_ENV === 'production') {
435
350
  headers
436
351
  };
437
352
  if (req.url.startsWith(apiPrefix)) {
438
- server.config.logger.info(`API request: ${req.method} ${req.url}`, { timestamp: true });
353
+ server.config.logger.info(`⚡ API: ${req.method} ${req.url}`, { timestamp: true });
439
354
  requestInit.body = Readable.toWeb(req);
440
355
  requestInit.duplex = "half";
441
- } else if (req.url.endsWith(".pageContext.json")) server.config.logger.info(`SPA Navigation request: ${req.url}`, { timestamp: true });
356
+ } else if (req.url.endsWith(".pageContext.json")) server.config.logger.info(`🔄 SPA Navigation: ${req.url}`, { timestamp: true });
442
357
  const response = await app.fetch(new Request(`http://${req.headers.host}${req.url}`, requestInit));
443
358
  res.statusCode = response.status;
444
359
  if (response.headers.get("content-type")?.includes("text/html")) {
445
- server.config.logger.info(`Page request: ${req.url}`, { timestamp: true });
360
+ server.config.logger.info(`📄 Page: ${req.url}`, { timestamp: true });
446
361
  let html = await response.text();
447
362
  html = await injectFOUCStyles(server, html);
448
363
  html = await server.transformIndexHtml(req.url, html);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike-lite",
3
- "version": "1.13.0",
3
+ "version": "1.13.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "module": "./dist/index.mjs",
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/node": "^26.1.1",
54
- "tsdown": "^0.22.4",
54
+ "tsdown": "^0.22.5",
55
55
  "vite": "^8.1.4"
56
56
  },
57
57
  "peerDependencies": {