@keyv/redis 4.5.0 → 5.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/README.md CHANGED
@@ -25,11 +25,15 @@ Redis storage adapter for [Keyv](https://github.com/jaredwray/keyv).
25
25
 
26
26
  # Table of Contents
27
27
  * [Usage](#usage)
28
+ * [Migrating from v4 to v5](#migrating-from-v4-to-v5)
29
+ * [Using the createKeyv function](#using-the-createkeyv-function)
30
+ * [Using the createKeyvNonBlocking function](#using-the-createkeyvnonblocking-function)
28
31
  * [Namespaces](#namespaces)
32
+ * [Fixing Double Prefixing of Keys](#fixing-double-prefixing-of-keys)
29
33
  * [Using Generic Types](#using-generic-types)
30
34
  * [Performance Considerations](#performance-considerations)
31
35
  * [High Memory Usage on Redis Server](#high-memory-usage-on-redis-server)
32
- * [Gracefully Handling Connection Errors, Retries, and Timeouts](#gracefully-handling-connection-errors-retries-and-timeouts)
36
+ * [Gracefully Handling Errors and Timeouts](#gracefully-handling-errors-and-timeouts)
33
37
  * [Using Cacheable with Redis](#using-cacheable-with-redis)
34
38
  * [Clustering and TLS Support](#clustering-and-tls-support)
35
39
  * [API](#api)
@@ -100,6 +104,10 @@ const keyvRedis = new KeyvRedis(redis);
100
104
  const keyv = new Keyv({ store: keyvRedis});
101
105
  ```
102
106
 
107
+ # Migrating from v4 to v5
108
+
109
+ The major change from v4 to v5 is that we are now using v5 of the `@redis/client` library which has a new API. This means that some methods have changed but it should be a drop-in replacement for most use cases.
110
+
103
111
  # Keyv Redis Options
104
112
 
105
113
  You can pass in options to the `KeyvRedis` constructor. Here are the available options:
@@ -131,10 +139,26 @@ export type KeyvRedisOptions = {
131
139
  noNamespaceAffectsAll?: boolean;
132
140
 
133
141
  /**
134
- * Timeout for connecting to Redis in milliseconds. This is used to prevent hanging indefinitely when connecting to Redis.
135
- * Defaults to `200`.
142
+ * This is used to throw an error if the client is not connected when trying to connect. By default, this is
143
+ * set to true so that it throws an error when trying to connect to the Redis server fails.
136
144
  */
137
- connectTimeout?: number;
145
+ throwOnConnectError?: boolean;
146
+
147
+ /**
148
+ * This is used to throw an error if at any point there is a failure. Use this if you want to
149
+ * ensure that all operations are successful and you want to handle errors. By default, this is
150
+ * set to false so that it does not throw an error on every operation and instead emits an error event
151
+ * and returns no-op responses.
152
+ * @default false
153
+ */
154
+ throwOnErrors?: boolean;
155
+
156
+ /**
157
+ * Timeout in milliseconds for the connection. Default is undefined, which uses the default timeout of the Redis client.
158
+ * If set, it will throw an error if the connection does not succeed within the specified time.
159
+ * @default undefined
160
+ */
161
+ connectionTimeout?: number;
138
162
  };
139
163
  ```
140
164
  You can pass these options when creating a new `KeyvRedis` instance:
@@ -164,6 +188,30 @@ const keyv = createKeyv('redis://user:pass@localhost:6379');
164
188
  keyv.store.namespace = 'my-namespace';
165
189
  ```
166
190
 
191
+ # Using the `createKeyv` function
192
+
193
+ The `createKeyv` function is a convenience function that creates a new `Keyv` instance with the `@keyv/redis` store. It automatically sets the `useKeyPrefix` option to `false`. Here is an example of how to use it:
194
+
195
+ ```js
196
+ import { createKeyv } from '@keyv/redis';
197
+ const keyv = createKeyv('redis://user:pass@localhost:6379');
198
+ ```
199
+
200
+ To use a namespace you can do it here and this will set Keyv up correctly to avoid the double namespace issue:
201
+
202
+ ```js
203
+ import { createKeyv } from '@keyv/redis';
204
+ const keyv = createKeyv('redis://user:pass@localhost:6379', {namespace: 'my-namespace'});
205
+ ```
206
+
207
+ # Using the `createKeyvNonBlocking` function
208
+
209
+ The `createKeyvNonBlocking` function is a convenience function that creates a new `Keyv` instance with the `@keyv/redis` store does what `createKeyv` does but also disables throwing errors, removes the offline queue redis functionality, and reconnect strategy so that when used as a secondary cache in libraries such as [cacheable](https://npmjs.org/package/cacheable) it does not block the primary cache. This is useful when you want to use Redis as a secondary cache and do not want to block the primary cache on connection errors or timeouts when using `nonBlocking`. Here is an example of how to use it:
210
+
211
+ ```js
212
+ import { createKeyvNonBlocking } from '@keyv/redis';
213
+ const keyv = createKeyvNonBlocking('redis://user:pass@localhost:6379');
214
+ ```
167
215
 
168
216
  # Namespaces
169
217
 
@@ -175,10 +223,17 @@ import KeyvRedis, { createClient } from '@keyv/redis';
175
223
 
176
224
  const redis = createClient('redis://user:pass@localhost:6379');
177
225
  const keyvRedis = new KeyvRedis(redis);
178
- const keyv = new Keyv({ store: keyvRedis, namespace: 'my-namespace' });
226
+ const keyv = new Keyv({ store: keyvRedis, namespace: 'my-namespace', useKeyPrefix: false });
179
227
  ```
180
228
 
181
- This will prefix all keys with `my-namespace:`. You can also set the namespace after the fact:
229
+ To make this easier, you can use the `createKeyv` function which will automatically set the `namespace` option to the `KeyvRedis` instance:
230
+
231
+ ```js
232
+ import { createKeyv } from '@keyv/redis';
233
+ const keyv = createKeyv('redis://user:pass@localhost:6379', { namespace: 'my-namespace' });
234
+ ```
235
+
236
+ This will prefix all keys with `my-namespace:` and will also set `useKeyPrefix` to `false`. This is done to avoid double prefixing of keys as we transition out of the legacy behavior in Keyv. You can also set the namespace after the fact:
182
237
 
183
238
  ```js
184
239
  keyv.namespace = 'my-namespace';
@@ -186,6 +241,24 @@ keyv.namespace = 'my-namespace';
186
241
 
187
242
  NOTE: If you plan to do many clears or deletes, it is recommended to read the [Performance Considerations](#performance-considerations) section.
188
243
 
244
+ # Fixing Double Prefixing of Keys
245
+
246
+ If you are using `Keyv` with `@keyv/redis` as the storage adapter, you may notice that keys are being prefixed twice. This is because `Keyv` has a default prefixing behavior that is applied to all keys. To fix this, you can set the `useKeyPrefix` option to `false` when creating the `Keyv` instance:
247
+
248
+ ```js
249
+ import Keyv from 'keyv';
250
+ import KeyvRedis from '@keyv/redis';
251
+
252
+ const keyv = new Keyv(new KeyvRedis('redis://user:pass@localhost:6379'), { useKeyPrefix: false });
253
+ ```
254
+
255
+ To make this easier, you can use the `createKeyv` function which will automatically set the `useKeyPrefix` option to `false`:
256
+
257
+ ```js
258
+ import { createKeyv } from '@keyv/redis';
259
+ const keyv = createKeyv('redis://user:pass@localhost:6379');
260
+ ```
261
+
189
262
  ## Using Generic Types
190
263
 
191
264
  When initializing `KeyvRedis`, you can specify the type of the values you are storing and you can also specify types when calling methods:
@@ -241,7 +314,7 @@ const keyv = new Keyv(new KeyvRedis('redis://user:pass@localhost:6379', { useUnl
241
314
  keyv.useUnlink = false;
242
315
  ```
243
316
 
244
- # Gracefully Handling Connection Errors, Retries, and Timeouts
317
+ # Gracefully Handling Errors and Timeouts
245
318
 
246
319
  When using `@keyv/redis`, it is important to handle connection errors gracefully. You can do this by listening to the `error` event on the `KeyvRedis` instance. Here is an example of how to do that:
247
320
 
@@ -254,11 +327,23 @@ keyv.on('error', (error) => {
254
327
  });
255
328
  ```
256
329
 
257
- We also attempt to connect to Redis and have a `connectTimeout` option that defaults to `200ms`. If the connection is not established within this time, it will emit an error. You can catch this error and handle it accordingly.
330
+ By default, the `KeyvRedis` instance will `throw an error` if the connection fails to connect. You can disable this behavior by setting the `throwOnConnectError` option to `false` when creating the `KeyvRedis` instance. If you want this to throw you will need to also set the Keyv instance to `throwOnErrors: true`:
331
+
332
+ ```js
333
+ import Keyv from 'keyv';
334
+ import KeyvRedis from '@keyv/redis';
335
+
336
+ const keyv = new Keyv(new KeyvRedis('redis://bad-uri:1111', { throwOnConnectError: false }));
337
+ keyv.throwOnErrors = true; // This will throw an error if the connection fails
338
+
339
+ await keyv.set('key', 'value'); // this will throw the connection error only.
340
+ ```
341
+
342
+ On `get`, `getMany`, `set`, `setMany`, `delete`, and `deleteMany`, if the connection is lost, it will emit an error and return a no-op value. You can catch this error and handle it accordingly. This is important to ensure that your application does not crash due to a lost connection to Redis.
258
343
 
259
- On `get`, `getMany`, `set`, `setMany`, `delete`, `deleteMany`, and `clear` methods, if the connection is lost, it will emit an error and return a no-op value. You can catch this error and handle it accordingly. This is important to ensure that your application does not crash due to a lost connection to Redis.
344
+ If you want to handle connection errors, retries, and timeouts more gracefully, you can use the `throwOnErrors` option. This will throw an error if any operation fails, allowing you to catch it and handle it accordingly:
260
345
 
261
- If you pass in just a `uri` connection string we will automatically create a Redis client for you with the following reconnect strategy:
346
+ There is a default `Reconnect Strategy` if you pass in just a `uri` connection string we will automatically create a Redis client for you with the following reconnect strategy:
262
347
 
263
348
  ```typescript
264
349
  export const defaultReconnectStrategy = (attempts: number): number | Error => {