fix: a popup save no longer undoes a network switch the background saved during it (closes #641)
The popup's saveState() and the background's updateState() each read the stored record, change it and write it back, and each was ordered only within its own context, so a write by one could land between the other's read and write and be lost. Both now hold the browser's lock (navigator.locks, shared by every page and the background except a page in a Firefox private window) from the read to the write, through withLock() in src/shared/browserApi.js; the recovery screen's reset takes it too. The lock also orders a page's own saves, so both per-context queues are gone. The unit tests get a small lock from a Jest setup file. Model: opus-5-5
This commit is contained in:
@@ -1389,6 +1389,19 @@ carries a `schemaVersion` — `STATE_SCHEMA_VERSION` in
|
||||
`saveState()` and the background's `updateState()` both do, so whichever context
|
||||
wrote last, the record says which build's shape it is in.
|
||||
|
||||
Each write reads the record, changes it and writes it back, holding a lock from
|
||||
the read to the write: the browser's own (`navigator.locks`), taken through
|
||||
`withLock()` in `src/shared/browserApi.js`. Every page of the extension and its
|
||||
background share it, except a page in a Firefox private window, which Firefox
|
||||
gives locks of its own (see https://git.eeqj.de/sneak/AutistMask/issues/646).
|
||||
The popup's `saveState()`, the background's `updateState()` and the
|
||||
StateRecovery reset all take it, so among the pages and the background that
|
||||
share it, no write lands between another write's read and its write, where it
|
||||
would be lost. Chrome has it from version 69, older than any Chrome that runs a
|
||||
Manifest V3 extension, in pages and in the service worker; Firefox from version
|
||||
96, older than the 115 `manifest/firefox.json` declares. Where it is missing, a
|
||||
write fails rather than going ahead without it.
|
||||
|
||||
Version 1 is the shape that shipped before versions existed, so a stored record
|
||||
with no `schemaVersion` is version 1 rather than a defect: it loads normally and
|
||||
is migrated in place by being stamped on the first write. An upgrade never shows
|
||||
|
||||
Reference in New Issue
Block a user