@node-ts-cache/ioredis-storage 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Himmet Avsar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # @node-ts-cache/ioredis-storage
2
+
3
+ [![npm](https://img.shields.io/npm/v/@node-ts-cache/ioredis-storage.svg)](https://www.npmjs.org/package/@node-ts-cache/ioredis-storage)
4
+
5
+ Modern Redis storage adapter for [@node-ts-cache/core](https://www.npmjs.com/package/@node-ts-cache/core) using [ioredis](https://github.com/redis/ioredis) with optional Snappy compression.
6
+
7
+ ## Features
8
+
9
+ - Modern `ioredis` client
10
+ - Optional Snappy compression for reduced bandwidth
11
+ - Multi-get/set operations for batch caching
12
+ - Built-in TTL support (uses Redis native SETEX)
13
+ - Custom error handler support
14
+ - Non-blocking write operations (optional)
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @node-ts-cache/core @node-ts-cache/ioredis-storage ioredis
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ### Basic Usage
25
+
26
+ ```typescript
27
+ import { Cache, ExpirationStrategy } from '@node-ts-cache/core';
28
+ import RedisIOStorage from '@node-ts-cache/ioredis-storage';
29
+ import Redis from 'ioredis';
30
+
31
+ const redisClient = new Redis({
32
+ host: 'localhost',
33
+ port: 6379
34
+ });
35
+
36
+ const storage = new RedisIOStorage(
37
+ () => redisClient,
38
+ { maxAge: 3600 } // TTL in seconds (default: 86400 = 24 hours)
39
+ );
40
+
41
+ const strategy = new ExpirationStrategy(storage);
42
+
43
+ class UserService {
44
+ @Cache(strategy, { ttl: 300 })
45
+ async getUser(id: string): Promise<User> {
46
+ return await db.users.findById(id);
47
+ }
48
+ }
49
+ ```
50
+
51
+ ### With Compression
52
+
53
+ Enable Snappy compression to reduce bandwidth usage (useful for large objects):
54
+
55
+ ```typescript
56
+ const storage = new RedisIOStorage(() => redisClient, { maxAge: 3600, compress: true });
57
+ ```
58
+
59
+ ### With Error Handler
60
+
61
+ Configure a custom error handler for non-blocking write operations:
62
+
63
+ ```typescript
64
+ const storage = new RedisIOStorage(() => redisClient, { maxAge: 3600 });
65
+
66
+ storage.onError(error => {
67
+ // Log errors without blocking the application
68
+ console.error('Redis cache error:', error);
69
+ metrics.incrementCacheError();
70
+ });
71
+ ```
72
+
73
+ When an error handler is set, write operations don't await the Redis response, making them non-blocking.
74
+
75
+ ### Multi-Operations with @MultiCache
76
+
77
+ This storage supports batch operations, making it ideal for multi-tier caching:
78
+
79
+ ```typescript
80
+ import { MultiCache, ExpirationStrategy } from '@node-ts-cache/core';
81
+ import RedisIOStorage from '@node-ts-cache/ioredis-storage';
82
+ import NodeCacheStorage from '@node-ts-cache/node-cache-storage';
83
+
84
+ const localCache = new ExpirationStrategy(new NodeCacheStorage());
85
+ const redisCache = new RedisIOStorage(() => redisClient, { maxAge: 3600 });
86
+
87
+ class UserService {
88
+ @MultiCache([localCache, redisCache], 0, id => `user:${id}`)
89
+ async getUsersByIds(ids: string[]): Promise<User[]> {
90
+ return await db.users.findByIds(ids);
91
+ }
92
+ }
93
+ ```
94
+
95
+ ### Direct API Usage
96
+
97
+ ```typescript
98
+ const storage = new RedisIOStorage(() => redisClient, { maxAge: 3600 });
99
+
100
+ // Single item operations
101
+ await storage.setItem('user:123', { name: 'John' }, { ttl: 60 });
102
+ const user = await storage.getItem<{ name: string }>('user:123');
103
+
104
+ // Multi-item operations
105
+ const users = await storage.getItems<User>(['user:1', 'user:2', 'user:3']);
106
+ await storage.setItems(
107
+ [
108
+ { key: 'user:1', content: { name: 'Alice' } },
109
+ { key: 'user:2', content: { name: 'Bob' } }
110
+ ],
111
+ { ttl: 60 }
112
+ );
113
+
114
+ // Clear all (uses FLUSHDB - use with caution!)
115
+ await storage.clear();
116
+ ```
117
+
118
+ ## Constructor
119
+
120
+ ```typescript
121
+ new RedisIOStorage(
122
+ redis: () => Redis.Redis,
123
+ options?: {
124
+ maxAge?: number; // TTL in seconds (default: 86400)
125
+ compress?: boolean; // Enable Snappy compression (default: false)
126
+ }
127
+ )
128
+ ```
129
+
130
+ | Parameter | Type | Description |
131
+ | ------------------ | ------------------- | ----------------------------------------------------- |
132
+ | `redis` | `() => Redis.Redis` | Factory function returning an ioredis client instance |
133
+ | `options.maxAge` | `number` | Default TTL in seconds (default: 86400 = 24 hours) |
134
+ | `options.compress` | `boolean` | Enable Snappy compression (default: false) |
135
+
136
+ ## Interface
137
+
138
+ ```typescript
139
+ interface IAsynchronousCacheType {
140
+ getItem<T>(key: string): Promise<T | undefined>;
141
+ setItem(key: string, content: any, options?: { ttl?: number }): Promise<void>;
142
+ clear(): Promise<void>;
143
+ }
144
+
145
+ interface IMultiIAsynchronousCacheType {
146
+ getItems<T>(keys: string[]): Promise<{ [key: string]: T | undefined }>;
147
+ setItems(values: { key: string; content: any }[], options?: { ttl?: number }): Promise<void>;
148
+ clear(): Promise<void>;
149
+ }
150
+ ```
151
+
152
+ ## TTL Behavior
153
+
154
+ This storage uses Redis native TTL (SETEX command) rather than relying solely on ExpirationStrategy:
155
+
156
+ - `options.maxAge` in constructor sets the default TTL
157
+ - `options.ttl` in setItem/setItems overrides the default
158
+ - When used with ExpirationStrategy, both TTLs apply (Redis TTL for storage-level, strategy TTL for metadata)
159
+
160
+ ## Value Handling
161
+
162
+ - `undefined`: Deletes the key from Redis
163
+ - `null`: Stores as empty string `""`
164
+ - Objects: JSON stringified before storage
165
+ - Primitives: Stored directly
166
+
167
+ ## Dependencies
168
+
169
+ - `ioredis` ^5.3.2 - Modern Redis client
170
+ - `snappy` ^7.0.5 - Fast compression library
171
+
172
+ ## Requirements
173
+
174
+ - Node.js >= 18.0.0
175
+ - Redis server
176
+
177
+ ## License
178
+
179
+ MIT
@@ -0,0 +1,2 @@
1
+ import { RedisIOStorage } from './redisio.storage.js';
2
+ export default RedisIOStorage;
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import { RedisIOStorage } from './redisio.storage.js';
2
+ export default RedisIOStorage;
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,eAAe,cAAc,CAAC"}
@@ -0,0 +1,29 @@
1
+ /// <reference types="node" />
2
+ import { IAsynchronousCacheType, IMultiIAsynchronousCacheType } from '@node-ts-cache/core';
3
+ import * as Redis from 'ioredis';
4
+ export declare class RedisIOStorage implements IAsynchronousCacheType, IMultiIAsynchronousCacheType {
5
+ private redis;
6
+ private options;
7
+ constructor(redis: () => Redis.Redis, options?: {
8
+ maxAge: number;
9
+ compress?: boolean;
10
+ });
11
+ private errorHandler;
12
+ onError(listener: (error: Error) => void): void;
13
+ getItems<T>(keys: string[]): Promise<{
14
+ [key: string]: T | undefined;
15
+ }>;
16
+ compress(uncompressed: string): Promise<Buffer>;
17
+ uncompress(compressed: Buffer): Promise<string>;
18
+ setItems<T = unknown>(values: {
19
+ key: string;
20
+ content: T | undefined;
21
+ }[], options?: {
22
+ ttl?: number;
23
+ }): Promise<void>;
24
+ getItem<T>(key: string): Promise<T | undefined>;
25
+ setItem<T = unknown>(key: string, content: T | undefined, options?: {
26
+ ttl?: number;
27
+ }): Promise<void>;
28
+ clear(): Promise<void>;
29
+ }
@@ -0,0 +1,121 @@
1
+ import * as snappy from 'snappy';
2
+ export class RedisIOStorage {
3
+ constructor(redis, options = { maxAge: 86400 }) {
4
+ this.redis = redis;
5
+ this.options = options;
6
+ }
7
+ onError(listener) {
8
+ this.errorHandler = listener;
9
+ }
10
+ async getItems(keys) {
11
+ const mget = this.options.compress
12
+ ? await this.redis().mgetBuffer(...keys)
13
+ : await this.redis().mget(...keys);
14
+ const res = Object.fromEntries(await Promise.all(mget.map(async (entry, i) => {
15
+ if (entry === null) {
16
+ return [keys[i], undefined]; // value does not exist yet
17
+ }
18
+ if (entry === '') {
19
+ return [keys[i], null]; // value does exist, but is empty
20
+ }
21
+ // Decompress if needed, result is a string
22
+ const stringValue = entry && this.options.compress
23
+ ? await this.uncompress(entry)
24
+ : entry;
25
+ // Try to parse as JSON
26
+ let parsedItem = stringValue;
27
+ try {
28
+ if (stringValue) {
29
+ parsedItem = JSON.parse(stringValue);
30
+ }
31
+ }
32
+ catch (error) {
33
+ /** Not JSON, keep as string */
34
+ }
35
+ return [keys[i], parsedItem];
36
+ })));
37
+ return res;
38
+ }
39
+ async compress(uncompressed) {
40
+ const result = await snappy.compress(uncompressed);
41
+ return result;
42
+ }
43
+ async uncompress(compressed) {
44
+ const result = await snappy.uncompress(compressed, { asBuffer: false });
45
+ return result.toString();
46
+ }
47
+ async setItems(values, options) {
48
+ const redisPipeline = this.redis().pipeline();
49
+ await Promise.all(values.map(async (val) => {
50
+ if (val.content === undefined)
51
+ return;
52
+ let content = JSON.stringify(val.content);
53
+ if (this.options.compress) {
54
+ content = await this.compress(content);
55
+ }
56
+ const ttl = options?.ttl ?? this.options.maxAge;
57
+ if (ttl) {
58
+ redisPipeline.setex(val.key, ttl, content);
59
+ }
60
+ else {
61
+ redisPipeline.set(val.key, content);
62
+ }
63
+ }));
64
+ const savePromise = redisPipeline.exec();
65
+ if (this.errorHandler) {
66
+ // if we have an error handler, we do not need to await the result
67
+ savePromise.catch(err => this.errorHandler && this.errorHandler(err));
68
+ }
69
+ else {
70
+ await savePromise;
71
+ }
72
+ }
73
+ async getItem(key) {
74
+ const entry = this.options.compress
75
+ ? await this.redis().getBuffer(key)
76
+ : await this.redis().get(key);
77
+ if (entry === null) {
78
+ return undefined;
79
+ }
80
+ if (entry === '') {
81
+ return null; // value exists but is empty
82
+ }
83
+ // Decompress if needed, result is a string
84
+ const stringValue = entry && this.options.compress ? await this.uncompress(entry) : entry;
85
+ // Try to parse as JSON
86
+ let parsedItem = stringValue;
87
+ try {
88
+ parsedItem = JSON.parse(stringValue);
89
+ }
90
+ catch (error) {
91
+ /** Not JSON, keep as string */
92
+ }
93
+ return parsedItem;
94
+ }
95
+ async setItem(key, content, options) {
96
+ if (content === undefined) {
97
+ await this.redis().del(key);
98
+ return;
99
+ }
100
+ // Serialize to string, then optionally compress
101
+ let serialized = typeof content === 'object' ? JSON.stringify(content) : String(content);
102
+ if (this.options.compress) {
103
+ serialized = await this.compress(serialized);
104
+ }
105
+ const ttl = options?.ttl ?? this.options.maxAge;
106
+ const savePromise = ttl
107
+ ? this.redis().setex(key, ttl, serialized)
108
+ : this.redis().set(key, serialized);
109
+ if (this.errorHandler) {
110
+ // if we have an error handler, we do not need to await the result
111
+ savePromise.catch(err => this.errorHandler && this.errorHandler(err));
112
+ }
113
+ else {
114
+ await savePromise;
115
+ }
116
+ }
117
+ async clear() {
118
+ await this.redis().flushdb();
119
+ }
120
+ }
121
+ //# sourceMappingURL=redisio.storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redisio.storage.js","sourceRoot":"","sources":["../src/redisio.storage.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@node-ts-cache/ioredis-storage",
3
+ "version": "1.0.0",
4
+ "description": "Simple and extensible caching module supporting decorators",
5
+ "keywords": [
6
+ "node",
7
+ "nodejs",
8
+ "cache",
9
+ "typescript",
10
+ "ts",
11
+ "caching",
12
+ "memcache",
13
+ "memory-cache",
14
+ "redis-cache",
15
+ "redis",
16
+ "file-cache",
17
+ "node-cache",
18
+ "ts-cache"
19
+ ],
20
+ "homepage": "https://github.com/simllll/node-ts-cache/tree/master/storages/redisio#readme",
21
+ "bugs": {
22
+ "url": "https://github.com/simllll/node-ts-cache/issues"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/simllll/node-ts-cache.git"
27
+ },
28
+ "license": "MIT",
29
+ "author": "Simon Tretter <s.tretter@gmail.com>",
30
+ "type": "module",
31
+ "main": "dist/index.js",
32
+ "types": "dist/index.d.ts",
33
+ "files": [
34
+ "dist"
35
+ ],
36
+ "dependencies": {
37
+ "ioredis": "^5.3.2",
38
+ "snappy": "^7.0.5",
39
+ "@node-ts-cache/core": "1.0.0"
40
+ },
41
+ "devDependencies": {
42
+ "ioredis-mock": "^8.9.0"
43
+ },
44
+ "engines": {
45
+ "node": ">=18.0.0"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public"
49
+ },
50
+ "gitHead": "c938eba762060f940a34bc192bec03bc76ea4017",
51
+ "scripts": {
52
+ "build": "tsc -p .",
53
+ "clean": "git clean -fdx src",
54
+ "dev": "tsc -p . -w",
55
+ "tdd": "mocha --loader=ts-node/esm -w",
56
+ "tdd-debug-brk": "mocha --loader=ts-node/esm --inspect-brk",
57
+ "test": "mocha --loader=ts-node/esm test/**/*.test.ts"
58
+ }
59
+ }