@lovable.dev/vite-tanstack-config 2.19.0 → 2.19.1

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.cjs CHANGED
@@ -152,7 +152,7 @@ function bundledDevCssUrlShim() {
152
152
  //#endregion
153
153
  //#region package.json
154
154
  var name = "@lovable.dev/vite-tanstack-config";
155
- var version = "2.19.0";
155
+ var version = "2.19.1";
156
156
  //#endregion
157
157
  //#region src/logging.ts
158
158
  const PACKAGE_NAME = "@lovable.dev/vite-tanstack-config";
@@ -255,13 +255,19 @@ function serializeDocumentSet(entries, generator) {
255
255
  });
256
256
  }
257
257
  const EXISTENCE_BATCH_SIZE = 64;
258
+ async function inBatches(items, run) {
259
+ const results = [];
260
+ for (let i = 0; i < items.length; i += EXISTENCE_BATCH_SIZE) results.push(...await Promise.all(items.slice(i, i + EXISTENCE_BATCH_SIZE).map(run)));
261
+ return results;
262
+ }
258
263
  async function whichExist(paths, access) {
259
- const exists = [];
260
- for (let i = 0; i < paths.length; i += EXISTENCE_BATCH_SIZE) {
261
- const batch = paths.slice(i, i + EXISTENCE_BATCH_SIZE).map((path) => access(path).then(() => true, () => false));
262
- exists.push(...await Promise.all(batch));
263
- }
264
- return exists;
264
+ return inBatches(paths, (path) => access(path).then(() => true, () => false));
265
+ }
266
+ async function whichMatch(pairs, readFile) {
267
+ const read = (path) => readFile(path).catch((error) => {
268
+ if (error.code !== "ENOENT") logWarning(`Could not read ${path} while checking prerender collisions: ${String(error)}`);
269
+ });
270
+ return inBatches(pairs, ([left, right]) => Promise.all([read(left), read(right)]).then(([a, b]) => a !== void 0 && b !== void 0 && a.equals(b)));
265
271
  }
266
272
  /** How the error names the public dir, which vite lets a project point anywhere. */
267
273
  function publicDirLabel(root, publicDir, nodePath) {
@@ -292,13 +298,15 @@ function createDocumentSet(routerBasePath) {
292
298
  buildApp: {
293
299
  order: "post",
294
300
  async handler() {
295
- const { access, mkdir, rm, writeFile } = await import("node:fs/promises");
301
+ const { access, mkdir, readFile, rm, writeFile } = await import("node:fs/promises");
296
302
  const nodePath = await import("node:path");
297
303
  const artifact = nodePath.join(root, PUBLISH_OUTPUT_DIR, DOCUMENT_SET_DIR, DOCUMENT_SET_FILE);
298
304
  await rm(artifact, { force: true }).catch((error) => {
299
305
  logWarning(`Could not remove a previous build's document set: ${String(error)}`);
300
306
  });
301
307
  if (documents.size === 0) return;
308
+ const clientDir = nodePath.resolve(root, clientOutputDir);
309
+ const label = publicDirLabel(root, publicDir, nodePath);
302
310
  const collisions = [];
303
311
  if (publicDir !== "") {
304
312
  const candidates = [...documents].map(([route, file]) => ({
@@ -306,14 +314,21 @@ function createDocumentSet(routerBasePath) {
306
314
  file
307
315
  }));
308
316
  const committed = await whichExist(candidates.map(({ file }) => nodePath.join(publicDir, file)), access);
309
- for (const [index, candidate] of candidates.entries()) if (committed[index]) collisions.push(candidate);
317
+ const suspects = candidates.filter((_candidate, index) => committed[index]);
318
+ const survived = await whichMatch(suspects.map(({ file }) => [nodePath.join(publicDir, file), nodePath.resolve(clientDir, file)]), readFile);
319
+ for (const [index, suspect] of suspects.entries()) {
320
+ if (!survived[index]) {
321
+ collisions.push(suspect);
322
+ continue;
323
+ }
324
+ documents.delete(suspect.route);
325
+ logWarning(`Not publishing prerendered route ${suspect.route}: it would serve the committed ${label}/${suspect.file}, which the prerender pass left untouched.`);
326
+ }
310
327
  }
311
328
  if (collisions.length > 0) {
312
- const label = publicDirLabel(root, publicDir, nodePath);
313
329
  const pairs = collisions.sort(compareRoutes).map(({ route, file }) => ` ${route} overwrites ${label}/${file}`);
314
330
  throw new Error(`[${PACKAGE_NAME}] Prerendering would overwrite ${collisions.length} committed file(s) under ${label}/:\n${pairs.join("\n")}\nEach route's prerendered HTML is written into the client build after vite copies ${label}/, so every committed file above is replaced by its rendered route and never ships.\nFix each line above in one of two ways: delete or rename the ${label}/ file, or stop prerendering the route (drop it from \`pages\` in vite.config, or return false for it from \`prerender.filter\`).`);
315
331
  }
316
- const clientDir = nodePath.resolve(root, clientOutputDir);
317
332
  const entries = [...documents].map(([route, file]) => ({
318
333
  route,
319
334
  file
package/dist/index.js CHANGED
@@ -128,7 +128,7 @@ function bundledDevCssUrlShim() {
128
128
  //#endregion
129
129
  //#region package.json
130
130
  var name = "@lovable.dev/vite-tanstack-config";
131
- var version = "2.19.0";
131
+ var version = "2.19.1";
132
132
  //#endregion
133
133
  //#region src/logging.ts
134
134
  const PACKAGE_NAME = "@lovable.dev/vite-tanstack-config";
@@ -231,13 +231,19 @@ function serializeDocumentSet(entries, generator) {
231
231
  });
232
232
  }
233
233
  const EXISTENCE_BATCH_SIZE = 64;
234
+ async function inBatches(items, run) {
235
+ const results = [];
236
+ for (let i = 0; i < items.length; i += EXISTENCE_BATCH_SIZE) results.push(...await Promise.all(items.slice(i, i + EXISTENCE_BATCH_SIZE).map(run)));
237
+ return results;
238
+ }
234
239
  async function whichExist(paths, access) {
235
- const exists = [];
236
- for (let i = 0; i < paths.length; i += EXISTENCE_BATCH_SIZE) {
237
- const batch = paths.slice(i, i + EXISTENCE_BATCH_SIZE).map((path) => access(path).then(() => true, () => false));
238
- exists.push(...await Promise.all(batch));
239
- }
240
- return exists;
240
+ return inBatches(paths, (path) => access(path).then(() => true, () => false));
241
+ }
242
+ async function whichMatch(pairs, readFile) {
243
+ const read = (path) => readFile(path).catch((error) => {
244
+ if (error.code !== "ENOENT") logWarning(`Could not read ${path} while checking prerender collisions: ${String(error)}`);
245
+ });
246
+ return inBatches(pairs, ([left, right]) => Promise.all([read(left), read(right)]).then(([a, b]) => a !== void 0 && b !== void 0 && a.equals(b)));
241
247
  }
242
248
  /** How the error names the public dir, which vite lets a project point anywhere. */
243
249
  function publicDirLabel(root, publicDir, nodePath) {
@@ -268,13 +274,15 @@ function createDocumentSet(routerBasePath) {
268
274
  buildApp: {
269
275
  order: "post",
270
276
  async handler() {
271
- const { access, mkdir, rm, writeFile } = await import("node:fs/promises");
277
+ const { access, mkdir, readFile, rm, writeFile } = await import("node:fs/promises");
272
278
  const nodePath = await import("node:path");
273
279
  const artifact = nodePath.join(root, PUBLISH_OUTPUT_DIR, DOCUMENT_SET_DIR, DOCUMENT_SET_FILE);
274
280
  await rm(artifact, { force: true }).catch((error) => {
275
281
  logWarning(`Could not remove a previous build's document set: ${String(error)}`);
276
282
  });
277
283
  if (documents.size === 0) return;
284
+ const clientDir = nodePath.resolve(root, clientOutputDir);
285
+ const label = publicDirLabel(root, publicDir, nodePath);
278
286
  const collisions = [];
279
287
  if (publicDir !== "") {
280
288
  const candidates = [...documents].map(([route, file]) => ({
@@ -282,14 +290,21 @@ function createDocumentSet(routerBasePath) {
282
290
  file
283
291
  }));
284
292
  const committed = await whichExist(candidates.map(({ file }) => nodePath.join(publicDir, file)), access);
285
- for (const [index, candidate] of candidates.entries()) if (committed[index]) collisions.push(candidate);
293
+ const suspects = candidates.filter((_candidate, index) => committed[index]);
294
+ const survived = await whichMatch(suspects.map(({ file }) => [nodePath.join(publicDir, file), nodePath.resolve(clientDir, file)]), readFile);
295
+ for (const [index, suspect] of suspects.entries()) {
296
+ if (!survived[index]) {
297
+ collisions.push(suspect);
298
+ continue;
299
+ }
300
+ documents.delete(suspect.route);
301
+ logWarning(`Not publishing prerendered route ${suspect.route}: it would serve the committed ${label}/${suspect.file}, which the prerender pass left untouched.`);
302
+ }
286
303
  }
287
304
  if (collisions.length > 0) {
288
- const label = publicDirLabel(root, publicDir, nodePath);
289
305
  const pairs = collisions.sort(compareRoutes).map(({ route, file }) => ` ${route} overwrites ${label}/${file}`);
290
306
  throw new Error(`[${PACKAGE_NAME}] Prerendering would overwrite ${collisions.length} committed file(s) under ${label}/:\n${pairs.join("\n")}\nEach route's prerendered HTML is written into the client build after vite copies ${label}/, so every committed file above is replaced by its rendered route and never ships.\nFix each line above in one of two ways: delete or rename the ${label}/ file, or stop prerendering the route (drop it from \`pages\` in vite.config, or return false for it from \`prerender.filter\`).`);
291
307
  }
292
- const clientDir = nodePath.resolve(root, clientOutputDir);
293
308
  const entries = [...documents].map(([route, file]) => ({
294
309
  route,
295
310
  file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovable.dev/vite-tanstack-config",
3
- "version": "2.19.0",
3
+ "version": "2.19.1",
4
4
  "description": "Vite config wrapper for Lovable TanStack Start projects",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",