aboutsummaryrefslogtreecommitdiffstats
path: root/src/nwc-lock.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/nwc-lock.js')
-rw-r--r--src/nwc-lock.js18
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();