{"_id":"@absolutejs/sync-bus-redis","_rev":"4-5c8acd9144211d57c6a5fc3b2810e0e9","name":"@absolutejs/sync-bus-redis","dist-tags":{"latest":"0.1.1"},"versions":{"0.0.1":{"name":"@absolutejs/sync-bus-redis","version":"0.0.1","keywords":["absolutejs","sync","cluster","redis","pubsub","horizontal-scale","multi-region"],"author":"Alex Kahn","license":"Apache-2.0","_id":"@absolutejs/sync-bus-redis@0.0.1","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"dist":{"shasum":"04cf9932563680507dd8a6274c2866264ad66ba0","tarball":"https://registry.npmjs.org/@absolutejs/sync-bus-redis/-/sync-bus-redis-0.0.1.tgz","fileCount":6,"integrity":"sha512-Lt/mifssXloijuehUqw71A+9EmwDMKgeYsNGhnU2Y7wlG4t0uIEXwCWmiLg1M5vQNzgBZyNZ8p3P85EqH5u4+w==","signatures":[{"sig":"MEUCIQDesKVBraW+PlfIQXkAL/3KbimjHUEFYCmGR6DJI/q2VgIgVXEAnlyCjh1t2Ngf/KtC6PozP/jp/LjDWR1dCU5kKF0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":20902},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","shasum":"04cf9932563680507dd8a6274c2866264ad66ba0","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"scripts":{"test":"bun test","build":"rm -rf dist && bun build src/index.ts --outdir dist --sourcemap --target=bun --external @absolutejs/sync && tsc --project tsconfig.build.json","format":"prettier --write \"./**/*.{ts,json,md}\"","release":"bun run format && bun run build && bun publish","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"_integrity":"sha512-Lt/mifssXloijuehUqw71A+9EmwDMKgeYsNGhnU2Y7wlG4t0uIEXwCWmiLg1M5vQNzgBZyNZ8p3P85EqH5u4+w==","repository":{"url":"https://github.com/absolutejs/sync-adapters.git","type":"git","directory":"redis"},"_npmVersion":"10.8.3","description":"Redis pub/sub ClusterBus for @absolutejs/sync — cross-instance fan-out via PUBLISH/SUBSCRIBE. Sibling to @absolutejs/sync-bus-pg; faster fanout, better geo-replication story. Works with any Redis client (ioredis, node-redis, etc.) via a narrow tag-templat","directories":{},"_nodeVersion":"24.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"prettier":"3.5.3","@types/bun":"1.3.14","typescript":"5.8.3","@absolutejs/sync":"^1.21.0"},"peerDependencies":{"@absolutejs/sync":">= 1.17.0"},"_npmOperationalInternal":{"tmp":"tmp/sync-bus-redis_0.0.1_1780172434461_0.3543360724630136","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@absolutejs/sync-bus-redis","version":"0.0.2","keywords":["absolutejs","sync","cluster","redis","pubsub","horizontal-scale","multi-region"],"author":"Alex Kahn","license":"Apache-2.0","_id":"@absolutejs/sync-bus-redis@0.0.2","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/sync-adapters/tree/main/redis","bugs":{"url":"https://github.com/absolutejs/sync-adapters/issues"},"dist":{"shasum":"0a5716e6ae7853b82e39a78b89bb80abb92db90d","tarball":"https://registry.npmjs.org/@absolutejs/sync-bus-redis/-/sync-bus-redis-0.0.2.tgz","fileCount":11,"integrity":"sha512-a8mJ7c5ymZx++Ueq4N+jLvVFAaPdIDevJPTDpOLkdD2g2i8ZGxW/L7Xy/VvZhr89EN25kcg+TG4kydQ/w5J4Pw==","signatures":[{"sig":"MEQCIGAQlUJVA9JrWVdjn1qAAmwkVUQ1lBTwAq95xpwsEAHSAiB2WLiuSs1QcE4ovvX3bB85grU1GCpm+qHGP7KTh6LojQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1116602},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","shasum":"0a5716e6ae7853b82e39a78b89bb80abb92db90d","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./manifest":{"types":"./dist/manifest.d.ts","import":"./dist/manifest.js","default":"./dist/manifest.js"},"./manifest.json":"./dist/manifest.json"},"scripts":{"test":"bun test","build":"rm -rf dist && bun build src/index.ts src/manifest.ts --outdir dist --sourcemap --target=bun --external @absolutejs/sync && tsc --project tsconfig.build.json && absolute-manifest emit","format":"prettier --write \"./**/*.{ts,json,md}\"","release":"bun run format && bun run build && bun publish","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"_integrity":"sha512-a8mJ7c5ymZx++Ueq4N+jLvVFAaPdIDevJPTDpOLkdD2g2i8ZGxW/L7Xy/VvZhr89EN25kcg+TG4kydQ/w5J4Pw==","absolutejs":{"manifestContract":1},"repository":{"url":"https://github.com/absolutejs/sync-adapters.git","type":"git","directory":"redis"},"_npmVersion":"10.8.3","description":"Redis pub/sub ClusterBus for @absolutejs/sync — cross-instance fan-out via PUBLISH/SUBSCRIBE. Sibling to @absolutejs/sync-bus-pg; faster fanout, better geo-replication story. Works with any Redis client (ioredis, node-redis, etc.) via a narrow tag-templat","directories":{},"_nodeVersion":"24.3.0","dependencies":{"@sinclair/typebox":"^0.34.0","@absolutejs/manifest":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"prettier":"3.5.3","@types/bun":"1.3.14","typescript":"5.8.3","@absolutejs/sync":"^1.21.0"},"peerDependencies":{"@absolutejs/sync":">= 1.17.0"},"_npmOperationalInternal":{"tmp":"tmp/sync-bus-redis_0.0.2_1783965132696_0.8076450444993002","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@absolutejs/sync-bus-redis","version":"0.1.0","keywords":["absolutejs","sync","cluster","redis","pubsub","horizontal-scale","multi-region"],"author":"Alex Kahn","license":"Apache-2.0","_id":"@absolutejs/sync-bus-redis@0.1.0","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/sync-adapters/tree/main/redis","bugs":{"url":"https://github.com/absolutejs/sync-adapters/issues"},"dist":{"shasum":"ca668efa1a352e6afe2c12d1234937f3fdeb1a1e","tarball":"https://registry.npmjs.org/@absolutejs/sync-bus-redis/-/sync-bus-redis-0.1.0.tgz","fileCount":11,"integrity":"sha512-FCIoddmMpL9MMbxFEcbiyurB/90nY8aaNFzBlfOCpS5VvNRp7CAHDqCR5Tgan0XEe3diQRZ4O/kRbYTq052qZg==","signatures":[{"sig":"MEUCIQD04+PhNhlfrDtfTfD17pjvLJOpbbl9v1tghbgDwq1UowIgNUaexUbasuBHv7ZnST0vOzeDLLq6b/Nr6OmXndKNgb4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1120953},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","shasum":"ca668efa1a352e6afe2c12d1234937f3fdeb1a1e","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./manifest":{"types":"./dist/manifest.d.ts","import":"./dist/manifest.js","default":"./dist/manifest.js"},"./manifest.json":"./dist/manifest.json"},"scripts":{"test":"bun test","build":"rm -rf dist && bun build src/index.ts src/manifest.ts --outdir dist --sourcemap --target=bun --external @absolutejs/sync && tsc --project tsconfig.build.json && absolute-manifest emit","format":"prettier --write \"./**/*.{ts,json,md}\"","release":"bun run format && bun run build && bun publish","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"_integrity":"sha512-FCIoddmMpL9MMbxFEcbiyurB/90nY8aaNFzBlfOCpS5VvNRp7CAHDqCR5Tgan0XEe3diQRZ4O/kRbYTq052qZg==","absolutejs":{"manifestContract":1},"repository":{"url":"https://github.com/absolutejs/sync-adapters.git","type":"git","directory":"redis"},"_npmVersion":"10.8.3","description":"Redis pub/sub ClusterBus for @absolutejs/sync — cross-instance fan-out via PUBLISH/SUBSCRIBE. Sibling to @absolutejs/sync-bus-pg; faster fanout, better geo-replication story. Works with any Redis client (ioredis, node-redis, etc.) via a narrow tag-templat","directories":{},"_nodeVersion":"24.3.0","dependencies":{"@sinclair/typebox":"^0.34.0","@absolutejs/manifest":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"prettier":"3.5.3","@types/bun":"1.3.14","typescript":"5.8.3","@absolutejs/sync":"^1.21.0"},"peerDependencies":{"@absolutejs/sync":">= 1.17.0"},"_npmOperationalInternal":{"tmp":"tmp/sync-bus-redis_0.1.0_1784162868933_0.9428580642516629","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@absolutejs/sync-bus-redis","version":"0.1.1","description":"Redis pub/sub ClusterBus for @absolutejs/sync — cross-instance fan-out via PUBLISH/SUBSCRIBE. Sibling to @absolutejs/sync-bus-pg; faster fanout, better geo-replication story. Works with any Redis client (ioredis, node-redis, etc.) via a narrow tag-templat","repository":{"type":"git","url":"https://github.com/absolutejs/sync-adapters.git","directory":"redis"},"homepage":"https://github.com/absolutejs/sync-adapters/tree/main/redis","bugs":{"url":"https://github.com/absolutejs/sync-adapters/issues"},"main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","type":"module","license":"Apache-2.0","author":"Alex Kahn","publishConfig":{"access":"public"},"keywords":["absolutejs","sync","cluster","redis","pubsub","horizontal-scale","multi-region"],"scripts":{"build":"rm -rf dist && bun build src/index.ts src/manifest.ts --outdir dist --sourcemap --target=bun --external @absolutejs/sync && tsc --project tsconfig.build.json && absolute-manifest emit","test":"bun test","typecheck":"tsc --noEmit","format":"prettier --write \"./**/*.{ts,json,md}\"","release":"bun run format && bun run build && bun publish"},"peerDependencies":{"@absolutejs/sync":">=2.11.0 <3"},"devDependencies":{"@absolutejs/sync":"2.11.0","@types/bun":"1.3.14","prettier":"3.5.3","typescript":"5.8.3"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./manifest":{"types":"./dist/manifest.d.ts","import":"./dist/manifest.js","default":"./dist/manifest.js"},"./manifest.json":"./dist/manifest.json"},"absolutejs":{"manifestContract":2,"runtimePeers":{"@absolutejs/sync":{"artifactImports":[],"buildExternals":["@absolutejs/sync"],"range":">=2.11.0 <3","tested":"2.11.0"}}},"dependencies":{"@absolutejs/manifest":"^0.7.1","@sinclair/typebox":"^0.34.0"},"_id":"@absolutejs/sync-bus-redis@0.1.1","_integrity":"sha512-98ouWbHI4xNtW7lICt3iElR30K2zTWMgP4WhAURj4G7cdy4V5JHqyMRhn8HzInL9Wn+MOhPjqiinFCTJIyFyrQ==","_nodeVersion":"24.3.0","_npmVersion":"10.8.3","shasum":"2c9c718a39f462956da1bea5ede7176066f1e669","dist":{"integrity":"sha512-98ouWbHI4xNtW7lICt3iElR30K2zTWMgP4WhAURj4G7cdy4V5JHqyMRhn8HzInL9Wn+MOhPjqiinFCTJIyFyrQ==","shasum":"2c9c718a39f462956da1bea5ede7176066f1e669","tarball":"https://registry.npmjs.org/@absolutejs/sync-bus-redis/-/sync-bus-redis-0.1.1.tgz","fileCount":11,"unpackedSize":483677,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAVhy+AN6a9o4XkwsnznW32d73hedf5QDkSv+3VMHc4+AiBzVlBjrSjOO4IlhgNnbpNdkOpzRSCP2s261DwEq9N14Q=="}]},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"directories":{},"maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sync-bus-redis_0.1.1_1784913336542_0.6142969596384382"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-30T20:20:34.294Z","modified":"2026-07-24T17:15:36.853Z","0.0.1":"2026-05-30T20:20:34.625Z","0.0.2":"2026-07-13T17:52:12.830Z","0.1.0":"2026-07-16T00:47:49.125Z","0.1.1":"2026-07-24T17:15:36.674Z"},"bugs":{"url":"https://github.com/absolutejs/sync-adapters/issues"},"author":"Alex Kahn","license":"Apache-2.0","homepage":"https://github.com/absolutejs/sync-adapters/tree/main/redis","keywords":["absolutejs","sync","cluster","redis","pubsub","horizontal-scale","multi-region"],"repository":{"type":"git","url":"https://github.com/absolutejs/sync-adapters.git","directory":"redis"},"description":"Redis pub/sub ClusterBus for @absolutejs/sync — cross-instance fan-out via PUBLISH/SUBSCRIBE. Sibling to @absolutejs/sync-bus-pg; faster fanout, better geo-replication story. Works with any Redis client (ioredis, node-redis, etc.) via a narrow tag-templat","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"readme":"# @absolutejs/sync-bus-redis\n\nRedis pub/sub `ClusterBus` for\n[@absolutejs/sync](https://github.com/absolutejs/sync). Sibling to\n[`@absolutejs/sync-bus-pg`](../bus-pg) — same `ClusterBus` contract,\ndifferent transport.\n\n**Docs:** [absolutejs.com/documentation/cluster-bus-overview#redis-adapter](https://absolutejs.com/documentation/cluster-bus-overview#redis-adapter)\n\n## When to use Redis vs Postgres\n\n| Concern | `sync-bus-redis` | `sync-bus-pg` |\n|---|---|---|\n| Payload size | No cap — JSON through | 8KB NOTIFY cap (spill-table fallback) |\n| Fan-out latency at 10+ subscribers | In-memory, low | WAL-replicated, higher |\n| Geo-replication | Native (Redis Cluster, ElastiCache, Memorystore, Upstash) | Heavy ops (PG logical replication) |\n| Delivery semantics | At-most-once (no message retention) | At-most-once (NOTIFY) + spill rows for oversized |\n| Already in your stack? | If yes → win-win | If yes → win-win |\n\n**The headline tradeoff.** Redis is in-memory pub/sub — a subscriber\nthat's disconnected when a message fires misses it. For\ncross-instance resume past shard reboot, pair with\n`engine.exportChangeLog()` / `importChangeLog()` (sync 1.19.0+)\nregardless of which bus you use.\n\n## Install\n\n```sh\nbun add @absolutejs/sync @absolutejs/sync-bus-redis\n# Plus a Redis client — bring your own:\nbun add ioredis            # OR\nbun add redis              # node-redis v4+\n```\n\nThe adapter has no hard runtime dep on a specific Redis client.\n\n## Usage with `ioredis`\n\n```ts\nimport { Redis } from 'ioredis';\nimport { createSyncEngine } from '@absolutejs/sync/engine';\nimport { createRedisClusterBus } from '@absolutejs/sync-bus-redis';\n\nconst publisher = new Redis(process.env.REDIS_URL!);\nconst subscriberClient = new Redis(process.env.REDIS_URL!);\n\n// ioredis: a subscribed connection can't issue other commands.\n// Bridge its EventEmitter API into our (channel, listener) shape:\nconst subscriber = {\n  subscribe: async (channel: string, listener: (msg: string) => void) => {\n    await subscriberClient.subscribe(channel);\n    const handler = (chan: string, msg: string) => {\n      if (chan === channel) listener(msg);\n    };\n    subscriberClient.on('message', handler);\n    return async () => {\n      subscriberClient.off('message', handler);\n      await subscriberClient.unsubscribe(channel);\n    };\n  },\n};\n\nconst bus = createRedisClusterBus({ publisher, subscriber });\nconst engine = createSyncEngine({ instanceId: 'shard-A' });\nawait engine.connectCluster(bus);\n```\n\n## Usage with `node-redis` v4+\n\n```ts\nimport { createClient } from 'redis';\nimport { createRedisClusterBus } from '@absolutejs/sync-bus-redis';\n\nconst publisher = createClient({ url: process.env.REDIS_URL });\nconst subscriberClient = publisher.duplicate();\nawait Promise.all([publisher.connect(), subscriberClient.connect()]);\n\n// node-redis: subscribe takes a callback directly.\nconst subscriber = {\n  subscribe: async (channel: string, listener: (msg: string) => void) => {\n    await subscriberClient.subscribe(channel, listener);\n    return async () => {\n      await subscriberClient.unsubscribe(channel);\n    };\n  },\n};\n\nconst bus = createRedisClusterBus({ publisher, subscriber });\n```\n\n## API\n\n```ts\ncreateRedisClusterBus({\n  publisher,         // RedisPublisher — publish(channel, message)\n  subscriber,        // RedisSubscriber — subscribe(channel, listener) → unsubscribe fn\n  channel?,          // default 'absolutejs_sync_cluster'\n  onError?,          // logger for parse / delivery failures\n});\n```\n\nReturns `ClusterBus & { metrics() }`. Pass to `engine.connectCluster(bus)`.\n\n### `bus.metrics()`\n\n```ts\n{\n  published: number;             // PUBLISH calls\n  received: number;              // messages parsed + delivered to onMessage\n  publishErrors: number;         // publisher.publish() rejections\n  subscribeErrors: number;       // JSON.parse failures on incoming messages\n  totalSubscribersReached: number; // sum of counts Redis returned from PUBLISH\n                                 // — a drop to 0 when you expect peers signals\n                                 // subscriber disconnects (partition, restart)\n}\n```\n\n## License\n\n[Apache 2.0](../LICENSE). Tier B substrate-adjacent under the\nAbsoluteJS licensing policy — rides `@absolutejs/sync` (BSL Tier A).\n","readmeFilename":"README.md"}