@keyv/redis 5.0.0 → 5.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 +200 -5
- package/dist/index.cjs +26 -2
- package/dist/index.d.cts +12 -5
- package/dist/index.d.ts +12 -5
- package/dist/index.js +29 -4
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -35,11 +35,14 @@ Redis storage adapter for [Keyv](https://github.com/jaredwray/keyv).
|
|
|
35
35
|
* [High Memory Usage on Redis Server](#high-memory-usage-on-redis-server)
|
|
36
36
|
* [Gracefully Handling Errors and Timeouts](#gracefully-handling-errors-and-timeouts)
|
|
37
37
|
* [Using Cacheable with Redis](#using-cacheable-with-redis)
|
|
38
|
-
* [Clustering
|
|
38
|
+
* [Clustering](#clustering)
|
|
39
|
+
* [Sentinel](#sentinel)
|
|
40
|
+
* [TLS Support](#tls-support)
|
|
39
41
|
* [API](#api)
|
|
40
42
|
* [Using Custom Redis Client Events](#using-custom-redis-client-events)
|
|
41
43
|
* [Migrating from v3 to v4](#migrating-from-v3-to-v4)
|
|
42
44
|
* [About Redis Sets and its Support in v4](#about-redis-sets-and-its-support-in-v4)
|
|
45
|
+
* [Using with NestJS](#using-with-nestjs)
|
|
43
46
|
* [License](#license)
|
|
44
47
|
|
|
45
48
|
# Installation
|
|
@@ -379,9 +382,9 @@ const cache = new Cacheable( { secondary, nonBlocking: true } );
|
|
|
379
382
|
|
|
380
383
|
This will make it so that the secondary does not block the primary cache and will be very fast. 🚀
|
|
381
384
|
|
|
382
|
-
# Clustering
|
|
385
|
+
# Clustering
|
|
383
386
|
|
|
384
|
-
If you are using a Redis Cluster
|
|
387
|
+
If you are using a Redis Cluster, you can pass in the `redisOptions` directly. Here is an example of how to do that:
|
|
385
388
|
|
|
386
389
|
```js
|
|
387
390
|
import Keyv from 'keyv';
|
|
@@ -404,9 +407,42 @@ const cluster = createCluster({
|
|
|
404
407
|
const keyv = new Keyv({ store: new KeyvRedis(cluster) });
|
|
405
408
|
```
|
|
406
409
|
|
|
407
|
-
You can learn more about the `createCluster` function in the [documentation](https://github.com/redis/node-redis/blob/master/docs/clustering.md) at https://github.com/redis/node-redis/tree/master/docs.
|
|
410
|
+
You can learn more about the `createCluster` function in the [documentation](https://github.com/redis/node-redis/blob/master/docs/clustering.md) at https://github.com/redis/node-redis/tree/master/docs.
|
|
408
411
|
|
|
409
|
-
|
|
412
|
+
# Sentinel
|
|
413
|
+
|
|
414
|
+
If you are using Sentinel to provide high availability for your Redis instances, you can pass in the `redisOptions` directly. Here is an example of how to do that:
|
|
415
|
+
|
|
416
|
+
```js
|
|
417
|
+
import Keyv from 'keyv';
|
|
418
|
+
import KeyvRedis, { createSentinel } from '@keyv/redis';
|
|
419
|
+
|
|
420
|
+
const sentinel = createSentinel({
|
|
421
|
+
name: 'sentinel-db',
|
|
422
|
+
sentinelRootNodes: [
|
|
423
|
+
{
|
|
424
|
+
host: '127.0.0.1',
|
|
425
|
+
port: 26379,
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
host: '127.0.0.1',
|
|
429
|
+
port: 26380,
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
host: '127.0.0.1',
|
|
433
|
+
port: 26381,
|
|
434
|
+
},
|
|
435
|
+
],
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
const keyv = new Keyv({ store: new KeyvRedis(sentinel) });
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
You can learn more about the `createSentinel` function in the [documentation](https://github.com/redis/node-redis/blob/master/docs/sentinel.md) at https://github.com/redis/node-redis/tree/master/docs.
|
|
442
|
+
|
|
443
|
+
# TLS Support
|
|
444
|
+
|
|
445
|
+
Here is an example of how to use TLS using the `redisOptions`:
|
|
410
446
|
|
|
411
447
|
```js
|
|
412
448
|
import Keyv from 'keyv';
|
|
@@ -500,6 +536,165 @@ This will make it so the storage adapter `@keyv/redis` will handle the namespace
|
|
|
500
536
|
|
|
501
537
|
We no longer support redis sets. This is due to the fact that it caused significant performance issues and was not a good fit for the library.
|
|
502
538
|
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
# Using with NestJS
|
|
542
|
+
|
|
543
|
+
> You can integrate `@keyv/redis` with NestJS by creating a custom `CacheModule`. This allows you to use Keyv as a cache store in your application.
|
|
544
|
+
|
|
545
|
+
### 1. Install Dependencies
|
|
546
|
+
|
|
547
|
+
```bash
|
|
548
|
+
npm install @keyv/redis keyv @nestjs/cache-manager cache-manager cacheable
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### 2. Create a Cache Module
|
|
552
|
+
|
|
553
|
+
Create a file `cache.module.ts`:
|
|
554
|
+
|
|
555
|
+
```ts
|
|
556
|
+
import { Module } from '@nestjs/common';
|
|
557
|
+
import { CacheModule as NestCacheModule } from '@nestjs/cache-manager';
|
|
558
|
+
import { createKeyv } from '@keyv/redis';
|
|
559
|
+
|
|
560
|
+
@Module({
|
|
561
|
+
imports: [
|
|
562
|
+
NestCacheModule.registerAsync({
|
|
563
|
+
useFactory: () => ({
|
|
564
|
+
stores: [createKeyv('redis://localhost:6379')],
|
|
565
|
+
}),
|
|
566
|
+
}),
|
|
567
|
+
],
|
|
568
|
+
providers: [],
|
|
569
|
+
exports: [],
|
|
570
|
+
})
|
|
571
|
+
export class CacheModule {}
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### 3. Import the Cache Module in AppModule
|
|
575
|
+
Update `app.module.ts`:
|
|
576
|
+
|
|
577
|
+
```ts
|
|
578
|
+
import { Module } from '@nestjs/common';
|
|
579
|
+
import { CacheModule } from './modules/config/cache/cache.module';
|
|
580
|
+
|
|
581
|
+
@Module({
|
|
582
|
+
imports: [
|
|
583
|
+
CacheModule, // Import your custom cache module
|
|
584
|
+
// other modules...
|
|
585
|
+
],
|
|
586
|
+
})
|
|
587
|
+
export class AppModule {}
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
### 4. Create the Cache Service
|
|
591
|
+
Create a file `cache.service.ts`:
|
|
592
|
+
|
|
593
|
+
```ts
|
|
594
|
+
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
|
595
|
+
import { Inject, Injectable } from '@nestjs/common';
|
|
596
|
+
import { Cache } from 'cache-manager';
|
|
597
|
+
|
|
598
|
+
@Injectable()
|
|
599
|
+
export class CacheService {
|
|
600
|
+
constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
|
|
601
|
+
|
|
602
|
+
async get<T>(key: string): Promise<T | undefined> {
|
|
603
|
+
return this.cacheManager.get<T>(key);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
async set<T>(key: string, value: T, ttl?: number): Promise<void> {
|
|
607
|
+
await this.cacheManager.set(key, value, ttl);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
async delete(key: string): Promise<void> {
|
|
611
|
+
await this.cacheManager.del(key);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### 5. Register CacheService in CacheModule
|
|
617
|
+
Update `cache.module.ts`:
|
|
618
|
+
|
|
619
|
+
```ts
|
|
620
|
+
import { Module } from '@nestjs/common';
|
|
621
|
+
import { CacheModule as NestCacheModule } from '@nestjs/cache-manager';
|
|
622
|
+
import { createKeyv } from '@keyv/redis';
|
|
623
|
+
import { CacheService } from './services/cache.service';
|
|
624
|
+
|
|
625
|
+
@Module({
|
|
626
|
+
imports: [
|
|
627
|
+
NestCacheModule.registerAsync({
|
|
628
|
+
useFactory: () => ({
|
|
629
|
+
stores: [createKeyv('redis://localhost:6379')],
|
|
630
|
+
}),
|
|
631
|
+
}),
|
|
632
|
+
],
|
|
633
|
+
providers: [CacheService],
|
|
634
|
+
exports: [CacheService],
|
|
635
|
+
})
|
|
636
|
+
export class CacheModule {}
|
|
637
|
+
```
|
|
638
|
+
### 6. Import CacheModule in the Target Module (e.g. TaskModule)
|
|
639
|
+
```ts
|
|
640
|
+
import { Module } from '@nestjs/common';
|
|
641
|
+
import { TaskService } from './task.service';
|
|
642
|
+
import { TaskRepository } from './repositories/task.repository';
|
|
643
|
+
import { CacheModule } from 'src/modules/config/cache/cache.module';
|
|
644
|
+
|
|
645
|
+
@Module({
|
|
646
|
+
imports: [CacheModule],
|
|
647
|
+
providers: [TaskService, TaskRepository],
|
|
648
|
+
})
|
|
649
|
+
export class TaskModule {}
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
### 7. Using the Cache in a Service
|
|
653
|
+
|
|
654
|
+
```ts
|
|
655
|
+
import { Injectable, NotFoundException } from '@nestjs/common';
|
|
656
|
+
import { TaskRepository } from '../repositories/task.repository';
|
|
657
|
+
import { TaskDto } from '../dto/task.dto';
|
|
658
|
+
import { CacheService } from 'src/modules/config/cache/services/cache.service';
|
|
659
|
+
|
|
660
|
+
@Injectable()
|
|
661
|
+
export class TaskService {
|
|
662
|
+
constructor(
|
|
663
|
+
private readonly taskRepository: TaskRepository,
|
|
664
|
+
private readonly cache: CacheService, // Inject the CacheService
|
|
665
|
+
) {}
|
|
666
|
+
|
|
667
|
+
async findById(id: number): Promise<TaskDto> {
|
|
668
|
+
const cacheKey = `task:${id}`;
|
|
669
|
+
|
|
670
|
+
// 1. Try to get from cache
|
|
671
|
+
const cached = await this.cache.get<TaskDto>(cacheKey);
|
|
672
|
+
|
|
673
|
+
if (cached) {
|
|
674
|
+
return cached;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
// 2. If not found in cache, fetch from database
|
|
678
|
+
const task = await this.taskRepository.findById(id);
|
|
679
|
+
|
|
680
|
+
if (!task) {
|
|
681
|
+
throw new NotFoundException('Task not found');
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// 3. Set in cache for future requests
|
|
685
|
+
await this.cache.set(cacheKey, task, 300 * 1000); // 5 minutes TTL
|
|
686
|
+
return task;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
You can learn more about caching in NestJS in the [official documentation](https://docs.nestjs.com/techniques/caching#in-memory-cache).
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
---
|
|
696
|
+
|
|
697
|
+
|
|
503
698
|
# License
|
|
504
699
|
|
|
505
700
|
[MIT © Jared Wray](LISCENCE)
|
package/dist/index.cjs
CHANGED
|
@@ -36,6 +36,7 @@ __export(index_exports, {
|
|
|
36
36
|
createCluster: () => import_client2.createCluster,
|
|
37
37
|
createKeyv: () => createKeyv,
|
|
38
38
|
createKeyvNonBlocking: () => createKeyvNonBlocking,
|
|
39
|
+
createSentinel: () => import_client2.createSentinel,
|
|
39
40
|
default: () => KeyvRedis,
|
|
40
41
|
defaultReconnectStrategy: () => defaultReconnectStrategy
|
|
41
42
|
});
|
|
@@ -80,9 +81,21 @@ var KeyvRedis = class extends import_hookified.Hookified {
|
|
|
80
81
|
if (typeof connect === "string") {
|
|
81
82
|
this._client = (0, import_client.createClient)({ url: connect, socket });
|
|
82
83
|
} else if (connect.connect !== void 0) {
|
|
83
|
-
|
|
84
|
+
if (this.isClientSentinel(connect)) {
|
|
85
|
+
this._client = connect;
|
|
86
|
+
} else if (this.isClientCluster(connect)) {
|
|
87
|
+
this._client = connect;
|
|
88
|
+
} else {
|
|
89
|
+
this._client = connect;
|
|
90
|
+
}
|
|
84
91
|
} else if (connect instanceof Object) {
|
|
85
|
-
|
|
92
|
+
if (connect.sentinelRootNodes !== void 0) {
|
|
93
|
+
this._client = (0, import_client.createSentinel)(connect);
|
|
94
|
+
} else if (connect.rootNodes === void 0) {
|
|
95
|
+
this._client = (0, import_client.createClient)(connect);
|
|
96
|
+
} else {
|
|
97
|
+
this._client = (0, import_client.createCluster)(connect);
|
|
98
|
+
}
|
|
86
99
|
}
|
|
87
100
|
}
|
|
88
101
|
this.setOptions(options);
|
|
@@ -506,6 +519,13 @@ var KeyvRedis = class extends import_hookified.Hookified {
|
|
|
506
519
|
isCluster() {
|
|
507
520
|
return this.isClientCluster(this._client);
|
|
508
521
|
}
|
|
522
|
+
/**
|
|
523
|
+
* Is the client a sentinel.
|
|
524
|
+
* @returns {boolean} - true if the client is a sentinel, false if not
|
|
525
|
+
*/
|
|
526
|
+
isSentinel() {
|
|
527
|
+
return this.isClientSentinel(this._client);
|
|
528
|
+
}
|
|
509
529
|
/**
|
|
510
530
|
* Get the master nodes in the cluster. If not a cluster, it will return the single client.
|
|
511
531
|
*
|
|
@@ -648,6 +668,9 @@ var KeyvRedis = class extends import_hookified.Hookified {
|
|
|
648
668
|
isClientCluster(client) {
|
|
649
669
|
return client.slots !== void 0;
|
|
650
670
|
}
|
|
671
|
+
isClientSentinel(client) {
|
|
672
|
+
return client.getSentinelNode !== void 0;
|
|
673
|
+
}
|
|
651
674
|
setOptions(options) {
|
|
652
675
|
if (!options) {
|
|
653
676
|
return;
|
|
@@ -747,5 +770,6 @@ function createKeyvNonBlocking(connect, options) {
|
|
|
747
770
|
createCluster,
|
|
748
771
|
createKeyv,
|
|
749
772
|
createKeyvNonBlocking,
|
|
773
|
+
createSentinel,
|
|
750
774
|
defaultReconnectStrategy
|
|
751
775
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RedisClientOptions, RedisClusterOptions, RedisClientType, RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping, RedisClusterType } from '@redis/client';
|
|
2
|
-
export { RedisClientOptions, RedisClientType, RedisClusterOptions, RedisClusterType, createClient, createCluster } from '@redis/client';
|
|
1
|
+
import { RedisClientOptions, RedisClusterOptions, RedisSentinelOptions, RedisClientType, RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping, RedisClusterType, RedisSentinelType } from '@redis/client';
|
|
2
|
+
export { RedisClientOptions, RedisClientType, RedisClusterOptions, RedisClusterType, RedisSentinelType, createClient, createCluster, createSentinel } from '@redis/client';
|
|
3
3
|
import { Hookified } from 'hookified';
|
|
4
4
|
import { KeyvStoreAdapter, KeyvEntry, Keyv } from 'keyv';
|
|
5
5
|
export { Keyv } from 'keyv';
|
|
@@ -80,7 +80,8 @@ declare enum RedisErrorMessages {
|
|
|
80
80
|
declare const defaultReconnectStrategy: (attempts: number) => number | Error;
|
|
81
81
|
type RedisConnectionClientType = RedisClientType | RedisClientType<RedisModules, RedisFunctions, RedisScripts, RespVersions> | RedisClientType<RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping>;
|
|
82
82
|
type RedisConnectionClusterType = RedisClusterType | RedisClusterType<RedisModules, RedisFunctions, RedisScripts, RespVersions> | RedisClusterType<RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping>;
|
|
83
|
-
type
|
|
83
|
+
type RedisConnectionSentinelType = RedisSentinelType | RedisSentinelType<RedisModules, RedisFunctions, RedisScripts, RespVersions> | RedisSentinelType<RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping>;
|
|
84
|
+
type RedisClientConnectionType = RedisConnectionClientType | RedisConnectionClusterType | RedisConnectionSentinelType;
|
|
84
85
|
declare class KeyvRedis<T> extends Hookified implements KeyvStoreAdapter {
|
|
85
86
|
private _client;
|
|
86
87
|
private _namespace;
|
|
@@ -96,7 +97,7 @@ declare class KeyvRedis<T> extends Hookified implements KeyvStoreAdapter {
|
|
|
96
97
|
* @param {string | RedisClientOptions | RedisClientType} [connect] How to connect to the Redis server. If string pass in the url, if object pass in the options, if RedisClient pass in the client.
|
|
97
98
|
* @param {KeyvRedisOptions} [options] Options for the adapter such as namespace, keyPrefixSeparator, and clearBatchSize.
|
|
98
99
|
*/
|
|
99
|
-
constructor(connect?: string | RedisClientOptions | RedisClusterOptions | RedisClientConnectionType, options?: KeyvRedisOptions);
|
|
100
|
+
constructor(connect?: string | RedisClientOptions | RedisClusterOptions | RedisSentinelOptions | RedisClientConnectionType, options?: KeyvRedisOptions);
|
|
100
101
|
/**
|
|
101
102
|
* Get the Redis client.
|
|
102
103
|
*/
|
|
@@ -278,6 +279,11 @@ declare class KeyvRedis<T> extends Hookified implements KeyvStoreAdapter {
|
|
|
278
279
|
* @returns {boolean} - true if the client is a cluster, false if not
|
|
279
280
|
*/
|
|
280
281
|
isCluster(): boolean;
|
|
282
|
+
/**
|
|
283
|
+
* Is the client a sentinel.
|
|
284
|
+
* @returns {boolean} - true if the client is a sentinel, false if not
|
|
285
|
+
*/
|
|
286
|
+
isSentinel(): boolean;
|
|
281
287
|
/**
|
|
282
288
|
* Get the master nodes in the cluster. If not a cluster, it will return the single client.
|
|
283
289
|
*
|
|
@@ -320,6 +326,7 @@ declare class KeyvRedis<T> extends Hookified implements KeyvStoreAdapter {
|
|
|
320
326
|
*/
|
|
321
327
|
private getSlotMap;
|
|
322
328
|
private isClientCluster;
|
|
329
|
+
private isClientSentinel;
|
|
323
330
|
private setOptions;
|
|
324
331
|
private initClient;
|
|
325
332
|
private createTimeoutPromise;
|
|
@@ -333,4 +340,4 @@ declare class KeyvRedis<T> extends Hookified implements KeyvStoreAdapter {
|
|
|
333
340
|
declare function createKeyv(connect?: string | RedisClientOptions | RedisClientType, options?: KeyvRedisOptions): Keyv;
|
|
334
341
|
declare function createKeyvNonBlocking(connect?: string | RedisClientOptions | RedisClientType, options?: KeyvRedisOptions): Keyv;
|
|
335
342
|
|
|
336
|
-
export { type KeyvRedisEntry, type KeyvRedisOptions, type KeyvRedisPropertyOptions, type RedisClientConnectionType, type RedisConnectionClientType, type RedisConnectionClusterType, RedisErrorMessages, createKeyv, createKeyvNonBlocking, KeyvRedis as default, defaultReconnectStrategy };
|
|
343
|
+
export { type KeyvRedisEntry, type KeyvRedisOptions, type KeyvRedisPropertyOptions, type RedisClientConnectionType, type RedisConnectionClientType, type RedisConnectionClusterType, type RedisConnectionSentinelType, RedisErrorMessages, createKeyv, createKeyvNonBlocking, KeyvRedis as default, defaultReconnectStrategy };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RedisClientOptions, RedisClusterOptions, RedisClientType, RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping, RedisClusterType } from '@redis/client';
|
|
2
|
-
export { RedisClientOptions, RedisClientType, RedisClusterOptions, RedisClusterType, createClient, createCluster } from '@redis/client';
|
|
1
|
+
import { RedisClientOptions, RedisClusterOptions, RedisSentinelOptions, RedisClientType, RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping, RedisClusterType, RedisSentinelType } from '@redis/client';
|
|
2
|
+
export { RedisClientOptions, RedisClientType, RedisClusterOptions, RedisClusterType, RedisSentinelType, createClient, createCluster, createSentinel } from '@redis/client';
|
|
3
3
|
import { Hookified } from 'hookified';
|
|
4
4
|
import { KeyvStoreAdapter, KeyvEntry, Keyv } from 'keyv';
|
|
5
5
|
export { Keyv } from 'keyv';
|
|
@@ -80,7 +80,8 @@ declare enum RedisErrorMessages {
|
|
|
80
80
|
declare const defaultReconnectStrategy: (attempts: number) => number | Error;
|
|
81
81
|
type RedisConnectionClientType = RedisClientType | RedisClientType<RedisModules, RedisFunctions, RedisScripts, RespVersions> | RedisClientType<RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping>;
|
|
82
82
|
type RedisConnectionClusterType = RedisClusterType | RedisClusterType<RedisModules, RedisFunctions, RedisScripts, RespVersions> | RedisClusterType<RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping>;
|
|
83
|
-
type
|
|
83
|
+
type RedisConnectionSentinelType = RedisSentinelType | RedisSentinelType<RedisModules, RedisFunctions, RedisScripts, RespVersions> | RedisSentinelType<RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping>;
|
|
84
|
+
type RedisClientConnectionType = RedisConnectionClientType | RedisConnectionClusterType | RedisConnectionSentinelType;
|
|
84
85
|
declare class KeyvRedis<T> extends Hookified implements KeyvStoreAdapter {
|
|
85
86
|
private _client;
|
|
86
87
|
private _namespace;
|
|
@@ -96,7 +97,7 @@ declare class KeyvRedis<T> extends Hookified implements KeyvStoreAdapter {
|
|
|
96
97
|
* @param {string | RedisClientOptions | RedisClientType} [connect] How to connect to the Redis server. If string pass in the url, if object pass in the options, if RedisClient pass in the client.
|
|
97
98
|
* @param {KeyvRedisOptions} [options] Options for the adapter such as namespace, keyPrefixSeparator, and clearBatchSize.
|
|
98
99
|
*/
|
|
99
|
-
constructor(connect?: string | RedisClientOptions | RedisClusterOptions | RedisClientConnectionType, options?: KeyvRedisOptions);
|
|
100
|
+
constructor(connect?: string | RedisClientOptions | RedisClusterOptions | RedisSentinelOptions | RedisClientConnectionType, options?: KeyvRedisOptions);
|
|
100
101
|
/**
|
|
101
102
|
* Get the Redis client.
|
|
102
103
|
*/
|
|
@@ -278,6 +279,11 @@ declare class KeyvRedis<T> extends Hookified implements KeyvStoreAdapter {
|
|
|
278
279
|
* @returns {boolean} - true if the client is a cluster, false if not
|
|
279
280
|
*/
|
|
280
281
|
isCluster(): boolean;
|
|
282
|
+
/**
|
|
283
|
+
* Is the client a sentinel.
|
|
284
|
+
* @returns {boolean} - true if the client is a sentinel, false if not
|
|
285
|
+
*/
|
|
286
|
+
isSentinel(): boolean;
|
|
281
287
|
/**
|
|
282
288
|
* Get the master nodes in the cluster. If not a cluster, it will return the single client.
|
|
283
289
|
*
|
|
@@ -320,6 +326,7 @@ declare class KeyvRedis<T> extends Hookified implements KeyvStoreAdapter {
|
|
|
320
326
|
*/
|
|
321
327
|
private getSlotMap;
|
|
322
328
|
private isClientCluster;
|
|
329
|
+
private isClientSentinel;
|
|
323
330
|
private setOptions;
|
|
324
331
|
private initClient;
|
|
325
332
|
private createTimeoutPromise;
|
|
@@ -333,4 +340,4 @@ declare class KeyvRedis<T> extends Hookified implements KeyvStoreAdapter {
|
|
|
333
340
|
declare function createKeyv(connect?: string | RedisClientOptions | RedisClientType, options?: KeyvRedisOptions): Keyv;
|
|
334
341
|
declare function createKeyvNonBlocking(connect?: string | RedisClientOptions | RedisClientType, options?: KeyvRedisOptions): Keyv;
|
|
335
342
|
|
|
336
|
-
export { type KeyvRedisEntry, type KeyvRedisOptions, type KeyvRedisPropertyOptions, type RedisClientConnectionType, type RedisConnectionClientType, type RedisConnectionClusterType, RedisErrorMessages, createKeyv, createKeyvNonBlocking, KeyvRedis as default, defaultReconnectStrategy };
|
|
343
|
+
export { type KeyvRedisEntry, type KeyvRedisOptions, type KeyvRedisPropertyOptions, type RedisClientConnectionType, type RedisConnectionClientType, type RedisConnectionClusterType, type RedisConnectionSentinelType, RedisErrorMessages, createKeyv, createKeyvNonBlocking, KeyvRedis as default, defaultReconnectStrategy };
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import {
|
|
3
3
|
createClient,
|
|
4
|
-
createCluster
|
|
4
|
+
createCluster,
|
|
5
|
+
createSentinel
|
|
5
6
|
} from "@redis/client";
|
|
6
7
|
import { Hookified } from "hookified";
|
|
7
8
|
import { Keyv } from "keyv";
|
|
8
9
|
import calculateSlot from "cluster-key-slot";
|
|
9
10
|
import {
|
|
10
11
|
createClient as createClient2,
|
|
11
|
-
createCluster as createCluster2
|
|
12
|
+
createCluster as createCluster2,
|
|
13
|
+
createSentinel as createSentinel2
|
|
12
14
|
} from "@redis/client";
|
|
13
15
|
import {
|
|
14
16
|
Keyv as Keyv2
|
|
@@ -47,9 +49,21 @@ var KeyvRedis = class extends Hookified {
|
|
|
47
49
|
if (typeof connect === "string") {
|
|
48
50
|
this._client = createClient({ url: connect, socket });
|
|
49
51
|
} else if (connect.connect !== void 0) {
|
|
50
|
-
|
|
52
|
+
if (this.isClientSentinel(connect)) {
|
|
53
|
+
this._client = connect;
|
|
54
|
+
} else if (this.isClientCluster(connect)) {
|
|
55
|
+
this._client = connect;
|
|
56
|
+
} else {
|
|
57
|
+
this._client = connect;
|
|
58
|
+
}
|
|
51
59
|
} else if (connect instanceof Object) {
|
|
52
|
-
|
|
60
|
+
if (connect.sentinelRootNodes !== void 0) {
|
|
61
|
+
this._client = createSentinel(connect);
|
|
62
|
+
} else if (connect.rootNodes === void 0) {
|
|
63
|
+
this._client = createClient(connect);
|
|
64
|
+
} else {
|
|
65
|
+
this._client = createCluster(connect);
|
|
66
|
+
}
|
|
53
67
|
}
|
|
54
68
|
}
|
|
55
69
|
this.setOptions(options);
|
|
@@ -473,6 +487,13 @@ var KeyvRedis = class extends Hookified {
|
|
|
473
487
|
isCluster() {
|
|
474
488
|
return this.isClientCluster(this._client);
|
|
475
489
|
}
|
|
490
|
+
/**
|
|
491
|
+
* Is the client a sentinel.
|
|
492
|
+
* @returns {boolean} - true if the client is a sentinel, false if not
|
|
493
|
+
*/
|
|
494
|
+
isSentinel() {
|
|
495
|
+
return this.isClientSentinel(this._client);
|
|
496
|
+
}
|
|
476
497
|
/**
|
|
477
498
|
* Get the master nodes in the cluster. If not a cluster, it will return the single client.
|
|
478
499
|
*
|
|
@@ -615,6 +636,9 @@ var KeyvRedis = class extends Hookified {
|
|
|
615
636
|
isClientCluster(client) {
|
|
616
637
|
return client.slots !== void 0;
|
|
617
638
|
}
|
|
639
|
+
isClientSentinel(client) {
|
|
640
|
+
return client.getSentinelNode !== void 0;
|
|
641
|
+
}
|
|
618
642
|
setOptions(options) {
|
|
619
643
|
if (!options) {
|
|
620
644
|
return;
|
|
@@ -713,6 +737,7 @@ export {
|
|
|
713
737
|
createCluster2 as createCluster,
|
|
714
738
|
createKeyv,
|
|
715
739
|
createKeyvNonBlocking,
|
|
740
|
+
createSentinel2 as createSentinel,
|
|
716
741
|
KeyvRedis as default,
|
|
717
742
|
defaultReconnectStrategy
|
|
718
743
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keyv/redis",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "Redis storage adapter for Keyv",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
},
|
|
35
35
|
"homepage": "https://github.com/jaredwray/keyv",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@redis/client": "^5.
|
|
37
|
+
"@redis/client": "^5.7.0",
|
|
38
38
|
"cluster-key-slot": "^1.1.2",
|
|
39
|
-
"hookified": "^1.
|
|
39
|
+
"hookified": "^1.11.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"keyv": "^5.
|
|
42
|
+
"keyv": "^5.5.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@faker-js/faker": "^9.9.0",
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"timekeeper": "^2.3.1",
|
|
49
49
|
"tsd": "^0.32.0",
|
|
50
50
|
"vitest": "^3.2.4",
|
|
51
|
-
"xo": "^1.
|
|
52
|
-
"@keyv/test-suite": "^2.0
|
|
51
|
+
"xo": "^1.2.1",
|
|
52
|
+
"@keyv/test-suite": "^2.1.0"
|
|
53
53
|
},
|
|
54
54
|
"tsd": {
|
|
55
55
|
"directory": "test"
|