{"id":46675,"library":"ts-safe-redis-leader","title":"ts-safe-redis-leader","description":"A TypeScript library for distributed Redis leader election with race-condition-free guarantees. Version 0.0.5 is the latest stable release; the project appears to be a fork of safe-redis-leader with TypeScript support, new events (elected/notElected), and tests verifying single-leader-at-a-time. Key differentiators include async/await API, removal of race conditions from the original redis-leader package, and Jest-based testing against a real Redis instance via Docker Compose. The library is small, focused, and suitable for Node.js applications needing reliable leader election without external dependencies beyond ioredis.","status":"active","version":"0.0.5","language":"javascript","source_language":"en","source_url":"https://github.com/Nesci28/safe-redis-leader","tags":["javascript","redis","leader","elections","distributed","typescript"],"install":[{"cmd":"npm install ts-safe-redis-leader","lang":"bash","label":"npm"},{"cmd":"yarn add ts-safe-redis-leader","lang":"bash","label":"yarn"},{"cmd":"pnpm add ts-safe-redis-leader","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for Redis client instance passed to SafeRedisLeader constructor","package":"ioredis","optional":false}],"imports":[{"note":"Package exports only SafeRedisLeader as a named export. Default import will not work.","wrong":"const SafeRedisLeader = require('ts-safe-redis-leader');","symbol":"SafeRedisLeader","correct":"import { SafeRedisLeader } from 'ts-safe-redis-leader';"},{"note":"Default import is incorrect; use named import.","wrong":"import SafeRedisLeader from 'ts-safe-redis-leader';","symbol":"SafeRedisLeader","correct":"import { SafeRedisLeader } from 'ts-safe-redis-leader';"},{"note":"CommonJS destructured require works; .default property is not available.","wrong":"const SafeRedisLeader = require('ts-safe-redis-leader').default;","symbol":"SafeRedisLeader","correct":"const { SafeRedisLeader } = require('ts-safe-redis-leader');"}],"quickstart":{"code":"import Redis from 'ioredis';\nimport { SafeRedisLeader } from 'ts-safe-redis-leader';\n\nconst redisConfig = {\n  port: 6379,\n  host: 'localhost',\n  autoResubscribe: false,\n  lazyConnect: true,\n  maxRetriesPerRequest: 0,\n};\nconst redisClient = new Redis(redisConfig);\n\nconst leaderElectionKey = 'the-election';\nconst safeLeader = new SafeRedisLeader(redisClient, 1500, 3000, leaderElectionKey);\n\nsafeLeader.on('elected', () => {\n  console.log('I am the leader');\n});\n\nsafeLeader.on('notElected', () => {\n  console.log('I am not the leader');\n});\n\nasync function start() {\n  await safeLeader.elect();\n}\n\nstart().catch(console.error);","lang":"typescript","description":"Creates a Redis client and SafeRedisLeader instance then starts leader election with event listeners for elected/notElected."},"warnings":[{"fix":"Set lazyConnect: true and maxRetriesPerRequest: 0 in ioredis options.","message":"Redis client must be configured with `lazyConnect: true` and `maxRetriesPerRequest: 0` to avoid connection issues.","severity":"gotcha","affected_versions":">=0.0.0"},{"fix":"Listen for 'elected' and 'notElected' events instead of custom event names.","message":"The library uses events 'elected' and 'notElected' (not 'leader' or 'follower').","severity":"gotcha","affected_versions":">=0.0.0"},{"fix":"Refer to ts-safe-redis-leader documentation for correct API.","message":"Package is a fork; API differs from original safe-redis-leader (e.g., events renamed).","severity":"breaking","affected_versions":">=0.0.0"},{"fix":"Pass exactly (Redis client, ttl, interval, election key string).","message":"Constructor arguments: (redisClient, ttl, interval, key) - order matters and units are in milliseconds.","severity":"gotcha","affected_versions":">=0.0.0"}],"env_vars":null,"search_vec":"'0.0.5':21 'api':58 'appear':29 'applic':92 'async/await':57 'base':73 'beyond':100 'compos':82 'condit':17,62 'depend':99 'differenti':55 'distribut':10,106 'docker':81 'elect':13,96,105 'elected/notelected':44 'event':43 'extern':98 'focus':87 'fork':33 'free':18 'guarante':19 'includ':56 'instanc':79 'ioredi':101 'javascript':102 'jest':72 'jest-bas':71 'key':54 'latest':24 'leader':5,12,38,50,68,95,104 'librari':8,84 'need':93 'new':42 'node.js':91 'origin':65 'packag':69 'project':28 'race':16,61 'race-condition-fre':15 'real':77 'redi':4,11,37,67,78,103 'redis-lead':66 'releas':26 'reliabl':94 'remov':59 'safe':3,36 'safe-redis-lead':35 'singl':49 'single-leader-at-a-tim':48 'small':86 'stabl':25 'suitabl':89 'support':41 'test':46,74 'time':53 'ts':2 'ts-safe-redis-lead':1 'typescript':7,40,107 'verifi':47 'version':20 'via':80 'without':97","created_at":"2026-06-07T13:01:04.420429+00:00","updated_at":"2026-06-07T13:01:04.420429+00:00","problems":[{"fix":"Ensure ioredis is initialized with { lazyConnect: true } and call connect() before elect() if needed.","cause":"Redis client is not connected or lazyConnect is not set to true.","error":"TypeError: redisClient.connect is not a function"},{"fix":"Pass a non-empty string as the fourth argument to SafeRedisLeader constructor.","cause":"Election key was not provided or is undefined.","error":"Error: The leader election key is required"},{"fix":"Import SafeRedisLeader as named export and ensure it is an instance of SafeRedisLeader.","cause":"Attempting to use event methods on a non-event-emitter instance, possibly due to wrong import.","error":"TypeError: safeLeader.on is not a function"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/Nesci28/safe-redis-leader/blob/master/README.md","github":"https://github.com/Nesci28/safe-redis-leader","docs":null,"changelog":null,"pypi":null,"npm":"ts-safe-redis-leader","openapi_spec":null,"status_page":null,"smithery":null,"categories":["storage","devops"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-07","next_check":"2026-09-05","install_tag":null}}