npm package: @tamasha/redis-connection
Description: Singleton Redis connection manager with optimized connection handling
Author: Tamasha Team
Latest version: 1.0.0

# @tamasha/redis-connection

Simple and efficient Redis connection manager for Node.js applications. Automatically manages connections, handles reconnection, and provides a clean API.

## Quick Start

### Step 1: Install

```bash
npm install @tamasha/redis-connection
```

### Step 2: Import

**TypeScript / ES Modules:**
```typescript
import { RedisConnection } from '@tamasha/redis-connection';
```

**JavaScript (CommonJS):**
```javascript
const { RedisConnection } = require('@tamasha/redis-connection');
```

**JavaScript (ES Modules):**
```javascript
import { RedisConnection } from '@tamasha/redis-connection';
```

### Step 3: Use

```typescript
// Define configuration
const redisConfig = {
  host: 'localhost',  // or process.env.REDIS_HOST
  port: 6379,          // or process.env.REDIS_PORT
};

// Get Redis client (connection is automatic)
const client = await RedisConnection.getInstance(redisConfig);

// Use Redis commands
await client.set('key', 'value');
const value = await client.get('key');
console.log(value); // 'value'
```

That's it! The connection is managed automatically. You can call `getInstance()` multiple times with the same config and it will reuse the same connection.

## Common Use Cases

### 1. Simple Caching

```typescript
const client = await RedisConnection.getInstance({
  host: 'localhost',
  port: 6379,
});

// Store data with expiration (1 hour)
await client.set('user:123', JSON.stringify(userData), { EX: 3600 });

// Retrieve data
const cached = await client.get('user:123');
if (cached) {
  const user = JSON.parse(cached);
}
```

### 2. Create Helper Functions

```typescript
// utils/redis.ts
import { RedisConnection } from '@tamasha/redis-connection';

const config = {
  host: process.env.REDIS_HOST || 'localhost',
  port: parseInt(process.env.REDIS_PORT || '6379'),
};

export async function cacheGet(key: string): Promise<string | null> {
  const client = await RedisConnection.getInstance(config);
  return await client.get(key);
}

export async function cacheSet(key: string, value: string, seconds?: number): Promise<void> {
  const client = await RedisConnection.getInstance(config);
  if (seconds) {
    await client.set(key, value, { EX: seconds });
  } else {
    await client.set(key, value);
  }
}

// Use in your app
import { cacheGet, cacheSet } from './utils/redis';

await cacheSet('mykey', 'myvalue', 300); // Cache for 5 minutes
const value = await cacheGet('mykey');
```

### 3. Express.js Integration

```typescript
import express from 'express';
import { RedisConnection } from '@tamasha/redis-connection';

const app = express();
const redisConfig = { host: 'localhost', port: 6379 };

app.get('/api/users/:id', async (req, res) => {
  const client = await RedisConnection.getInstance(redisConfig);
  const cacheKey = `user:${req.params.id}`;
  
  // Try cache first
  const cached = await client.get(cacheKey);
  if (cached) {
    return res.json(JSON.parse(cached));
  }
  
  // Fetch from database
  const user = await db.getUser(req.params.id);
  
  // Cache for 10 minutes
  await client.set(cacheKey, JSON.stringify(user), { EX: 600 });
  
  res.json(user);
});
```

### 4. Session Management

```typescript
const client = await RedisConnection.getInstance({ host: 'localhost', port: 6379 });

// Store session (24 hours)
const sessionId = 'session_abc123';
await client.set(
  `session:${sessionId}`,
  JSON.stringify({ userId: '123', email: 'user@example.com' }),
  { EX: 86400 }
);

// Retrieve session
const session = await client.get(`session:${sessionId}`);
if (session) {
  const data = JSON.parse(session);
}

// Delete session on logout
await client.del(`session:${sessionId}`);
```

### 5. Rate Limiting

```typescript
const client = await RedisConnection.getInstance({ host: 'localhost', port: 6379 });

const userId = 'user123';
const rateLimitKey = `ratelimit:${userId}`;

// Check current count
const count = await client.get(rateLimitKey);
const requestCount = count ? parseInt(count) : 0;

if (requestCount >= 100) {
  console.log('Rate limit exceeded!');
} else {
  // Increment counter
  if (requestCount === 0) {
    await client.set(rateLimitKey, '1', { EX: 3600 }); // 1 hour window
  } else {
    await client.incr(rateLimitKey);
  }
}
```

## Configuration

### Basic Configuration (Required)

```typescript
{
  host: string;  // Redis server host
  port: number;  // Redis server port (1-65535)
}
```

### Advanced Configuration (Optional)

```typescript
{
  host: 'localhost',
  port: 6379,
  connectTimeout: 5000,  // Connection timeout in ms (default: 5000)
  socket: {
    connectTimeout: 5000,
    reconnectStrategy: (retries) => {
      // Custom reconnection strategy
      if (retries > 10) return new Error('Max retries reached');
      return Math.min(1000 * Math.pow(2, retries), 30000);
    },
  },
}
```

### Environment Variables

```bash
# .env
REDIS_HOST=localhost
REDIS_PORT=6379
```

```typescript
const redisConfig = {
  host: process.env.REDIS_HOST || 'localhost',
  port: parseInt(process.env.REDIS_PORT || '6379'),
};
```

## API Reference

### `RedisConnection.getInstance(config)`

Get or create a Redis client instance. Returns the same instance for the same configuration (singleton pattern).

```typescript
const client = await RedisConnection.getInstance({
  host: 'localhost',
  port: 6379,
});
```

### `RedisConnection.isConnected(config)`

Check if a connection exists and is open.

```typescript
const isConnected = RedisConnection.isConnected({
  host: 'localhost',
  port: 6379,
});
```

### `RedisConnection.disconnect(config)`

Disconnect a specific Redis connection.

```typescript
await RedisConnection.disconnect({
  host: 'localhost',
  port: 6379,
});
```

### `RedisConnection.disconnectAll()`

Disconnect all Redis connections (useful for cleanup on app shutdown).

```typescript
// In your app shutdown handler
process.on('SIGTERM', async () => {
  await RedisConnection.disconnectAll();
  process.exit(0);
});
```

## Features

- ✅ **Singleton Pattern** - One connection per host:port (efficient resource usage)
- ✅ **Simple API** - Only requires host and port
- ✅ **Automatic Reconnection** - Handles disconnections automatically
- ✅ **Type-Safe** - Full TypeScript support
- ✅ **Error Handling** - Built-in error handling and logging
- ✅ **Production Ready** - Used in production environments

## Examples

See `examples/usage.ts` for complete, real-world usage examples showing:

- How to import the package
- Basic usage patterns
- Service class implementation
- Express.js integration
- Session management
- Rate limiting
- And more practical examples

### Quick Example

```typescript
// 1. Install: npm install @tamasha/redis-connection

// 2. Import
import { RedisConnection } from '@tamasha/redis-connection';

// 3. Use in your code
const client = await RedisConnection.getInstance({
  host: process.env.REDIS_HOST || 'localhost',
  port: parseInt(process.env.REDIS_PORT || '6379'),
});

await client.set('key', 'value');
const value = await client.get('key');
```

## Redis Commands

Since this package uses the official `redis` package, you can use all Redis commands:

```typescript
const client = await RedisConnection.getInstance({ host: 'localhost', port: 6379 });

// Strings
await client.set('key', 'value');
await client.get('key');
await client.del('key');

// Hashes
await client.hSet('user:1', { name: 'John', email: 'john@example.com' });
await client.hGetAll('user:1');

// Lists
await client.lPush('tasks', ['task1', 'task2']);
await client.lRange('tasks', 0, -1);

// Sets
await client.sAdd('tags', ['javascript', 'typescript']);
await client.sMembers('tags');

// And many more...
```

See [Redis Commands Reference](https://redis.io/commands) for all available commands.

## Best Practices

1. **Initialize Once**: Create connections at application startup
2. **Reuse Connections**: The singleton pattern ensures efficient connection reuse
3. **Use Environment Variables**: Store connection details in environment variables
4. **Cleanup on Shutdown**: Disconnect all connections when your app shuts down
5. **Error Handling**: Wrap Redis operations in try-catch blocks

## License

MIT

## Links

- [Redis Node.js Client](https://github.com/redis/node-redis)
- [Redis Commands](https://redis.io/commands)