diff --git a/plugin/src/sync-functions/locks.ts b/plugin/src/sync-functions/locks.ts new file mode 100644 index 0000000..279da85 --- /dev/null +++ b/plugin/src/sync-functions/locks.ts @@ -0,0 +1,39 @@ +import { DocumentId } from "src/database/document-metadata"; + +const locked = new Set(); +const waiters = new Map void>>(); + +export function tryLockDocument(documentId: DocumentId): boolean { + if (locked.has(documentId)) { + return false; + } + + locked.add(documentId); + return true; +} + +export function waitForDocumentLock(documentId: DocumentId): Promise { + if (tryLockDocument(documentId)) { + return Promise.resolve(); + } + + return new Promise((resolve) => { + if (!waiters.has(documentId)) { + waiters.set(documentId, []); + } + + waiters.get(documentId)!.push(resolve); + }); +} + +export function unlockDocument(documentId: DocumentId): void { + if (!locked.has(documentId)) { + throw new Error(`Document ${documentId} is not locked`); + } + + if (waiters.has(documentId)) { + waiters.get(documentId)!.shift()?.(); + } else { + locked.delete(documentId); + } +}