npm package: @raburski/next-api-inmemory-cache
Description: In-memory caching middleware for Next.js API routes with TTL support and cache invalidation
Latest version: 0.1.0

# @raburski/next-api-inmemory-cache

In-memory caching middleware for Next.js API routes with TTL support and cache invalidation.

## Installation

```bash
npm install @raburski/next-api-inmemory-cache
```

## Features

- ✅ In-memory Node.js runtime caching
- ✅ TTL-based expiration (1 hour default)
- ✅ Key-based cache invalidation
- ✅ Pattern-based cache invalidation
- ✅ Composable middleware (works with `@raburski/next-api-middleware`)
- ✅ Automatic response cloning for reusability

## Usage

### Basic Cache Middleware

```typescript
import { withCache } from "@raburski/next-api-inmemory-cache"
import { APIHandler, APIContext } from "@raburski/next-api-middleware"
import { NextRequest, NextResponse } from "next/server"

const handler: APIHandler = async (request: NextRequest, context: APIContext) => {
	const data = await fetchExpensiveData()
	return NextResponse.json(data)
}

export const GET = withCache((request) => {
	// Generate cache key from request
	return `my-cache-key`
})(handler)
```

### Using with compose

```typescript
import { compose } from "@raburski/next-api-middleware"
import { withCache } from "@raburski/next-api-inmemory-cache"
import { withAuth } from "@raburski/next-auth-permissions/server"

export const GET = compose(
	withAuth,
	withCache((req) => `cache-key`)
)(handler)
```

### Manual Cache Operations

```typescript
import { cacheService } from "@raburski/next-api-inmemory-cache"

// Invalidate specific key
cacheService.invalidate("my-cache-key")

// Invalidate by pattern
cacheService.invalidatePattern("^options:")

// Get cache statistics
const stats = cacheService.getStats()
console.log(`Cache size: ${stats.size}`)
console.log(`Cached keys: ${stats.keys.join(", ")}`)

// Clear entire cache
cacheService.clear()
```

### Custom Cache Service

```typescript
import { CacheService } from "@raburski/next-api-inmemory-cache"

// Create a cache with custom TTL (30 minutes)
const customCache = new CacheService(1000 * 60 * 30)

// Use the custom cache service
const cachedResponse = customCache.get("my-key")
```

## How It Works

1. **Cache Hit**: When a request matches a cached key, the cached response is returned immediately
2. **Cache Miss**: When no cache exists, the handler executes, and successful responses (status 200) are cached
3. **Cache Invalidation**: When data changes, the relevant cache keys are deleted
4. **TTL Expiration**: Cached entries automatically expire after the TTL period (default: 1 hour)

## Implementation Details

### Response Storage

Instead of storing `NextResponse` objects directly (which can't be reused once their body is read), the cache stores response data in a plain format:
- Body content (as string)
- Status code
- Status text
- Headers (as plain object)
- Timestamp

When retrieving from cache, a fresh `NextResponse` is created from this stored data, allowing unlimited reuse.

## Limitations

- In-memory cache is not shared across multiple server instances
- Cache is cleared when the server restarts
- Not suitable for user-specific or frequently changing data
- Only successful responses (status 200) are cached

## License

MIT