-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathkeep-alive.js
More file actions
58 lines (52 loc) · 1.74 KB
/
Copy pathkeep-alive.js
File metadata and controls
58 lines (52 loc) · 1.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
* Background keep-alive for the non-persistent background context
* (Firefox MV3 event page / Chrome MV3 service worker).
*
* Long-running operations (sync, push, pull, restore) can exceed the browser's
* ~30s idle lifetime. When that happens the browser terminates the background
* mid-operation: the work is aborted and the popup's pending `sendMessage`
* rejects with "Could not establish connection. Receiving end does not exist."
* (issue #143).
*
* Periodically touching a lightweight extension API resets the idle timer so the
* operation can run to completion. Reference-counted so overlapping callers do
* not stop the timer prematurely.
*/
const browserObj =
typeof browser !== 'undefined' ? browser : typeof chrome !== 'undefined' ? chrome : null;
// Touch interval well under the ~30s idle limit so the timer always resets in time.
const KEEP_ALIVE_INTERVAL_MS = 20000;
let timer = null;
let activeCount = 0;
function touch() {
try {
const result = browserObj?.runtime?.getPlatformInfo?.();
if (result && typeof result.then === 'function') {
result.catch(() => {
/* best-effort keep-alive; ignore failures */
});
}
} catch {
/* best-effort keep-alive; ignore failures */
}
}
/**
* Begin keeping the background alive. Safe to call repeatedly (reference counted).
*/
export function startKeepAlive() {
activeCount += 1;
if (timer || !browserObj?.runtime?.getPlatformInfo) return;
touch();
timer = setInterval(touch, KEEP_ALIVE_INTERVAL_MS);
}
/**
* Release one keep-alive hold; the timer stops once all holds are released.
*/
export function stopKeepAlive() {
if (activeCount > 0) activeCount -= 1;
if (activeCount > 0) return;
if (timer) {
clearInterval(timer);
timer = null;
}
}