@lovable.dev/vite-tanstack-config 2.19.4 → 2.20.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/index.cjs CHANGED
@@ -153,7 +153,7 @@ function bundledDevCssUrlShim() {
153
153
  //#endregion
154
154
  //#region package.json
155
155
  var name = "@lovable.dev/vite-tanstack-config";
156
- var version = "2.19.4";
156
+ var version = "2.20.0";
157
157
  //#endregion
158
158
  //#region src/logging.ts
159
159
  const PACKAGE_NAME = "@lovable.dev/vite-tanstack-config";
@@ -425,6 +425,23 @@ function pinPrerenderOptions(source, pins, label) {
425
425
  }
426
426
  return result;
427
427
  }
428
+ const PRERENDER_REPORT_MARKER_OPEN = "[lovable-prerender-report]";
429
+ const PRERENDER_REPORT_MARKER_CLOSE = "[/lovable-prerender-report]";
430
+ const MAX_REPORTED_ROUTES = 50;
431
+ const MAX_REPORTED_ROUTE_LENGTH = 200;
432
+ function boundRoutes(routes) {
433
+ return routes.slice(0, MAX_REPORTED_ROUTES).map((route) => route.slice(0, MAX_REPORTED_ROUTE_LENGTH));
434
+ }
435
+ function emitPrerenderReport(attempted, rendered, skipped) {
436
+ const payload = JSON.stringify({
437
+ attempted,
438
+ rendered,
439
+ skipped: boundRoutes(skipped)
440
+ });
441
+ try {
442
+ process.stderr.write(`\n${PRERENDER_REPORT_MARKER_OPEN}\n${payload}\n${PRERENDER_REPORT_MARKER_CLOSE}\n`);
443
+ } catch {}
444
+ }
428
445
  function pinPrerenderForLovableBuild(userOptions) {
429
446
  const attempted = /* @__PURE__ */ new Set();
430
447
  const rendered = /* @__PURE__ */ new Set();
@@ -458,6 +475,14 @@ function pinPrerenderForLovableBuild(userOptions) {
458
475
  prerender: pinned
459
476
  };
460
477
  });
478
+ const spa = userOptions.spa;
479
+ if (typeof spa?.prerender?.onSuccess === "function") startOptions.spa = {
480
+ ...spa,
481
+ prerender: {
482
+ ...spa.prerender,
483
+ onSuccess: withRenderTracking(spa.prerender.onSuccess)
484
+ }
485
+ };
461
486
  return {
462
487
  startOptions,
463
488
  skipReporter: {
@@ -467,7 +492,9 @@ function pinPrerenderForLovableBuild(userOptions) {
467
492
  buildApp: {
468
493
  order: "post",
469
494
  async handler() {
495
+ if (attempted.size === 0) return;
470
496
  const skipped = [...attempted].filter((route) => !rendered.has(route));
497
+ emitPrerenderReport(attempted.size, rendered.size, skipped);
471
498
  if (skipped.length === 0) return;
472
499
  logWarning(`Prerender skipped ${skipped.length} route(s) that failed to render; they fall back to SSR: ${skipped.join(", ")}`);
473
500
  }
@@ -732,9 +759,14 @@ function lovableBuildErrorDiagnostics() {
732
759
  }
733
760
  };
734
761
  }
762
+ function nitroEmitDirs(dirs) {
763
+ if (!dirs) return [SERVER_OUTPUT_DIR];
764
+ const found = [dirs.nitroOutput.serverDir, ...dirs.entryDirs].filter((dir) => !!dir);
765
+ return [...new Set(found)];
766
+ }
735
767
  const NODEJS_COMPAT_DEFAULT_ON_DATE = "2026-08-04";
736
- const SANDBOX_WRANGLER_CONFIG_PATH = `${SERVER_OUTPUT_DIR}/wrangler.json`;
737
- function stripRedundantNodejsCompatFlag() {
768
+ const NITRO_WRANGLER_CONFIG = "wrangler.json";
769
+ function stripRedundantNodejsCompatFlag(dirs) {
738
770
  let root = process.cwd();
739
771
  return {
740
772
  name: "lovable-strip-redundant-nodejs-compat",
@@ -746,13 +778,18 @@ function stripRedundantNodejsCompatFlag() {
746
778
  order: "post",
747
779
  handler: async () => {
748
780
  const { readFile, writeFile } = await import("node:fs/promises");
749
- const configPath = (0, node_path.join)(root, SANDBOX_WRANGLER_CONFIG_PATH);
781
+ let configPath;
750
782
  let parsed;
751
- try {
752
- parsed = JSON.parse(await readFile(configPath, "utf8"));
753
- } catch {
754
- return;
783
+ for (const dir of nitroEmitDirs(dirs)) {
784
+ configPath = (0, node_path.join)((0, node_path.resolve)(root, dir), NITRO_WRANGLER_CONFIG);
785
+ try {
786
+ parsed = JSON.parse(await readFile(configPath, "utf8"));
787
+ break;
788
+ } catch {
789
+ configPath = void 0;
790
+ }
755
791
  }
792
+ if (configPath === void 0) return;
756
793
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return;
757
794
  const config = parsed;
758
795
  if (typeof config.compatibility_date !== "string") return;
@@ -771,7 +808,6 @@ function stripRedundantNodejsCompatFlag() {
771
808
  const NITRO_SERVER_ENTRY = "index.mjs";
772
809
  const NITRO_DEFAULT_OUTPUT_DIR = ".output";
773
810
  const VITE_DEFAULT_OUTPUT_DIR = "dist";
774
- const NITRO_WRANGLER_CONFIG = "wrangler.json";
775
811
  const DEFAULT_SERVER_ENTRY_NAME = "server";
776
812
  const PRERENDER_PREVIEW_HOST = "127.0.0.1";
777
813
  const TSS_PRERENDERING_ENV = "TSS_PRERENDERING";
@@ -859,8 +895,7 @@ function prerenderPreviewShim(state, dirs) {
859
895
  return false;
860
896
  }
861
897
  };
862
- const found = [dirs.nitroOutput.serverDir, ...dirs.entryDirs].filter((dir) => !!dir);
863
- const candidates = [...new Set(found)];
898
+ const candidates = nitroEmitDirs(dirs);
864
899
  let entryDir;
865
900
  for (const candidate of candidates) {
866
901
  const resolved = (0, node_path.resolve)(root, candidate);
@@ -1154,13 +1189,13 @@ function defineConfig(configOrOptions = {}) {
1154
1189
  };
1155
1190
  }
1156
1191
  } else if (!nitroOpts.preset && !await nitroSupportsDefaultPreset()) logWarning("The installed `nitro` predates the `defaultPreset` option (3.0.260603-beta), so the Cloudflare fallback is ignored and a zero-config build may target Node instead. Upgrade nitro to >=3.0.260603-beta, or set an explicit `nitro: { preset: \"cloudflare-module\" }`.");
1157
- const shimDirs = prerenderEnabled ? prerenderShimDirs(options.vite, nitroOpts) : void 0;
1192
+ const nitroDirs = prerenderEnabled || isSandbox ? prerenderShimDirs(options.vite, nitroOpts) : void 0;
1158
1193
  internalPlugins.push(nitro(nitroOpts));
1159
- if (shimDirs) {
1194
+ if (prerenderEnabled && nitroDirs) {
1160
1195
  const shimState = {};
1161
- internalPlugins.push(prerenderPreviewShim(shimState, shimDirs), prerenderPreviewShimCleanup(shimState));
1196
+ internalPlugins.push(prerenderPreviewShim(shimState, nitroDirs), prerenderPreviewShimCleanup(shimState));
1162
1197
  }
1163
- if (isSandbox) internalPlugins.push(stripRedundantNodejsCompatFlag());
1198
+ if (isSandbox) internalPlugins.push(stripRedundantNodejsCompatFlag(nitroDirs));
1164
1199
  }
1165
1200
  }
1166
1201
  const viteReact = (await import("@vitejs/plugin-react")).default;
package/dist/index.d.cts CHANGED
@@ -18,7 +18,18 @@ type PrerenderPage = {
18
18
  };
19
19
  //#endregion
20
20
  //#region src/index.d.ts
21
- declare function stripRedundantNodejsCompatFlag(): Plugin;
21
+ declare function stripRedundantNodejsCompatFlag(dirs?: PrerenderShimDirs): Plugin;
22
+ type NitroOutput = {
23
+ serverDir?: string;
24
+ };
25
+ type PrerenderShimDirs = {
26
+ /** Where upstream's preview middleware imports the server build from. */
27
+ shimDir: string;
28
+ /** Ordered fallbacks for the directory nitro emitted its entry into. */
29
+ entryDirs: string[];
30
+ /** Filled by nitro's `compiled` hook, which fires inside its own post-order `buildApp`. */
31
+ nitroOutput: NitroOutput;
32
+ };
22
33
  interface LovableViteTanstackOptions {
23
34
  plugins?: PluginOption[];
24
35
  vite?: UserConfig;
package/dist/index.d.ts CHANGED
@@ -18,7 +18,18 @@ type PrerenderPage = {
18
18
  };
19
19
  //#endregion
20
20
  //#region src/index.d.ts
21
- declare function stripRedundantNodejsCompatFlag(): Plugin;
21
+ declare function stripRedundantNodejsCompatFlag(dirs?: PrerenderShimDirs): Plugin;
22
+ type NitroOutput = {
23
+ serverDir?: string;
24
+ };
25
+ type PrerenderShimDirs = {
26
+ /** Where upstream's preview middleware imports the server build from. */
27
+ shimDir: string;
28
+ /** Ordered fallbacks for the directory nitro emitted its entry into. */
29
+ entryDirs: string[];
30
+ /** Filled by nitro's `compiled` hook, which fires inside its own post-order `buildApp`. */
31
+ nitroOutput: NitroOutput;
32
+ };
22
33
  interface LovableViteTanstackOptions {
23
34
  plugins?: PluginOption[];
24
35
  vite?: UserConfig;
package/dist/index.js CHANGED
@@ -129,7 +129,7 @@ function bundledDevCssUrlShim() {
129
129
  //#endregion
130
130
  //#region package.json
131
131
  var name = "@lovable.dev/vite-tanstack-config";
132
- var version = "2.19.4";
132
+ var version = "2.20.0";
133
133
  //#endregion
134
134
  //#region src/logging.ts
135
135
  const PACKAGE_NAME = "@lovable.dev/vite-tanstack-config";
@@ -401,6 +401,23 @@ function pinPrerenderOptions(source, pins, label) {
401
401
  }
402
402
  return result;
403
403
  }
404
+ const PRERENDER_REPORT_MARKER_OPEN = "[lovable-prerender-report]";
405
+ const PRERENDER_REPORT_MARKER_CLOSE = "[/lovable-prerender-report]";
406
+ const MAX_REPORTED_ROUTES = 50;
407
+ const MAX_REPORTED_ROUTE_LENGTH = 200;
408
+ function boundRoutes(routes) {
409
+ return routes.slice(0, MAX_REPORTED_ROUTES).map((route) => route.slice(0, MAX_REPORTED_ROUTE_LENGTH));
410
+ }
411
+ function emitPrerenderReport(attempted, rendered, skipped) {
412
+ const payload = JSON.stringify({
413
+ attempted,
414
+ rendered,
415
+ skipped: boundRoutes(skipped)
416
+ });
417
+ try {
418
+ process.stderr.write(`\n${PRERENDER_REPORT_MARKER_OPEN}\n${payload}\n${PRERENDER_REPORT_MARKER_CLOSE}\n`);
419
+ } catch {}
420
+ }
404
421
  function pinPrerenderForLovableBuild(userOptions) {
405
422
  const attempted = /* @__PURE__ */ new Set();
406
423
  const rendered = /* @__PURE__ */ new Set();
@@ -434,6 +451,14 @@ function pinPrerenderForLovableBuild(userOptions) {
434
451
  prerender: pinned
435
452
  };
436
453
  });
454
+ const spa = userOptions.spa;
455
+ if (typeof spa?.prerender?.onSuccess === "function") startOptions.spa = {
456
+ ...spa,
457
+ prerender: {
458
+ ...spa.prerender,
459
+ onSuccess: withRenderTracking(spa.prerender.onSuccess)
460
+ }
461
+ };
437
462
  return {
438
463
  startOptions,
439
464
  skipReporter: {
@@ -443,7 +468,9 @@ function pinPrerenderForLovableBuild(userOptions) {
443
468
  buildApp: {
444
469
  order: "post",
445
470
  async handler() {
471
+ if (attempted.size === 0) return;
446
472
  const skipped = [...attempted].filter((route) => !rendered.has(route));
473
+ emitPrerenderReport(attempted.size, rendered.size, skipped);
447
474
  if (skipped.length === 0) return;
448
475
  logWarning(`Prerender skipped ${skipped.length} route(s) that failed to render; they fall back to SSR: ${skipped.join(", ")}`);
449
476
  }
@@ -708,9 +735,14 @@ function lovableBuildErrorDiagnostics() {
708
735
  }
709
736
  };
710
737
  }
738
+ function nitroEmitDirs(dirs) {
739
+ if (!dirs) return [SERVER_OUTPUT_DIR];
740
+ const found = [dirs.nitroOutput.serverDir, ...dirs.entryDirs].filter((dir) => !!dir);
741
+ return [...new Set(found)];
742
+ }
711
743
  const NODEJS_COMPAT_DEFAULT_ON_DATE = "2026-08-04";
712
- const SANDBOX_WRANGLER_CONFIG_PATH = `${SERVER_OUTPUT_DIR}/wrangler.json`;
713
- function stripRedundantNodejsCompatFlag() {
744
+ const NITRO_WRANGLER_CONFIG = "wrangler.json";
745
+ function stripRedundantNodejsCompatFlag(dirs) {
714
746
  let root = process.cwd();
715
747
  return {
716
748
  name: "lovable-strip-redundant-nodejs-compat",
@@ -722,13 +754,18 @@ function stripRedundantNodejsCompatFlag() {
722
754
  order: "post",
723
755
  handler: async () => {
724
756
  const { readFile, writeFile } = await import("node:fs/promises");
725
- const configPath = join(root, SANDBOX_WRANGLER_CONFIG_PATH);
757
+ let configPath;
726
758
  let parsed;
727
- try {
728
- parsed = JSON.parse(await readFile(configPath, "utf8"));
729
- } catch {
730
- return;
759
+ for (const dir of nitroEmitDirs(dirs)) {
760
+ configPath = join(resolve(root, dir), NITRO_WRANGLER_CONFIG);
761
+ try {
762
+ parsed = JSON.parse(await readFile(configPath, "utf8"));
763
+ break;
764
+ } catch {
765
+ configPath = void 0;
766
+ }
731
767
  }
768
+ if (configPath === void 0) return;
732
769
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return;
733
770
  const config = parsed;
734
771
  if (typeof config.compatibility_date !== "string") return;
@@ -747,7 +784,6 @@ function stripRedundantNodejsCompatFlag() {
747
784
  const NITRO_SERVER_ENTRY = "index.mjs";
748
785
  const NITRO_DEFAULT_OUTPUT_DIR = ".output";
749
786
  const VITE_DEFAULT_OUTPUT_DIR = "dist";
750
- const NITRO_WRANGLER_CONFIG = "wrangler.json";
751
787
  const DEFAULT_SERVER_ENTRY_NAME = "server";
752
788
  const PRERENDER_PREVIEW_HOST = "127.0.0.1";
753
789
  const TSS_PRERENDERING_ENV = "TSS_PRERENDERING";
@@ -835,8 +871,7 @@ function prerenderPreviewShim(state, dirs) {
835
871
  return false;
836
872
  }
837
873
  };
838
- const found = [dirs.nitroOutput.serverDir, ...dirs.entryDirs].filter((dir) => !!dir);
839
- const candidates = [...new Set(found)];
874
+ const candidates = nitroEmitDirs(dirs);
840
875
  let entryDir;
841
876
  for (const candidate of candidates) {
842
877
  const resolved = resolve(root, candidate);
@@ -1130,13 +1165,13 @@ function defineConfig(configOrOptions = {}) {
1130
1165
  };
1131
1166
  }
1132
1167
  } else if (!nitroOpts.preset && !await nitroSupportsDefaultPreset()) logWarning("The installed `nitro` predates the `defaultPreset` option (3.0.260603-beta), so the Cloudflare fallback is ignored and a zero-config build may target Node instead. Upgrade nitro to >=3.0.260603-beta, or set an explicit `nitro: { preset: \"cloudflare-module\" }`.");
1133
- const shimDirs = prerenderEnabled ? prerenderShimDirs(options.vite, nitroOpts) : void 0;
1168
+ const nitroDirs = prerenderEnabled || isSandbox ? prerenderShimDirs(options.vite, nitroOpts) : void 0;
1134
1169
  internalPlugins.push(nitro(nitroOpts));
1135
- if (shimDirs) {
1170
+ if (prerenderEnabled && nitroDirs) {
1136
1171
  const shimState = {};
1137
- internalPlugins.push(prerenderPreviewShim(shimState, shimDirs), prerenderPreviewShimCleanup(shimState));
1172
+ internalPlugins.push(prerenderPreviewShim(shimState, nitroDirs), prerenderPreviewShimCleanup(shimState));
1138
1173
  }
1139
- if (isSandbox) internalPlugins.push(stripRedundantNodejsCompatFlag());
1174
+ if (isSandbox) internalPlugins.push(stripRedundantNodejsCompatFlag(nitroDirs));
1140
1175
  }
1141
1176
  }
1142
1177
  const viteReact = (await import("@vitejs/plugin-react")).default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovable.dev/vite-tanstack-config",
3
- "version": "2.19.4",
3
+ "version": "2.20.0",
4
4
  "description": "Vite config wrapper for Lovable TanStack Start projects",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",