{"_id":"@codylabs/nestjs-redlock","_rev":"4-76324d7e767a375edd1192e8da6c9160","name":"@codylabs/nestjs-redlock","dist-tags":{"latest":"0.1.0"},"versions":{"0.0.1":{"name":"@codylabs/nestjs-redlock","version":"0.0.1","author":"Cody Nguyen","license":"MIT","_id":"@codylabs/nestjs-redlock@0.0.1","maintainers":[{"name":"cuongnd1705","email":"cuongnd.work@gmail.com"}],"dist":{"shasum":"8b157f8c406d61a116a0f583760ede4b29a3e80e","tarball":"https://registry.npmjs.org/@codylabs/nestjs-redlock/-/nestjs-redlock-0.0.1.tgz","fileCount":42,"integrity":"sha512-FurXyFxRx2Nv5zPKWb10bcbfu1fDeykmtFJwQpWnCIRBNDGZFzmjOI3AV1mZYscchTgt2xZgraofKFtXKw9YdA==","signatures":[{"sig":"MEUCIG3p1cSaRQzSmfw6kzETk/5PVTvodk09ADbb0gGWoGU4AiEA27gafr8Xnwmly5hJ/jp5BmQvuiCfOtejkUUOrEt4Mow=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":341894},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"scripts":{"test":"jest --passWithNoTests","build":"tsc -p tsconfig.build.json","clean":"rm -rf .turbo node_modules dist","prebuild":"rimraf dist","test:watch":"jest --watch"},"_npmUser":{"name":"cuongnd1705","email":"cuongnd.work@gmail.com"},"description":"Redis-based distributed lock module for NestJS, built on @codylabs/redlock","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@nestjs/testing":"^11.1.24","@codylabs/typescript-configs":"0.0.8"},"peerDependencies":{"redis":"^5.0.0","@nestjs/common":"^10.0.0 || ^11.0.0","@codylabs/redlock":"0.0.1"},"_npmOperationalInternal":{"tmp":"tmp/nestjs-redlock_0.0.1_1779866802079_0.8234492278117742","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@codylabs/nestjs-redlock","version":"0.0.2","author":"Cody Nguyen","license":"MIT","_id":"@codylabs/nestjs-redlock@0.0.2","maintainers":[{"name":"cuongnd1705","email":"cuongnd.work@gmail.com"}],"homepage":"https://github.com/cuongnd1705/codylabs#readme","bugs":{"url":"https://github.com/cuongnd1705/codylabs/issues"},"dist":{"shasum":"bc11df1c681e4ccc2e5ceca31836ff11969af9e3","tarball":"https://registry.npmjs.org/@codylabs/nestjs-redlock/-/nestjs-redlock-0.0.2.tgz","fileCount":42,"integrity":"sha512-FNA2YCjXSSUMvDhMHbjl5u0N+Ak4/FkHZ58etOoRLQsJxnemzYU2WsLf1Ug8GK5MXxik37JwTCFzSFH5CUZLfA==","signatures":[{"sig":"MEUCIQDQl92y1CUXuq9ryj+ofEV6I+gk4lSd7ogyKoO1A9du5gIgLOClSW3GQBes6Rf114MFUZPS7Kd8mLGavIJTjcJbrWg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":342127},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"scripts":{"test":"jest --passWithNoTests","build":"tsc -p tsconfig.build.json","clean":"rm -rf .turbo node_modules dist","prebuild":"rimraf dist","test:watch":"jest --watch"},"_npmUser":{"name":"cuongnd1705","email":"cuongnd.work@gmail.com"},"repository":{"url":"git+https://github.com/cuongnd1705/codylabs.git","type":"git"},"description":"Redis-based distributed lock module for NestJS, built on @codylabs/redlock","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@nestjs/testing":"^11.1.24","@codylabs/typescript-configs":"0.0.9"},"peerDependencies":{"redis":"^6.0.0","@nestjs/common":"^11.0.0","@codylabs/redlock":"0.0.2"},"_npmOperationalInternal":{"tmp":"tmp/nestjs-redlock_0.0.2_1780126504698_0.42579520425643214","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@codylabs/nestjs-redlock","version":"0.0.3","author":"Cody Nguyen","license":"MIT","_id":"@codylabs/nestjs-redlock@0.0.3","maintainers":[{"name":"cuongnd1705","email":"cuongnd.work@gmail.com"}],"homepage":"https://github.com/cuongnd1705/codylabs#readme","bugs":{"url":"https://github.com/cuongnd1705/codylabs/issues"},"dist":{"shasum":"e88f807038168782ee729ecb94f9b4382f67c953","tarball":"https://registry.npmjs.org/@codylabs/nestjs-redlock/-/nestjs-redlock-0.0.3.tgz","fileCount":42,"integrity":"sha512-uOg2OeoMgdXM7rUyOcvFBRHau3Csq+vpPTrc5SBrLonZNAHEjiqSKbdobhVWB9pHjf1LpgUQtrEb0kxObu3Fqw==","signatures":[{"sig":"MEUCIH1u2uXAplp/P6HGULSW19i1PiVlJ4rXL/Ki+bADGDOpAiEAzHbKxZ2f0NF5uEXfLoBr3VXiwh14DsKSmNW6OTsh3rI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":345922},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"scripts":{"test":"jest --passWithNoTests","build":"tsc -p tsconfig.build.json","clean":"rm -rf .turbo node_modules dist","prebuild":"rimraf dist","test:watch":"jest --watch"},"_npmUser":{"name":"cuongnd1705","email":"cuongnd.work@gmail.com"},"repository":{"url":"git+https://github.com/cuongnd1705/codylabs.git","type":"git"},"description":"Redis-based distributed lock module for NestJS, built on @codylabs/redlock","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@nestjs/testing":"^11.1.28","@codylabs/redlock":"0.0.2","@codylabs/typescript-configs":"0.0.9"},"peerDependencies":{"redis":"^6.0.0","@nestjs/common":"^11.0.0","@codylabs/redlock":"0.0.2"},"_npmOperationalInternal":{"tmp":"tmp/nestjs-redlock_0.0.3_1784477196594_0.5796736898287098","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@codylabs/nestjs-redlock","version":"0.1.0","description":"Redis-based distributed lock module for NestJS, built on @codylabs/redlock","homepage":"https://github.com/cuongnd1705/codylabs#readme","bugs":{"url":"https://github.com/cuongnd1705/codylabs/issues"},"license":"MIT","author":"Cody Nguyen","repository":{"type":"git","url":"git+https://github.com/cuongnd1705/codylabs.git"},"type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"publishConfig":{"access":"public"},"devDependencies":{"@codylabs/redlock":"0.1.0","@codylabs/typescript-configs":"0.1.0","@nestjs/testing":"^12.0.1","@swc/core":"^1.16.1","unplugin-swc":"^1.5.11","vitest":"^4.1.11"},"peerDependencies":{"@codylabs/redlock":"0.1.0","@nestjs/common":"^12.0.0","redis":"^6.0.0"},"scripts":{"build":"tsc -p tsconfig.build.json","clean":"rm -rf .turbo node_modules dist","prebuild":"rimraf dist","test":"vitest run --passWithNoTests","test:watch":"vitest"},"_nodeVersion":"24.20.0","_id":"@codylabs/nestjs-redlock@0.1.0","dist":{"integrity":"sha512-LLSAqeLF0ct12azwMlNgICYatT73RsteYYyLZb0659nJ/hrkaPMst1VUHjOO3ENZhLZlFyEYYCN1FkezZjETYA==","shasum":"5773dac94044f7c15fce3bc3858efaf60ba1a7ec","tarball":"https://registry.npmjs.org/@codylabs/nestjs-redlock/-/nestjs-redlock-0.1.0.tgz","fileCount":36,"unpackedSize":236441,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIG/x7sGCAGK4WXfxld63dG7hU6R8/1C7Otcl4I3ulBAzAiEAoCVcJB1oHzC+lVYgvqAC9LThegrcvszGuuBEs31s5WU="}]},"_npmUser":{"name":"cuongnd1705","email":"cuongnd.work@gmail.com"},"directories":{},"maintainers":[{"name":"cuongnd1705","email":"cuongnd.work@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nestjs-redlock_0.1.0_1788017133367_0.057994158655858996"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-27T07:26:41.938Z","modified":"2026-08-29T15:25:33.697Z","0.0.1":"2026-05-27T07:26:42.231Z","0.0.2":"2026-05-30T07:35:04.865Z","0.0.3":"2026-07-19T16:06:36.743Z","0.1.0":"2026-08-29T15:25:33.502Z"},"bugs":{"url":"https://github.com/cuongnd1705/codylabs/issues"},"author":"Cody Nguyen","license":"MIT","homepage":"https://github.com/cuongnd1705/codylabs#readme","repository":{"type":"git","url":"git+https://github.com/cuongnd1705/codylabs.git"},"description":"Redis-based distributed lock module for NestJS, built on @codylabs/redlock","maintainers":[{"name":"cuongnd1705","email":"cuongnd.work@gmail.com"}],"readme":"# @codylabs/nestjs-redlock\n\nNestJS module for distributed locking via the [Redlock algorithm](https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/), built on [`@codylabs/redlock`](../redlock).\n\n## Features\n\n- `RedlockModule` with `forRoot` / `forRootAsync` — plugs into any NestJS application\n- `RedlockService` — injectable service extending `Redlock` directly (full API available)\n- `@Redlock()` decorator — wraps any method in a distributed lock with a single line\n- `isGlobal` support (defaults to `true`)\n\n## Installation\n\n```sh\n# npm\nnpm install @codylabs/nestjs-redlock @codylabs/redlock redis\n\n# pnpm\npnpm add @codylabs/nestjs-redlock @codylabs/redlock redis\n```\n\n`@codylabs/redlock` and `redis` (v5+) are required peer dependencies.\n\n> **Tip**: If you already use [`@codylabs/nestjs-redis`](../nestjs-redis) in your application, you can inject the managed Redis client directly into `RedlockModule` instead of creating clients manually. See [Using with @codylabs/nestjs-redis](#using-with-codylabsnestjs-redis).\n\n## Usage\n\n### Module setup\n\n```typescript\nimport { Module } from '@nestjs/common';\nimport { createClient } from 'redis';\nimport { RedlockModule } from '@codylabs/nestjs-redlock';\n\n@Module({\n  imports: [\n    RedlockModule.forRoot({\n      clients: [\n        createClient({ url: 'redis://redis1:6379' }),\n        createClient({ url: 'redis://redis2:6379' }),\n        createClient({ url: 'redis://redis3:6379' }),\n      ],\n      redlockConfig: {\n        retryDelayMs: 200,\n        maxRetryAttempts: 3,\n      },\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n`clients` accepts `RedisClientType`, `RedisClusterType`, and `RedisSentinelType`. For a single-node HA setup, pass one Cluster or Sentinel client; for full Redlock fault tolerance, pass multiple independent instances.\n\n```typescript\nimport { createCluster, createSentinel } from 'redis';\n\n// Redis Cluster\nRedlockModule.forRoot({\n  clients: [createCluster({ rootNodes: [{ url: 'redis://node1:6379' }] })],\n});\n\n// Redis Sentinel\nRedlockModule.forRoot({\n  clients: [createSentinel({ sentinelRootNodes: [{ host: 'sentinel1', port: 26379 }], name: 'mymaster' })],\n});\n```\n\n#### Async setup\n\n```typescript\n@Module({\n  imports: [\n    RedlockModule.forRootAsync({\n      inject: [ConfigService],\n      useFactory: (config: ConfigService) => ({\n        clients: config.get('redisClients'),\n      }),\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n### `@Redlock()` decorator\n\nWrap a method in a distributed lock — the lock is acquired before the method runs and released automatically when it returns or throws.\n\n```typescript\nimport { Injectable } from '@nestjs/common';\nimport { Redlock } from '@codylabs/nestjs-redlock';\n\n@Injectable()\nexport class OrderService {\n  // Single resource\n  @Redlock('order:process', 10_000)\n  async processOrder(orderId: string) {\n    // only one instance runs this at a time\n  }\n\n  // Multiple resources (acquired atomically, sorted to prevent deadlocks)\n  @Redlock(['user:123', 'order:456'], 10_000)\n  async transferFunds(userId: string, orderId: string) {\n    // locks both resources atomically\n  }\n\n  // With per-call retry and auto-extension options\n  @Redlock('report:generate', 60_000, { maxRetryAttempts: 5, extensionThresholdMs: 10_000 })\n  async generateReport() {\n    // lock auto-extends when within 10s of expiry\n  }\n}\n```\n\n> **Note**: `RedlockModule` must be imported in the same module (or registered as `isGlobal: true`, the default) for the decorator injection to work.\n\n### `RedlockService`\n\n`RedlockService` extends `Redlock` directly, so the full API is available:\n\n```typescript\nimport { Injectable } from '@nestjs/common';\nimport { RedlockService } from '@codylabs/nestjs-redlock';\n\n@Injectable()\nexport class PaymentService {\n  constructor(private readonly redlock: RedlockService) {}\n\n  async processPayment(paymentId: string) {\n    // withLock — acquires, auto-extends, and always releases\n    return this.redlock.withLock(`payment:${paymentId}`, 30_000, async (signal) => {\n      if (signal.aborted) throw signal.reason;\n      return await this.charge(paymentId);\n    });\n  }\n\n  async reserveInventory(itemId: string) {\n    // Manual acquire / release\n    const lock = await this.redlock.acquire(`inventory:${itemId}`, 5_000);\n    if (!lock) throw new Error('Could not acquire inventory lock');\n\n    try {\n      return await this.deductStock(itemId);\n    } finally {\n      await lock.release();\n    }\n  }\n}\n```\n\nSee [`@codylabs/redlock`](../redlock/README.md) for the full API reference.\n\n## Using with @codylabs/nestjs-redis\n\nIf your application already uses [`@codylabs/nestjs-redis`](../nestjs-redis) to manage Redis connections, you can reuse those clients directly — no need to create separate clients for locking.\n\n```sh\npnpm add @codylabs/nestjs-redis\n```\n\n```typescript\nimport { Module } from '@nestjs/common';\nimport { RedisModule, RedisToken } from '@codylabs/nestjs-redis';\nimport { RedlockModule } from '@codylabs/nestjs-redlock';\nimport type { RedisClientType } from 'redis';\n\n@Module({\n  imports: [\n    RedisModule.forRoot({\n      options: { url: 'redis://localhost:6379' },\n      isGlobal: true,\n    }),\n    RedlockModule.forRootAsync({\n      inject: [RedisToken()],\n      useFactory: (client: RedisClientType) => ({\n        clients: [client],\n      }),\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\nThis way `@codylabs/nestjs-redis` owns the connection lifecycle and `RedlockModule` simply borrows the client.\n\n> **Note**: Redis client lifecycle (connect/quit) is always the caller's responsibility. `RedlockModule` does not open or close connections.\n\n## Configuration\n\n| Option          | Type                | Default | Description                                                                 |\n| --------------- | ------------------- | ------- | --------------------------------------------------------------------------- |\n| `clients`       | `RedisClientLike[]` | —       | Independent Redis clients (standard, cluster, or sentinel). Recommended: 5. |\n| `redlockConfig` | `RedlockOptions`    | —       | Retry and drift options. See `@codylabs/redlock`.                           |\n| `isGlobal`      | `boolean`           | `true`  | Register the module globally.                                               |\n\n## License\n\nMIT\n","readmeFilename":""}