@tanstack/offline-transactions
Version:
Offline-first transaction capabilities for TanStack DB
1 lines • 3.6 kB
Source Map (JSON)
{"version":3,"file":"WebLocksLeader.cjs","sources":["../../../src/coordination/WebLocksLeader.ts"],"sourcesContent":["import { BaseLeaderElection } from './LeaderElection'\n\nexport class WebLocksLeader extends BaseLeaderElection {\n private lockName: string\n private releaseLock: (() => void) | null = null\n\n constructor(lockName = `offline-executor-leader`) {\n super()\n this.lockName = lockName\n }\n\n async requestLeadership(): Promise<boolean> {\n if (!this.isWebLocksSupported()) {\n return false\n }\n\n if (this.isLeaderState) {\n return true\n }\n\n try {\n // First try to acquire the lock with ifAvailable\n const available = await navigator.locks.request(\n this.lockName,\n {\n mode: `exclusive`,\n ifAvailable: true,\n },\n (lock) => {\n return lock !== null\n },\n )\n\n if (!available) {\n return false\n }\n\n // Set state immediately to prevent duplicate notifications\n // when the async lock acquisition calls notifyLeadershipChange(true).\n // The guard in notifyLeadershipChange checks `isLeaderState !== isLeader`,\n // so setting this to true here prevents the callback from firing again.\n this.isLeaderState = true\n\n // Lock is available, now acquire it for real and hold it\n navigator.locks.request(\n this.lockName,\n {\n mode: `exclusive`,\n },\n async (lock) => {\n if (lock) {\n this.notifyLeadershipChange(true)\n // Hold the lock until released\n return new Promise<void>((resolve) => {\n this.releaseLock = () => {\n this.notifyLeadershipChange(false)\n resolve()\n }\n })\n }\n },\n )\n\n return true\n } catch (error) {\n if (error instanceof Error && error.name === `AbortError`) {\n return false\n }\n console.warn(`Web Locks leadership request failed:`, error)\n return false\n }\n }\n\n releaseLeadership(): void {\n if (this.releaseLock) {\n this.releaseLock()\n this.releaseLock = null\n }\n }\n\n private isWebLocksSupported(): boolean {\n return typeof navigator !== `undefined` && `locks` in navigator\n }\n\n static isSupported(): boolean {\n return typeof navigator !== `undefined` && `locks` in navigator\n }\n}\n"],"names":["BaseLeaderElection"],"mappings":";;;AAEO,MAAM,uBAAuBA,eAAAA,mBAAmB;AAAA,EAIrD,YAAY,WAAW,2BAA2B;AAChD,UAAA;AAHF,SAAQ,cAAmC;AAIzC,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,MAAM,oBAAsC;AAC1C,QAAI,CAAC,KAAK,uBAAuB;AAC/B,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,eAAe;AACtB,aAAO;AAAA,IACT;AAEA,QAAI;AAEF,YAAM,YAAY,MAAM,UAAU,MAAM;AAAA,QACtC,KAAK;AAAA,QACL;AAAA,UACE,MAAM;AAAA,UACN,aAAa;AAAA,QAAA;AAAA,QAEf,CAAC,SAAS;AACR,iBAAO,SAAS;AAAA,QAClB;AAAA,MAAA;AAGF,UAAI,CAAC,WAAW;AACd,eAAO;AAAA,MACT;AAMA,WAAK,gBAAgB;AAGrB,gBAAU,MAAM;AAAA,QACd,KAAK;AAAA,QACL;AAAA,UACE,MAAM;AAAA,QAAA;AAAA,QAER,OAAO,SAAS;AACd,cAAI,MAAM;AACR,iBAAK,uBAAuB,IAAI;AAEhC,mBAAO,IAAI,QAAc,CAAC,YAAY;AACpC,mBAAK,cAAc,MAAM;AACvB,qBAAK,uBAAuB,KAAK;AACjC,wBAAA;AAAA,cACF;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MAAA;AAGF,aAAO;AAAA,IACT,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,SAAS,cAAc;AACzD,eAAO;AAAA,MACT;AACA,cAAQ,KAAK,wCAAwC,KAAK;AAC1D,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,oBAA0B;AACxB,QAAI,KAAK,aAAa;AACpB,WAAK,YAAA;AACL,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEQ,sBAA+B;AACrC,WAAO,OAAO,cAAc,eAAe,WAAW;AAAA,EACxD;AAAA,EAEA,OAAO,cAAuB;AAC5B,WAAO,OAAO,cAAc,eAAe,WAAW;AAAA,EACxD;AACF;;"}