diff options
Diffstat (limited to 'src/nwc-lock.js')
| -rw-r--r-- | src/nwc-lock.js | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/src/nwc-lock.js b/src/nwc-lock.js index c4fec08..bd8586a 100644 --- a/src/nwc-lock.js +++ b/src/nwc-lock.js @@ -7,6 +7,24 @@ // the sats had gone. Web Locks are shared by every same-origin context, so // the first to claim a request's lock answers it and the rest stay quiet. // Where locks are unavailable (tests, ancient engines) the caller just runs. +// The worker's wallet work, one push at a time. Every push handler builds +// its own manager over the one shared mirror, and two of them driving the +// same send at once would sign it twice (a client's retry lands seconds +// after its lookup). A waiting push keeps its waitUntil and reads the mirror +// fresh once it gets the lock. +// The Web Lock alone didn't hold on iOS (two workers at once, neither +// waited), so the lease in the worker's store (nwc-bg.js) is taken inside it. +export async function withWorkLock(fn, { lease = null } = {}) { + const locks = typeof navigator !== 'undefined' && navigator.locks; + const run = async () => { + if (!lease) return fn(0); + const l = await lease(); + try { return await fn(l.waited); } finally { await l.release(); } + }; + if (!locks) return run(); + return locks.request('nwc-bg-work', run); +} + export async function withRequestLock(id, fn, held = () => undefined) { const locks = typeof navigator !== 'undefined' && navigator.locks; if (!locks || !id) return fn(); |
