@lovable.dev/vite-tanstack-config 2.13.0 → 2.14.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/hmr-gate.cjs CHANGED
@@ -18,6 +18,25 @@ function gateStatusHeaders(req) {
18
18
  return headers;
19
19
  }
20
20
  const DEV_SERVER_MODE_EVENT = "lovable:dev-server-mode";
21
+ const BOOT_PROGRESS_EVENT = "lovable:boot-progress";
22
+ const BOOT_PROGRESS_MIN_INTERVAL_MS = 500;
23
+ function firstBuildError(error) {
24
+ if (error == null || typeof error !== "object") return null;
25
+ const errors = error.errors;
26
+ const e = Array.isArray(errors) && errors.length > 0 ? errors[0] : error;
27
+ const message = typeof e.message === "string" ? e.message : "Build failed";
28
+ let file = null;
29
+ if (typeof e.loc?.file === "string") file = e.loc.file;
30
+ else if (typeof e.id === "string") file = e.id;
31
+ return {
32
+ message,
33
+ file,
34
+ line: typeof e.loc?.line === "number" ? e.loc.line : null
35
+ };
36
+ }
37
+ function hookEnvironmentName(context) {
38
+ return context.environment?.name ?? "shared";
39
+ }
21
40
  const EDIT_FREE_RELOAD_MARKER = "edit-free";
22
41
  /** Host-controlled default for `fullReload`; an explicit option still wins. */
23
42
  const FULL_RELOAD_ENV_VAR = "LOVABLE_HMR_FULL_RELOAD";
@@ -33,6 +52,57 @@ function hmrGatePlugin(options = {}) {
33
52
  const lastFlushedHashes = /* @__PURE__ */ new Map();
34
53
  let originalEmit = null;
35
54
  let server = null;
55
+ let generation = null;
56
+ const transformsByEnv = /* @__PURE__ */ new Map();
57
+ const buildErrorsByEnv = /* @__PURE__ */ new Map();
58
+ let bootProgressSentAt = 0;
59
+ let bootProgressTimer = null;
60
+ let lastBootProgressKey = "";
61
+ function bootProgressData() {
62
+ const now = Date.now();
63
+ const idle = (name) => {
64
+ const at = transformsByEnv.get(name)?.lastTransformAt;
65
+ return at === void 0 ? null : now - at;
66
+ };
67
+ return {
68
+ ssrModules: transformsByEnv.get("ssr")?.ids.size ?? 0,
69
+ clientModules: transformsByEnv.get("client")?.ids.size ?? 0,
70
+ ssrIdleMs: idle("ssr"),
71
+ clientIdleMs: idle("client"),
72
+ buildError: buildErrorsByEnv.values().next().value ?? null
73
+ };
74
+ }
75
+ function bootProgressKey(data) {
76
+ const error = data.buildError;
77
+ const errorKey = error ? `${error.message}:${error.file ?? ""}:${error.line ?? ""}` : "";
78
+ return `${data.ssrModules}:${data.clientModules}:${errorKey}`;
79
+ }
80
+ function broadcastBootProgress() {
81
+ const data = bootProgressData();
82
+ const key = bootProgressKey(data);
83
+ if (key === lastBootProgressKey) return;
84
+ lastBootProgressKey = key;
85
+ bootProgressSentAt = Date.now();
86
+ server?.ws.send({
87
+ type: "custom",
88
+ event: BOOT_PROGRESS_EVENT,
89
+ data
90
+ });
91
+ }
92
+ function scheduleBootProgress() {
93
+ if (bootProgressTimer !== null) return;
94
+ const waitMs = bootProgressSentAt + BOOT_PROGRESS_MIN_INTERVAL_MS - Date.now();
95
+ if (waitMs <= 0) {
96
+ broadcastBootProgress();
97
+ return;
98
+ }
99
+ bootProgressTimer = setTimeout(() => {
100
+ bootProgressTimer = null;
101
+ broadcastBootProgress();
102
+ }, waitMs);
103
+ bootProgressTimer.unref?.();
104
+ }
105
+ let classicFailOpenTimer = null;
36
106
  let transportMode = false;
37
107
  let swallowedUpdates = 0;
38
108
  let heldReload = false;
@@ -106,15 +176,55 @@ function hmrGatePlugin(options = {}) {
106
176
  apply: "serve",
107
177
  configResolved(config) {
108
178
  transportMode = config.experimental?.bundledDev === true;
179
+ const rawGeneration = process.env.LOVABLE_SPAWN_GENERATION;
180
+ const parsed = rawGeneration === void 0 || rawGeneration === "" ? null : Number(rawGeneration);
181
+ generation = parsed !== null && Number.isSafeInteger(parsed) ? parsed : null;
182
+ },
183
+ transform(_code, id, options) {
184
+ const name = this.environment?.name ?? (options?.ssr === true ? "ssr" : "client");
185
+ let progress = transformsByEnv.get(name);
186
+ if (!progress) {
187
+ progress = {
188
+ ids: /* @__PURE__ */ new Set(),
189
+ lastTransformAt: 0
190
+ };
191
+ transformsByEnv.set(name, progress);
192
+ }
193
+ progress.ids.add(id);
194
+ progress.lastTransformAt = Date.now();
195
+ scheduleBootProgress();
196
+ return null;
197
+ },
198
+ buildStart() {
199
+ buildErrorsByEnv.delete(hookEnvironmentName(this));
200
+ scheduleBootProgress();
201
+ },
202
+ buildEnd(error) {
203
+ const name = hookEnvironmentName(this);
204
+ const parsed = error == null ? null : firstBuildError(error);
205
+ if (parsed === null) buildErrorsByEnv.delete(name);
206
+ else buildErrorsByEnv.set(name, parsed);
207
+ scheduleBootProgress();
109
208
  },
110
209
  configureServer(srv) {
111
210
  server = srv;
211
+ transformsByEnv.clear();
212
+ buildErrorsByEnv.clear();
213
+ lastBootProgressKey = "";
112
214
  srv.ws.on?.("connection", (socket) => {
113
215
  try {
114
216
  socket.send(JSON.stringify({
115
217
  type: "custom",
116
218
  event: DEV_SERVER_MODE_EVENT,
117
- data: { mode: transportMode ? "bundled" : "classic" }
219
+ data: {
220
+ mode: transportMode ? "bundled" : "classic",
221
+ ...generation !== null ? { generation } : {}
222
+ }
223
+ }));
224
+ socket.send(JSON.stringify({
225
+ type: "custom",
226
+ event: BOOT_PROGRESS_EVENT,
227
+ data: bootProgressData()
118
228
  }));
119
229
  } catch {}
120
230
  });
@@ -239,6 +349,25 @@ function hmrGatePlugin(options = {}) {
239
349
  }
240
350
  const _emit = srv.watcher.emit.bind(srv.watcher);
241
351
  originalEmit = _emit;
352
+ const flushPending = () => {
353
+ if (classicFailOpenTimer !== null) {
354
+ clearTimeout(classicFailOpenTimer);
355
+ classicFailOpenTimer = null;
356
+ }
357
+ const entries = Array.from(pending.entries());
358
+ pending.clear();
359
+ for (const [f] of entries) srv.moduleGraph.onFileChange(f);
360
+ if (entries.length > 0) {
361
+ for (const [f, events] of entries) {
362
+ for (const event of events) _emit(event, f);
363
+ const hash = fileContentHash(f);
364
+ if (hash === null) lastFlushedHashes.delete(f);
365
+ else lastFlushedHashes.set(f, hash);
366
+ }
367
+ if (fullReload) srv.ws.send({ type: "full-reload" });
368
+ }
369
+ return entries;
370
+ };
242
371
  srv.watcher.emit = ((event, ...args) => {
243
372
  if (typeof event === "string" && gatedEvents.has(event) && !isPassthrough(args[0])) {
244
373
  const filePath = args[0];
@@ -246,6 +375,10 @@ function hmrGatePlugin(options = {}) {
246
375
  const hash = fileContentHash(filePath);
247
376
  if (hash !== null && hash === lastFlushedHashes.get(filePath)) {
248
377
  pending.delete(filePath);
378
+ if (pending.size === 0 && classicFailOpenTimer !== null) {
379
+ clearTimeout(classicFailOpenTimer);
380
+ classicFailOpenTimer = null;
381
+ }
249
382
  return false;
250
383
  }
251
384
  }
@@ -255,24 +388,20 @@ function hmrGatePlugin(options = {}) {
255
388
  pending.set(filePath, events);
256
389
  }
257
390
  events.add(event);
391
+ if (classicFailOpenTimer === null) {
392
+ classicFailOpenTimer = setTimeout(() => {
393
+ classicFailOpenTimer = null;
394
+ flushPending();
395
+ }, maxHoldMs);
396
+ classicFailOpenTimer.unref?.();
397
+ }
258
398
  return false;
259
399
  }
260
400
  return _emit(event, ...args);
261
401
  });
262
402
  srv.middlewares.use((req, res, next) => {
263
403
  if (req.method !== "POST" || requestPathname(req) !== "/__hmr_flush") return next();
264
- const entries = Array.from(pending.entries());
265
- pending.clear();
266
- for (const [f] of entries) srv.moduleGraph.onFileChange(f);
267
- if (entries.length > 0) {
268
- for (const [f, events] of entries) {
269
- for (const event of events) _emit(event, f);
270
- const hash = fileContentHash(f);
271
- if (hash === null) lastFlushedHashes.delete(f);
272
- else lastFlushedHashes.set(f, hash);
273
- }
274
- if (fullReload) srv.ws.send({ type: "full-reload" });
275
- }
404
+ const entries = flushPending();
276
405
  const files = entries.map(([f]) => f);
277
406
  const body = JSON.stringify({
278
407
  flushed: files,
@@ -309,6 +438,18 @@ function hmrGatePlugin(options = {}) {
309
438
  clearTimeout(reloadFailOpenTimer);
310
439
  reloadFailOpenTimer = null;
311
440
  }
441
+ if (classicFailOpenTimer !== null) {
442
+ clearTimeout(classicFailOpenTimer);
443
+ classicFailOpenTimer = null;
444
+ }
445
+ if (bootProgressTimer !== null) {
446
+ clearTimeout(bootProgressTimer);
447
+ bootProgressTimer = null;
448
+ }
449
+ transformsByEnv.clear();
450
+ buildErrorsByEnv.clear();
451
+ bootProgressSentAt = 0;
452
+ lastBootProgressKey = "";
312
453
  bufferedReloadNeeded.clear();
313
454
  pendingReplay.clear();
314
455
  reloadNeededListener = null;
@@ -324,6 +465,7 @@ function hmrGatePlugin(options = {}) {
324
465
  };
325
466
  }
326
467
  //#endregion
468
+ exports.BOOT_PROGRESS_EVENT = BOOT_PROGRESS_EVENT;
327
469
  exports.DEV_SERVER_MODE_EVENT = DEV_SERVER_MODE_EVENT;
328
470
  exports.FULL_RELOAD_ENV_VAR = FULL_RELOAD_ENV_VAR;
329
471
  exports.hmrGatePlugin = hmrGatePlugin;
@@ -1,6 +1,20 @@
1
1
  import { Plugin } from "vite";
2
2
  //#region src/hmr-gate/index.d.ts
3
3
  declare const DEV_SERVER_MODE_EVENT = "lovable:dev-server-mode";
4
+ declare const BOOT_PROGRESS_EVENT = "lovable:boot-progress";
5
+ interface BootProgressData {
6
+ ssrModules: number;
7
+ clientModules: number;
8
+ /** ms since the newest transform, measured on the server's own clock so the
9
+ browser never differences two machines' timestamps. */
10
+ ssrIdleMs: number | null;
11
+ clientIdleMs: number | null;
12
+ buildError: {
13
+ message: string;
14
+ file: string | null;
15
+ line: number | null;
16
+ } | null;
17
+ }
4
18
  /** Host-controlled default for `fullReload`; an explicit option still wins. */
5
19
  declare const FULL_RELOAD_ENV_VAR = "LOVABLE_HMR_FULL_RELOAD";
6
20
  interface HmrGateOptions {
@@ -10,8 +24,8 @@ interface HmrGateOptions {
10
24
  /** Bundled dev only: ms the gate stays open after a flush so the client's
11
25
  * queued patch fetches drain. Default 1500. */
12
26
  drainMs?: number;
13
- /** Bundled dev only: max ms a patch response is parked before it
14
- * fail-opens. Default 240000. */
27
+ /** Max ms held work survives without a flush before the gate fail-opens
28
+ * (classic self-flushes; bundled dev releases parked patches). Default 240000. */
15
29
  maxHoldMs?: number;
16
30
  /** Bundled dev only: ms after server start during which full-reload frames
17
31
  * (Vite's restart resync) pass through live. Default 5000. */
@@ -24,4 +38,4 @@ interface HmrGateOptions {
24
38
  }
25
39
  declare function hmrGatePlugin(options?: HmrGateOptions): Plugin;
26
40
  //#endregion
27
- export { DEV_SERVER_MODE_EVENT, FULL_RELOAD_ENV_VAR, HmrGateOptions, hmrGatePlugin };
41
+ export { BOOT_PROGRESS_EVENT, BootProgressData, DEV_SERVER_MODE_EVENT, FULL_RELOAD_ENV_VAR, HmrGateOptions, hmrGatePlugin };
@@ -1,6 +1,20 @@
1
1
  import { Plugin } from "vite";
2
2
  //#region src/hmr-gate/index.d.ts
3
3
  declare const DEV_SERVER_MODE_EVENT = "lovable:dev-server-mode";
4
+ declare const BOOT_PROGRESS_EVENT = "lovable:boot-progress";
5
+ interface BootProgressData {
6
+ ssrModules: number;
7
+ clientModules: number;
8
+ /** ms since the newest transform, measured on the server's own clock so the
9
+ browser never differences two machines' timestamps. */
10
+ ssrIdleMs: number | null;
11
+ clientIdleMs: number | null;
12
+ buildError: {
13
+ message: string;
14
+ file: string | null;
15
+ line: number | null;
16
+ } | null;
17
+ }
4
18
  /** Host-controlled default for `fullReload`; an explicit option still wins. */
5
19
  declare const FULL_RELOAD_ENV_VAR = "LOVABLE_HMR_FULL_RELOAD";
6
20
  interface HmrGateOptions {
@@ -10,8 +24,8 @@ interface HmrGateOptions {
10
24
  /** Bundled dev only: ms the gate stays open after a flush so the client's
11
25
  * queued patch fetches drain. Default 1500. */
12
26
  drainMs?: number;
13
- /** Bundled dev only: max ms a patch response is parked before it
14
- * fail-opens. Default 240000. */
27
+ /** Max ms held work survives without a flush before the gate fail-opens
28
+ * (classic self-flushes; bundled dev releases parked patches). Default 240000. */
15
29
  maxHoldMs?: number;
16
30
  /** Bundled dev only: ms after server start during which full-reload frames
17
31
  * (Vite's restart resync) pass through live. Default 5000. */
@@ -24,4 +38,4 @@ interface HmrGateOptions {
24
38
  }
25
39
  declare function hmrGatePlugin(options?: HmrGateOptions): Plugin;
26
40
  //#endregion
27
- export { DEV_SERVER_MODE_EVENT, FULL_RELOAD_ENV_VAR, HmrGateOptions, hmrGatePlugin };
41
+ export { BOOT_PROGRESS_EVENT, BootProgressData, DEV_SERVER_MODE_EVENT, FULL_RELOAD_ENV_VAR, HmrGateOptions, hmrGatePlugin };
package/dist/hmr-gate.js CHANGED
@@ -17,6 +17,25 @@ function gateStatusHeaders(req) {
17
17
  return headers;
18
18
  }
19
19
  const DEV_SERVER_MODE_EVENT = "lovable:dev-server-mode";
20
+ const BOOT_PROGRESS_EVENT = "lovable:boot-progress";
21
+ const BOOT_PROGRESS_MIN_INTERVAL_MS = 500;
22
+ function firstBuildError(error) {
23
+ if (error == null || typeof error !== "object") return null;
24
+ const errors = error.errors;
25
+ const e = Array.isArray(errors) && errors.length > 0 ? errors[0] : error;
26
+ const message = typeof e.message === "string" ? e.message : "Build failed";
27
+ let file = null;
28
+ if (typeof e.loc?.file === "string") file = e.loc.file;
29
+ else if (typeof e.id === "string") file = e.id;
30
+ return {
31
+ message,
32
+ file,
33
+ line: typeof e.loc?.line === "number" ? e.loc.line : null
34
+ };
35
+ }
36
+ function hookEnvironmentName(context) {
37
+ return context.environment?.name ?? "shared";
38
+ }
20
39
  const EDIT_FREE_RELOAD_MARKER = "edit-free";
21
40
  /** Host-controlled default for `fullReload`; an explicit option still wins. */
22
41
  const FULL_RELOAD_ENV_VAR = "LOVABLE_HMR_FULL_RELOAD";
@@ -32,6 +51,57 @@ function hmrGatePlugin(options = {}) {
32
51
  const lastFlushedHashes = /* @__PURE__ */ new Map();
33
52
  let originalEmit = null;
34
53
  let server = null;
54
+ let generation = null;
55
+ const transformsByEnv = /* @__PURE__ */ new Map();
56
+ const buildErrorsByEnv = /* @__PURE__ */ new Map();
57
+ let bootProgressSentAt = 0;
58
+ let bootProgressTimer = null;
59
+ let lastBootProgressKey = "";
60
+ function bootProgressData() {
61
+ const now = Date.now();
62
+ const idle = (name) => {
63
+ const at = transformsByEnv.get(name)?.lastTransformAt;
64
+ return at === void 0 ? null : now - at;
65
+ };
66
+ return {
67
+ ssrModules: transformsByEnv.get("ssr")?.ids.size ?? 0,
68
+ clientModules: transformsByEnv.get("client")?.ids.size ?? 0,
69
+ ssrIdleMs: idle("ssr"),
70
+ clientIdleMs: idle("client"),
71
+ buildError: buildErrorsByEnv.values().next().value ?? null
72
+ };
73
+ }
74
+ function bootProgressKey(data) {
75
+ const error = data.buildError;
76
+ const errorKey = error ? `${error.message}:${error.file ?? ""}:${error.line ?? ""}` : "";
77
+ return `${data.ssrModules}:${data.clientModules}:${errorKey}`;
78
+ }
79
+ function broadcastBootProgress() {
80
+ const data = bootProgressData();
81
+ const key = bootProgressKey(data);
82
+ if (key === lastBootProgressKey) return;
83
+ lastBootProgressKey = key;
84
+ bootProgressSentAt = Date.now();
85
+ server?.ws.send({
86
+ type: "custom",
87
+ event: BOOT_PROGRESS_EVENT,
88
+ data
89
+ });
90
+ }
91
+ function scheduleBootProgress() {
92
+ if (bootProgressTimer !== null) return;
93
+ const waitMs = bootProgressSentAt + BOOT_PROGRESS_MIN_INTERVAL_MS - Date.now();
94
+ if (waitMs <= 0) {
95
+ broadcastBootProgress();
96
+ return;
97
+ }
98
+ bootProgressTimer = setTimeout(() => {
99
+ bootProgressTimer = null;
100
+ broadcastBootProgress();
101
+ }, waitMs);
102
+ bootProgressTimer.unref?.();
103
+ }
104
+ let classicFailOpenTimer = null;
35
105
  let transportMode = false;
36
106
  let swallowedUpdates = 0;
37
107
  let heldReload = false;
@@ -105,15 +175,55 @@ function hmrGatePlugin(options = {}) {
105
175
  apply: "serve",
106
176
  configResolved(config) {
107
177
  transportMode = config.experimental?.bundledDev === true;
178
+ const rawGeneration = process.env.LOVABLE_SPAWN_GENERATION;
179
+ const parsed = rawGeneration === void 0 || rawGeneration === "" ? null : Number(rawGeneration);
180
+ generation = parsed !== null && Number.isSafeInteger(parsed) ? parsed : null;
181
+ },
182
+ transform(_code, id, options) {
183
+ const name = this.environment?.name ?? (options?.ssr === true ? "ssr" : "client");
184
+ let progress = transformsByEnv.get(name);
185
+ if (!progress) {
186
+ progress = {
187
+ ids: /* @__PURE__ */ new Set(),
188
+ lastTransformAt: 0
189
+ };
190
+ transformsByEnv.set(name, progress);
191
+ }
192
+ progress.ids.add(id);
193
+ progress.lastTransformAt = Date.now();
194
+ scheduleBootProgress();
195
+ return null;
196
+ },
197
+ buildStart() {
198
+ buildErrorsByEnv.delete(hookEnvironmentName(this));
199
+ scheduleBootProgress();
200
+ },
201
+ buildEnd(error) {
202
+ const name = hookEnvironmentName(this);
203
+ const parsed = error == null ? null : firstBuildError(error);
204
+ if (parsed === null) buildErrorsByEnv.delete(name);
205
+ else buildErrorsByEnv.set(name, parsed);
206
+ scheduleBootProgress();
108
207
  },
109
208
  configureServer(srv) {
110
209
  server = srv;
210
+ transformsByEnv.clear();
211
+ buildErrorsByEnv.clear();
212
+ lastBootProgressKey = "";
111
213
  srv.ws.on?.("connection", (socket) => {
112
214
  try {
113
215
  socket.send(JSON.stringify({
114
216
  type: "custom",
115
217
  event: DEV_SERVER_MODE_EVENT,
116
- data: { mode: transportMode ? "bundled" : "classic" }
218
+ data: {
219
+ mode: transportMode ? "bundled" : "classic",
220
+ ...generation !== null ? { generation } : {}
221
+ }
222
+ }));
223
+ socket.send(JSON.stringify({
224
+ type: "custom",
225
+ event: BOOT_PROGRESS_EVENT,
226
+ data: bootProgressData()
117
227
  }));
118
228
  } catch {}
119
229
  });
@@ -238,6 +348,25 @@ function hmrGatePlugin(options = {}) {
238
348
  }
239
349
  const _emit = srv.watcher.emit.bind(srv.watcher);
240
350
  originalEmit = _emit;
351
+ const flushPending = () => {
352
+ if (classicFailOpenTimer !== null) {
353
+ clearTimeout(classicFailOpenTimer);
354
+ classicFailOpenTimer = null;
355
+ }
356
+ const entries = Array.from(pending.entries());
357
+ pending.clear();
358
+ for (const [f] of entries) srv.moduleGraph.onFileChange(f);
359
+ if (entries.length > 0) {
360
+ for (const [f, events] of entries) {
361
+ for (const event of events) _emit(event, f);
362
+ const hash = fileContentHash(f);
363
+ if (hash === null) lastFlushedHashes.delete(f);
364
+ else lastFlushedHashes.set(f, hash);
365
+ }
366
+ if (fullReload) srv.ws.send({ type: "full-reload" });
367
+ }
368
+ return entries;
369
+ };
241
370
  srv.watcher.emit = ((event, ...args) => {
242
371
  if (typeof event === "string" && gatedEvents.has(event) && !isPassthrough(args[0])) {
243
372
  const filePath = args[0];
@@ -245,6 +374,10 @@ function hmrGatePlugin(options = {}) {
245
374
  const hash = fileContentHash(filePath);
246
375
  if (hash !== null && hash === lastFlushedHashes.get(filePath)) {
247
376
  pending.delete(filePath);
377
+ if (pending.size === 0 && classicFailOpenTimer !== null) {
378
+ clearTimeout(classicFailOpenTimer);
379
+ classicFailOpenTimer = null;
380
+ }
248
381
  return false;
249
382
  }
250
383
  }
@@ -254,24 +387,20 @@ function hmrGatePlugin(options = {}) {
254
387
  pending.set(filePath, events);
255
388
  }
256
389
  events.add(event);
390
+ if (classicFailOpenTimer === null) {
391
+ classicFailOpenTimer = setTimeout(() => {
392
+ classicFailOpenTimer = null;
393
+ flushPending();
394
+ }, maxHoldMs);
395
+ classicFailOpenTimer.unref?.();
396
+ }
257
397
  return false;
258
398
  }
259
399
  return _emit(event, ...args);
260
400
  });
261
401
  srv.middlewares.use((req, res, next) => {
262
402
  if (req.method !== "POST" || requestPathname(req) !== "/__hmr_flush") return next();
263
- const entries = Array.from(pending.entries());
264
- pending.clear();
265
- for (const [f] of entries) srv.moduleGraph.onFileChange(f);
266
- if (entries.length > 0) {
267
- for (const [f, events] of entries) {
268
- for (const event of events) _emit(event, f);
269
- const hash = fileContentHash(f);
270
- if (hash === null) lastFlushedHashes.delete(f);
271
- else lastFlushedHashes.set(f, hash);
272
- }
273
- if (fullReload) srv.ws.send({ type: "full-reload" });
274
- }
403
+ const entries = flushPending();
275
404
  const files = entries.map(([f]) => f);
276
405
  const body = JSON.stringify({
277
406
  flushed: files,
@@ -308,6 +437,18 @@ function hmrGatePlugin(options = {}) {
308
437
  clearTimeout(reloadFailOpenTimer);
309
438
  reloadFailOpenTimer = null;
310
439
  }
440
+ if (classicFailOpenTimer !== null) {
441
+ clearTimeout(classicFailOpenTimer);
442
+ classicFailOpenTimer = null;
443
+ }
444
+ if (bootProgressTimer !== null) {
445
+ clearTimeout(bootProgressTimer);
446
+ bootProgressTimer = null;
447
+ }
448
+ transformsByEnv.clear();
449
+ buildErrorsByEnv.clear();
450
+ bootProgressSentAt = 0;
451
+ lastBootProgressKey = "";
311
452
  bufferedReloadNeeded.clear();
312
453
  pendingReplay.clear();
313
454
  reloadNeededListener = null;
@@ -323,4 +464,4 @@ function hmrGatePlugin(options = {}) {
323
464
  };
324
465
  }
325
466
  //#endregion
326
- export { DEV_SERVER_MODE_EVENT, FULL_RELOAD_ENV_VAR, hmrGatePlugin };
467
+ export { BOOT_PROGRESS_EVENT, DEV_SERVER_MODE_EVENT, FULL_RELOAD_ENV_VAR, hmrGatePlugin };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovable.dev/vite-tanstack-config",
3
- "version": "2.13.0",
3
+ "version": "2.14.0",
4
4
  "description": "Vite config wrapper for Lovable TanStack Start projects",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",