{"_id":"@actvalue/prisma-extension-redis","_rev":"4-8496816d2433776d35ee618ae1a98f32","name":"@actvalue/prisma-extension-redis","dist-tags":{"latest":"2.3.2"},"versions":{"3.0.1":{"name":"@actvalue/prisma-extension-redis","version":"3.0.1","keywords":["prisma","extension","redis","cache","uncache","dragonfly","middleware","manager"],"author":{"name":"ActValue"},"license":"MIT","_id":"@actvalue/prisma-extension-redis@3.0.1","maintainers":[{"name":"pmosconi","email":"pmosconi@gmail.com"},{"name":"albertomosconi","email":"albertomaria.mosconi@gmail.com"}],"homepage":"https://github.com/pmosconi/prisma-extension-redis","bugs":{"url":"https://github.com/pmosconi/prisma-extension-redis/issues"},"dist":{"shasum":"7b537cefd7fc8a05cfce658b3d931a0f16f9d47b","tarball":"https://registry.npmjs.org/@actvalue/prisma-extension-redis/-/prisma-extension-redis-3.0.1.tgz","fileCount":8,"integrity":"sha512-Gore/lZNk9qeJ5F3OVcihMkINeDH1m4tjwFKVjl+rJqFbcknQ9kycoMplFbMYIusmpDTMhKrrnky85OD3cfEJg==","signatures":[{"sig":"MEUCIQD/qooRVAOFZnqrXnDxlLld/jHo4h0HTW4k/DYwjroh/gIgK7jZX84CDise7KFTJXW9Y2H6IFFxLl8f+qekTTjwNa0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":472058},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"bfd4817de4da2c338fec111d78fef4d4f6b99c95","release":{"branches":["main","next","beta"]},"scripts":{"dev":"tsup --watch","fix":"biome format --fix","lint":"biome lint","test":"bun test","biome":"biome","build":"tsup","clean":"biome clean","format":"biome format","compile":"tsc","prepare":"bun run compile","pretest":"docker compose -f test/compose.yaml up -d && bunx prisma@5 migrate dev --schema ./test/prisma/schema.prisma","release":"semantic-release","posttest":"bun run lint"},"_npmUser":{"name":"pmosconi","email":"pmosconi@gmail.com"},"repository":{"url":"git+https://github.com/pmosconi/prisma-extension-redis.git","type":"git"},"_npmVersion":"10.9.0","description":"Extensive Prisma extension designed for efficient caching and cache invalidation using Redis and Dragonfly Databases","directories":{},"_nodeVersion":"22.12.0","dependencies":{"iovalkey":"^0.2.1","micromatch":"^4.0.7","object-code":"^1.3.3","@prisma/client":"^5.18.0","promise-coalesce":"^1.1.2"},"publishConfig":{"access":"public"},"typesVersions":{"*":{}},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.2.4","@types/bun":"^1.1.13","typescript":"^5.5.4","@types/node":"^20.16.1","@biomejs/biome":"^1.9.4","@types/lodash-es":"^4.17.12","semantic-release":"^24.2.0","@types/micromatch":"^4.0.9"},"_npmOperationalInternal":{"tmp":"tmp/prisma-extension-redis_3.0.1_1744908341220_0.8925169615984954","host":"s3://npm-registry-packages-npm-production"}},"2.3.2":{"name":"@actvalue/prisma-extension-redis","version":"2.3.2","description":"Extensive Prisma extension designed for efficient caching and cache invalidation using Redis and Dragonfly Databases","repository":{"type":"git","url":"git+https://github.com/pmosconi/prisma-extension-redis.git"},"homepage":"https://github.com/pmosconi/prisma-extension-redis","bugs":{"url":"https://github.com/pmosconi/prisma-extension-redis/issues"},"author":{"name":"ActValue"},"keywords":["prisma","extension","redis","cache","uncache","dragonfly","middleware","manager"],"license":"MIT","main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","require":"./dist/index.js","import":"./dist/index.mjs"},"./package.json":"./package.json"},"typesVersions":{"*":{}},"scripts":{"build":"tsup","biome":"biome","dev":"tsup --watch","format":"biome format","test":"bun test","lint":"biome lint","clean":"biome clean","compile":"tsc","fix":"biome format --fix","prepare":"bun run compile","pretest":"docker compose -f test/compose.yaml up -d && bunx prisma@5 migrate dev --schema ./test/prisma/schema.prisma","posttest":"bun run lint","release":"semantic-release"},"devDependencies":{"@biomejs/biome":"^1.9.4","@types/bun":"^1.1.13","@types/lodash-es":"^4.17.12","@types/micromatch":"^4.0.9","@types/node":"^20.16.1","semantic-release":"^24.2.0","tsup":"^8.2.4","typescript":"^5.5.4"},"publishConfig":{"access":"public"},"release":{"branches":["main","next","beta"]},"dependencies":{"@prisma/client":"^5.18.0","iovalkey":"^0.2.1","micromatch":"^4.0.7","object-code":"^1.3.3","promise-coalesce":"^1.1.2"},"_id":"@actvalue/prisma-extension-redis@2.3.2","gitHead":"c798f0f63d5be610804619c52500542916206c83","_nodeVersion":"22.12.0","_npmVersion":"10.9.0","dist":{"integrity":"sha512-75X99kMib8kfoigcFc7CIOYhB3UbKUOHnCRBcwOqaR5MEZkfq9ktV7cChiInYrpqMU+Zy/jpyRH25mb7TDJjRw==","shasum":"a8511c48fa54c6ddcd974a1af7d43cedb45efb36","tarball":"https://registry.npmjs.org/@actvalue/prisma-extension-redis/-/prisma-extension-redis-2.3.2.tgz","fileCount":8,"unpackedSize":473345,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIDasMJtYLw8JTzLWMiqUeHrkXsakufGS+xZS4bwMxhoGAiAO9My1TYn+F7UvXhX3YqEip+KIE79ftEyV3AYG4MPPQQ=="}]},"_npmUser":{"name":"pmosconi","email":"pmosconi@gmail.com"},"directories":{},"maintainers":[{"name":"pmosconi","email":"pmosconi@gmail.com"},{"name":"albertomosconi","email":"albertomaria.mosconi@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/prisma-extension-redis_2.3.2_1744973843298_0.010244936336756716"},"_hasShrinkwrap":false}},"time":{"created":"2025-04-17T16:45:41.113Z","modified":"2025-04-18T10:57:23.711Z","3.0.1":"2025-04-17T16:45:41.444Z","2.3.1":"2025-04-18T10:46:08.883Z","2.3.2":"2025-04-18T10:57:23.516Z"},"bugs":{"url":"https://github.com/pmosconi/prisma-extension-redis/issues"},"author":{"name":"ActValue"},"license":"MIT","homepage":"https://github.com/pmosconi/prisma-extension-redis","keywords":["prisma","extension","redis","cache","uncache","dragonfly","middleware","manager"],"repository":{"type":"git","url":"git+https://github.com/pmosconi/prisma-extension-redis.git"},"description":"Extensive Prisma extension designed for efficient caching and cache invalidation using Redis and Dragonfly Databases","maintainers":[{"name":"pmosconi","email":"pmosconi@gmail.com"},{"name":"albertomosconi","email":"albertomaria.mosconi@gmail.com"}],"readme":"\n# Prisma Extension Redis\n\n[![test](https://github.com/yxx4c/prisma-extension-redis/actions/workflows/test.yml/badge.svg)](https://github.com/yxx4c/prisma-extension-redis/actions/workflows/test.yml)\n[![codecov](https://codecov.io/github/yxx4c/prisma-extension-redis/graph/badge.svg?token=G7O92H6I7T)](https://codecov.io/github/yxx4c/prisma-extension-redis)\n![NPM License](https://img.shields.io/npm/l/prisma-extension-redis)\n![NPM Version (latest)](https://img.shields.io/npm/v/prisma-extension-redis/latest)\n![NPM Version (next)](https://img.shields.io/npm/v/prisma-extension-redis/next)\n![NPM Downloads](https://img.shields.io/npm/dw/prisma-extension-redis)\n\n`prisma-extension-redis` provides seamless integration with Prisma and Redis/Dragonfly databases, offering efficient caching mechanisms to improve data access times and overall application performance.\n\n🚀 If `prisma-extension-redis` proves helpful, consider giving it a star! [⭐ Star Me!](https://github.com/yxx4c/prisma-extension-redis)\n\n---\n\n## Installation\n\nYou can install `prisma-extension-redis` using your preferred package manager:\n\n**Using npm:**\n\n```bash\nnpm install prisma-extension-redis\n```\n\n**Using yarn:**\n\n```bash\nyarn add prisma-extension-redis\n```\n\n**Using pnpm:**\n\n```bash\npnpm add prisma-extension-redis\n```\n\n**Using bun:**\n\n```bash\nbun add prisma-extension-redis\n```\n\n---\n\n## Setup and Configuration\n\n### Step 1: Initialize Required Clients\n\nBefore setting up caching, initialize your Prisma client, Redis client config, and logger:\n\n```javascript\nimport pino from 'pino';\nimport { PrismaClient } from '@prisma/client';\nimport { Redis } from 'iovalkey';\nimport {SuperJSON} from 'superjson';\n\nimport {\n  CacheCase,\n  PrismaExtensionRedis,\n  type AutoCacheConfig,\n  type CacheConfig,\n} from 'prisma-extension-redis';\n\n\n// Prisma Client\nconst prisma = new PrismaClient();\n\n// Redis client config\nconst client = {\n  host: process.env.REDIS_HOST_NAME, // Redis host\n  port: process.env.REDIS_PORT,      // Redis port\n};\n\n// Create a logger using pino (optional)\nconst logger = pino();\n```\n\n### Step 2: Configure Auto-Cache Settings\n\n`auto` settings enable automated caching for read operations with flexible customization.\n\n#### Example Auto-Cache Configuration\n\n```javascript\nconst auto: AutoCacheConfig = {\n  excludedModels: ['Post'], // Models excluded from auto-caching\n  excludedOperations: ['findFirst', 'count', 'findMany'], // Operations excluded from auto-caching\n  models: [\n    {\n      model: 'User', // Model-specific auto-cache settings\n      excludedOperations: ['count'], // Operations to exclude\n      ttl: 10,  // Time-to-live (TTL) for cache in seconds\n      stale: 5, // Stale time in seconds\n    },\n  ],\n  ttl: 30, // Default TTL for cache in seconds\n};\n```\n\n**Note**:\n\n 1. Excluded operations and models will not benefit from auto-caching.\n 2. Use `ttl` and `stale` values to define caching duration.\n\n### Step 3: Configure Cache Client\n\nThe cache client configuration is necessary to enable caching, either automatically or manually.\n\n#### Example Cache Configuration\n\n```javascript\nconst config: CacheConfig = {\n ttl: 60, // Default Time-to-live for caching in seconds\n  stale: 30, // Default Stale time after ttl in seconds\n  auto, // Auto-caching options (configured above)\n  logger, // Logger for cache events (configured above)\n  transformer: {\n    // Custom serialize and deserialize function for additional functionality if required\n    deserialize: data => SuperJSON.parse(data),\n    serialize: data => SuperJSON.stringify(data),\n  },\n  type: 'JSON', // Redis cache type, whether you prefer the data to be stored as JSON or STRING in Redis\n  cacheKey: { // Inbuilt cache key configuration\n    case: CacheCase.SNAKE_CASE, // Select a cache case conversion option for generated keys from CacheCase\n    delimiter: '*', // Delimiter for keys (default value: ':')\n    prefix: 'awesomeness', // Cache key prefix (default value: 'prisma')\n  },\n};\n```\n\n**Note**: Cache case conversion strips all non alpha numeric characters\n\n### Step 4: Extend Prisma Client\n\nNow, extend your Prisma client with caching capabilities using `prisma-extension-redis`:\n\n```javascript\nconst extendedPrisma = prisma.$extends(\n  PrismaExtensionRedis({ config, client })\n);\n```\n\n---\n\n## Usage Guide\n\n### Automatic Caching\n\nWith auto-caching, read operations (e.g., `findUnique`, `findMany`) are cached automatically based on the defined configuration.\n\n**Basic Example:**\n\n```javascript\n// Cached automatically based on auto-cache settings\nextendedPrisma.user.findUnique({\n  where: { id: userId },\n});\n\n// Manually enable cache for a query\nextendedPrisma.user.findUnique({\n  where: { id: userId },\n  cache: true, // Toggle caching on\n});\n\n// Disable cache for specific query\nextendedPrisma.user.findFirst({\n  where: { id: userId },\n  cache: false, // Toggle caching off\n});\n```\n\n**Note**:\n\n1. If `auto-cache` is set to `false` and `cache` is set to `true` for the query, the default values from the cache configuration will be applied.\n2. If `cache` is set to `false` and `auto-cache` is set to `true`, the query will not be cached.\n\n### Custom Caching with `getKey`\n\nFor greater control over caching, generate custom cache keys and TTL settings.\n\n**Example with Custom Cache Key:**\n\n```javascript\nconst customKey = extendedPrisma.getKey({ params: [{ prisma: 'User' }, { id: userId }] });\n\nextendedPrisma.user.findUnique({\n  where: { id: userId },\n  cache: { ttl: 5, key: customKey }, // Custom TTL and cache key\n});\n```\n\n### Cache Invalidation\n\nCache invalidation ensures data consistency by removing or updating cached data when changes occur in the database.\n\n**Example of Cache Invalidation:**\n\n```javascript\n// Invalidate cache when updating a user's information\nextendedPrisma.user.update({\n  where: { id: userId },\n  data: { username: newUsername },\n  uncache: {\n    uncacheKeys: [\n      extendedPrisma.getKey({ params: [{ prisma: 'User' }, { id: userId }] }), // Specific key to invalidate\n      extendedPrisma.getKeyPattern({ params: [{ prisma: '*' }, { id: userId }]}), // Pattern for wildcard invalidation\n      extendedPrisma.getKeyPattern({ params: [{ prisma: 'Post' }, { id: userId }, { glob: '*' }]}), // Use glob for more complex patterns\n    ],\n    hasPattern: true, // Use pattern matching for invalidation\n  },\n});\n```\n\n**Explanation of Cache Invalidation:**\n\n- **`uncacheKeys`**: Specifies the keys or patterns to be invalidated.\n- **`hasPattern`**: Indicates if wildcard patterns are used for key matching.\n\n---\n\n## Key Concepts Explained\n\n### 1. **Time-to-Live (TTL)**\n\n- Specifies how long (in seconds) a cached entry should remain before expiring.\n- **Default TTL**: Used when no specific TTL is provided for a query.\n\n### 2. **Stale Time**\n\n- After the TTL expires, stale time defines how long expired data can still be used while refreshing data in the background.\n- This ensures that users experience minimal latency even when data is being updated.\n\n### 3. **Cache Key Management**\n\n- **`getKey`**: Generates a unique key for caching queries from provided key context parameters.\n- **`getAutoKey`**: Generates a unique key for auto-caching queries, based on query parameters.\n- **`getKeyPattern`**: Creates patterns for more complex invalidation scenarios, using wildcards.\n\n---\n\n## Key Features\n\n- **Auto-Caching**: Automatically cache read operations, reducing redundant queries and improving performance.\n- **Selective Caching**: Customize which queries to cache, how long to cache them, and whether to cache them at all.\n- **Efficient Invalidation**: Keep cached data up-to-date by selectively invalidating caches when updates or deletions occur.\n- **Granular Control**: Easily toggle caching on or off for individual queries as needed.\n- **Logger Support**: Integrate logging to monitor cache hits, misses, and invalidations for easier debugging and optimization.\n\n---\n\n## Prerequisites\n\n- Ensure you have a running Redis or Dragonfly instance. If using Redis, `Redis.JSON` must be enabled to use JSON type cache (by default, it is enabled in Dragonfly).\n\n## Dependencies\n\n- `iovalkey` package is used for Redis connectivity.\n- `micromatch` is used for patter matching for keys.\n- `object-code` is used for generating unique hash in auto-caching keys.\n- `lodash-es` is used for CacheCase logic in key management.\n\n---\n\n## Final Thoughts\n\n`prisma-extension-redis` offers an efficient and powerful way to manage caching in Prisma-based applications. By leveraging both automatic and custom caching, you can optimize your application's performance while maintaining data consistency.\n\nUpgrade to `prisma-extension-redis` for an optimized caching strategy and contribute to its growth by starring the repository if you find it useful!\n","readmeFilename":"README.md"}