@b9g/cache-redis 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,195 @@
1
+ # @b9g/cache-redis
2
+
3
+ Redis cache adapter for Shovel's universal cache system.
4
+
5
+ ## Features
6
+
7
+ - **HTTP-aware caching**: Stores complete HTTP responses with headers and status codes
8
+ - **TTL support**: Configurable time-to-live for cache entries
9
+ - **Size limits**: Configurable maximum entry size to prevent memory issues
10
+ - **Connection pooling**: Uses the official Redis client with connection management
11
+ - **Error resilience**: Graceful handling of Redis connection issues
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ bun install @b9g/cache-redis
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Basic Usage
22
+
23
+ ```typescript
24
+ import {CustomCacheStorage} from "@b9g/cache";
25
+ import {createRedisFactory} from "@b9g/cache-redis";
26
+
27
+ // Create cache storage with Redis backend
28
+ const cacheStorage = new CustomCacheStorage(createRedisFactory({
29
+ redis: {
30
+ url: "redis://localhost:6379"
31
+ },
32
+ defaultTTL: 3600, // 1 hour
33
+ prefix: "myapp"
34
+ }));
35
+
36
+ // Use the cache
37
+ const cache = await cacheStorage.open("pages");
38
+ await cache.put(request, response);
39
+ const cached = await cache.match(request);
40
+ ```
41
+
42
+ ### With Platform Integration
43
+
44
+ ```typescript
45
+ import {CustomCacheStorage} from "@b9g/cache";
46
+ import {createRedisFactory} from "@b9g/cache-redis";
47
+
48
+ // In your platform configuration
49
+ const platform = createBunPlatform({
50
+ cache: {
51
+ factory: createRedisFactory({
52
+ redis: {
53
+ url: process.env.REDIS_URL || "redis://localhost:6379",
54
+ password: process.env.REDIS_PASSWORD
55
+ },
56
+ defaultTTL: 3600,
57
+ maxEntrySize: 5 * 1024 * 1024 // 5MB max per entry
58
+ })
59
+ }
60
+ });
61
+ ```
62
+
63
+ ## Configuration Options
64
+
65
+ ### RedisCacheOptions
66
+
67
+ - `redis?: RedisClientOptions` - Redis connection configuration
68
+ - `prefix?: string` - Key prefix for Redis keys (default: "cache")
69
+ - `defaultTTL?: number` - Default TTL in seconds (0 = no expiration)
70
+ - `maxEntrySize?: number` - Maximum cache entry size in bytes (default: 10MB)
71
+
72
+ ### Redis Connection Options
73
+
74
+ The `redis` option accepts all standard Redis client options:
75
+
76
+ ```typescript
77
+ {
78
+ redis: {
79
+ url: "redis://localhost:6379",
80
+ password: "your-password",
81
+ database: 0,
82
+ connectTimeout: 10000,
83
+ lazyConnect: true
84
+ }
85
+ }
86
+ ```
87
+
88
+ ## Environment Variables
89
+
90
+ Common Redis configuration via environment variables:
91
+
92
+ - `REDIS_URL` - Complete Redis connection URL
93
+ - `REDIS_HOST` - Redis hostname
94
+ - `REDIS_PORT` - Redis port
95
+ - `REDIS_PASSWORD` - Redis password
96
+ - `REDIS_DB` - Redis database number
97
+
98
+ ## Performance Considerations
99
+
100
+ ### Entry Size Limits
101
+
102
+ Large responses are automatically rejected to prevent memory issues:
103
+
104
+ ```typescript
105
+ const cache = new RedisCache("large-files", {
106
+ maxEntrySize: 1024 * 1024 // 1MB limit
107
+ });
108
+ ```
109
+
110
+ ### TTL Configuration
111
+
112
+ Configure TTL based on your caching strategy:
113
+
114
+ ```typescript
115
+ // Short-lived API responses
116
+ const apiCache = new RedisCache("api", {
117
+ defaultTTL: 300 // 5 minutes
118
+ });
119
+
120
+ // Long-lived static assets
121
+ const staticCache = new RedisCache("static", {
122
+ defaultTTL: 86400 // 24 hours
123
+ });
124
+
125
+ // Permanent cache (manual invalidation)
126
+ const permanentCache = new RedisCache("permanent", {
127
+ defaultTTL: 0 // No expiration
128
+ });
129
+ ```
130
+
131
+ ### Connection Pooling
132
+
133
+ The Redis client automatically manages connection pooling. For high-traffic applications, consider tuning connection settings:
134
+
135
+ ```typescript
136
+ {
137
+ redis: {
138
+ socket: {
139
+ connectTimeout: 10000,
140
+ keepAlive: true,
141
+ noDelay: true
142
+ },
143
+ isolationPoolOptions: {
144
+ min: 2,
145
+ max: 10
146
+ }
147
+ }
148
+ }
149
+ ```
150
+
151
+ ## Error Handling
152
+
153
+ The Redis cache gracefully handles connection issues:
154
+
155
+ - Failed connections return `undefined` for cache misses
156
+ - Connection errors are logged but don't crash the application
157
+ - Automatic reconnection when Redis becomes available
158
+
159
+ ## Cache Statistics
160
+
161
+ Get insights into cache performance:
162
+
163
+ ```typescript
164
+ const cache = new RedisCache("my-cache");
165
+ const stats = await cache.getStats();
166
+
167
+ console.log({
168
+ connected: stats.connected,
169
+ keyCount: stats.keyCount,
170
+ totalSize: stats.totalSize,
171
+ prefix: stats.prefix
172
+ });
173
+ ```
174
+
175
+ ## Cleanup
176
+
177
+ Properly dispose of cache instances:
178
+
179
+ ```typescript
180
+ // Dispose single cache
181
+ await cache.dispose();
182
+
183
+ // Dispose entire cache storage
184
+ await cacheStorage.dispose();
185
+ ```
186
+
187
+ ## Shovel Integration
188
+
189
+ This cache adapter is designed to work seamlessly with Shovel's cache-first architecture:
190
+
191
+ - **Platform agnostic**: Works with any Shovel platform (Bun, Node.js, Cloudflare)
192
+ - **HTTP-aware**: Preserves response headers and status codes
193
+ - **ServiceWorker compatible**: Implements the standard Cache API interface
194
+
195
+ For more information about Shovel's caching system, see the [@b9g/cache](../cache) documentation.
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "@b9g/cache-redis",
3
+ "version": "0.1.0",
4
+ "description": "Redis cache adapter for Shovel cache system",
5
+ "keywords": [
6
+ "cache",
7
+ "redis",
8
+ "shovel",
9
+ "metaframework",
10
+ "cache-adapter"
11
+ ],
12
+ "author": "Shovel Team",
13
+ "license": "MIT",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/b9g/shovel.git",
17
+ "directory": "packages/cache-redis"
18
+ },
19
+ "dependencies": {
20
+ "redis": "^4.6.10"
21
+ },
22
+ "devDependencies": {
23
+ "@b9g/libuild": "^0.1.10"
24
+ },
25
+ "peerDependencies": {
26
+ "@b9g/cache": "workspace:*"
27
+ },
28
+ "type": "module",
29
+ "types": "src/index.d.ts",
30
+ "files": [
31
+ "README.md",
32
+ "src/"
33
+ ],
34
+ "main": "src/index.cjs",
35
+ "module": "src/index.js",
36
+ "exports": {
37
+ ".": {
38
+ "types": "./src/index.d.ts",
39
+ "import": "./src/index.js",
40
+ "require": "./src/index.cjs"
41
+ },
42
+ "./factory": {
43
+ "types": "./src/factory.d.ts",
44
+ "import": "./src/factory.js",
45
+ "require": "./src/factory.cjs"
46
+ },
47
+ "./factory.js": {
48
+ "types": "./src/factory.d.ts",
49
+ "import": "./src/factory.js",
50
+ "require": "./src/factory.cjs"
51
+ },
52
+ "./index": {
53
+ "types": "./src/index.d.ts",
54
+ "import": "./src/index.js",
55
+ "require": "./src/index.cjs"
56
+ },
57
+ "./index.js": {
58
+ "types": "./src/index.d.ts",
59
+ "import": "./src/index.js",
60
+ "require": "./src/index.cjs"
61
+ },
62
+ "./redis-cache": {
63
+ "types": "./src/redis-cache.d.ts",
64
+ "import": "./src/redis-cache.js",
65
+ "require": "./src/redis-cache.cjs"
66
+ },
67
+ "./redis-cache.js": {
68
+ "types": "./src/redis-cache.d.ts",
69
+ "import": "./src/redis-cache.js",
70
+ "require": "./src/redis-cache.cjs"
71
+ },
72
+ "./package.json": "./package.json"
73
+ }
74
+ }
@@ -0,0 +1,34 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/factory.ts
20
+ var factory_exports = {};
21
+ __export(factory_exports, {
22
+ createRedisFactory: () => createRedisFactory
23
+ });
24
+ module.exports = __toCommonJS(factory_exports);
25
+ var import_redis_cache = require("./redis-cache.cjs");
26
+ function createRedisFactory(options = {}) {
27
+ return (name) => {
28
+ return new import_redis_cache.RedisCache(name, options);
29
+ };
30
+ }
31
+ // Annotate the CommonJS export names for ESM import in node:
32
+ 0 && (module.exports = {
33
+ createRedisFactory
34
+ });
@@ -0,0 +1,19 @@
1
+ import { type CacheFactory } from "@b9g/cache";
2
+ import { type RedisCacheOptions } from "./redis-cache.js";
3
+ /**
4
+ * Create a Redis cache factory for use with CustomCacheStorage
5
+ *
6
+ * Example usage:
7
+ * ```typescript
8
+ * import {CustomCacheStorage} from "@b9g/cache";
9
+ * import {createRedisFactory} from "@b9g/cache-redis";
10
+ *
11
+ * const cacheStorage = new CustomCacheStorage(createRedisFactory({
12
+ * redis: { url: "redis://localhost:6379" },
13
+ * defaultTTL: 3600 // 1 hour
14
+ * }));
15
+ *
16
+ * const cache = await cacheStorage.open("my-cache");
17
+ * ```
18
+ */
19
+ export declare function createRedisFactory(options?: RedisCacheOptions): CacheFactory;
package/src/factory.js ADDED
@@ -0,0 +1,11 @@
1
+ /// <reference types="./factory.d.ts" />
2
+ // src/factory.ts
3
+ import { RedisCache } from "./redis-cache.js";
4
+ function createRedisFactory(options = {}) {
5
+ return (name) => {
6
+ return new RedisCache(name, options);
7
+ };
8
+ }
9
+ export {
10
+ createRedisFactory
11
+ };
package/src/index.cjs ADDED
@@ -0,0 +1,32 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/index.ts
20
+ var src_exports = {};
21
+ __export(src_exports, {
22
+ RedisCache: () => import_redis_cache.RedisCache,
23
+ createRedisFactory: () => import_factory.createRedisFactory
24
+ });
25
+ module.exports = __toCommonJS(src_exports);
26
+ var import_redis_cache = require("./redis-cache.cjs");
27
+ var import_factory = require("./factory.cjs");
28
+ // Annotate the CommonJS export names for ESM import in node:
29
+ 0 && (module.exports = {
30
+ RedisCache,
31
+ createRedisFactory
32
+ });
package/src/index.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @b9g/cache-redis - Redis cache adapter for Shovel
3
+ *
4
+ * Provides Redis-backed caching with HTTP-aware storage and retrieval
5
+ */
6
+ export { RedisCache, type RedisCacheOptions } from "./redis-cache.js";
7
+ export { createRedisFactory } from "./factory.js";
package/src/index.js ADDED
@@ -0,0 +1,8 @@
1
+ /// <reference types="./index.d.ts" />
2
+ // src/index.ts
3
+ import { RedisCache } from "./redis-cache.js";
4
+ import { createRedisFactory } from "./factory.js";
5
+ export {
6
+ RedisCache,
7
+ createRedisFactory
8
+ };