@steve31415/baselib 3.48.1 → 3.48.3
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.
|
@@ -17,6 +17,16 @@ export declare const ATTEMPT_KEY = "selfUpdateAttempt";
|
|
|
17
17
|
export declare const LOADED_KEY = "selfUpdateLoaded";
|
|
18
18
|
/** chrome.storage.session: epoch ms until which the extension is busy (an open overlay renews it). */
|
|
19
19
|
export declare const BUSY_LEASE_KEY = "selfUpdateBusyUntil";
|
|
20
|
+
/** chrome.storage.session: epoch ms of the previous check (to notice the machine just woke). */
|
|
21
|
+
export declare const LAST_CHECK_KEY = "selfUpdateLastCheck";
|
|
22
|
+
/**
|
|
23
|
+
* A check that comes more than this long after the previous one follows a
|
|
24
|
+
* sleep (checks run on a 1-minute alarm): it only waits. Chrome fires the
|
|
25
|
+
* overdue alarm the moment the machine wakes, before a page's lease-renewal
|
|
26
|
+
* timer has had its turn, so a lease that lapsed during the sleep must not
|
|
27
|
+
* count as "not busy" yet.
|
|
28
|
+
*/
|
|
29
|
+
export declare const WOKE_GAP_MS: number;
|
|
20
30
|
interface Seen {
|
|
21
31
|
code: string;
|
|
22
32
|
since: number;
|
|
@@ -36,13 +46,25 @@ export declare function codeIdOf(files: Record<string, string>): Promise<string>
|
|
|
36
46
|
*/
|
|
37
47
|
export declare function diskCode(): Promise<string | null>;
|
|
38
48
|
/**
|
|
39
|
-
* Record the code Chrome just loaded. Call from runtime.onInstalled
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
49
|
+
* Record the code Chrome just loaded. Call from runtime.onInstalled ONLY: that
|
|
50
|
+
* is when Chrome registers the worker script afresh from disk (install,
|
|
51
|
+
* chrome.runtime.reload(), a click on reload). Not from runtime.onStartup: a
|
|
52
|
+
* browser restart re-reads an unpacked extension's manifest and content
|
|
53
|
+
* scripts from disk but keeps running the worker script it registered
|
|
54
|
+
* earlier, even when the file on disk changed (measured 2026-11-02: Lurch's
|
|
55
|
+
* card said 2.6 after a restart while its worker still ran 2.5's code). And
|
|
56
|
+
* never on a worker restart after eviction, which also runs the registered
|
|
57
|
+
* script whatever the disk holds now.
|
|
43
58
|
*/
|
|
44
59
|
export declare function recordLoadedCode(): Promise<string>;
|
|
45
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* The code this extension runs: the record from its last load. 'unverified'
|
|
62
|
+
* when there is no record, or when the record predates the manifest Chrome now
|
|
63
|
+
* shows (a browser restart picked up a new manifest while the worker may still
|
|
64
|
+
* be the old script) — never re-read from disk, which would label an old
|
|
65
|
+
* worker as the new code. 'unverified' differs from every deployed id, so the
|
|
66
|
+
* extension reloads itself into the deployed code once it is on disk.
|
|
67
|
+
*/
|
|
46
68
|
export declare function loadedCode(): Promise<string>;
|
|
47
69
|
/** Mark the extension busy for BUSY_LEASE_MS (an open overlay calls this through the worker every ~10 s). */
|
|
48
70
|
export declare function extendBusyLease(now?: number): Promise<void>;
|
|
@@ -65,10 +87,12 @@ export declare function decideUpdate(input: {
|
|
|
65
87
|
/**
|
|
66
88
|
* Check and reload when the rules allow. `shipped`: the code the server last
|
|
67
89
|
* said it deployed (null when unknown). `busy`: the extension's own work in
|
|
68
|
-
* flight
|
|
90
|
+
* flight — pass a function, so it is read at the moment of the reload rather
|
|
91
|
+
* than before the disk checks; the busy lease and open extension pages are
|
|
92
|
+
* checked here too. The first check after a sleep only waits (WOKE_GAP_MS).
|
|
69
93
|
*/
|
|
70
94
|
export declare function maybeSelfUpdate(options: {
|
|
71
|
-
busy: boolean;
|
|
95
|
+
busy: boolean | (() => boolean);
|
|
72
96
|
shipped: string | null | undefined;
|
|
73
97
|
log?: (message: string) => void;
|
|
74
98
|
}): Promise<UpdateAction | 'busy'>;
|
|
@@ -35,6 +35,16 @@ export const ATTEMPT_KEY = 'selfUpdateAttempt';
|
|
|
35
35
|
export const LOADED_KEY = 'selfUpdateLoaded';
|
|
36
36
|
/** chrome.storage.session: epoch ms until which the extension is busy (an open overlay renews it). */
|
|
37
37
|
export const BUSY_LEASE_KEY = 'selfUpdateBusyUntil';
|
|
38
|
+
/** chrome.storage.session: epoch ms of the previous check (to notice the machine just woke). */
|
|
39
|
+
export const LAST_CHECK_KEY = 'selfUpdateLastCheck';
|
|
40
|
+
/**
|
|
41
|
+
* A check that comes more than this long after the previous one follows a
|
|
42
|
+
* sleep (checks run on a 1-minute alarm): it only waits. Chrome fires the
|
|
43
|
+
* overdue alarm the moment the machine wakes, before a page's lease-renewal
|
|
44
|
+
* timer has had its turn, so a lease that lapsed during the sleep must not
|
|
45
|
+
* count as "not busy" yet.
|
|
46
|
+
*/
|
|
47
|
+
export const WOKE_GAP_MS = 2 * 60 * 1000;
|
|
38
48
|
function hex(bytes) {
|
|
39
49
|
return Array.from(new Uint8Array(bytes), (b) => b.toString(16).padStart(2, '0')).join('');
|
|
40
50
|
}
|
|
@@ -95,10 +105,15 @@ export async function diskCode() {
|
|
|
95
105
|
return id;
|
|
96
106
|
}
|
|
97
107
|
/**
|
|
98
|
-
* Record the code Chrome just loaded. Call from runtime.onInstalled
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
108
|
+
* Record the code Chrome just loaded. Call from runtime.onInstalled ONLY: that
|
|
109
|
+
* is when Chrome registers the worker script afresh from disk (install,
|
|
110
|
+
* chrome.runtime.reload(), a click on reload). Not from runtime.onStartup: a
|
|
111
|
+
* browser restart re-reads an unpacked extension's manifest and content
|
|
112
|
+
* scripts from disk but keeps running the worker script it registered
|
|
113
|
+
* earlier, even when the file on disk changed (measured 2026-11-02: Lurch's
|
|
114
|
+
* card said 2.6 after a restart while its worker still ran 2.5's code). And
|
|
115
|
+
* never on a worker restart after eviction, which also runs the registered
|
|
116
|
+
* script whatever the disk holds now.
|
|
102
117
|
*/
|
|
103
118
|
export async function recordLoadedCode() {
|
|
104
119
|
const code = (await diskCode()) ?? 'unverified';
|
|
@@ -106,13 +121,20 @@ export async function recordLoadedCode() {
|
|
|
106
121
|
await chrome.storage.local.set({ [LOADED_KEY]: record });
|
|
107
122
|
return code;
|
|
108
123
|
}
|
|
109
|
-
/**
|
|
124
|
+
/**
|
|
125
|
+
* The code this extension runs: the record from its last load. 'unverified'
|
|
126
|
+
* when there is no record, or when the record predates the manifest Chrome now
|
|
127
|
+
* shows (a browser restart picked up a new manifest while the worker may still
|
|
128
|
+
* be the old script) — never re-read from disk, which would label an old
|
|
129
|
+
* worker as the new code. 'unverified' differs from every deployed id, so the
|
|
130
|
+
* extension reloads itself into the deployed code once it is on disk.
|
|
131
|
+
*/
|
|
110
132
|
export async function loadedCode() {
|
|
111
133
|
const { [LOADED_KEY]: stored } = await chrome.storage.local.get(LOADED_KEY);
|
|
112
134
|
const record = stored;
|
|
113
135
|
if (record && typeof record.code === 'string' && record.version === chrome.runtime.getManifest().version)
|
|
114
136
|
return record.code;
|
|
115
|
-
return
|
|
137
|
+
return 'unverified';
|
|
116
138
|
}
|
|
117
139
|
/** Mark the extension busy for BUSY_LEASE_MS (an open overlay calls this through the worker every ~10 s). */
|
|
118
140
|
export async function extendBusyLease(now = Date.now()) {
|
|
@@ -149,9 +171,15 @@ export function decideUpdate(input) {
|
|
|
149
171
|
/**
|
|
150
172
|
* Check and reload when the rules allow. `shipped`: the code the server last
|
|
151
173
|
* said it deployed (null when unknown). `busy`: the extension's own work in
|
|
152
|
-
* flight
|
|
174
|
+
* flight — pass a function, so it is read at the moment of the reload rather
|
|
175
|
+
* than before the disk checks; the busy lease and open extension pages are
|
|
176
|
+
* checked here too. The first check after a sleep only waits (WOKE_GAP_MS).
|
|
153
177
|
*/
|
|
154
178
|
export async function maybeSelfUpdate(options) {
|
|
179
|
+
const { [LAST_CHECK_KEY]: lastCheck } = await chrome.storage.session.get(LAST_CHECK_KEY);
|
|
180
|
+
const started = Date.now();
|
|
181
|
+
await chrome.storage.session.set({ [LAST_CHECK_KEY]: started });
|
|
182
|
+
const justWoke = typeof lastCheck === 'number' && started - lastCheck > WOKE_GAP_MS;
|
|
155
183
|
const loaded = await loadedCode();
|
|
156
184
|
const disk = await diskCode();
|
|
157
185
|
const { [SEEN_KEY]: seen } = await chrome.storage.session.get(SEEN_KEY);
|
|
@@ -169,7 +197,10 @@ export async function maybeSelfUpdate(options) {
|
|
|
169
197
|
if (decision.action !== 'reload' || !decision.seen)
|
|
170
198
|
return decision.action;
|
|
171
199
|
const target = decision.seen.code;
|
|
172
|
-
if (
|
|
200
|
+
if (justWoke)
|
|
201
|
+
return 'wait';
|
|
202
|
+
const busy = typeof options.busy === 'function' ? options.busy() : options.busy;
|
|
203
|
+
if (busy || (await busyLeaseActive(Date.now())) || (await extensionPageOpen()))
|
|
173
204
|
return 'busy';
|
|
174
205
|
options.log?.(`code ${target} is deployed and on disk (running ${loaded}): reloading.`);
|
|
175
206
|
await chrome.storage.local.set({ [ATTEMPT_KEY]: { code: target, at: now } });
|
package/package.json
CHANGED