{"_id":"@apiratorjs/locking-redis","_rev":"7-247a793416b52354f5a965cf793339ae","name":"@apiratorjs/locking-redis","dist-tags":{"latest":"2.0.0"},"versions":{"1.0.0":{"name":"@apiratorjs/locking-redis","version":"1.0.0","keywords":["distributed-lock","concurrency","synchronization","distributed-locking","distributed-mutex","distributed-semaphore","critical-section","race-condition","resource-sharing","thread-safety","concurrent-access","redis-lock"],"author":{"url":"https://oleksiizaitsev.com","name":"Oleksii Zaitsev"},"license":"MIT","_id":"@apiratorjs/locking-redis@1.0.0","maintainers":[{"name":"apiratorjs","email":"apirator.framework@gmail.com"}],"homepage":"https://github.com/apiratorjs/locking-redis#readme","bugs":{"url":"https://github.com/apiratorjs/locking-redis/issues"},"dist":{"shasum":"6dc990f612911a9c7f4264e7b2d611b2b1feb625","tarball":"https://registry.npmjs.org/@apiratorjs/locking-redis/-/locking-redis-1.0.0.tgz","fileCount":35,"integrity":"sha512-pk8vYiz4Xn/ZJWCF2aC2rkexP7/LvOvTGa1IfdGn23cLM4M1tFKsLGqL8LziOlo+/2N9WtRIxIZ17qhLpnKvTw==","signatures":[{"sig":"MEYCIQDNZR1LMWIiIlc7q57SGarc0dDqxSBogJK6rJ83KbjeKgIhAPH9ppA+Bi6c3qZPNFtSoHZEFC5PrKdbbQGxeHCYO8I/","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42576},"main":"dist/src/index.js","type":"commonjs","types":"dist/src/index.d.ts","engines":{"node":">=16.4.0"},"gitHead":"f207d853278ebb3788a5bb519fca875d4886412e","scripts":{"test":"node --test dist/test","build":"rm -rf dist && tsc","watch":"tsc --watch","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"apiratorjs","email":"apirator.framework@gmail.com"},"repository":{"url":"git+https://github.com/apiratorjs/locking-redis.git","type":"git"},"_npmVersion":"10.9.2","description":"An extension to the core @apiratorjs/locking library, providing Redis-based implementations of distributed mutexes and semaphores for true cross-process concurrency control in Node.js.","directories":{},"_nodeVersion":"23.7.0","dependencies":{"redis":"^4.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","typescript":"^5.7.3","@types/node":"^22.13.1","@types/redis":"^4.0.10","@apiratorjs/locking":"^2.0.0"},"_npmOperationalInternal":{"tmp":"tmp/locking-redis_1.0.0_1742047980570_0.9037422673371212","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@apiratorjs/locking-redis","version":"1.0.1","keywords":["distributed-lock","concurrency","synchronization","distributed-locking","distributed-mutex","distributed-semaphore","critical-section","race-condition","resource-sharing","thread-safety","concurrent-access","redis-lock"],"author":{"url":"https://oleksiizaitsev.com","name":"Oleksii Zaitsev"},"license":"MIT","_id":"@apiratorjs/locking-redis@1.0.1","maintainers":[{"name":"apiratorjs","email":"apirator.framework@gmail.com"}],"homepage":"https://github.com/apiratorjs/locking-redis#readme","bugs":{"url":"https://github.com/apiratorjs/locking-redis/issues"},"dist":{"shasum":"cd0616bbdce50cac9bec2209b219596273dda844","tarball":"https://registry.npmjs.org/@apiratorjs/locking-redis/-/locking-redis-1.0.1.tgz","fileCount":35,"integrity":"sha512-H2CxgdAs/BGaVJaWUEf74DC67VpUSjPqNlNfb4apSvqXFBHIfdaz6p6syzziDRTnLxTrXQDvCGxO3mTW+3o5tg==","signatures":[{"sig":"MEYCIQDomttWkeJNqS91nhz1dXgRPJrasDlMV9NnFWIb7mif5gIhAIDnnfc3EL4DiO/ZdJDwoFUWssAGwuq7rsvG5QzdZXq+","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42588},"main":"dist/src/index.js","type":"commonjs","types":"dist/src/index.d.ts","engines":{"node":">=16.4.0"},"gitHead":"004b00099162b20e962d18c9f8c93a2ec71d7de9","scripts":{"test":"node --test dist/test","build":"rm -rf dist && tsc","watch":"tsc --watch","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"apiratorjs","email":"apirator.framework@gmail.com"},"repository":{"url":"git+https://github.com/apiratorjs/locking-redis.git","type":"git"},"_npmVersion":"10.9.2","description":"An extension to the core @apiratorjs/locking library, providing Redis-based implementations of distributed mutexes and semaphores for true cross-process concurrency control in Node.js.","directories":{},"_nodeVersion":"23.7.0","dependencies":{"redis":"^4.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","typescript":"^5.7.3","@types/node":"^22.13.1","@types/redis":"^4.0.10","@apiratorjs/locking":"^2.0.0"},"_npmOperationalInternal":{"tmp":"tmp/locking-redis_1.0.1_1742048362422_0.9236060471475231","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@apiratorjs/locking-redis","version":"1.0.2","keywords":["distributed-lock","concurrency","synchronization","distributed-locking","distributed-mutex","distributed-semaphore","critical-section","race-condition","resource-sharing","thread-safety","concurrent-access","redis-lock"],"author":{"url":"https://oleksiizaitsev.com","name":"Oleksii Zaitsev"},"license":"MIT","_id":"@apiratorjs/locking-redis@1.0.2","maintainers":[{"name":"apiratorjs","email":"apirator.framework@gmail.com"}],"homepage":"https://github.com/apiratorjs/locking-redis#readme","bugs":{"url":"https://github.com/apiratorjs/locking-redis/issues"},"dist":{"shasum":"143c618c9b4c827bacc758697b31d88fa2b5027f","tarball":"https://registry.npmjs.org/@apiratorjs/locking-redis/-/locking-redis-1.0.2.tgz","fileCount":35,"integrity":"sha512-uXcDE0mrwEQNn7GXhq9cQN+l8v9cxySP6xMXY9VOqSY1I6POntWJ4oPqdkGe+wPHJYl9QOR2rKKg1IjbQwVlyA==","signatures":[{"sig":"MEYCIQC+DTjGyUg5MC4+eNsh2A9n3sRoVPATopALESt6nSjc6QIhAN9H3OaxPwypp120WANP4YAt3ag78r1V9ec//E8BQ4Ja","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42580},"main":"dist/src/index.js","type":"commonjs","types":"dist/src/index.d.ts","engines":{"node":">=16.4.0"},"gitHead":"cc2cfdb8de12cba289882ceb8694ede74cef732c","scripts":{"test":"node --test dist/test","build":"rm -rf dist && tsc","watch":"tsc --watch","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"apiratorjs","email":"apirator.framework@gmail.com"},"repository":{"url":"git+https://github.com/apiratorjs/locking-redis.git","type":"git"},"_npmVersion":"10.9.2","description":"An extension to the core @apiratorjs/locking library, providing Redis-based implementations of distributed mutexes and semaphores for true cross-process concurrency control in Node.js.","directories":{},"_nodeVersion":"23.7.0","dependencies":{"redis":"^4.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","typescript":"^5.7.3","@types/node":"^22.13.1","@types/redis":"^4.0.10","@apiratorjs/locking":"^2.0.0"},"_npmOperationalInternal":{"tmp":"tmp/locking-redis_1.0.2_1742049901240_0.6720139499664979","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@apiratorjs/locking-redis","version":"1.0.3","keywords":["distributed-lock","concurrency","synchronization","distributed-locking","distributed-mutex","distributed-semaphore","critical-section","race-condition","resource-sharing","thread-safety","concurrent-access","redis-lock"],"author":{"url":"https://oleksiizaitsev.com","name":"Oleksii Zaitsev"},"license":"MIT","_id":"@apiratorjs/locking-redis@1.0.3","maintainers":[{"name":"apiratorjs","email":"apirator.framework@gmail.com"}],"homepage":"https://github.com/apiratorjs/locking-redis#readme","bugs":{"url":"https://github.com/apiratorjs/locking-redis/issues"},"dist":{"shasum":"6e3fe7b95d3831992dd0f0b99df52654fd8dae96","tarball":"https://registry.npmjs.org/@apiratorjs/locking-redis/-/locking-redis-1.0.3.tgz","fileCount":35,"integrity":"sha512-kpFxPpp4d0XZMwNd55+TT7InNK8vRgAap1ZUUU+oUR/KzNqcLkWWkMk0yBKCVenHklQSpbUiMUeCzStySEo75w==","signatures":[{"sig":"MEUCIQDlepkOwN/JY7vy/uelDuJnuBWp9VLrkwRu7VzUXiRnegIgK9J0cQ29hTyvRD10ZWS0BG5y0Vxb+Ayz9HcPM/X3lKI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42568},"main":"dist/src/index.js","type":"commonjs","types":"dist/src/index.d.ts","engines":{"node":">=16.4.0"},"gitHead":"0de0d6fd4c79976fb394807b6ed5a87ec5f51388","scripts":{"test":"node --test dist/test","build":"rm -rf dist && tsc","watch":"tsc --watch","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"apiratorjs","email":"apirator.framework@gmail.com"},"repository":{"url":"git+https://github.com/apiratorjs/locking-redis.git","type":"git"},"_npmVersion":"10.9.2","description":"An extension to the core @apiratorjs/locking library, providing Redis-based implementations of distributed mutexes and semaphores for true cross-process concurrency control in Node.js.","directories":{},"_nodeVersion":"23.7.0","dependencies":{"redis":"^4.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","typescript":"^5.7.3","@types/node":"^22.13.1","@types/redis":"^4.0.10","@apiratorjs/locking":"^2.0.0"},"_npmOperationalInternal":{"tmp":"tmp/locking-redis_1.0.3_1742334348165_0.20644193087786","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@apiratorjs/locking-redis","version":"1.0.4","keywords":["distributed-lock","concurrency","synchronization","distributed-locking","distributed-mutex","distributed-semaphore","critical-section","race-condition","resource-sharing","thread-safety","concurrent-access","redis-lock"],"author":{"url":"https://oleksiizaitsev.com","name":"Oleksii Zaitsev"},"license":"MIT","_id":"@apiratorjs/locking-redis@1.0.4","maintainers":[{"name":"apiratorjs","email":"apirator.framework@gmail.com"}],"homepage":"https://github.com/apiratorjs/locking-redis#readme","bugs":{"url":"https://github.com/apiratorjs/locking-redis/issues"},"dist":{"shasum":"661c319bbfa4cd60962aa72e01f00d04fdda9a56","tarball":"https://registry.npmjs.org/@apiratorjs/locking-redis/-/locking-redis-1.0.4.tgz","fileCount":35,"integrity":"sha512-StTIe865kSId1KbtcZOVO1o0/z3HBPc3ox9KnL+uk9Z8BPuj2vjP0lzpVLFcqu3TpzXQISP9DS20ytx1AcedJQ==","signatures":[{"sig":"MEYCIQD9xAsJbBbYSD9emlndxOqCPdjIZtk5h6v7qpdgSHJwMQIhAMr6Rdq8YVUmNTfadF9/8Y2gZNHiolZ6G9yVfloDehPh","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42572},"main":"dist/src/index.js","type":"commonjs","types":"dist/src/index.d.ts","engines":{"node":">=16.4.0"},"gitHead":"66c7938d16c8667954fcf1fb5974206551a3822b","scripts":{"test":"npm run build && node --test dist/test","build":"rm -rf dist && tsc","watch":"tsc --watch","prepublishOnly":"npm run test"},"_npmUser":{"name":"apiratorjs","email":"apirator.framework@gmail.com"},"repository":{"url":"git+https://github.com/apiratorjs/locking-redis.git","type":"git"},"_npmVersion":"10.9.2","description":"An extension to the core @apiratorjs/locking library, providing Redis-based implementations of distributed mutexes and semaphores for true cross-process concurrency control in Node.js.","directories":{},"_nodeVersion":"23.7.0","dependencies":{"redis":"^4.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","typescript":"^5.7.3","@types/node":"^22.13.1","@types/redis":"^4.0.10","@apiratorjs/locking":"^3.0.2"},"_npmOperationalInternal":{"tmp":"tmp/locking-redis_1.0.4_1742662755219_0.7225811816619367","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@apiratorjs/locking-redis","version":"1.0.5","keywords":["distributed-lock","concurrency","synchronization","distributed-locking","distributed-mutex","distributed-semaphore","critical-section","race-condition","resource-sharing","thread-safety","concurrent-access","redis-lock"],"author":{"url":"https://oleksiizaitsev.com","name":"Oleksii Zaitsev"},"license":"MIT","_id":"@apiratorjs/locking-redis@1.0.5","maintainers":[{"name":"apiratorjs","email":"apirator.framework@gmail.com"}],"homepage":"https://github.com/apiratorjs/locking-redis#readme","bugs":{"url":"https://github.com/apiratorjs/locking-redis/issues"},"dist":{"shasum":"3f6d6c4bf23c0f0008b9c44f6a79b1410d79c1bc","tarball":"https://registry.npmjs.org/@apiratorjs/locking-redis/-/locking-redis-1.0.5.tgz","fileCount":35,"integrity":"sha512-GxT0HHeV0HIsaKu4lAMlhbv4Pocm4UdgL6tXpZd6yy88wvdMSA5Ckzv9tTjfa3ySBYMg4bFvSpae+Ki8X9PD4A==","signatures":[{"sig":"MEUCIGDUinFu2J8fb0MhtfZ2szzFVg1pkav98iRlmEDV8jFkAiEAyRFWloQK94L0/kWBdnKtkEzFIw8l1qEBLJc2MmAIqoc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":46579},"main":"dist/src/index.js","type":"commonjs","types":"dist/src/index.d.ts","engines":{"node":">=16.4.0"},"gitHead":"29d62e4177d5747990e7d268bab4b4c54759e42e","scripts":{"test":"npm run build && node --test --test-concurrency=1 dist/test","build":"rm -rf dist && tsc","watch":"tsc --watch","prepublishOnly":"npm run test"},"_npmUser":{"name":"apiratorjs","email":"apirator.framework@gmail.com"},"repository":{"url":"git+https://github.com/apiratorjs/locking-redis.git","type":"git"},"_npmVersion":"10.8.2","description":"An extension to the core @apiratorjs/locking library, providing Redis-based implementations of distributed mutexes and semaphores for true cross-process concurrency control in Node.js.","directories":{},"_nodeVersion":"20.19.2","dependencies":{"redis":"^4.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","typescript":"^5.7.3","@types/node":"^22.13.1","@types/redis":"^4.0.10","@apiratorjs/locking":"^4.0.2"},"_npmOperationalInternal":{"tmp":"tmp/locking-redis_1.0.5_1748863878270_0.6640321994650427","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@apiratorjs/locking-redis","version":"2.0.0","description":"An extension to the core @apiratorjs/locking library, providing Redis-based implementations of distributed mutexes and semaphores for true cross-process concurrency control in Node.js.","author":{"name":"Oleksii Zaitsev","url":"https://alexeyzaitsev.com/"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/apiratorjs/locking-redis.git"},"main":"dist/src/index.js","types":"dist/src/index.d.ts","publishConfig":{"access":"public"},"keywords":["distributed-lock","concurrency","synchronization","distributed-locking","distributed-mutex","distributed-semaphore","critical-section","race-condition","resource-sharing","thread-safety","concurrent-access","redis-lock"],"type":"commonjs","engines":{"node":">=16.4.0"},"peerDependencies":{"@apiratorjs/locking":"^5.0.0"},"devDependencies":{"@apiratorjs/locking":"^5.0.0","@types/node":"^26.1.1","@types/redis":"^4.0.11","tsx":"^4.23.1","typescript":"^7.0.2"},"dependencies":{"redis":"^6.1.0"},"scripts":{"build":"rm -rf dist && tsc","watch":"tsc --watch","test":"npm run build && node --test --test-concurrency=1 dist/test"},"_nodeVersion":"26.0.0","_id":"@apiratorjs/locking-redis@2.0.0","dist":{"integrity":"sha512-VWzH8iNU5OvMM1IeoxWL0aTwYFvGBZxLsspEMnpjofiMHLq1+qGmo8IZ4obEhb9Z7esYpJa7h6IEZMZZJWpnZQ==","shasum":"f3c504712ad13aaf264f643d93cf96f551301621","tarball":"https://registry.npmjs.org/@apiratorjs/locking-redis/-/locking-redis-2.0.0.tgz","fileCount":44,"unpackedSize":86765,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC7DxGvcb5gE1ApXuhBYsRaFAxmiH0y1Eyd1OGbpvzLCAIhAPckidR/qthZAif17XhMv4PGmAcwdN4fFeNmFuncBxv5"}]},"_npmUser":{"name":"apiratorjs","email":"apirator.framework@gmail.com"},"directories":{},"maintainers":[{"name":"apiratorjs","email":"apirator.framework@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/locking-redis_2.0.0_1785075075842_0.48493697773337074"},"_hasShrinkwrap":false}},"time":{"created":"2025-03-15T14:13:00.467Z","modified":"2026-07-26T14:11:16.157Z","1.0.0":"2025-03-15T14:13:00.786Z","1.0.1":"2025-03-15T14:19:22.615Z","1.0.2":"2025-03-15T14:45:01.511Z","1.0.3":"2025-03-18T21:45:48.361Z","1.0.4":"2025-03-22T16:59:15.431Z","1.0.5":"2025-06-02T11:31:18.469Z","2.0.0":"2026-07-26T14:11:16.017Z"},"author":{"name":"Oleksii Zaitsev","url":"https://alexeyzaitsev.com/"},"license":"MIT","keywords":["distributed-lock","concurrency","synchronization","distributed-locking","distributed-mutex","distributed-semaphore","critical-section","race-condition","resource-sharing","thread-safety","concurrent-access","redis-lock"],"repository":{"type":"git","url":"git+https://github.com/apiratorjs/locking-redis.git"},"description":"An extension to the core @apiratorjs/locking library, providing Redis-based implementations of distributed mutexes and semaphores for true cross-process concurrency control in Node.js.","maintainers":[{"name":"apiratorjs","email":"apirator.framework@gmail.com"}],"readme":"# @apiratorjs/locking-redis\n\n[![NPM version](https://img.shields.io/npm/v/@apiratorjs/locking-redis.svg)](https://www.npmjs.com/package/@apiratorjs/locking-redis)\n[![License: MIT](https://img.shields.io/npm/l/@apiratorjs/locking-redis.svg)](https://github.com/apiratorjs/locking-redis/blob/main/LICENSE)\n\nAn extension to the core [@apiratorjs/locking](https://github.com/apiratorjs/locking) library, providing a Redis-backed\n`IDistributedLockManager` with distributed mutexes and semaphores for true cross-process concurrency control in Node.js.\n\n> **Note:** Requires Node.js version **>=16.4.0**, [@apiratorjs/locking](https://github.com/apiratorjs/locking) **^5.0.0**,\n> and a running Redis instance (version 5+ recommended).\n>\n> Upgrading from 1.x? See [CHANGELOG](./CHANGELOG.md) and [2.0.0 release notes](./RELEASE_NOTES.md).\n\n---\n\n## Why Use Redis for Distributed Locking?\n\n- **Multi-instance deployments**: If you have multiple Node.js processes or servers behind a load balancer, an in-memory\n  lock is insufficient. Redis provides a single, centralized coordination point.\n- **Fault tolerance**: Configurable timeouts (TTLs) prevent indefinite locks if a process crashes.\n- **Scalability**: Redis can handle many simultaneous locking requests at scale.\n\n---\n\n## Features\n\n- **`RedisDistributedLockManager`** — implements `types.IDistributedLockManager` from `@apiratorjs/locking`.\n- **Distributed Mutex and Semaphore** — same acquire / release / cancel / wait-for-unlock API as the core distributed\n  primitives, coordinated through Redis.\n- **Named locks** — the same name returns the same live instance while it is alive; `list()`, `count()`, `snapshot()`,\n  `cancelAll()`, and `destroyAll()` for inspection and shutdown.\n- **Time-limited locks (TTL)** — prevents deadlocks if processes crash without releasing.\n- **Cancellation, timeouts, and FIFO waiters** — cancel blocked acquisitions, fail fast with `timeoutMs: 0`, queue\n  waiters in order.\n- **Read-write locks** — not implemented yet; `readWriteLock()` throws `LockingError`.\n\n---\n\n## Installation\n\nInstall with npm:\n\n```bash\nnpm install @apiratorjs/locking @apiratorjs/locking-redis\n```\n\nOr with yarn:\n\n```bash\nyarn add @apiratorjs/locking @apiratorjs/locking-redis\n```\n\n---\n\n## Usage\n\n> Default acquire timeout is 1 minute (same as the core library). Pass `timeoutMs: 0` to fail fast with a\n> `TimeoutLockingError` when the lock is not immediately available.\n>\n> `cancel()` / `cancelAll()` reject pending acquisitions only: held locks stay held, and\n> `waitForUnlock()` / `waitForAnyUnlock()` / `waitForFullyUnlock()` keep waiting until holders release (or until\n> `destroy()` / `destroyAll()`, which resolves those waiters).\n\n### Quick start\n\n```typescript\nimport { RedisDistributedLockManager } from \"@apiratorjs/locking-redis\";\n\nconst locks = await RedisDistributedLockManager.create({\n  url: \"redis://localhost:6379\",\n});\n\nasync function example() {\n  const mutex = locks.mutex(\"shared-resource\");\n\n  const releaser = await mutex.acquire({ timeoutMs: 5000 });\n  try {\n    console.log(\"Distributed mutex acquired\");\n  } finally {\n    await releaser.release();\n  }\n\n  await locks.semaphore(\"api-rate-limiter\", 5).runExclusive(async () => {\n    console.log(\"Distributed semaphore slot acquired\");\n  });\n}\n\nprocess.on(\"SIGTERM\", async () => {\n  await locks.destroyAll(\"Shutting down\");\n  await locks.disconnect();\n});\n```\n\n### Inject an existing Redis client\n\nWhen you already own a `redis` client, pass it into the constructor. In that case `disconnect()` is a no-op — you close\nthe client yourself.\n\n```typescript\nimport { createClient } from \"redis\";\nimport { RedisDistributedLockManager } from \"@apiratorjs/locking-redis\";\n\nconst redisClient = createClient({ url: \"redis://localhost:6379\" });\nawait redisClient.connect();\n\nconst locks = new RedisDistributedLockManager({ redisClient });\n```\n\n### Distributed Mutex\n\n```typescript\nconst mutex = locks.mutex(\"orders\");\n\nconst releaser = await mutex.acquire({ timeoutMs: 5000 });\ntry {\n  // Critical section — exclusive across all processes sharing this Redis\n} finally {\n  await releaser.release();\n}\n\nawait mutex.runExclusive(async () => {\n  // Acquired and released automatically\n});\n\nawait mutex.cancel(\"Operation cancelled\");\nawait mutex.waitForUnlock();\n```\n\n### Distributed Semaphore\n\n```typescript\nconst semaphore = locks.semaphore(\"uploads\", 5);\n\nconst releaser = await semaphore.acquire({ timeoutMs: 5000 });\ntry {\n  // Up to 5 concurrent holders across processes\n} finally {\n  await releaser.release();\n}\n\nawait semaphore.runExclusive(async () => {\n  // Acquired and released automatically\n});\n\nawait semaphore.cancelAll(\"Operation cancelled\");\nawait semaphore.waitForAnyUnlock();\nawait semaphore.waitForFullyUnlock();\n```\n\n### Managing locks\n\n```typescript\nimport { ELockDisplayType } from \"@apiratorjs/locking\";\n\nlocks.hasMutex(\"orders\");\nlocks.hasSemaphore(\"uploads\");\nlocks.count();\nlocks.count(ELockDisplayType.Semaphore);\nlocks.list();\nawait locks.snapshot();\n\nawait locks.cancelAll(\"Draining before deploy\");\nawait locks.destroyAll(\"Shutting down\");\n```\n\nRequesting the same semaphore name with a different `maxCount` throws `LockConfigMismatchError`.\n\n### Swapping backends\n\nBecause both managers implement `IDistributedLockManager`, application code can depend on the interface and receive\neither an in-memory or Redis manager:\n\n```typescript\nimport { types, InMemoryDistributedLockManager } from \"@apiratorjs/locking\";\nimport { RedisDistributedLockManager } from \"@apiratorjs/locking-redis\";\n\nexport const locks: types.IDistributedLockManager =\n  process.env.REDIS_URL\n    ? await RedisDistributedLockManager.create({ url: process.env.REDIS_URL })\n    : new InMemoryDistributedLockManager();\n```\n\nNothing is global, so a Redis-backed manager and an in-memory one can coexist — useful when only part of the system needs\ncross-process coordination, and in tests.\n\n### Low-level classes\n\n`RedisDistributedMutex` and `RedisDistributedSemaphore` are also exported for advanced use (for example custom\nmanagers). Prefer `RedisDistributedLockManager` in application code so named instances, listing, and shutdown stay\nconsistent.\n\n---\n\n## Error handling\n\nErrors come from `@apiratorjs/locking`:\n\n| Error Class | When thrown |\n|-------------|-------------|\n| `TimeoutLockingError` | `acquire()` exceeds `timeoutMs` |\n| `CancelledLockingError` | `cancel()` / `cancelAll()` or destroy |\n| `LockNotFoundError` | Lock was destroyed |\n| `LockConfigMismatchError` | Same name requested with conflicting `maxCount` |\n| `LockingError` | Base class; also thrown by unimplemented `readWriteLock()` |\n\n---\n\n## Contributing\n\nContributions, issues, and feature requests are welcome!\nPlease open an issue or submit a pull request on [GitHub](https://github.com/apiratorjs/locking-redis).\n","readmeFilename":""}