livedesk 0.1.607 → 0.1.609
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/electron/installer-quit-gate.mjs +183 -0
- package/electron/main.mjs +249 -102
- package/electron/runtime-window-load-owner.mjs +153 -0
- package/electron/update-manager.mjs +762 -144
- package/package.json +1 -1
- package/web/dist/app.webmanifest +1 -1
- package/web/dist/assets/LiveDeskApp-Dr77Bkmu.js +179 -0
- package/web/dist/assets/{icons-JxbtiHLQ.js → icons-tFaWqIIe.js} +1 -1
- package/web/dist/assets/{index-C4QRbhif.js → index-Dzx6WcDO.js} +4 -4
- package/web/dist/assets/{react-hDor0Pi9.js → react-BQos8uGS.js} +1 -1
- package/web/dist/assets/supabase-C7qjtLN3.js +29 -0
- package/web/dist/index.html +3 -3
- package/web/dist/livedesk-build-evidence.json +25 -25
- package/web/dist/sw.js +1 -1
- package/web/dist/assets/LiveDeskApp-Dw86X0VP.js +0 -179
- package/web/dist/assets/supabase-C0Z0FS3K.js +0 -29
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
const DEFAULT_RETRY_DELAY_MS = 1_000;
|
|
2
|
+
|
|
3
|
+
function normalizeDelay(value, fallback = 0) {
|
|
4
|
+
const milliseconds = Number(value);
|
|
5
|
+
return Number.isFinite(milliseconds) && milliseconds >= 0
|
|
6
|
+
? Math.round(milliseconds)
|
|
7
|
+
: fallback;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Owns the one retry timer and one in-flight load attempt for a BrowserWindow.
|
|
12
|
+
* A successfully mounted runtime document is never reloaded by start(). Only a
|
|
13
|
+
* real main-frame failure or renderer termination opens a new generation.
|
|
14
|
+
*/
|
|
15
|
+
export function createRuntimeWindowLoadOwner({
|
|
16
|
+
probeRuntime,
|
|
17
|
+
showRecovery = async () => undefined,
|
|
18
|
+
loadRuntime,
|
|
19
|
+
onLoaded = () => undefined,
|
|
20
|
+
onAttemptError = () => undefined,
|
|
21
|
+
retryDelayMs = DEFAULT_RETRY_DELAY_MS,
|
|
22
|
+
setTimer = setTimeout,
|
|
23
|
+
clearTimer = clearTimeout
|
|
24
|
+
} = {}) {
|
|
25
|
+
if (typeof probeRuntime !== 'function') throw new Error('runtime-window-probe-required');
|
|
26
|
+
if (typeof loadRuntime !== 'function') throw new Error('runtime-window-loader-required');
|
|
27
|
+
|
|
28
|
+
const retryDelay = normalizeDelay(retryDelayMs, DEFAULT_RETRY_DELAY_MS);
|
|
29
|
+
let generation = 1;
|
|
30
|
+
let stopped = false;
|
|
31
|
+
let loaded = false;
|
|
32
|
+
let recoveryVisible = false;
|
|
33
|
+
let timer = null;
|
|
34
|
+
let operation = null;
|
|
35
|
+
let attemptCount = 0;
|
|
36
|
+
let pendingReason = 'created';
|
|
37
|
+
let pendingRetryDelay = retryDelay;
|
|
38
|
+
|
|
39
|
+
const snapshot = () => ({
|
|
40
|
+
generation,
|
|
41
|
+
stopped,
|
|
42
|
+
loaded,
|
|
43
|
+
recoveryVisible,
|
|
44
|
+
retryScheduled: timer !== null,
|
|
45
|
+
attemptPending: operation !== null,
|
|
46
|
+
attemptCount,
|
|
47
|
+
pendingReason
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const reportAttemptError = (error, context) => {
|
|
51
|
+
try {
|
|
52
|
+
onAttemptError(error, context);
|
|
53
|
+
} catch {
|
|
54
|
+
// Diagnostics cannot take ownership from the load recovery path.
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const ensureRecoveryVisible = async context => {
|
|
59
|
+
if (stopped || loaded || recoveryVisible || context.generation !== generation) return;
|
|
60
|
+
try {
|
|
61
|
+
await showRecovery(context);
|
|
62
|
+
if (!stopped && !loaded && context.generation === generation) recoveryVisible = true;
|
|
63
|
+
} catch (error) {
|
|
64
|
+
reportAttemptError(error, { ...context, phase: 'recovery-page' });
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const schedule = (reason = 'retry', delayMs = 0) => {
|
|
69
|
+
if (stopped || loaded || timer !== null || operation !== null) return false;
|
|
70
|
+
pendingReason = String(reason || 'retry');
|
|
71
|
+
const ownerGeneration = generation;
|
|
72
|
+
timer = setTimer(() => {
|
|
73
|
+
timer = null;
|
|
74
|
+
if (stopped || loaded || ownerGeneration !== generation) return;
|
|
75
|
+
const context = {
|
|
76
|
+
generation: ownerGeneration,
|
|
77
|
+
attempt: ++attemptCount,
|
|
78
|
+
reason: pendingReason
|
|
79
|
+
};
|
|
80
|
+
const currentOperation = (async () => {
|
|
81
|
+
const ready = await probeRuntime(context);
|
|
82
|
+
if (stopped || loaded || ownerGeneration !== generation) return;
|
|
83
|
+
if (!ready) {
|
|
84
|
+
await ensureRecoveryVisible({ ...context, phase: 'runtime-wait' });
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
await loadRuntime(context);
|
|
88
|
+
if (stopped || loaded || ownerGeneration !== generation) return;
|
|
89
|
+
loaded = true;
|
|
90
|
+
recoveryVisible = false;
|
|
91
|
+
try {
|
|
92
|
+
onLoaded(context);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
reportAttemptError(error, { ...context, phase: 'loaded-callback' });
|
|
95
|
+
}
|
|
96
|
+
})()
|
|
97
|
+
.catch(async error => {
|
|
98
|
+
if (stopped || loaded || ownerGeneration !== generation) return;
|
|
99
|
+
reportAttemptError(error, { ...context, phase: 'runtime-load' });
|
|
100
|
+
await ensureRecoveryVisible({ ...context, phase: 'runtime-load' });
|
|
101
|
+
})
|
|
102
|
+
.finally(() => {
|
|
103
|
+
if (operation !== currentOperation) return;
|
|
104
|
+
operation = null;
|
|
105
|
+
if (!stopped && !loaded) {
|
|
106
|
+
const delay = pendingRetryDelay;
|
|
107
|
+
pendingRetryDelay = retryDelay;
|
|
108
|
+
schedule(pendingReason || 'retry', delay);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
operation = currentOperation;
|
|
112
|
+
}, normalizeDelay(delayMs));
|
|
113
|
+
timer?.unref?.();
|
|
114
|
+
return true;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const beginNewGeneration = reason => {
|
|
118
|
+
if (stopped) return false;
|
|
119
|
+
generation += 1;
|
|
120
|
+
loaded = false;
|
|
121
|
+
recoveryVisible = false;
|
|
122
|
+
pendingReason = String(reason || 'reload');
|
|
123
|
+
pendingRetryDelay = 0;
|
|
124
|
+
if (timer !== null) {
|
|
125
|
+
clearTimer(timer);
|
|
126
|
+
timer = null;
|
|
127
|
+
}
|
|
128
|
+
schedule(pendingReason, 0);
|
|
129
|
+
return true;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
getStatus: snapshot,
|
|
134
|
+
start(reason = 'start') {
|
|
135
|
+
return schedule(reason, 0);
|
|
136
|
+
},
|
|
137
|
+
noteMainFrameFailure(reason = 'main-frame-failed') {
|
|
138
|
+
return beginNewGeneration(reason);
|
|
139
|
+
},
|
|
140
|
+
noteRendererGone(reason = 'renderer-gone') {
|
|
141
|
+
return beginNewGeneration(reason);
|
|
142
|
+
},
|
|
143
|
+
stop() {
|
|
144
|
+
if (stopped) return;
|
|
145
|
+
stopped = true;
|
|
146
|
+
generation += 1;
|
|
147
|
+
if (timer !== null) {
|
|
148
|
+
clearTimer(timer);
|
|
149
|
+
timer = null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|