🔒

Web Locks API をもっとシンプルに扱う ― `disposable-lock` を公開しました

に公開

ブラウザが提供する Web Locks API は、タブ間や非同期処理間でリソースの競合を避ける便利な仕組みですが、
コールバックベースで扱いづらい という課題があります。

そこで、Web Locks API をより現代的に使えるようにした軽量な TypeScript ライブラリ
disposable-lock を公開しました。


🚀 disposable-lock とは?

Web Locks API をシンプルに扱うための、依存ゼロの TypeScript ライブラリ
Promise ベース & await using による自動解放に対応

  • 🧩 依存なし・Pure TypeScript
  • 🔁 Promise ベースのロック取得 / 解放
  • 🪄 await using 対応Symbol.asyncDispose
  • 🧠 custom LockManager を注入可能(Node.js / テストで便利)

📦 インストール

npm install disposable-lock
# or
pnpm add disposable-lock

✋ まずは基本の使い方

import { lock } from "disposable-lock";

async function main() {
  const { request } = lock("user-data");

  const acquired = await request({ mode: "exclusive" });

  if (acquired.name) {
    console.log(`Lock acquired: ${acquired.name}`);

    await doSomethingCritical();

    await acquired.release();
  } else {
    console.log("Lock not available.");
  }
}

Web Locks API の複雑なコールバックを隠蔽し、
「ロックを取得 → 作業 → release」
という流れを直感的に書けます。

🪄 await using で自動解放

Node.js 20+ / 最新ブラウザなら、Symbol.asyncDispose を使えます。

(※ Safari はまだ対応していないので tsconfig で target:es2022 等で 変換されるように調整が必要です

import { lock } from "disposable-lock";

async function cacheUpdate() {
  const cacheLock = lock("cache");

  // スコープ終了時に自動解放される
  await using acquired = await cacheLock.request();

  await updateCache();
}

release() の書き忘れがなくなり、安全なロック管理ができます。

🔍 Lock の状態を調べたい

const userLock = lock("user-data");
const state = await userLock.query();

console.log("Held:", state.held);
console.log("Pending:", state.pending);

Web Locks API の内部状態が確認しづらい問題を、
query() でシンプルに解決できます。

🧪 テスト環境(Node.js)で LockManager を差し替える

navigator.locks が無い環境でも動かせます。

import { lock } from "disposable-lock";
import { createMockLockManager } from "./mock";

const locks = createMockLockManager();
const fileLock = lock("file-access", { locks });

await using acquired = await fileLock.request();
// テストが書きやすい!

テストしやすいように LockManager の DI を前提として設計しています。

🎯 なぜ作ったのか?

Web Locks API は強力ですが…

  • コールバック構造が複雑
  • dispose(スコープ終了処理)と相性が悪い
  • ロック解放忘れが起きやすい
  • テストしづらい

といった弱点があります。

disposable-lock はこれらを解消し、
「現代的な JS/TS で快適に使える Lock API」 を目指して作りました。

📚 リポジトリ・パッケージ

📝 まとめ

disposable-lock

  • Web Locks API を驚くほど使いやすく
  • TypeScript で型安全
  • await using で確実にロック解放
  • Node.js でもテストでも問題なく動作

という、小さいけれど実用的なロック管理ライブラリです。

ブラウザで排他制御を使う方、
タブ間競合を避けたい方、
テスト可能なロック API がほしい方にぴったりです。

Discussion