saveStateOnce() in src/shared/state.js takes its snapshot when it starts, writes that snapshot, and then sets baseline (what the next save compares against) from the page's state as it is after the write. A change made while that save was waiting on storage ends up in the new baseline but not in what was written, so the next save sees nothing changed and keeps the stored value. The change is lost with no error; the page keeps showing it until the popup is reopened.
Reproduced in a unit test against the real module over tests/support/storageStub.js: save theme dark, and from inside that save's storage read set networkId to mainnet and call saveState(). After both saves, storage holds dark and sepolia while the page's state holds mainnet.
Where it bites:showView() saves on every navigation without waiting, so a Settings switch made just after Settings opens, or just after the popup reopens, can land inside that save and be dropped. The e2e failure in #446 (network back on sepolia after the restore) can come from this as well as from the close that issue describes. Introduced with the per-field merge for #304.
Unverified: wallets, allowedSites, deniedSites and networkEndpoints are compared against the same baseline, so a change to them made while the write is in flight should be dropped the same way.
Done when a change made while an earlier save is still running is stored by the save it queued, with a unit test that makes the change from inside the earlier save.
Model: opus-5-5
`saveStateOnce()` in `src/shared/state.js` takes its snapshot when it starts, writes that snapshot, and then sets `baseline` (what the next save compares against) from the page's state as it is after the write. A change made while that save was waiting on storage ends up in the new baseline but not in what was written, so the next save sees nothing changed and keeps the stored value. The change is lost with no error; the page keeps showing it until the popup is reopened.
**Reproduced** in a unit test against the real module over `tests/support/storageStub.js`: save theme `dark`, and from inside that save's storage read set `networkId` to `mainnet` and call `saveState()`. After both saves, storage holds `dark` and `sepolia` while the page's state holds `mainnet`.
**Where it bites:** `showView()` saves on every navigation without waiting, so a Settings switch made just after Settings opens, or just after the popup reopens, can land inside that save and be dropped. The e2e failure in https://git.eeqj.de/sneak/AutistMask/issues/446 (network back on `sepolia` after the restore) can come from this as well as from the close that issue describes. Introduced with the per-field merge for https://git.eeqj.de/sneak/AutistMask/issues/304.
Unverified: `wallets`, `allowedSites`, `deniedSites` and `networkEndpoints` are compared against the same baseline, so a change to them made while the write is in flight should be dropped the same way.
**Done when** a change made while an earlier save is still running is stored by the save it queued, with a unit test that makes the change from inside the earlier save.
Model: opus-5-5
Fixed in #450: a save now keeps the copy of the page's fields it wrote from as its baseline, so a change made while it runs is stored by the save queued after it.
The unverified claim holds for changes made during the earlier save's write: a wallet added there was dropped from storage, and an origin revoked there stayed allowed. During the read, those four fields were already written; only replaced settings such as networkId were lost there.
Model: opus-5-5
Fixed in https://git.eeqj.de/sneak/AutistMask/pulls/450: a save now keeps the copy of the page's fields it wrote from as its baseline, so a change made while it runs is stored by the save queued after it.
The unverified claim holds for changes made during the earlier save's write: a wallet added there was dropped from storage, and an origin revoked there stayed allowed. During the read, those four fields were already written; only replaced settings such as `networkId` were lost there.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
saveStateOnce()insrc/shared/state.jstakes its snapshot when it starts, writes that snapshot, and then setsbaseline(what the next save compares against) from the page's state as it is after the write. A change made while that save was waiting on storage ends up in the new baseline but not in what was written, so the next save sees nothing changed and keeps the stored value. The change is lost with no error; the page keeps showing it until the popup is reopened.Reproduced in a unit test against the real module over
tests/support/storageStub.js: save themedark, and from inside that save's storage read setnetworkIdtomainnetand callsaveState(). After both saves, storage holdsdarkandsepoliawhile the page's state holdsmainnet.Where it bites:
showView()saves on every navigation without waiting, so a Settings switch made just after Settings opens, or just after the popup reopens, can land inside that save and be dropped. The e2e failure in #446 (network back onsepoliaafter the restore) can come from this as well as from the close that issue describes. Introduced with the per-field merge for #304.Unverified:
wallets,allowedSites,deniedSitesandnetworkEndpointsare compared against the same baseline, so a change to them made while the write is in flight should be dropped the same way.Done when a change made while an earlier save is still running is stored by the save it queued, with a unit test that makes the change from inside the earlier save.
Model: opus-5-5
Fixed in #450: a save now keeps the copy of the page's fields it wrote from as its baseline, so a change made while it runs is stored by the save queued after it.
The unverified claim holds for changes made during the earlier save's write: a wallet added there was dropped from storage, and an origin revoked there stayed allowed. During the read, those four fields were already written; only replaced settings such as
networkIdwere lost there.Model: opus-5-5