@myko.pk/redis
v1.5.0
Published
Redis client and Bloom filter for MYKO NestJS services
Downloads
1,211
Readme
📑 Table of Contents
📝 Description
@myko.pk/redis provides a standardised Redis client and Bloom filter for MYKO NestJS services.
- Dual-mode Redis — auto-detects between
ioredis(TCP) andUpstash Redis(REST) at startup - Auto-namespacing — every key is prefixed with
{serviceName}:to prevent cross-service collisions - Bloom filter — in-memory probabilistic data structure for fast existence checks
✨ Key Features
- 🧩 Dual Client — Works with both ioredis (Railway Redis) and Upstash Redis REST API
- 🏷️ Namespaced Keys — Automatic
{serviceName}:prefix on every operation - 📦 Pipeline Support —
setMultipleand Upstash pipeline for batch writes - 🔍 Pattern Invalidation — Wildcard-based cache invalidation via SCAN + DEL
- 🪣 Bloom Filter — Configurable capacity/FP rate, MD5 hashing, load from DB
- 🏗️ Global Modules — Both modules are
@Global()— import once, inject anywhere - 📘 Fully Typed — Full TypeScript support with typed interfaces
⚡ Quick Start
npm install @myko.pk/redisRedis
import { Module } from '@nestjs/common';
import { RedisModule } from '@myko.pk/redis';
@Module({
imports: [RedisModule],
})
export class AppModule {}import { Injectable } from '@nestjs/common';
import { RedisService } from '@myko.pk/redis';
@Injectable()
export class MyService {
constructor(private readonly redis: RedisService) {}
async cacheUser(id: string, data: any) {
await this.redis.setNamespaced(`user:${id}`, data, { ex: 3600 });
}
async getUser(id: string) {
return this.redis.getNamespaced(`user:${id}`);
}
}Keys are automatically namespaced: my-service:user:abc123
Bloom Filter
import { Module } from '@nestjs/common';
import { BloomFilterModule } from '@myko.pk/redis/bloom';
@Module({
imports: [BloomFilterModule],
})
export class AppModule {}import { Injectable, OnModuleInit } from '@nestjs/common';
import { BloomFilterService } from '@myko.pk/redis/bloom';
@Injectable()
export class MyService implements OnModuleInit {
constructor(private readonly bloom: BloomFilterService) {}
async onModuleInit() {
await this.bloom.initialize(async () => {
const users = await this.userRepo.findAll();
return users.map(u => `email:${u.email.toLowerCase()}`);
});
}
async isEmailUsed(email: string): Promise<boolean> {
return this.bloom.has(`email:${email.toLowerCase()}`);
}
}Modules
RedisModule
| Export | Description |
|--------|-------------|
| RedisModule | @Global() module — auto-configures from env |
| RedisService | Injectable dual-mode Redis client |
Environment Variables:
| Variable | Purpose |
|----------|---------|
| REDIS_PUBLIC_URL | Use ioredis (Railway Redis) |
| UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN | Use Upstash Redis REST |
| APP_NAME | Namespace prefix for all keys |
RedisService Methods:
| Method | Description |
|--------|-------------|
| setNamespaced(key, value, opts?) | Set with auto-namespacing + TTL |
| getNamespaced(key) | Get and deserialize |
| getAndDeleteNamespaced(key) | Atomic GETDEL (Redis 6.2+) |
| delNamespaced(key) | Delete |
| existsNamespaced(key) | Check existence |
| expireNamespaced(key, sec) | Set TTL |
| setMultiple(entries) | Pipeline batch set |
| invalidatePattern(pattern) | Wildcard invalidation (SCAN + DEL) |
| getServiceKeys(pattern?) | List all keys for this service |
| clearServiceCache() | Delete all keys for this service |
| ping() | Health check |
| lpush(key, ...values) | Push to list head |
| rpop(key) | Pop from list tail |
| llen(key) | List length |
BloomFilterModule
| Export | Description |
|--------|-------------|
| BloomFilterModule | @Global() module |
| BloomFilterService | Injectable in-memory Bloom filter |
BloomFilterService Methods:
| Method | Description |
|--------|-------------|
| initialize(fetcher) | Load items from async callback |
| has(item) | Check if item might exist |
| add(item) | Insert single item |
| addMany(items) | Insert multiple items |
| info() | Get filter stats |
| clear() | Reset filter |
| estimatedFalsePositiveRate() | Current FP rate estimate |
API Reference
Types
| Type | Source | Description |
|------|--------|-------------|
| RedisSetOptions | @myko.pk/types | { ex?, px?, nx?, xx? } |
| BloomFilterOptions | ./bloom/bloom-filter.types | { expectedElements?, falsePositiveRate? } |
| BloomFilterInfo | ./bloom/bloom-filter.types | Filter stats |
DI Tokens
None — both modules are @Global() and their services are injectable directly.
🚀 Available Scripts
- build —
npm run build - dev —
npm run dev - typecheck —
npm run typecheck
👥 Contributors
See the full list of contributors →
👥 Contributing
Contributions are welcome! Here's the standard flow:
- Fork the repository
- Clone your fork:
git clone https://github.com/mykopk/redis.git - Branch:
git checkout -b feature/your-feature - Commit:
git commit -m 'feat: add some feature' - Push:
git push origin feature/your-feature - Open a pull request
📜 License
This project is licensed under the MIT License.
MYKO Pakistan
Detail Information Website myko.pk Email [email protected] About Building digital infrastructure and super-app experiences for millions of users across Pakistan. Built with ❤️ in Pakistan 🇵🇰
