koatty_store 1.9.4 → 2.0.1
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/.turbo/turbo-build.log +11 -11
- package/CHANGELOG.md +14 -0
- package/dist/index.d.ts +36 -7
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +5 -5
- package/dist/LICENSE +0 -29
- package/dist/README.md +0 -373
- package/dist/package.json +0 -103
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> koatty_store@
|
|
3
|
+
> koatty_store@2.0.1 build /Users/richen/Workspace/nodejs/koatty-monorepo/packages/koatty-store
|
|
4
4
|
> npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
> koatty_store@
|
|
7
|
+
> koatty_store@2.0.1 build:js
|
|
8
8
|
> npx rollup --bundleConfigAsCjs -c .rollup.config.js
|
|
9
9
|
|
|
10
|
-
[1G[0K[1G[0K[36m
|
|
10
|
+
[1G[0K[1G[0K⠙[1G[0K[36m
|
|
11
11
|
[1m./src/index.ts[22m → [1m./dist/index.js, ./dist/index.mjs[22m...[39m
|
|
12
|
-
[32mcreated [1m./dist/index.js, ./dist/index.mjs[22m in [
|
|
12
|
+
[32mcreated [1m./dist/index.js, ./dist/index.mjs[22m in [1m2s[22m[39m
|
|
13
13
|
[1G[0K⠙[1G[0K[1G[0K⠙[1G[0K
|
|
14
|
-
> koatty_store@
|
|
14
|
+
> koatty_store@2.0.1 build:dts
|
|
15
15
|
> bash ../../scripts/build-dts.sh
|
|
16
16
|
|
|
17
17
|
[1G[0K🔨 Building type declarations for koatty-store...
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
✓ koatty_lib type declarations ready
|
|
22
22
|
✓ koatty_logger type declarations ready
|
|
23
23
|
|
|
24
|
-
✅ All dependencies ready (waited
|
|
24
|
+
✅ All dependencies ready (waited 0ms)
|
|
25
25
|
📝 Running TypeScript compiler...
|
|
26
26
|
[1G[0K⠙[1G[0K[1G[0K⠙[1G[0K📦 Running API Extractor...
|
|
27
|
-
[1G[0K
|
|
27
|
+
[1G[0K
|
|
28
28
|
[1mapi-extractor 7.55.2 [36m - https://api-extractor.com/[39m
|
|
29
29
|
[22m
|
|
30
30
|
Using configuration from ./api-extractor.json
|
|
@@ -520,10 +520,10 @@ Analysis will use the bundled TypeScript version 5.8.2
|
|
|
520
520
|
API Extractor completed successfully
|
|
521
521
|
[1G[0K⠙[1G[0K✅ Type declarations built successfully
|
|
522
522
|
[1G[0K⠙[1G[0K
|
|
523
|
-
> koatty_store@
|
|
523
|
+
> koatty_store@2.0.1 build:doc
|
|
524
524
|
> npx api-documenter markdown --input temp --output docs/api
|
|
525
525
|
|
|
526
|
-
[1G[0K[1G[0K
|
|
526
|
+
[1G[0K[1G[0K
|
|
527
527
|
[1mapi-documenter 7.28.2 [36m - https://api-extractor.com/[39m
|
|
528
528
|
[22m
|
|
529
529
|
Reading koatty_store.api.json
|
|
@@ -545,7 +545,7 @@ Unsupported block tag: @static
|
|
|
545
545
|
Unsupported block tag: @export
|
|
546
546
|
Unsupported block tag: @class
|
|
547
547
|
[1G[0K⠙[1G[0K[1G[0K⠙[1G[0K
|
|
548
|
-
> koatty_store@
|
|
548
|
+
> koatty_store@2.0.1 build:cp
|
|
549
549
|
> node scripts/postBuild && npx copyfiles package.json LICENSE README.md dist/
|
|
550
550
|
|
|
551
|
-
[1G[0K[1G[0K
|
|
551
|
+
[1G[0K[1G[0K[1G[0K⠙[1G[0K[1G[0K⠙[1G[0K
|
package/CHANGELOG.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* @Author: richen
|
|
3
|
-
* @Date: 2026-01-28 17:22:16
|
|
4
|
-
* @License: BSD (3-Clause)
|
|
5
|
-
* @Copyright (c) - <richenlin(at)gmail.com>
|
|
6
|
-
* @HomePage: https://koatty.org/
|
|
7
|
-
*/
|
|
8
1
|
import { Cluster } from 'ioredis';
|
|
9
2
|
import { ClusterOptions } from 'ioredis';
|
|
10
3
|
import { default as default_2 } from 'ioredis';
|
|
@@ -22,6 +15,7 @@ import { RedisOptions } from 'ioredis';
|
|
|
22
15
|
export declare class CacheStore implements CacheStoreInterface {
|
|
23
16
|
client: MemoryStore | RedisStore;
|
|
24
17
|
options: StoreOptions;
|
|
18
|
+
private static instances;
|
|
25
19
|
/**
|
|
26
20
|
* Creates an instance of CacheStore.
|
|
27
21
|
* @param {StoreOptions} options
|
|
@@ -43,6 +37,7 @@ export declare class CacheStore implements CacheStoreInterface {
|
|
|
43
37
|
* @param {StoreOptions} options
|
|
44
38
|
* @returns {string}
|
|
45
39
|
*/
|
|
40
|
+
private static generateConfigHash;
|
|
46
41
|
/**
|
|
47
42
|
* 清理指定实例
|
|
48
43
|
* @static
|
|
@@ -71,6 +66,7 @@ export declare class CacheStore implements CacheStoreInterface {
|
|
|
71
66
|
* @returns {*}
|
|
72
67
|
* @memberof RedisStore
|
|
73
68
|
*/
|
|
69
|
+
protected wrap(name: string, data: any[]): Promise<any>;
|
|
74
70
|
/**
|
|
75
71
|
* 字符串获取
|
|
76
72
|
* @param name
|
|
@@ -329,11 +325,16 @@ declare interface CacheStoreInterface {
|
|
|
329
325
|
declare type CallbackFunction<T = any> = (err: Error | null, result?: T) => void;
|
|
330
326
|
|
|
331
327
|
declare class MemoryCache extends EventEmitter {
|
|
328
|
+
private databases;
|
|
332
329
|
options: MemoryCacheOptions;
|
|
333
330
|
currentDBIndex: number;
|
|
334
331
|
connected: boolean;
|
|
335
332
|
lastSave: number;
|
|
336
333
|
multiMode: boolean;
|
|
334
|
+
private cache;
|
|
335
|
+
private responseMessages;
|
|
336
|
+
private ttlCheckTimer;
|
|
337
|
+
private lock;
|
|
337
338
|
/**
|
|
338
339
|
* Creates an instance of MemoryCache.
|
|
339
340
|
* @param {MemoryCacheOptions} options
|
|
@@ -343,19 +344,24 @@ declare class MemoryCache extends EventEmitter {
|
|
|
343
344
|
/**
|
|
344
345
|
* 创建LRU缓存实例
|
|
345
346
|
*/
|
|
347
|
+
private createLRUCache;
|
|
346
348
|
/**
|
|
347
349
|
* 启动TTL检查定时器
|
|
348
350
|
*/
|
|
351
|
+
private startTTLCheck;
|
|
349
352
|
/**
|
|
350
353
|
* 清理过期键
|
|
351
354
|
*/
|
|
355
|
+
private cleanExpiredKeys;
|
|
352
356
|
/**
|
|
353
357
|
* 停止TTL检查
|
|
354
358
|
*/
|
|
359
|
+
private stopTTLCheck;
|
|
355
360
|
/**
|
|
356
361
|
* 清理所有资源
|
|
357
362
|
* @private
|
|
358
363
|
*/
|
|
364
|
+
private cleanup;
|
|
359
365
|
/**
|
|
360
366
|
*
|
|
361
367
|
*
|
|
@@ -384,6 +390,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
384
390
|
/**
|
|
385
391
|
* 估算内存使用量
|
|
386
392
|
*/
|
|
393
|
+
private getMemoryUsage;
|
|
387
394
|
/**
|
|
388
395
|
*
|
|
389
396
|
*
|
|
@@ -719,6 +726,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
719
726
|
* @returns {*}
|
|
720
727
|
* @memberof MemoryCache
|
|
721
728
|
*/
|
|
729
|
+
private pttl;
|
|
722
730
|
/**
|
|
723
731
|
*
|
|
724
732
|
*
|
|
@@ -728,6 +736,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
728
736
|
* @returns {*}
|
|
729
737
|
* @memberof MemoryCache
|
|
730
738
|
*/
|
|
739
|
+
private persist;
|
|
731
740
|
/**
|
|
732
741
|
*
|
|
733
742
|
*
|
|
@@ -736,6 +745,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
736
745
|
* @returns {*} {boolean}
|
|
737
746
|
* @memberof MemoryCache
|
|
738
747
|
*/
|
|
748
|
+
private _hasKey;
|
|
739
749
|
/**
|
|
740
750
|
*
|
|
741
751
|
*
|
|
@@ -746,6 +756,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
746
756
|
* @returns {*}
|
|
747
757
|
* @memberof MemoryCache
|
|
748
758
|
*/
|
|
759
|
+
private _makeKey;
|
|
749
760
|
/**
|
|
750
761
|
*
|
|
751
762
|
*
|
|
@@ -754,6 +765,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
754
765
|
* @returns {*}
|
|
755
766
|
* @memberof MemoryCache
|
|
756
767
|
*/
|
|
768
|
+
private _key;
|
|
757
769
|
/**
|
|
758
770
|
*
|
|
759
771
|
*
|
|
@@ -764,6 +776,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
764
776
|
* @returns {*}
|
|
765
777
|
* @memberof MemoryCache
|
|
766
778
|
*/
|
|
779
|
+
private _addToKey;
|
|
767
780
|
/**
|
|
768
781
|
*
|
|
769
782
|
*
|
|
@@ -775,6 +788,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
775
788
|
* @returns {*}
|
|
776
789
|
* @memberof MemoryCache
|
|
777
790
|
*/
|
|
791
|
+
private _testType;
|
|
778
792
|
/**
|
|
779
793
|
*
|
|
780
794
|
*
|
|
@@ -783,6 +797,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
783
797
|
* @returns {*}
|
|
784
798
|
* @memberof MemoryCache
|
|
785
799
|
*/
|
|
800
|
+
private _getKey;
|
|
786
801
|
/**
|
|
787
802
|
*
|
|
788
803
|
*
|
|
@@ -791,6 +806,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
791
806
|
* @param {(number | string)} value
|
|
792
807
|
* @memberof MemoryCache
|
|
793
808
|
*/
|
|
809
|
+
private _setKey;
|
|
794
810
|
/**
|
|
795
811
|
*
|
|
796
812
|
*
|
|
@@ -803,6 +819,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
803
819
|
* @returns {*}
|
|
804
820
|
* @memberof MemoryCache
|
|
805
821
|
*/
|
|
822
|
+
private _addToField;
|
|
806
823
|
/**
|
|
807
824
|
*
|
|
808
825
|
*
|
|
@@ -812,6 +829,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
812
829
|
* @returns {*}
|
|
813
830
|
* @memberof MemoryCache
|
|
814
831
|
*/
|
|
832
|
+
private _getField;
|
|
815
833
|
/**
|
|
816
834
|
*
|
|
817
835
|
*
|
|
@@ -821,6 +839,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
821
839
|
* @returns {*} {boolean}
|
|
822
840
|
* @memberof MemoryCache
|
|
823
841
|
*/
|
|
842
|
+
private _hasField;
|
|
824
843
|
/**
|
|
825
844
|
*
|
|
826
845
|
*
|
|
@@ -841,6 +860,8 @@ declare class MemoryCache extends EventEmitter {
|
|
|
841
860
|
* @returns {*}
|
|
842
861
|
* @memberof MemoryCache
|
|
843
862
|
*/
|
|
863
|
+
private _handleCallback;
|
|
864
|
+
private _logReturn;
|
|
844
865
|
/**
|
|
845
866
|
*
|
|
846
867
|
*
|
|
@@ -849,6 +870,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
849
870
|
* @returns {*}
|
|
850
871
|
* @memberof MemoryCache
|
|
851
872
|
*/
|
|
873
|
+
private _retrieveCallback;
|
|
852
874
|
/**
|
|
853
875
|
* 字符串追加操作
|
|
854
876
|
* @param key
|
|
@@ -901,6 +923,7 @@ declare class MemoryCache extends EventEmitter {
|
|
|
901
923
|
* @param key
|
|
902
924
|
* @param pattern
|
|
903
925
|
*/
|
|
926
|
+
private matchPattern;
|
|
904
927
|
/**
|
|
905
928
|
* 获取随机键
|
|
906
929
|
* @param callback
|
|
@@ -1068,12 +1091,16 @@ declare class RedisStore {
|
|
|
1068
1091
|
options: RedisStoreOpt;
|
|
1069
1092
|
pool: genericPool.Pool<Redis | Cluster>;
|
|
1070
1093
|
client: Redis | Cluster;
|
|
1094
|
+
private reconnectAttempts;
|
|
1095
|
+
private maxReconnectAttempts;
|
|
1096
|
+
private reconnectDelay;
|
|
1071
1097
|
/**
|
|
1072
1098
|
* Creates an instance of RedisStore.
|
|
1073
1099
|
* @param {RedisStoreOpt} options
|
|
1074
1100
|
* @memberof RedisStore
|
|
1075
1101
|
*/
|
|
1076
1102
|
constructor(options: RedisStoreOpt);
|
|
1103
|
+
private parseOpt;
|
|
1077
1104
|
/**
|
|
1078
1105
|
* create connection by native with improved error handling
|
|
1079
1106
|
*
|
|
@@ -1081,11 +1108,13 @@ declare class RedisStore {
|
|
|
1081
1108
|
* @returns {*} {Promise<Redis | Cluster>}
|
|
1082
1109
|
* @memberof RedisStore
|
|
1083
1110
|
*/
|
|
1111
|
+
private connect;
|
|
1084
1112
|
/**
|
|
1085
1113
|
* 计划重连,使用指数退避策略
|
|
1086
1114
|
* @private
|
|
1087
1115
|
* @param {number} connNum
|
|
1088
1116
|
*/
|
|
1117
|
+
private scheduleReconnect;
|
|
1089
1118
|
/**
|
|
1090
1119
|
* get connection from pool with improved configuration
|
|
1091
1120
|
*
|
package/dist/index.js
CHANGED
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koatty_store",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Cache store for koatty.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -79,14 +79,14 @@
|
|
|
79
79
|
"async-lock": "^1.4.1",
|
|
80
80
|
"generic-pool": "^3.9.0",
|
|
81
81
|
"ioredis": "^5.9.2",
|
|
82
|
-
"koatty_lib": "^1.4.5",
|
|
83
|
-
"koatty_logger": "^2.3.4",
|
|
84
82
|
"lodash": "^4.17.23",
|
|
85
|
-
"lru-cache": "^11.2.5"
|
|
83
|
+
"lru-cache": "^11.2.5",
|
|
84
|
+
"koatty_lib": "1.4.5",
|
|
85
|
+
"koatty_logger": "2.4.1"
|
|
86
86
|
},
|
|
87
87
|
"peerDependencies": {
|
|
88
88
|
"koatty_lib": "^1.4.5",
|
|
89
|
-
"koatty_logger": "^2.
|
|
89
|
+
"koatty_logger": "^2.4.1"
|
|
90
90
|
},
|
|
91
91
|
"scripts": {
|
|
92
92
|
"build": "npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp",
|
package/dist/LICENSE
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
BSD 3-Clause License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2020, Koatty
|
|
4
|
-
All rights reserved.
|
|
5
|
-
|
|
6
|
-
Redistribution and use in source and binary forms, with or without
|
|
7
|
-
modification, are permitted provided that the following conditions are met:
|
|
8
|
-
|
|
9
|
-
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
-
list of conditions and the following disclaimer.
|
|
11
|
-
|
|
12
|
-
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
-
this list of conditions and the following disclaimer in the documentation
|
|
14
|
-
and/or other materials provided with the distribution.
|
|
15
|
-
|
|
16
|
-
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
-
contributors may be used to endorse or promote products derived from
|
|
18
|
-
this software without specific prior written permission.
|
|
19
|
-
|
|
20
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
-
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
-
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
-
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
-
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
-
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
-
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
-
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
-
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/dist/README.md
DELETED
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
# koatty_store
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/koatty_store)
|
|
4
|
-
[](https://npmjs.org/package/koatty_store)
|
|
5
|
-
|
|
6
|
-
Cache store (memory or redis) for Koatty framework.
|
|
7
|
-
|
|
8
|
-
## Features
|
|
9
|
-
|
|
10
|
-
- 🚀 **Dual Storage**: Support both in-memory and Redis storage
|
|
11
|
-
- 💾 **LRU Cache**: Built-in LRU cache with configurable size
|
|
12
|
-
- ⏰ **TTL Support**: Field-level TTL for hash operations
|
|
13
|
-
- 🔒 **Concurrency Safe**: Atomic operations with lock protection
|
|
14
|
-
- 📊 **Rich Data Types**: String, Hash, List, Set, Sorted Set
|
|
15
|
-
- 🔄 **Auto Reconnect**: Redis connection with retry mechanism
|
|
16
|
-
- 🎯 **Type Safe**: Full TypeScript support
|
|
17
|
-
- 📦 **Lightweight**: Minimal dependencies
|
|
18
|
-
|
|
19
|
-
## Installation
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npm install koatty_store
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Quick Start
|
|
26
|
-
|
|
27
|
-
### Memory Store
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
import { CacheStore } from 'koatty_store';
|
|
31
|
-
|
|
32
|
-
// Create memory store
|
|
33
|
-
const store = new CacheStore({
|
|
34
|
-
type: 'memory',
|
|
35
|
-
keyPrefix: 'myapp:',
|
|
36
|
-
maxKeys: 1000
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
// String operations
|
|
40
|
-
await store.set('user:1', 'John', 60); // Expires in 60 seconds
|
|
41
|
-
const value = await store.get('user:1');
|
|
42
|
-
|
|
43
|
-
// Hash operations
|
|
44
|
-
await store.hset('user:info', 'name', 'John');
|
|
45
|
-
await store.hset('user:info', 'age', '25');
|
|
46
|
-
const name = await store.hget('user:info', 'name');
|
|
47
|
-
|
|
48
|
-
// List operations
|
|
49
|
-
await store.rpush('queue', 'task1');
|
|
50
|
-
await store.rpush('queue', 'task2');
|
|
51
|
-
const task = await store.lpop('queue');
|
|
52
|
-
|
|
53
|
-
// Close store
|
|
54
|
-
await store.close();
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Redis Store
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
import { CacheStore } from 'koatty_store';
|
|
61
|
-
|
|
62
|
-
// Create redis store
|
|
63
|
-
const store = new CacheStore({
|
|
64
|
-
type: 'redis',
|
|
65
|
-
host: '127.0.0.1',
|
|
66
|
-
port: 6379,
|
|
67
|
-
password: 'your-password',
|
|
68
|
-
db: 0,
|
|
69
|
-
keyPrefix: 'myapp:',
|
|
70
|
-
poolSize: 10
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
// Use same API as memory store
|
|
74
|
-
await store.set('key', 'value');
|
|
75
|
-
await store.close();
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## Configuration
|
|
79
|
-
|
|
80
|
-
### Memory Store Options
|
|
81
|
-
|
|
82
|
-
```typescript
|
|
83
|
-
interface MemoryStoreOpt {
|
|
84
|
-
type: 'memory';
|
|
85
|
-
keyPrefix?: string; // Key prefix, default: 'Koatty'
|
|
86
|
-
db?: number; // Database index, default: 0
|
|
87
|
-
timeout?: number; // Default TTL in seconds, default: 600
|
|
88
|
-
maxKeys?: number; // LRU max keys, default: 1000
|
|
89
|
-
maxMemory?: number; // Max memory in bytes
|
|
90
|
-
evictionPolicy?: 'lru' | 'lfu' | 'random'; // Eviction policy, default: 'lru'
|
|
91
|
-
ttlCheckInterval?: number; // TTL check interval in ms, default: 60000
|
|
92
|
-
}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### Redis Store Options
|
|
96
|
-
|
|
97
|
-
```typescript
|
|
98
|
-
interface RedisStoreOpt {
|
|
99
|
-
type: 'redis';
|
|
100
|
-
host: string; // Redis host
|
|
101
|
-
port: number; // Redis port
|
|
102
|
-
password?: string; // Redis password
|
|
103
|
-
db?: number; // Database index, default: 0
|
|
104
|
-
keyPrefix?: string; // Key prefix, default: 'Koatty'
|
|
105
|
-
timeout?: number; // Default TTL in seconds, default: 600
|
|
106
|
-
poolSize?: number; // Connection pool size, default: 10
|
|
107
|
-
connectTimeout?: number; // Connection timeout in ms, default: 500
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
## API Reference
|
|
112
|
-
|
|
113
|
-
### String Operations
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
// Set a string value with optional TTL
|
|
117
|
-
await store.set(key: string, value: string | number, timeout?: number): Promise<string>
|
|
118
|
-
|
|
119
|
-
// Get a string value
|
|
120
|
-
await store.get(key: string): Promise<string | null>
|
|
121
|
-
|
|
122
|
-
// Delete a key
|
|
123
|
-
await store.del(key: string): Promise<number>
|
|
124
|
-
|
|
125
|
-
// Check if key exists
|
|
126
|
-
await store.exists(key: string): Promise<number>
|
|
127
|
-
|
|
128
|
-
// Get TTL of a key
|
|
129
|
-
await store.ttl(key: string): Promise<number>
|
|
130
|
-
|
|
131
|
-
// Set TTL for a key
|
|
132
|
-
await store.expire(key: string, timeout: number): Promise<number>
|
|
133
|
-
|
|
134
|
-
// Increment
|
|
135
|
-
await store.incr(key: string): Promise<number>
|
|
136
|
-
await store.incrby(key: string, increment: number): Promise<number>
|
|
137
|
-
|
|
138
|
-
// Decrement
|
|
139
|
-
await store.decr(key: string): Promise<number>
|
|
140
|
-
await store.decrby(key: string, decrement: number): Promise<number>
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Hash Operations
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
// Set hash field with optional TTL (field-level)
|
|
147
|
-
await store.hset(name: string, key: string, value: string | number, timeout?: number): Promise<number>
|
|
148
|
-
|
|
149
|
-
// Get hash field
|
|
150
|
-
await store.hget(name: string, key: string): Promise<string | null>
|
|
151
|
-
|
|
152
|
-
// Delete hash field
|
|
153
|
-
await store.hdel(name: string, key: string): Promise<number>
|
|
154
|
-
|
|
155
|
-
// Check if hash field exists
|
|
156
|
-
await store.hexists(name: string, key: string): Promise<number>
|
|
157
|
-
|
|
158
|
-
// Get all fields and values
|
|
159
|
-
await store.hgetall(name: string): Promise<any>
|
|
160
|
-
|
|
161
|
-
// Get all field names
|
|
162
|
-
await store.hkeys(name: string): Promise<string[]>
|
|
163
|
-
|
|
164
|
-
// Get all values
|
|
165
|
-
await store.hvals(name: string): Promise<any[]>
|
|
166
|
-
|
|
167
|
-
// Get hash length
|
|
168
|
-
await store.hlen(name: string): Promise<number>
|
|
169
|
-
|
|
170
|
-
// Increment hash field
|
|
171
|
-
await store.hincrby(name: string, key: string, increment: number): Promise<number>
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### List Operations
|
|
175
|
-
|
|
176
|
-
```typescript
|
|
177
|
-
// Push to right
|
|
178
|
-
await store.rpush(name: string, value: string | number): Promise<number>
|
|
179
|
-
|
|
180
|
-
// Push to left
|
|
181
|
-
await store.lpush(name: string, value: string | number): Promise<number>
|
|
182
|
-
|
|
183
|
-
// Pop from left
|
|
184
|
-
await store.lpop(name: string): Promise<string | null>
|
|
185
|
-
|
|
186
|
-
// Pop from right
|
|
187
|
-
await store.rpop(name: string): Promise<string | null>
|
|
188
|
-
|
|
189
|
-
// Get list length
|
|
190
|
-
await store.llen(name: string): Promise<number>
|
|
191
|
-
|
|
192
|
-
// Get range
|
|
193
|
-
await store.lrange(name: string, start: number, stop: number): Promise<any[]>
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### Set Operations
|
|
197
|
-
|
|
198
|
-
```typescript
|
|
199
|
-
// Add member with optional TTL
|
|
200
|
-
await store.sadd(name: string, value: string | number, timeout?: number): Promise<number>
|
|
201
|
-
|
|
202
|
-
// Remove member
|
|
203
|
-
await store.srem(name: string, key: string): Promise<number>
|
|
204
|
-
|
|
205
|
-
// Get set size
|
|
206
|
-
await store.scard(name: string): Promise<number>
|
|
207
|
-
|
|
208
|
-
// Check if member exists
|
|
209
|
-
await store.sismember(name: string, key: string): Promise<number>
|
|
210
|
-
|
|
211
|
-
// Get all members
|
|
212
|
-
await store.smembers(name: string): Promise<any[]>
|
|
213
|
-
|
|
214
|
-
// Pop random member
|
|
215
|
-
await store.spop(name: string): Promise<any>
|
|
216
|
-
|
|
217
|
-
// Move member between sets
|
|
218
|
-
await store.smove(source: string, destination: string, member: string): Promise<number>
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
## Advanced Features
|
|
222
|
-
|
|
223
|
-
### Field-Level TTL for Hash
|
|
224
|
-
|
|
225
|
-
```typescript
|
|
226
|
-
// Set hash field with TTL (expires in 60 seconds)
|
|
227
|
-
await store.hset('user:session', 'token', 'abc123', 60);
|
|
228
|
-
|
|
229
|
-
// Field will be automatically deleted after TTL expires
|
|
230
|
-
setTimeout(async () => {
|
|
231
|
-
const token = await store.hget('user:session', 'token');
|
|
232
|
-
console.log(token); // null
|
|
233
|
-
}, 61000);
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
### Singleton Pattern
|
|
237
|
-
|
|
238
|
-
```typescript
|
|
239
|
-
// Get singleton instance
|
|
240
|
-
const store1 = CacheStore.getInstance({
|
|
241
|
-
type: 'memory',
|
|
242
|
-
keyPrefix: 'app:'
|
|
243
|
-
}, 'cache1');
|
|
244
|
-
|
|
245
|
-
const store2 = CacheStore.getInstance({
|
|
246
|
-
type: 'memory',
|
|
247
|
-
keyPrefix: 'app:'
|
|
248
|
-
}, 'cache1');
|
|
249
|
-
|
|
250
|
-
console.log(store1 === store2); // true
|
|
251
|
-
|
|
252
|
-
// Clear specific instance
|
|
253
|
-
await CacheStore.clearInstance('cache1');
|
|
254
|
-
|
|
255
|
-
// Clear all instances
|
|
256
|
-
await CacheStore.clearAllInstances();
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
### Concurrency Safe Operations
|
|
260
|
-
|
|
261
|
-
All atomic operations (incr, decr, incrby, decrby, hincrby) are protected with locks to ensure data consistency in concurrent scenarios.
|
|
262
|
-
|
|
263
|
-
```typescript
|
|
264
|
-
// Safe concurrent increments
|
|
265
|
-
await Promise.all([
|
|
266
|
-
store.incr('counter'),
|
|
267
|
-
store.incr('counter'),
|
|
268
|
-
store.incr('counter')
|
|
269
|
-
]);
|
|
270
|
-
|
|
271
|
-
const count = await store.get('counter');
|
|
272
|
-
console.log(count); // "3" - guaranteed consistency
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
## Best Practices
|
|
276
|
-
|
|
277
|
-
### 1. Use Key Prefix
|
|
278
|
-
|
|
279
|
-
```typescript
|
|
280
|
-
const store = new CacheStore({
|
|
281
|
-
type: 'memory',
|
|
282
|
-
keyPrefix: 'myapp:' // Prefix all keys
|
|
283
|
-
});
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
### 2. Set Appropriate TTL
|
|
287
|
-
|
|
288
|
-
```typescript
|
|
289
|
-
// Short-lived data
|
|
290
|
-
await store.set('session:token', token, 3600); // 1 hour
|
|
291
|
-
|
|
292
|
-
// Long-lived data
|
|
293
|
-
await store.set('user:profile', profile, 86400); // 24 hours
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
### 3. Handle Errors Gracefully
|
|
297
|
-
|
|
298
|
-
```typescript
|
|
299
|
-
try {
|
|
300
|
-
await store.set('key', 'value');
|
|
301
|
-
} catch (error) {
|
|
302
|
-
console.error('Cache operation failed:', error.message);
|
|
303
|
-
// Fallback to database or other source
|
|
304
|
-
}
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### 4. Close Store on Exit
|
|
308
|
-
|
|
309
|
-
```typescript
|
|
310
|
-
process.on('SIGINT', async () => {
|
|
311
|
-
await store.close();
|
|
312
|
-
process.exit(0);
|
|
313
|
-
});
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
### 5. Use Connection Pool for Redis
|
|
317
|
-
|
|
318
|
-
```typescript
|
|
319
|
-
const store = new CacheStore({
|
|
320
|
-
type: 'redis',
|
|
321
|
-
host: '127.0.0.1',
|
|
322
|
-
port: 6379,
|
|
323
|
-
poolSize: 20 // Adjust based on load
|
|
324
|
-
});
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
## Testing
|
|
328
|
-
|
|
329
|
-
```bash
|
|
330
|
-
# Run tests
|
|
331
|
-
npm test
|
|
332
|
-
|
|
333
|
-
# Run tests with coverage
|
|
334
|
-
npm test -- --coverage
|
|
335
|
-
|
|
336
|
-
# Run specific test
|
|
337
|
-
npm test -- test/memory.test.ts
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
## Performance
|
|
341
|
-
|
|
342
|
-
### Memory Store
|
|
343
|
-
- **Operations**: ~1,000,000 ops/sec
|
|
344
|
-
- **LRU Eviction**: O(1)
|
|
345
|
-
- **TTL Check**: Background task, configurable interval
|
|
346
|
-
|
|
347
|
-
### Redis Store
|
|
348
|
-
- **Operations**: Depends on Redis server
|
|
349
|
-
- **Connection Pool**: Configurable size
|
|
350
|
-
- **Auto Reconnect**: Exponential backoff strategy
|
|
351
|
-
|
|
352
|
-
## Changelog
|
|
353
|
-
|
|
354
|
-
See [CHANGELOG.md](CHANGELOG.md) for release history.
|
|
355
|
-
|
|
356
|
-
## License
|
|
357
|
-
|
|
358
|
-
BSD-3-Clause
|
|
359
|
-
|
|
360
|
-
## Contributing
|
|
361
|
-
|
|
362
|
-
Contributions are welcome! Please read the [contributing guidelines](https://github.com/koatty/koatty_store/blob/master/CONTRIBUTING.md) first.
|
|
363
|
-
|
|
364
|
-
## Support
|
|
365
|
-
|
|
366
|
-
- [GitHub Issues](https://github.com/koatty/koatty_store/issues)
|
|
367
|
-
- [Documentation](https://koatty.com)
|
|
368
|
-
|
|
369
|
-
## Related Projects
|
|
370
|
-
|
|
371
|
-
- [koatty](https://github.com/koatty/koatty) - The Koatty framework
|
|
372
|
-
- [koatty_lib](https://github.com/koatty/koatty_lib) - Koatty utilities
|
|
373
|
-
- [koatty_logger](https://github.com/koatty/koatty_logger) - Koatty logger
|
package/dist/package.json
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "koatty_store",
|
|
3
|
-
"version": "1.9.4",
|
|
4
|
-
"description": "Cache store for koatty.",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"build": "npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp",
|
|
7
|
-
"build:cp": "node scripts/postBuild && npx copyfiles package.json LICENSE README.md dist/",
|
|
8
|
-
"build:js": "npx rollup --bundleConfigAsCjs -c .rollup.config.js",
|
|
9
|
-
"build:doc": "npx api-documenter markdown --input temp --output docs/api",
|
|
10
|
-
"build:dts": "bash ../../scripts/build-dts.sh",
|
|
11
|
-
"eslint": "eslint --ext .ts,.js ./",
|
|
12
|
-
"prepublishOnly": "npm test && npm run build",
|
|
13
|
-
"prerelease": "npm test && npm run build",
|
|
14
|
-
"pub": "git push --follow-tags origin && npm publish",
|
|
15
|
-
"test": "npm run eslint && jest --passWithNoTests"
|
|
16
|
-
},
|
|
17
|
-
"main": "./dist/index.js",
|
|
18
|
-
"exports": {
|
|
19
|
-
"require": "./dist/index.js",
|
|
20
|
-
"import": "./dist/index.mjs",
|
|
21
|
-
"types": "./dist/index.d.ts"
|
|
22
|
-
},
|
|
23
|
-
"repository": {
|
|
24
|
-
"type": "git",
|
|
25
|
-
"url": "git+https://github.com/koatty/koatty_store.git"
|
|
26
|
-
},
|
|
27
|
-
"keywords": [
|
|
28
|
-
"web",
|
|
29
|
-
"typescript",
|
|
30
|
-
"framework",
|
|
31
|
-
"mvc",
|
|
32
|
-
"koa2",
|
|
33
|
-
"restful",
|
|
34
|
-
"agile",
|
|
35
|
-
"koatty_store",
|
|
36
|
-
"koatty"
|
|
37
|
-
],
|
|
38
|
-
"engines": {
|
|
39
|
-
"node": ">10.0.0"
|
|
40
|
-
},
|
|
41
|
-
"author": {
|
|
42
|
-
"name": "richenlin",
|
|
43
|
-
"email": "richenlin@gmail.com"
|
|
44
|
-
},
|
|
45
|
-
"license": "BSD-3-Clause",
|
|
46
|
-
"bugs": {
|
|
47
|
-
"url": "https://github.com/koatty/koatty_store/issues"
|
|
48
|
-
},
|
|
49
|
-
"homepage": "https://github.com/koatty/koatty_store",
|
|
50
|
-
"maintainers": [
|
|
51
|
-
{
|
|
52
|
-
"name": "richenlin",
|
|
53
|
-
"email": "richenlin@gmail.com"
|
|
54
|
-
}
|
|
55
|
-
],
|
|
56
|
-
"devDependencies": {
|
|
57
|
-
"@commitlint/cli": "^19.x.x",
|
|
58
|
-
"@commitlint/config-conventional": "^19.x.x",
|
|
59
|
-
"@microsoft/api-documenter": "^7.x.x",
|
|
60
|
-
"@microsoft/api-extractor": "^7.x.x",
|
|
61
|
-
"@rollup/plugin-commonjs": "^28.x.x",
|
|
62
|
-
"@rollup/plugin-json": "^6.x.x",
|
|
63
|
-
"@rollup/plugin-node-resolve": "^15.x.x",
|
|
64
|
-
"@types/async-lock": "^1.4.2",
|
|
65
|
-
"@types/jest": "^29.x.x",
|
|
66
|
-
"@types/koa": "^2.x.x",
|
|
67
|
-
"@types/lodash": "^4.x.x",
|
|
68
|
-
"@types/lru-cache": "^7.10.9",
|
|
69
|
-
"@types/node": "^22.x.x",
|
|
70
|
-
"@typescript-eslint/eslint-plugin": "^8.x.x",
|
|
71
|
-
"@typescript-eslint/parser": "^8.x.x",
|
|
72
|
-
"conventional-changelog-cli": "^5.x.x",
|
|
73
|
-
"copyfiles": "^2.x.x",
|
|
74
|
-
"del-cli": "^6.x.x",
|
|
75
|
-
"eslint": "^8.x.x",
|
|
76
|
-
"eslint-plugin-jest": "^28.x.x",
|
|
77
|
-
"husky": "^4.x.x",
|
|
78
|
-
"jest": "^29.x.x",
|
|
79
|
-
"jest-html-reporters": "^3.x.x",
|
|
80
|
-
"reflect-metadata": "^0.x.x",
|
|
81
|
-
"rollup": "^4.x.x",
|
|
82
|
-
"rollup-plugin-delete": "^2.x.x",
|
|
83
|
-
"rollup-plugin-typescript2": "^0.x.x",
|
|
84
|
-
"standard-version": "^9.x.x",
|
|
85
|
-
"ts-jest": "^29.x.x",
|
|
86
|
-
"ts-node": "^10.x.x",
|
|
87
|
-
"tslib": "^2.x.x",
|
|
88
|
-
"typescript": "^5.x.x"
|
|
89
|
-
},
|
|
90
|
-
"dependencies": {
|
|
91
|
-
"async-lock": "^1.4.1",
|
|
92
|
-
"generic-pool": "^3.9.0",
|
|
93
|
-
"ioredis": "^5.9.2",
|
|
94
|
-
"koatty_lib": "^1.4.5",
|
|
95
|
-
"koatty_logger": "^2.3.4",
|
|
96
|
-
"lodash": "^4.17.23",
|
|
97
|
-
"lru-cache": "^11.2.5"
|
|
98
|
-
},
|
|
99
|
-
"peerDependencies": {
|
|
100
|
-
"koatty_lib": "^1.4.5",
|
|
101
|
-
"koatty_logger": "^2.3.4"
|
|
102
|
-
}
|
|
103
|
-
}
|