import { afterEach, describe, expect, it, vi } from "vitest"; import { createDefaultIndexedDbOwnerLivenessProvider } from "./indexeddb-binary-asset-liveness"; afterEach(() => vi.unstubAllGlobals()); describe("IndexedDB owner liveness provider", () => { it("uses fail-fast Web Locks only when request and query are available", async () => { const held = new Set(); const requests: { name: string; options?: { ifAvailable: true } }[] = []; const locks = { async query() { return { held: [...held].map((name) => ({ name })) }; }, async request( name: string, optionsOrCallback: | { ifAvailable: true } | ((lock: { name: string } | null) => Promise), optionalCallback?: ( lock: { name: string } | null, ) => Promise, ) { const options = typeof optionsOrCallback === "function" ? undefined : optionsOrCallback; const callback = typeof optionsOrCallback === "function" ? optionsOrCallback : optionalCallback!; requests.push({ name, options }); if (held.has(name)) { if (options?.ifAvailable) return callback(null); throw new Error("Blocking lock request would wait"); } held.add(name); try { return await callback({ name }); } finally { held.delete(name); } }, }; vi.stubGlobal("navigator", { locks }); const provider = createDefaultIndexedDbOwnerLivenessProvider(); const lease = await provider.acquire("database", "owner"); const ownerRequest = requests.find(({ name }) => name.endsWith(":owner")); await expect(provider.query("database")).resolves.toEqual( new Set(["owner"]), ); await expect(provider.acquire("database", "owner")).rejects.toThrow( /owner.*collision|already held/u, ); await lease.release(); expect(ownerRequest?.options).toEqual({ ifAvailable: true }); await expect(provider.query("database")).resolves.toEqual(new Set()); const request = vi.fn(); vi.stubGlobal("navigator", { locks: { request } }); const unavailable = createDefaultIndexedDbOwnerLivenessProvider(); const unavailableLease = await unavailable.acquire("database", "owner"); await expect(unavailable.query("database")).resolves.toBeNull(); expect(request).not.toHaveBeenCalled(); await unavailableLease.release(); }); });