@lovable.dev/vite-tanstack-config 2.13.0 → 2.13.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/hmr-gate.cjs CHANGED
@@ -33,6 +33,7 @@ function hmrGatePlugin(options = {}) {
33
33
  const lastFlushedHashes = /* @__PURE__ */ new Map();
34
34
  let originalEmit = null;
35
35
  let server = null;
36
+ let classicFailOpenTimer = null;
36
37
  let transportMode = false;
37
38
  let swallowedUpdates = 0;
38
39
  let heldReload = false;
@@ -239,6 +240,25 @@ function hmrGatePlugin(options = {}) {
239
240
  }
240
241
  const _emit = srv.watcher.emit.bind(srv.watcher);
241
242
  originalEmit = _emit;
243
+ const flushPending = () => {
244
+ if (classicFailOpenTimer !== null) {
245
+ clearTimeout(classicFailOpenTimer);
246
+ classicFailOpenTimer = null;
247
+ }
248
+ const entries = Array.from(pending.entries());
249
+ pending.clear();
250
+ for (const [f] of entries) srv.moduleGraph.onFileChange(f);
251
+ if (entries.length > 0) {
252
+ for (const [f, events] of entries) {
253
+ for (const event of events) _emit(event, f);
254
+ const hash = fileContentHash(f);
255
+ if (hash === null) lastFlushedHashes.delete(f);
256
+ else lastFlushedHashes.set(f, hash);
257
+ }
258
+ if (fullReload) srv.ws.send({ type: "full-reload" });
259
+ }
260
+ return entries;
261
+ };
242
262
  srv.watcher.emit = ((event, ...args) => {
243
263
  if (typeof event === "string" && gatedEvents.has(event) && !isPassthrough(args[0])) {
244
264
  const filePath = args[0];
@@ -246,6 +266,10 @@ function hmrGatePlugin(options = {}) {
246
266
  const hash = fileContentHash(filePath);
247
267
  if (hash !== null && hash === lastFlushedHashes.get(filePath)) {
248
268
  pending.delete(filePath);
269
+ if (pending.size === 0 && classicFailOpenTimer !== null) {
270
+ clearTimeout(classicFailOpenTimer);
271
+ classicFailOpenTimer = null;
272
+ }
249
273
  return false;
250
274
  }
251
275
  }
@@ -255,24 +279,20 @@ function hmrGatePlugin(options = {}) {
255
279
  pending.set(filePath, events);
256
280
  }
257
281
  events.add(event);
282
+ if (classicFailOpenTimer === null) {
283
+ classicFailOpenTimer = setTimeout(() => {
284
+ classicFailOpenTimer = null;
285
+ flushPending();
286
+ }, maxHoldMs);
287
+ classicFailOpenTimer.unref?.();
288
+ }
258
289
  return false;
259
290
  }
260
291
  return _emit(event, ...args);
261
292
  });
262
293
  srv.middlewares.use((req, res, next) => {
263
294
  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
- }
295
+ const entries = flushPending();
276
296
  const files = entries.map(([f]) => f);
277
297
  const body = JSON.stringify({
278
298
  flushed: files,
@@ -309,6 +329,10 @@ function hmrGatePlugin(options = {}) {
309
329
  clearTimeout(reloadFailOpenTimer);
310
330
  reloadFailOpenTimer = null;
311
331
  }
332
+ if (classicFailOpenTimer !== null) {
333
+ clearTimeout(classicFailOpenTimer);
334
+ classicFailOpenTimer = null;
335
+ }
312
336
  bufferedReloadNeeded.clear();
313
337
  pendingReplay.clear();
314
338
  reloadNeededListener = null;
@@ -10,8 +10,8 @@ interface HmrGateOptions {
10
10
  /** Bundled dev only: ms the gate stays open after a flush so the client's
11
11
  * queued patch fetches drain. Default 1500. */
12
12
  drainMs?: number;
13
- /** Bundled dev only: max ms a patch response is parked before it
14
- * fail-opens. Default 240000. */
13
+ /** Max ms held work survives without a flush before the gate fail-opens
14
+ * (classic self-flushes; bundled dev releases parked patches). Default 240000. */
15
15
  maxHoldMs?: number;
16
16
  /** Bundled dev only: ms after server start during which full-reload frames
17
17
  * (Vite's restart resync) pass through live. Default 5000. */
@@ -10,8 +10,8 @@ interface HmrGateOptions {
10
10
  /** Bundled dev only: ms the gate stays open after a flush so the client's
11
11
  * queued patch fetches drain. Default 1500. */
12
12
  drainMs?: number;
13
- /** Bundled dev only: max ms a patch response is parked before it
14
- * fail-opens. Default 240000. */
13
+ /** Max ms held work survives without a flush before the gate fail-opens
14
+ * (classic self-flushes; bundled dev releases parked patches). Default 240000. */
15
15
  maxHoldMs?: number;
16
16
  /** Bundled dev only: ms after server start during which full-reload frames
17
17
  * (Vite's restart resync) pass through live. Default 5000. */
package/dist/hmr-gate.js CHANGED
@@ -32,6 +32,7 @@ function hmrGatePlugin(options = {}) {
32
32
  const lastFlushedHashes = /* @__PURE__ */ new Map();
33
33
  let originalEmit = null;
34
34
  let server = null;
35
+ let classicFailOpenTimer = null;
35
36
  let transportMode = false;
36
37
  let swallowedUpdates = 0;
37
38
  let heldReload = false;
@@ -238,6 +239,25 @@ function hmrGatePlugin(options = {}) {
238
239
  }
239
240
  const _emit = srv.watcher.emit.bind(srv.watcher);
240
241
  originalEmit = _emit;
242
+ const flushPending = () => {
243
+ if (classicFailOpenTimer !== null) {
244
+ clearTimeout(classicFailOpenTimer);
245
+ classicFailOpenTimer = null;
246
+ }
247
+ const entries = Array.from(pending.entries());
248
+ pending.clear();
249
+ for (const [f] of entries) srv.moduleGraph.onFileChange(f);
250
+ if (entries.length > 0) {
251
+ for (const [f, events] of entries) {
252
+ for (const event of events) _emit(event, f);
253
+ const hash = fileContentHash(f);
254
+ if (hash === null) lastFlushedHashes.delete(f);
255
+ else lastFlushedHashes.set(f, hash);
256
+ }
257
+ if (fullReload) srv.ws.send({ type: "full-reload" });
258
+ }
259
+ return entries;
260
+ };
241
261
  srv.watcher.emit = ((event, ...args) => {
242
262
  if (typeof event === "string" && gatedEvents.has(event) && !isPassthrough(args[0])) {
243
263
  const filePath = args[0];
@@ -245,6 +265,10 @@ function hmrGatePlugin(options = {}) {
245
265
  const hash = fileContentHash(filePath);
246
266
  if (hash !== null && hash === lastFlushedHashes.get(filePath)) {
247
267
  pending.delete(filePath);
268
+ if (pending.size === 0 && classicFailOpenTimer !== null) {
269
+ clearTimeout(classicFailOpenTimer);
270
+ classicFailOpenTimer = null;
271
+ }
248
272
  return false;
249
273
  }
250
274
  }
@@ -254,24 +278,20 @@ function hmrGatePlugin(options = {}) {
254
278
  pending.set(filePath, events);
255
279
  }
256
280
  events.add(event);
281
+ if (classicFailOpenTimer === null) {
282
+ classicFailOpenTimer = setTimeout(() => {
283
+ classicFailOpenTimer = null;
284
+ flushPending();
285
+ }, maxHoldMs);
286
+ classicFailOpenTimer.unref?.();
287
+ }
257
288
  return false;
258
289
  }
259
290
  return _emit(event, ...args);
260
291
  });
261
292
  srv.middlewares.use((req, res, next) => {
262
293
  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
- }
294
+ const entries = flushPending();
275
295
  const files = entries.map(([f]) => f);
276
296
  const body = JSON.stringify({
277
297
  flushed: files,
@@ -308,6 +328,10 @@ function hmrGatePlugin(options = {}) {
308
328
  clearTimeout(reloadFailOpenTimer);
309
329
  reloadFailOpenTimer = null;
310
330
  }
331
+ if (classicFailOpenTimer !== null) {
332
+ clearTimeout(classicFailOpenTimer);
333
+ classicFailOpenTimer = null;
334
+ }
311
335
  bufferedReloadNeeded.clear();
312
336
  pendingReplay.clear();
313
337
  reloadNeededListener = null;
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.13.1",
4
4
  "description": "Vite config wrapper for Lovable TanStack Start projects",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",