@pracht/vite-plugin 0.3.1 → 0.3.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/README.md CHANGED
@@ -13,7 +13,7 @@ npm install @pracht/vite-plugin
13
13
  ```ts
14
14
  // vite.config.ts
15
15
  import { defineConfig } from "vite";
16
- import pracht from "@pracht/vite-plugin";
16
+ import { pracht } from "@pracht/vite-plugin";
17
17
 
18
18
  export default defineConfig({
19
19
  plugins: [pracht()],
@@ -24,7 +24,7 @@ export default defineConfig({
24
24
 
25
25
  - Generates virtual modules (`virtual:pracht/client`, `virtual:pracht/server`) from your route manifest
26
26
  - Builds client and SSR bundles via Vite's multi-environment mode
27
- - Pre-renders SSG and ISG routes at build time
27
+ - Pre-renders SSG and ISG routes at build time (`prerenderConcurrency` controls parallelism)
28
28
  - Provides HMR during development
29
29
 
30
30
  ## Peer Dependencies
package/dist/index.d.mts CHANGED
@@ -60,6 +60,8 @@ interface PrachtPluginOptions {
60
60
  pagesDir?: string;
61
61
  /** Default render mode for pages when RENDER_MODE is not exported. Defaults to "ssr". */
62
62
  pagesDefaultRender?: RenderMode$1;
63
+ /** Maximum number of SSG/ISG pages rendered concurrently during `pracht build`. */
64
+ prerenderConcurrency?: number;
63
65
  }
64
66
  //#endregion
65
67
  //#region src/plugin-codegen.d.ts
package/dist/index.mjs CHANGED
@@ -639,7 +639,8 @@ const SERVER_ONLY_EXPORTS = new Set([
639
639
  "loader",
640
640
  "head",
641
641
  "headers",
642
- "getStaticPaths"
642
+ "getStaticPaths",
643
+ "markdown"
643
644
  ]);
644
645
  function stripServerOnlyExportsForClient(code, id = "pracht-client-route.tsx") {
645
646
  const states = createStatementStates(parseAst(code, { lang: getRolldownLang(id) }));
@@ -993,13 +994,16 @@ const DEFAULTS = {
993
994
  serverDir: "/src/server",
994
995
  adapter: createDefaultNodeAdapter(),
995
996
  pagesDir: "",
996
- pagesDefaultRender: "ssr"
997
+ pagesDefaultRender: "ssr",
998
+ prerenderConcurrency: 10
997
999
  };
998
1000
  function resolveOptions(options) {
999
- return {
1001
+ const resolved = {
1000
1002
  ...DEFAULTS,
1001
1003
  ...options
1002
1004
  };
1005
+ if (!Number.isInteger(resolved.prerenderConcurrency) || resolved.prerenderConcurrency <= 0) throw new Error("pracht({ prerenderConcurrency }) expects a positive integer.");
1006
+ return resolved;
1003
1007
  }
1004
1008
  //#endregion
1005
1009
  //#region src/plugin-codegen.ts
@@ -1019,17 +1023,30 @@ function createPrachtClientModuleSource(options = {}, buildOptions = {}) {
1019
1023
  "const resolvedApp = resolveApp(app);",
1020
1024
  "",
1021
1025
  "function normalizeModuleKey(key) {",
1022
- " return key.split(\"?\")[0];",
1026
+ " return key.split(\"?\")[0].replace(/^\\.?\\//, \"\");",
1023
1027
  "}",
1024
1028
  "",
1025
- "function findModuleKey(modules, file) {",
1026
- " if (file in modules) return file;",
1027
- " const suffix = file.replace(/^\\.\\//,\"\");",
1029
+ "const moduleKeyIndexes = new WeakMap();",
1030
+ "function getModuleKeyIndex(modules) {",
1031
+ " let index = moduleKeyIndexes.get(modules);",
1032
+ " if (index) return index;",
1033
+ " index = new Map();",
1028
1034
  " for (const key of Object.keys(modules)) {",
1029
- " const normalizedKey = normalizeModuleKey(key);",
1030
- " if (normalizedKey.endsWith(\"/\" + suffix) || normalizedKey.endsWith(suffix)) return key;",
1035
+ " const normalized = normalizeModuleKey(key);",
1036
+ " if (!normalized) continue;",
1037
+ " if (!index.has(normalized)) index.set(normalized, key);",
1038
+ " for (let i = normalized.indexOf(\"/\"); i !== -1; i = normalized.indexOf(\"/\", i + 1)) {",
1039
+ " const suffix = normalized.slice(i + 1);",
1040
+ " if (suffix && !index.has(suffix)) index.set(suffix, key);",
1041
+ " }",
1031
1042
  " }",
1032
- " return null;",
1043
+ " moduleKeyIndexes.set(modules, index);",
1044
+ " return index;",
1045
+ "}",
1046
+ "",
1047
+ "function findModuleKey(modules, file) {",
1048
+ " if (file in modules) return file;",
1049
+ " return getModuleKeyIndex(modules).get(normalizeModuleKey(file)) ?? null;",
1033
1050
  "}",
1034
1051
  "",
1035
1052
  "const state = readHydrationState();",
@@ -1069,6 +1086,7 @@ function createPrachtServerModuleSource(options = {}, buildOptions = {}) {
1069
1086
  `export const clientEntryUrl = ${JSON.stringify(clientBuild.clientEntryUrl ?? "/@pracht/client.js")};`,
1070
1087
  `export const cssManifest = ${JSON.stringify(clientBuild.cssManifest)};`,
1071
1088
  `export const jsManifest = ${JSON.stringify(clientBuild.jsManifest)};`,
1089
+ `export const prerenderConcurrency = ${JSON.stringify(resolved.prerenderConcurrency)};`,
1072
1090
  "export { prerenderApp };",
1073
1091
  ""
1074
1092
  ];
@@ -1096,13 +1114,26 @@ function createPrachtRegistryModuleSource(options = {}) {
1096
1114
  "};"
1097
1115
  ].join("\n");
1098
1116
  }
1117
+ const pagesAppSourceCache = /* @__PURE__ */ new Map();
1118
+ function clearPagesAppSourceCache() {
1119
+ pagesAppSourceCache.clear();
1120
+ }
1099
1121
  function generatePagesAppInlineSource(options, root = process.cwd()) {
1100
1122
  const absPagesDir = resolve(root, options.pagesDir.slice(1));
1101
- return generatePagesManifestSource(scanPagesDirectory(absPagesDir), {
1123
+ const cacheKey = JSON.stringify({
1124
+ absPagesDir,
1125
+ pagesDefaultRender: options.pagesDefaultRender,
1126
+ pagesDirPrefix: options.pagesDir
1127
+ });
1128
+ const cached = pagesAppSourceCache.get(cacheKey);
1129
+ if (cached) return cached;
1130
+ const source = generatePagesManifestSource(scanPagesDirectory(absPagesDir), {
1102
1131
  pagesDir: absPagesDir,
1103
1132
  pagesDefaultRender: options.pagesDefaultRender,
1104
1133
  pagesDirPrefix: options.pagesDir
1105
1134
  });
1135
+ pagesAppSourceCache.set(cacheKey, source);
1136
+ return source;
1106
1137
  }
1107
1138
  //#endregion
1108
1139
  //#region src/plugin-dev-ssr.ts
@@ -1248,7 +1279,8 @@ async function pracht(options = {}) {
1248
1279
  return null;
1249
1280
  },
1250
1281
  transform(code, id) {
1251
- if (id !== resolve(root, resolved.appFile.slice(1))) return null;
1282
+ const appFileAbs = resolveConfigPath(root, resolved.appFile);
1283
+ if (toPosixPath(id.split("?")[0]) !== appFileAbs) return null;
1252
1284
  const transformed = code.replace(/\(\)\s*=>\s*import\(\s*(['"])([^'"]+)\1\s*\)/g, "$1$2$1");
1253
1285
  if (transformed === code) return null;
1254
1286
  return {
@@ -1264,9 +1296,11 @@ async function pracht(options = {}) {
1264
1296
  };
1265
1297
  },
1266
1298
  handleHotUpdate({ file, server }) {
1267
- const serverRoot = server.config.root;
1268
- const relative = file.startsWith(serverRoot) ? file.slice(serverRoot.length) : file;
1299
+ const serverRoot = toPosixPath(server.config.root);
1300
+ const normalizedFile = toPosixPath(file);
1301
+ const relative = normalizedFile.startsWith(serverRoot) ? normalizedFile.slice(serverRoot.length) : normalizedFile;
1269
1302
  if (isPagesMode && relative.startsWith(resolved.pagesDir)) {
1303
+ clearPagesAppSourceCache();
1270
1304
  invalidateVirtualModules(server);
1271
1305
  return;
1272
1306
  }
@@ -1309,12 +1343,18 @@ async function pracht(options = {}) {
1309
1343
  return plugins;
1310
1344
  }
1311
1345
  function watchPagesDirectory(server, resolved, root) {
1312
- const abs = resolve(root, resolved.pagesDir.slice(1));
1346
+ const abs = resolveConfigPath(root, resolved.pagesDir);
1313
1347
  server.watcher.on("add", (f) => {
1314
- if (f.startsWith(abs)) server.restart();
1348
+ if (toPosixPath(f).startsWith(toPosixPath(abs))) {
1349
+ clearPagesAppSourceCache();
1350
+ server.restart();
1351
+ }
1315
1352
  });
1316
1353
  server.watcher.on("unlink", (f) => {
1317
- if (f.startsWith(abs)) server.restart();
1354
+ if (toPosixPath(f).startsWith(toPosixPath(abs))) {
1355
+ clearPagesAppSourceCache();
1356
+ server.restart();
1357
+ }
1318
1358
  });
1319
1359
  }
1320
1360
  function invalidateVirtualModules(server) {
@@ -1332,7 +1372,7 @@ const ROUTE_FILE_EXTENSIONS = new Set([
1332
1372
  ".mdx"
1333
1373
  ]);
1334
1374
  function computeRouteFileDirs(root, resolved) {
1335
- return (resolved.pagesDir ? [resolved.pagesDir] : [resolved.routesDir, resolved.shellsDir]).map((dir) => toPosixPath(resolve(root, dir.replace(/^\//, "")))).map(withTrailingSep);
1375
+ return (resolved.pagesDir ? [resolved.pagesDir] : [resolved.routesDir, resolved.shellsDir]).map((dir) => resolveConfigPath(root, dir)).map(withTrailingSep);
1336
1376
  }
1337
1377
  function isRouteOrShellFile(id, dirs) {
1338
1378
  if (dirs.length === 0) return false;
@@ -1346,6 +1386,12 @@ function isRouteOrShellFile(id, dirs) {
1346
1386
  const normalized = toPosixPath(path);
1347
1387
  return dirs.some((dir) => normalized.startsWith(dir));
1348
1388
  }
1389
+ function resolveConfigPath(root, configPath) {
1390
+ const normalizedRoot = toPosixPath(root).replace(/\/$/, "");
1391
+ const relativePath = configPath.replace(/^\//, "");
1392
+ if (normalizedRoot.startsWith("/") && !/^[A-Za-z]:\//.test(normalizedRoot)) return `${normalizedRoot}/${relativePath}`;
1393
+ return toPosixPath(resolve(root, relativePath));
1394
+ }
1349
1395
  function toPosixPath(p) {
1350
1396
  return p.replace(/\\/g, "/");
1351
1397
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pracht/vite-plugin",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "license": "MIT",
5
5
  "homepage": "https://github.com/JoviDeCroock/pracht/tree/main/packages/vite-plugin",
6
6
  "bugs": {
@@ -31,8 +31,8 @@
31
31
  "dependencies": {
32
32
  "@preact/preset-vite": "^2.10.5",
33
33
  "@prefresh/vite": "^2.0.0",
34
- "@pracht/adapter-node": "0.1.10",
35
- "@pracht/core": "0.4.0"
34
+ "@pracht/adapter-node": "0.1.11",
35
+ "@pracht/core": "0.5.0"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "vite": "^8.0.0"