@lovable.dev/vite-tanstack-config 2.14.0 → 2.15.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 +155 -4
- package/dist/hmr-gate.d.cts +12 -1
- package/dist/hmr-gate.d.ts +12 -1
- package/dist/hmr-gate.js +155 -5
- package/package.json +1 -1
package/dist/hmr-gate.cjs
CHANGED
|
@@ -20,6 +20,12 @@ function gateStatusHeaders(req) {
|
|
|
20
20
|
const DEV_SERVER_MODE_EVENT = "lovable:dev-server-mode";
|
|
21
21
|
const BOOT_PROGRESS_EVENT = "lovable:boot-progress";
|
|
22
22
|
const BOOT_PROGRESS_MIN_INTERVAL_MS = 500;
|
|
23
|
+
const UPDATE_PROGRESS_EVENT = "lovable:update-progress";
|
|
24
|
+
const UPDATE_PROGRESS_MIN_INTERVAL_MS = 500;
|
|
25
|
+
const UPDATE_SETTLE_MS = 800;
|
|
26
|
+
const UPDATE_FLUSH_SETTLE_MS = 5e3;
|
|
27
|
+
const UPDATE_MIN_MODULES = 10;
|
|
28
|
+
const UPDATE_MIN_DURATION_MS = 1500;
|
|
23
29
|
function firstBuildError(error) {
|
|
24
30
|
if (error == null || typeof error !== "object") return null;
|
|
25
31
|
const errors = error.errors;
|
|
@@ -58,6 +64,12 @@ function hmrGatePlugin(options = {}) {
|
|
|
58
64
|
let bootProgressSentAt = 0;
|
|
59
65
|
let bootProgressTimer = null;
|
|
60
66
|
let lastBootProgressKey = "";
|
|
67
|
+
function currentBuildError() {
|
|
68
|
+
return buildErrorsByEnv.values().next().value ?? null;
|
|
69
|
+
}
|
|
70
|
+
function buildErrorKey(error) {
|
|
71
|
+
return error ? `${error.message}:${error.file ?? ""}:${error.line ?? ""}` : "";
|
|
72
|
+
}
|
|
61
73
|
function bootProgressData() {
|
|
62
74
|
const now = Date.now();
|
|
63
75
|
const idle = (name) => {
|
|
@@ -69,13 +81,11 @@ function hmrGatePlugin(options = {}) {
|
|
|
69
81
|
clientModules: transformsByEnv.get("client")?.ids.size ?? 0,
|
|
70
82
|
ssrIdleMs: idle("ssr"),
|
|
71
83
|
clientIdleMs: idle("client"),
|
|
72
|
-
buildError:
|
|
84
|
+
buildError: currentBuildError()
|
|
73
85
|
};
|
|
74
86
|
}
|
|
75
87
|
function bootProgressKey(data) {
|
|
76
|
-
|
|
77
|
-
const errorKey = error ? `${error.message}:${error.file ?? ""}:${error.line ?? ""}` : "";
|
|
78
|
-
return `${data.ssrModules}:${data.clientModules}:${errorKey}`;
|
|
88
|
+
return `${data.ssrModules}:${data.clientModules}:${buildErrorKey(data.buildError)}`;
|
|
79
89
|
}
|
|
80
90
|
function broadcastBootProgress() {
|
|
81
91
|
const data = bootProgressData();
|
|
@@ -102,6 +112,126 @@ function hmrGatePlugin(options = {}) {
|
|
|
102
112
|
}, waitMs);
|
|
103
113
|
bootProgressTimer.unref?.();
|
|
104
114
|
}
|
|
115
|
+
let updateBatchSeq = 0;
|
|
116
|
+
let updateBatch = null;
|
|
117
|
+
let updateSentAt = 0;
|
|
118
|
+
let lastUpdateKey = "";
|
|
119
|
+
let updateTimer = null;
|
|
120
|
+
let updateSettleTimer = null;
|
|
121
|
+
function updateBatchModuleCount(b) {
|
|
122
|
+
return (b.idsByEnv.get("ssr")?.size ?? 0) + (b.idsByEnv.get("client")?.size ?? 0);
|
|
123
|
+
}
|
|
124
|
+
function updateBatchEarned(b) {
|
|
125
|
+
const total = updateBatchModuleCount(b);
|
|
126
|
+
if (total >= UPDATE_MIN_MODULES) return true;
|
|
127
|
+
return total > 0 && Date.now() - b.openedAt >= UPDATE_MIN_DURATION_MS;
|
|
128
|
+
}
|
|
129
|
+
function broadcastUpdateProgress(opts = {}) {
|
|
130
|
+
const b = updateBatch;
|
|
131
|
+
if (b === null) return;
|
|
132
|
+
const trigger = opts.trigger ?? b.trigger;
|
|
133
|
+
if (trigger !== "restart" && !updateBatchEarned(b)) return;
|
|
134
|
+
const now = Date.now();
|
|
135
|
+
const data = {
|
|
136
|
+
batch: b.id,
|
|
137
|
+
trigger,
|
|
138
|
+
ssrModules: b.idsByEnv.get("ssr")?.size ?? 0,
|
|
139
|
+
clientModules: b.idsByEnv.get("client")?.size ?? 0,
|
|
140
|
+
idleMs: b.lastTransformAt === 0 ? null : now - b.lastTransformAt,
|
|
141
|
+
done: opts.done ?? false,
|
|
142
|
+
buildError: currentBuildError()
|
|
143
|
+
};
|
|
144
|
+
const key = `${data.batch}:${data.trigger}:${data.ssrModules}:${data.clientModules}:${data.done}:${buildErrorKey(data.buildError)}`;
|
|
145
|
+
if (key === lastUpdateKey) return;
|
|
146
|
+
lastUpdateKey = key;
|
|
147
|
+
updateSentAt = now;
|
|
148
|
+
server?.ws.send({
|
|
149
|
+
type: "custom",
|
|
150
|
+
event: UPDATE_PROGRESS_EVENT,
|
|
151
|
+
data
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
function scheduleUpdateProgress() {
|
|
155
|
+
if (updateTimer !== null) return;
|
|
156
|
+
const waitMs = updateSentAt + UPDATE_PROGRESS_MIN_INTERVAL_MS - Date.now();
|
|
157
|
+
if (waitMs <= 0) {
|
|
158
|
+
broadcastUpdateProgress();
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
updateTimer = setTimeout(() => {
|
|
162
|
+
updateTimer = null;
|
|
163
|
+
broadcastUpdateProgress();
|
|
164
|
+
}, waitMs);
|
|
165
|
+
updateTimer.unref?.();
|
|
166
|
+
}
|
|
167
|
+
function clearUpdateTimers() {
|
|
168
|
+
if (updateTimer !== null) {
|
|
169
|
+
clearTimeout(updateTimer);
|
|
170
|
+
updateTimer = null;
|
|
171
|
+
}
|
|
172
|
+
if (updateSettleTimer !== null) {
|
|
173
|
+
clearTimeout(updateSettleTimer);
|
|
174
|
+
updateSettleTimer = null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function armUpdateSettle(delayMs) {
|
|
178
|
+
if (updateSettleTimer !== null) clearTimeout(updateSettleTimer);
|
|
179
|
+
updateSettleTimer = setTimeout(() => {
|
|
180
|
+
updateSettleTimer = null;
|
|
181
|
+
if (updateBatch === null) return;
|
|
182
|
+
if (updateTimer !== null) {
|
|
183
|
+
clearTimeout(updateTimer);
|
|
184
|
+
updateTimer = null;
|
|
185
|
+
}
|
|
186
|
+
broadcastUpdateProgress({ done: true });
|
|
187
|
+
updateBatch = null;
|
|
188
|
+
}, delayMs);
|
|
189
|
+
updateSettleTimer.unref?.();
|
|
190
|
+
}
|
|
191
|
+
function openWatchBatchIfNone() {
|
|
192
|
+
if (updateBatch !== null) return;
|
|
193
|
+
updateBatchSeq++;
|
|
194
|
+
updateBatch = {
|
|
195
|
+
id: updateBatchSeq,
|
|
196
|
+
trigger: "watch",
|
|
197
|
+
openedAt: Date.now(),
|
|
198
|
+
idsByEnv: /* @__PURE__ */ new Map(),
|
|
199
|
+
lastTransformAt: 0
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function noteUpdateFlush() {
|
|
203
|
+
if (updateBatch === null) {
|
|
204
|
+
updateBatchSeq++;
|
|
205
|
+
updateBatch = {
|
|
206
|
+
id: updateBatchSeq,
|
|
207
|
+
trigger: "flush",
|
|
208
|
+
openedAt: Date.now(),
|
|
209
|
+
idsByEnv: /* @__PURE__ */ new Map(),
|
|
210
|
+
lastTransformAt: 0
|
|
211
|
+
};
|
|
212
|
+
} else {
|
|
213
|
+
updateBatch.trigger = "flush";
|
|
214
|
+
if (updateBatch.lastTransformAt === 0) updateBatch.openedAt = Date.now();
|
|
215
|
+
}
|
|
216
|
+
scheduleUpdateProgress();
|
|
217
|
+
armUpdateSettle(updateBatch.lastTransformAt === 0 ? UPDATE_FLUSH_SETTLE_MS : UPDATE_SETTLE_MS);
|
|
218
|
+
}
|
|
219
|
+
function noteUpdateRestart() {
|
|
220
|
+
if (updateBatch === null) noteUpdateFlush();
|
|
221
|
+
clearUpdateTimers();
|
|
222
|
+
broadcastUpdateProgress({
|
|
223
|
+
trigger: "restart",
|
|
224
|
+
done: true
|
|
225
|
+
});
|
|
226
|
+
updateBatch = null;
|
|
227
|
+
}
|
|
228
|
+
function resetUpdateProgress() {
|
|
229
|
+
clearUpdateTimers();
|
|
230
|
+
updateBatch = null;
|
|
231
|
+
updateBatchSeq = 0;
|
|
232
|
+
updateSentAt = 0;
|
|
233
|
+
lastUpdateKey = "";
|
|
234
|
+
}
|
|
105
235
|
let classicFailOpenTimer = null;
|
|
106
236
|
let transportMode = false;
|
|
107
237
|
let swallowedUpdates = 0;
|
|
@@ -146,6 +276,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
146
276
|
const type = frame?.type;
|
|
147
277
|
if (type === "update") {
|
|
148
278
|
swallowedUpdates++;
|
|
279
|
+
openWatchBatchIfNone();
|
|
149
280
|
return;
|
|
150
281
|
}
|
|
151
282
|
if (type === "full-reload") {
|
|
@@ -154,6 +285,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
154
285
|
return original(...args);
|
|
155
286
|
}
|
|
156
287
|
heldReload = true;
|
|
288
|
+
openWatchBatchIfNone();
|
|
157
289
|
return;
|
|
158
290
|
}
|
|
159
291
|
return original(...args);
|
|
@@ -193,6 +325,17 @@ function hmrGatePlugin(options = {}) {
|
|
|
193
325
|
progress.ids.add(id);
|
|
194
326
|
progress.lastTransformAt = Date.now();
|
|
195
327
|
scheduleBootProgress();
|
|
328
|
+
if (updateBatch !== null) {
|
|
329
|
+
let batchIds = updateBatch.idsByEnv.get(name);
|
|
330
|
+
if (!batchIds) {
|
|
331
|
+
batchIds = /* @__PURE__ */ new Set();
|
|
332
|
+
updateBatch.idsByEnv.set(name, batchIds);
|
|
333
|
+
}
|
|
334
|
+
batchIds.add(id);
|
|
335
|
+
updateBatch.lastTransformAt = Date.now();
|
|
336
|
+
scheduleUpdateProgress();
|
|
337
|
+
if (updateBatch.trigger === "flush") armUpdateSettle(UPDATE_SETTLE_MS);
|
|
338
|
+
}
|
|
196
339
|
return null;
|
|
197
340
|
},
|
|
198
341
|
buildStart() {
|
|
@@ -211,6 +354,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
211
354
|
transformsByEnv.clear();
|
|
212
355
|
buildErrorsByEnv.clear();
|
|
213
356
|
lastBootProgressKey = "";
|
|
357
|
+
resetUpdateProgress();
|
|
214
358
|
srv.ws.on?.("connection", (socket) => {
|
|
215
359
|
try {
|
|
216
360
|
socket.send(JSON.stringify({
|
|
@@ -244,6 +388,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
244
388
|
originalOn(event, (payload, client) => {
|
|
245
389
|
if (Date.now() < startupGraceUntil || initialBuildPending()) return listener(payload, client);
|
|
246
390
|
bufferedReloadNeeded.set(client, payload);
|
|
391
|
+
openWatchBatchIfNone();
|
|
247
392
|
if (reloadFailOpenTimer === null) {
|
|
248
393
|
reloadFailOpenTimer = setTimeout(() => {
|
|
249
394
|
reloadFailOpenTimer = null;
|
|
@@ -283,6 +428,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
283
428
|
const broadcastHeld = heldReload;
|
|
284
429
|
heldReload = false;
|
|
285
430
|
const reload = broadcastHeld || bufferedReloadNeeded.size > 0;
|
|
431
|
+
if (released > 0 || updates > 0 || reload) noteUpdateFlush();
|
|
286
432
|
let flushRestarts = false;
|
|
287
433
|
if (reload) {
|
|
288
434
|
const releaseDelayMs = Math.max(released > 0 ? drainMs : 0, priorDrainUntil - Date.now(), 0);
|
|
@@ -304,6 +450,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
304
450
|
restartTimer.unref?.();
|
|
305
451
|
} else if (typeof restart === "function") {
|
|
306
452
|
flushRestarts = true;
|
|
453
|
+
noteUpdateRestart();
|
|
307
454
|
bufferedReloadNeeded.clear();
|
|
308
455
|
pendingReplay.clear();
|
|
309
456
|
restartTimer = setTimeout(() => {
|
|
@@ -354,6 +501,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
354
501
|
clearTimeout(classicFailOpenTimer);
|
|
355
502
|
classicFailOpenTimer = null;
|
|
356
503
|
}
|
|
504
|
+
if (pending.size > 0) noteUpdateFlush();
|
|
357
505
|
const entries = Array.from(pending.entries());
|
|
358
506
|
pending.clear();
|
|
359
507
|
for (const [f] of entries) srv.moduleGraph.onFileChange(f);
|
|
@@ -388,6 +536,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
388
536
|
pending.set(filePath, events);
|
|
389
537
|
}
|
|
390
538
|
events.add(event);
|
|
539
|
+
openWatchBatchIfNone();
|
|
391
540
|
if (classicFailOpenTimer === null) {
|
|
392
541
|
classicFailOpenTimer = setTimeout(() => {
|
|
393
542
|
classicFailOpenTimer = null;
|
|
@@ -450,6 +599,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
450
599
|
buildErrorsByEnv.clear();
|
|
451
600
|
bootProgressSentAt = 0;
|
|
452
601
|
lastBootProgressKey = "";
|
|
602
|
+
resetUpdateProgress();
|
|
453
603
|
bufferedReloadNeeded.clear();
|
|
454
604
|
pendingReplay.clear();
|
|
455
605
|
reloadNeededListener = null;
|
|
@@ -468,4 +618,5 @@ function hmrGatePlugin(options = {}) {
|
|
|
468
618
|
exports.BOOT_PROGRESS_EVENT = BOOT_PROGRESS_EVENT;
|
|
469
619
|
exports.DEV_SERVER_MODE_EVENT = DEV_SERVER_MODE_EVENT;
|
|
470
620
|
exports.FULL_RELOAD_ENV_VAR = FULL_RELOAD_ENV_VAR;
|
|
621
|
+
exports.UPDATE_PROGRESS_EVENT = UPDATE_PROGRESS_EVENT;
|
|
471
622
|
exports.hmrGatePlugin = hmrGatePlugin;
|
package/dist/hmr-gate.d.cts
CHANGED
|
@@ -2,6 +2,17 @@ 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
4
|
declare const BOOT_PROGRESS_EVENT = "lovable:boot-progress";
|
|
5
|
+
declare const UPDATE_PROGRESS_EVENT = "lovable:update-progress";
|
|
6
|
+
type UpdateTrigger = "flush" | "watch" | "restart";
|
|
7
|
+
interface UpdateProgressData {
|
|
8
|
+
batch: number;
|
|
9
|
+
trigger: UpdateTrigger;
|
|
10
|
+
ssrModules: number;
|
|
11
|
+
clientModules: number;
|
|
12
|
+
idleMs: number | null;
|
|
13
|
+
done: boolean;
|
|
14
|
+
buildError: BootProgressData["buildError"];
|
|
15
|
+
}
|
|
5
16
|
interface BootProgressData {
|
|
6
17
|
ssrModules: number;
|
|
7
18
|
clientModules: number;
|
|
@@ -38,4 +49,4 @@ interface HmrGateOptions {
|
|
|
38
49
|
}
|
|
39
50
|
declare function hmrGatePlugin(options?: HmrGateOptions): Plugin;
|
|
40
51
|
//#endregion
|
|
41
|
-
export { BOOT_PROGRESS_EVENT, BootProgressData, DEV_SERVER_MODE_EVENT, FULL_RELOAD_ENV_VAR, HmrGateOptions, hmrGatePlugin };
|
|
52
|
+
export { BOOT_PROGRESS_EVENT, BootProgressData, DEV_SERVER_MODE_EVENT, FULL_RELOAD_ENV_VAR, HmrGateOptions, UPDATE_PROGRESS_EVENT, UpdateProgressData, UpdateTrigger, hmrGatePlugin };
|
package/dist/hmr-gate.d.ts
CHANGED
|
@@ -2,6 +2,17 @@ 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
4
|
declare const BOOT_PROGRESS_EVENT = "lovable:boot-progress";
|
|
5
|
+
declare const UPDATE_PROGRESS_EVENT = "lovable:update-progress";
|
|
6
|
+
type UpdateTrigger = "flush" | "watch" | "restart";
|
|
7
|
+
interface UpdateProgressData {
|
|
8
|
+
batch: number;
|
|
9
|
+
trigger: UpdateTrigger;
|
|
10
|
+
ssrModules: number;
|
|
11
|
+
clientModules: number;
|
|
12
|
+
idleMs: number | null;
|
|
13
|
+
done: boolean;
|
|
14
|
+
buildError: BootProgressData["buildError"];
|
|
15
|
+
}
|
|
5
16
|
interface BootProgressData {
|
|
6
17
|
ssrModules: number;
|
|
7
18
|
clientModules: number;
|
|
@@ -38,4 +49,4 @@ interface HmrGateOptions {
|
|
|
38
49
|
}
|
|
39
50
|
declare function hmrGatePlugin(options?: HmrGateOptions): Plugin;
|
|
40
51
|
//#endregion
|
|
41
|
-
export { BOOT_PROGRESS_EVENT, BootProgressData, DEV_SERVER_MODE_EVENT, FULL_RELOAD_ENV_VAR, HmrGateOptions, hmrGatePlugin };
|
|
52
|
+
export { BOOT_PROGRESS_EVENT, BootProgressData, DEV_SERVER_MODE_EVENT, FULL_RELOAD_ENV_VAR, HmrGateOptions, UPDATE_PROGRESS_EVENT, UpdateProgressData, UpdateTrigger, hmrGatePlugin };
|
package/dist/hmr-gate.js
CHANGED
|
@@ -19,6 +19,12 @@ function gateStatusHeaders(req) {
|
|
|
19
19
|
const DEV_SERVER_MODE_EVENT = "lovable:dev-server-mode";
|
|
20
20
|
const BOOT_PROGRESS_EVENT = "lovable:boot-progress";
|
|
21
21
|
const BOOT_PROGRESS_MIN_INTERVAL_MS = 500;
|
|
22
|
+
const UPDATE_PROGRESS_EVENT = "lovable:update-progress";
|
|
23
|
+
const UPDATE_PROGRESS_MIN_INTERVAL_MS = 500;
|
|
24
|
+
const UPDATE_SETTLE_MS = 800;
|
|
25
|
+
const UPDATE_FLUSH_SETTLE_MS = 5e3;
|
|
26
|
+
const UPDATE_MIN_MODULES = 10;
|
|
27
|
+
const UPDATE_MIN_DURATION_MS = 1500;
|
|
22
28
|
function firstBuildError(error) {
|
|
23
29
|
if (error == null || typeof error !== "object") return null;
|
|
24
30
|
const errors = error.errors;
|
|
@@ -57,6 +63,12 @@ function hmrGatePlugin(options = {}) {
|
|
|
57
63
|
let bootProgressSentAt = 0;
|
|
58
64
|
let bootProgressTimer = null;
|
|
59
65
|
let lastBootProgressKey = "";
|
|
66
|
+
function currentBuildError() {
|
|
67
|
+
return buildErrorsByEnv.values().next().value ?? null;
|
|
68
|
+
}
|
|
69
|
+
function buildErrorKey(error) {
|
|
70
|
+
return error ? `${error.message}:${error.file ?? ""}:${error.line ?? ""}` : "";
|
|
71
|
+
}
|
|
60
72
|
function bootProgressData() {
|
|
61
73
|
const now = Date.now();
|
|
62
74
|
const idle = (name) => {
|
|
@@ -68,13 +80,11 @@ function hmrGatePlugin(options = {}) {
|
|
|
68
80
|
clientModules: transformsByEnv.get("client")?.ids.size ?? 0,
|
|
69
81
|
ssrIdleMs: idle("ssr"),
|
|
70
82
|
clientIdleMs: idle("client"),
|
|
71
|
-
buildError:
|
|
83
|
+
buildError: currentBuildError()
|
|
72
84
|
};
|
|
73
85
|
}
|
|
74
86
|
function bootProgressKey(data) {
|
|
75
|
-
|
|
76
|
-
const errorKey = error ? `${error.message}:${error.file ?? ""}:${error.line ?? ""}` : "";
|
|
77
|
-
return `${data.ssrModules}:${data.clientModules}:${errorKey}`;
|
|
87
|
+
return `${data.ssrModules}:${data.clientModules}:${buildErrorKey(data.buildError)}`;
|
|
78
88
|
}
|
|
79
89
|
function broadcastBootProgress() {
|
|
80
90
|
const data = bootProgressData();
|
|
@@ -101,6 +111,126 @@ function hmrGatePlugin(options = {}) {
|
|
|
101
111
|
}, waitMs);
|
|
102
112
|
bootProgressTimer.unref?.();
|
|
103
113
|
}
|
|
114
|
+
let updateBatchSeq = 0;
|
|
115
|
+
let updateBatch = null;
|
|
116
|
+
let updateSentAt = 0;
|
|
117
|
+
let lastUpdateKey = "";
|
|
118
|
+
let updateTimer = null;
|
|
119
|
+
let updateSettleTimer = null;
|
|
120
|
+
function updateBatchModuleCount(b) {
|
|
121
|
+
return (b.idsByEnv.get("ssr")?.size ?? 0) + (b.idsByEnv.get("client")?.size ?? 0);
|
|
122
|
+
}
|
|
123
|
+
function updateBatchEarned(b) {
|
|
124
|
+
const total = updateBatchModuleCount(b);
|
|
125
|
+
if (total >= UPDATE_MIN_MODULES) return true;
|
|
126
|
+
return total > 0 && Date.now() - b.openedAt >= UPDATE_MIN_DURATION_MS;
|
|
127
|
+
}
|
|
128
|
+
function broadcastUpdateProgress(opts = {}) {
|
|
129
|
+
const b = updateBatch;
|
|
130
|
+
if (b === null) return;
|
|
131
|
+
const trigger = opts.trigger ?? b.trigger;
|
|
132
|
+
if (trigger !== "restart" && !updateBatchEarned(b)) return;
|
|
133
|
+
const now = Date.now();
|
|
134
|
+
const data = {
|
|
135
|
+
batch: b.id,
|
|
136
|
+
trigger,
|
|
137
|
+
ssrModules: b.idsByEnv.get("ssr")?.size ?? 0,
|
|
138
|
+
clientModules: b.idsByEnv.get("client")?.size ?? 0,
|
|
139
|
+
idleMs: b.lastTransformAt === 0 ? null : now - b.lastTransformAt,
|
|
140
|
+
done: opts.done ?? false,
|
|
141
|
+
buildError: currentBuildError()
|
|
142
|
+
};
|
|
143
|
+
const key = `${data.batch}:${data.trigger}:${data.ssrModules}:${data.clientModules}:${data.done}:${buildErrorKey(data.buildError)}`;
|
|
144
|
+
if (key === lastUpdateKey) return;
|
|
145
|
+
lastUpdateKey = key;
|
|
146
|
+
updateSentAt = now;
|
|
147
|
+
server?.ws.send({
|
|
148
|
+
type: "custom",
|
|
149
|
+
event: UPDATE_PROGRESS_EVENT,
|
|
150
|
+
data
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
function scheduleUpdateProgress() {
|
|
154
|
+
if (updateTimer !== null) return;
|
|
155
|
+
const waitMs = updateSentAt + UPDATE_PROGRESS_MIN_INTERVAL_MS - Date.now();
|
|
156
|
+
if (waitMs <= 0) {
|
|
157
|
+
broadcastUpdateProgress();
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
updateTimer = setTimeout(() => {
|
|
161
|
+
updateTimer = null;
|
|
162
|
+
broadcastUpdateProgress();
|
|
163
|
+
}, waitMs);
|
|
164
|
+
updateTimer.unref?.();
|
|
165
|
+
}
|
|
166
|
+
function clearUpdateTimers() {
|
|
167
|
+
if (updateTimer !== null) {
|
|
168
|
+
clearTimeout(updateTimer);
|
|
169
|
+
updateTimer = null;
|
|
170
|
+
}
|
|
171
|
+
if (updateSettleTimer !== null) {
|
|
172
|
+
clearTimeout(updateSettleTimer);
|
|
173
|
+
updateSettleTimer = null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function armUpdateSettle(delayMs) {
|
|
177
|
+
if (updateSettleTimer !== null) clearTimeout(updateSettleTimer);
|
|
178
|
+
updateSettleTimer = setTimeout(() => {
|
|
179
|
+
updateSettleTimer = null;
|
|
180
|
+
if (updateBatch === null) return;
|
|
181
|
+
if (updateTimer !== null) {
|
|
182
|
+
clearTimeout(updateTimer);
|
|
183
|
+
updateTimer = null;
|
|
184
|
+
}
|
|
185
|
+
broadcastUpdateProgress({ done: true });
|
|
186
|
+
updateBatch = null;
|
|
187
|
+
}, delayMs);
|
|
188
|
+
updateSettleTimer.unref?.();
|
|
189
|
+
}
|
|
190
|
+
function openWatchBatchIfNone() {
|
|
191
|
+
if (updateBatch !== null) return;
|
|
192
|
+
updateBatchSeq++;
|
|
193
|
+
updateBatch = {
|
|
194
|
+
id: updateBatchSeq,
|
|
195
|
+
trigger: "watch",
|
|
196
|
+
openedAt: Date.now(),
|
|
197
|
+
idsByEnv: /* @__PURE__ */ new Map(),
|
|
198
|
+
lastTransformAt: 0
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function noteUpdateFlush() {
|
|
202
|
+
if (updateBatch === null) {
|
|
203
|
+
updateBatchSeq++;
|
|
204
|
+
updateBatch = {
|
|
205
|
+
id: updateBatchSeq,
|
|
206
|
+
trigger: "flush",
|
|
207
|
+
openedAt: Date.now(),
|
|
208
|
+
idsByEnv: /* @__PURE__ */ new Map(),
|
|
209
|
+
lastTransformAt: 0
|
|
210
|
+
};
|
|
211
|
+
} else {
|
|
212
|
+
updateBatch.trigger = "flush";
|
|
213
|
+
if (updateBatch.lastTransformAt === 0) updateBatch.openedAt = Date.now();
|
|
214
|
+
}
|
|
215
|
+
scheduleUpdateProgress();
|
|
216
|
+
armUpdateSettle(updateBatch.lastTransformAt === 0 ? UPDATE_FLUSH_SETTLE_MS : UPDATE_SETTLE_MS);
|
|
217
|
+
}
|
|
218
|
+
function noteUpdateRestart() {
|
|
219
|
+
if (updateBatch === null) noteUpdateFlush();
|
|
220
|
+
clearUpdateTimers();
|
|
221
|
+
broadcastUpdateProgress({
|
|
222
|
+
trigger: "restart",
|
|
223
|
+
done: true
|
|
224
|
+
});
|
|
225
|
+
updateBatch = null;
|
|
226
|
+
}
|
|
227
|
+
function resetUpdateProgress() {
|
|
228
|
+
clearUpdateTimers();
|
|
229
|
+
updateBatch = null;
|
|
230
|
+
updateBatchSeq = 0;
|
|
231
|
+
updateSentAt = 0;
|
|
232
|
+
lastUpdateKey = "";
|
|
233
|
+
}
|
|
104
234
|
let classicFailOpenTimer = null;
|
|
105
235
|
let transportMode = false;
|
|
106
236
|
let swallowedUpdates = 0;
|
|
@@ -145,6 +275,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
145
275
|
const type = frame?.type;
|
|
146
276
|
if (type === "update") {
|
|
147
277
|
swallowedUpdates++;
|
|
278
|
+
openWatchBatchIfNone();
|
|
148
279
|
return;
|
|
149
280
|
}
|
|
150
281
|
if (type === "full-reload") {
|
|
@@ -153,6 +284,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
153
284
|
return original(...args);
|
|
154
285
|
}
|
|
155
286
|
heldReload = true;
|
|
287
|
+
openWatchBatchIfNone();
|
|
156
288
|
return;
|
|
157
289
|
}
|
|
158
290
|
return original(...args);
|
|
@@ -192,6 +324,17 @@ function hmrGatePlugin(options = {}) {
|
|
|
192
324
|
progress.ids.add(id);
|
|
193
325
|
progress.lastTransformAt = Date.now();
|
|
194
326
|
scheduleBootProgress();
|
|
327
|
+
if (updateBatch !== null) {
|
|
328
|
+
let batchIds = updateBatch.idsByEnv.get(name);
|
|
329
|
+
if (!batchIds) {
|
|
330
|
+
batchIds = /* @__PURE__ */ new Set();
|
|
331
|
+
updateBatch.idsByEnv.set(name, batchIds);
|
|
332
|
+
}
|
|
333
|
+
batchIds.add(id);
|
|
334
|
+
updateBatch.lastTransformAt = Date.now();
|
|
335
|
+
scheduleUpdateProgress();
|
|
336
|
+
if (updateBatch.trigger === "flush") armUpdateSettle(UPDATE_SETTLE_MS);
|
|
337
|
+
}
|
|
195
338
|
return null;
|
|
196
339
|
},
|
|
197
340
|
buildStart() {
|
|
@@ -210,6 +353,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
210
353
|
transformsByEnv.clear();
|
|
211
354
|
buildErrorsByEnv.clear();
|
|
212
355
|
lastBootProgressKey = "";
|
|
356
|
+
resetUpdateProgress();
|
|
213
357
|
srv.ws.on?.("connection", (socket) => {
|
|
214
358
|
try {
|
|
215
359
|
socket.send(JSON.stringify({
|
|
@@ -243,6 +387,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
243
387
|
originalOn(event, (payload, client) => {
|
|
244
388
|
if (Date.now() < startupGraceUntil || initialBuildPending()) return listener(payload, client);
|
|
245
389
|
bufferedReloadNeeded.set(client, payload);
|
|
390
|
+
openWatchBatchIfNone();
|
|
246
391
|
if (reloadFailOpenTimer === null) {
|
|
247
392
|
reloadFailOpenTimer = setTimeout(() => {
|
|
248
393
|
reloadFailOpenTimer = null;
|
|
@@ -282,6 +427,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
282
427
|
const broadcastHeld = heldReload;
|
|
283
428
|
heldReload = false;
|
|
284
429
|
const reload = broadcastHeld || bufferedReloadNeeded.size > 0;
|
|
430
|
+
if (released > 0 || updates > 0 || reload) noteUpdateFlush();
|
|
285
431
|
let flushRestarts = false;
|
|
286
432
|
if (reload) {
|
|
287
433
|
const releaseDelayMs = Math.max(released > 0 ? drainMs : 0, priorDrainUntil - Date.now(), 0);
|
|
@@ -303,6 +449,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
303
449
|
restartTimer.unref?.();
|
|
304
450
|
} else if (typeof restart === "function") {
|
|
305
451
|
flushRestarts = true;
|
|
452
|
+
noteUpdateRestart();
|
|
306
453
|
bufferedReloadNeeded.clear();
|
|
307
454
|
pendingReplay.clear();
|
|
308
455
|
restartTimer = setTimeout(() => {
|
|
@@ -353,6 +500,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
353
500
|
clearTimeout(classicFailOpenTimer);
|
|
354
501
|
classicFailOpenTimer = null;
|
|
355
502
|
}
|
|
503
|
+
if (pending.size > 0) noteUpdateFlush();
|
|
356
504
|
const entries = Array.from(pending.entries());
|
|
357
505
|
pending.clear();
|
|
358
506
|
for (const [f] of entries) srv.moduleGraph.onFileChange(f);
|
|
@@ -387,6 +535,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
387
535
|
pending.set(filePath, events);
|
|
388
536
|
}
|
|
389
537
|
events.add(event);
|
|
538
|
+
openWatchBatchIfNone();
|
|
390
539
|
if (classicFailOpenTimer === null) {
|
|
391
540
|
classicFailOpenTimer = setTimeout(() => {
|
|
392
541
|
classicFailOpenTimer = null;
|
|
@@ -449,6 +598,7 @@ function hmrGatePlugin(options = {}) {
|
|
|
449
598
|
buildErrorsByEnv.clear();
|
|
450
599
|
bootProgressSentAt = 0;
|
|
451
600
|
lastBootProgressKey = "";
|
|
601
|
+
resetUpdateProgress();
|
|
452
602
|
bufferedReloadNeeded.clear();
|
|
453
603
|
pendingReplay.clear();
|
|
454
604
|
reloadNeededListener = null;
|
|
@@ -464,4 +614,4 @@ function hmrGatePlugin(options = {}) {
|
|
|
464
614
|
};
|
|
465
615
|
}
|
|
466
616
|
//#endregion
|
|
467
|
-
export { BOOT_PROGRESS_EVENT, DEV_SERVER_MODE_EVENT, FULL_RELOAD_ENV_VAR, hmrGatePlugin };
|
|
617
|
+
export { BOOT_PROGRESS_EVENT, DEV_SERVER_MODE_EVENT, FULL_RELOAD_ENV_VAR, UPDATE_PROGRESS_EVENT, hmrGatePlugin };
|