koatty_store 1.6.2 → 1.7.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/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @Author: richen
3
- * @Date: 2023-12-20 19:11:59
3
+ * @Date: 2024-11-07 14:38:56
4
4
  * @License: BSD (3-Clause)
5
5
  * @Copyright (c) - <richenlin(at)gmail.com>
6
6
  * @HomePage: https://koatty.org/
@@ -33,1861 +33,1877 @@ function _interopNamespaceDefault(e) {
33
33
 
34
34
  var helper__namespace = /*#__PURE__*/_interopNamespaceDefault(helper);
35
35
 
36
- /*
37
- * @Description:
38
- * @Usage:
39
- * @Author: richen
40
- * @Date: 2021-12-02 11:03:20
41
- * @LastEditTime: 2023-12-20 19:04:29
42
- */
43
- /**
44
- *
45
- *
46
- * @enum {number}
47
- */
48
- var messages;
49
- (function (messages) {
50
- messages["ok"] = "OK";
51
- messages["queued"] = "QUEUED";
52
- messages["pong"] = "PONG";
53
- messages["noint"] = "ERR value is not an integer or out of range";
54
- messages["nofloat"] = "ERR value is not an float or out of range";
55
- messages["nokey"] = "ERR no such key";
56
- messages["nomultiinmulti"] = "ERR MULTI calls can not be nested";
57
- messages["nomultiexec"] = "ERR EXEC without MULTI";
58
- messages["nomultidiscard"] = "ERR DISCARD without MULTI";
59
- messages["busykey"] = "ERR target key name is busy";
60
- messages["syntax"] = "ERR syntax error";
61
- messages["unsupported"] = "MemoryCache does not support that operation";
62
- messages["wrongTypeOp"] = "WRONGTYPE Operation against a key holding the wrong kind of value";
63
- messages["wrongPayload"] = "DUMP payload version or checksum are wrong";
64
- messages["wrongArgCount"] = "ERR wrong number of arguments for '%0' command";
65
- messages["bitopnotWrongCount"] = "ERR BITOP NOT must be called with a single source key";
66
- messages["indexOutOfRange"] = "ERR index out of range";
67
- messages["invalidLexRange"] = "ERR min or max not valid string range item";
68
- messages["invalidDBIndex"] = "ERR invalid DB index";
69
- messages["invalidDBIndexNX"] = "ERR invalid DB index, '%0' does not exist";
70
- messages["mutuallyExclusiveNXXX"] = "ERR XX and NX options at the same time are not compatible";
71
- })(messages || (messages = {}));
72
- class MemoryCache extends events.EventEmitter {
73
- /**
74
- * Creates an instance of MemoryCache.
75
- * @param {*} options
76
- * @memberof MemoryCache
77
- */
78
- constructor(options) {
79
- super();
80
- this.databases = Object.create({});
81
- this.options = { ...{ database: "0" }, ...options };
82
- this.currentDBIndex = 0;
83
- this.connected = false;
84
- this.lastSave = Date.now();
85
- this.multiMode = false;
86
- }
87
- /**
88
- *
89
- *
90
- * @returns {*}
91
- * @memberof MemoryCache
92
- */
93
- createClient() {
94
- this.databases[this.options.database] = Object.create({});
95
- this.cache = this.databases[this.options.database];
96
- this.connected = true;
97
- // exit multi mode if we are in it
98
- this.discard(null, true);
99
- this.emit('connect');
100
- this.emit('ready');
101
- return this;
102
- }
103
- /**
104
- *
105
- *
106
- * @returns {*}
107
- * @memberof MemoryCache
108
- */
109
- quit() {
110
- this.connected = false;
111
- // exit multi mode if we are in it
112
- this.discard(null, true);
113
- this.emit('end');
114
- return this;
115
- }
116
- /**
117
- *
118
- *
119
- * @returns {*}
120
- * @memberof MemoryCache
121
- */
122
- end() {
123
- return this.quit();
124
- }
125
- /**
126
- *
127
- *
128
- * @param {string} message
129
- * @param {Function} [callback]
130
- * @returns {*}
131
- * @memberof MemoryCache
132
- */
133
- echo(message, callback) {
134
- return this._handleCallback(callback, message);
135
- }
136
- /**
137
- *
138
- *
139
- * @param {string} message
140
- * @param {Function} [callback]
141
- * @returns {*}
142
- * @memberof MemoryCache
143
- */
144
- ping(message, callback) {
145
- message = message || messages.pong;
146
- return this._handleCallback(callback, message);
147
- }
148
- /**
149
- *
150
- *
151
- * @param {string} password
152
- * @param {Function} [callback]
153
- * @returns {*}
154
- * @memberof MemoryCache
155
- */
156
- auth(password, callback) {
157
- return this._handleCallback(callback, messages.ok);
158
- }
159
- /**
160
- *
161
- *
162
- * @param {number} dbIndex
163
- * @param {Function} [callback]
164
- * @returns {*}
165
- * @memberof MemoryCache
166
- */
167
- select(dbIndex, callback) {
168
- if (!helper__namespace.isNumber(dbIndex)) {
169
- return this._handleCallback(callback, null, messages.invalidDBIndex);
170
- }
171
- if (!this.databases.hasOwnProperty(dbIndex)) {
172
- this.databases[dbIndex] = Object.create({});
173
- }
174
- this.multiMode = false;
175
- this.currentDBIndex = dbIndex;
176
- this.cache = this.databases[dbIndex];
177
- return this._handleCallback(callback, messages.ok);
178
- }
179
- // ---------------------------------------
180
- // Keys
181
- // ---------------------------------------
182
- get(key, callback) {
183
- let retVal = null;
184
- if (this._hasKey(key)) {
185
- this._testType(key, 'string', true, callback);
186
- retVal = this._getKey(key);
187
- }
188
- return this._handleCallback(callback, retVal);
189
- }
190
- /**
191
- * set(key, value, ttl, pttl, notexist, onlyexist, callback)
192
- *
193
- * @param {string} key
194
- * @param {(string | number)} value
195
- * @param {...any[]} params
196
- * @returns {*}
197
- * @memberof MemoryCache
198
- */
199
- set(key, value, ...params) {
200
- const retVal = null;
201
- params = lodash.flatten(params);
202
- const callback = this._retrieveCallback(params);
203
- let ttl, pttl, notexist, onlyexist;
204
- // parse parameters
205
- while (params.length > 0) {
206
- const param = params.shift();
207
- switch (param.toString().toLowerCase()) {
208
- case 'nx':
209
- notexist = true;
210
- break;
211
- case 'xx':
212
- onlyexist = true;
213
- break;
214
- case 'ex':
215
- if (params.length === 0) {
216
- return this._handleCallback(callback, null, messages.syntax);
217
- }
218
- ttl = parseInt(params.shift());
219
- if (isNaN(ttl)) {
220
- return this._handleCallback(callback, null, messages.noint);
221
- }
222
- break;
223
- case 'px':
224
- if (params.length === 0) {
225
- return this._handleCallback(callback, null, messages.syntax);
226
- }
227
- pttl = parseInt(params.shift());
228
- if (isNaN(pttl)) {
229
- return this._handleCallback(callback, null, messages.noint);
230
- }
231
- break;
232
- default:
233
- return this._handleCallback(callback, null, messages.syntax);
234
- }
235
- }
236
- if (!lodash.isNil(ttl) && !lodash.isNil(pttl)) {
237
- return this._handleCallback(callback, null, messages.syntax);
238
- }
239
- if (notexist && onlyexist) {
240
- return this._handleCallback(callback, null, messages.syntax);
241
- }
242
- pttl = pttl || ttl * 1000 || null;
243
- if (!lodash.isNil(pttl)) {
244
- pttl = Date.now() + pttl;
245
- }
246
- if (this._hasKey(key)) {
247
- this._testType(key, 'string', true, callback);
248
- if (notexist) {
249
- return this._handleCallback(callback, retVal);
250
- }
251
- }
252
- else if (onlyexist) {
253
- return this._handleCallback(callback, retVal);
254
- }
255
- this.cache[key] = this._makeKey(value.toString(), 'string', pttl);
256
- return this._handleCallback(callback, messages.ok);
257
- }
258
- /**
259
- *
260
- *
261
- * @param {string} key
262
- * @param {Function} [callback]
263
- * @returns {*}
264
- * @memberof MemoryCache
265
- */
266
- ttl(key, callback) {
267
- let retVal = this.pttl(key);
268
- if (retVal >= 0 || retVal <= -3) {
269
- retVal = Math.floor(retVal / 1000);
270
- }
271
- return this._handleCallback(callback, retVal);
272
- }
273
- /**
274
- *
275
- *
276
- * @param {string} key
277
- * @param {number} seconds
278
- * @param {Function} [callback]
279
- * @returns {*}
280
- * @memberof MemoryCache
281
- */
282
- expire(key, seconds, callback) {
283
- let retVal = 0;
284
- if (this._hasKey(key)) {
285
- this.cache[key].timeout = Date.now() + seconds * 1000;
286
- retVal = 1;
287
- }
288
- return this._handleCallback(callback, retVal);
289
- }
290
- /**
291
- *
292
- *
293
- * @param {...any[]} keys
294
- * @returns {*}
295
- * @memberof MemoryCache
296
- */
297
- del(...keys) {
298
- let retVal = 0;
299
- const callback = this._retrieveCallback(keys);
300
- // Flatten the array in case an array was passed
301
- keys = lodash.flatten(keys);
302
- for (let itr = 0; itr < keys.length; itr++) {
303
- const key = keys[itr];
304
- if (this._hasKey(key)) {
305
- delete this.cache[key];
306
- retVal++;
307
- }
308
- }
309
- return this._handleCallback(callback, retVal);
310
- }
311
- /**
312
- *
313
- *
314
- * @param {...any[]} keys
315
- * @returns {*}
316
- * @memberof MemoryCache
317
- */
318
- exists(...keys) {
319
- let retVal = 0;
320
- const callback = this._retrieveCallback(keys);
321
- for (let itr = 0; itr < keys.length; itr++) {
322
- const key = keys[itr];
323
- if (this._hasKey(key)) {
324
- retVal++;
325
- }
326
- }
327
- return this._handleCallback(callback, retVal);
328
- }
329
- /**
330
- *
331
- *
332
- * @param {string} key
333
- * @param {Function} [callback]
334
- * @returns {*}
335
- * @memberof MemoryCache
336
- */
337
- incr(key, callback) {
338
- let retVal = null;
339
- try {
340
- retVal = this._addToKey(key, 1);
341
- }
342
- catch (err) {
343
- return this._handleCallback(callback, null, err);
344
- }
345
- return this._handleCallback(callback, retVal);
346
- }
347
- /**
348
- *
349
- *
350
- * @param {string} key
351
- * @param {number} amount
352
- * @param {Function} [callback]
353
- * @returns {*}
354
- * @memberof MemoryCache
355
- */
356
- incrby(key, amount, callback) {
357
- let retVal = null;
358
- try {
359
- retVal = this._addToKey(key, amount);
360
- }
361
- catch (err) {
362
- return this._handleCallback(callback, null, err);
363
- }
364
- return this._handleCallback(callback, retVal);
365
- }
366
- /**
367
- *
368
- *
369
- * @param {string} key
370
- * @param {Function} [callback]
371
- * @returns {*}
372
- * @memberof MemoryCache
373
- */
374
- decr(key, callback) {
375
- let retVal = null;
376
- try {
377
- retVal = this._addToKey(key, -1);
378
- }
379
- catch (err) {
380
- return this._handleCallback(callback, null, err);
381
- }
382
- return this._handleCallback(callback, retVal);
383
- }
384
- /**
385
- *
386
- *
387
- * @param {string} key
388
- * @param {number} amount
389
- * @param {Function} [callback]
390
- * @returns {*}
391
- * @memberof MemoryCache
392
- */
393
- decrby(key, amount, callback) {
394
- let retVal = null;
395
- try {
396
- retVal = this._addToKey(key, -amount);
397
- }
398
- catch (err) {
399
- return this._handleCallback(callback, null, err);
400
- }
401
- return this._handleCallback(callback, retVal);
402
- }
403
- // ---------------------------------------
404
- // ## Hash ##
405
- // ---------------------------------------
406
- hset(key, field, value, callback) {
407
- let retVal = 0;
408
- if (this._hasKey(key)) {
409
- this._testType(key, 'hash', true, callback);
410
- }
411
- else {
412
- this.cache[key] = this._makeKey({}, 'hash');
413
- }
414
- if (!this._hasField(key, field)) {
415
- retVal = 1;
416
- }
417
- this._setField(key, field, value.toString());
418
- this.persist(key);
419
- return this._handleCallback(callback, retVal);
420
- }
421
- /**
422
- *
423
- *
424
- * @param {string} key
425
- * @param {string} field
426
- * @param {Function} [callback]
427
- * @returns {*}
428
- * @memberof MemoryCache
429
- */
430
- hget(key, field, callback) {
431
- let retVal = null;
432
- if (this._hasKey(key)) {
433
- this._testType(key, 'hash', true, callback);
434
- if (this._hasField(key, field)) {
435
- retVal = this._getKey(key)[field];
436
- }
437
- }
438
- return this._handleCallback(callback, retVal);
439
- }
440
- /**
441
- *
442
- *
443
- * @param {string} key
444
- * @param {string} field
445
- * @param {Function} [callback]
446
- * @returns {*}
447
- * @memberof MemoryCache
448
- */
449
- hexists(key, field, callback) {
450
- let retVal = 0;
451
- if (this._hasKey(key)) {
452
- this._testType(key, 'hash', true, callback);
453
- if (this._hasField(key, field)) {
454
- retVal = 1;
455
- }
456
- }
457
- return this._handleCallback(callback, retVal);
458
- }
459
- /**
460
- *
461
- *
462
- * @param {string} key
463
- * @param {...any[]} fields
464
- * @returns {*}
465
- * @memberof MemoryCache
466
- */
467
- hdel(key, ...fields) {
468
- let retVal = 0;
469
- const callback = this._retrieveCallback(fields);
470
- if (this._hasKey(key)) {
471
- this._testType(key, 'hash', true, callback);
472
- for (let itr = 0; itr < fields.length; itr++) {
473
- const field = fields[itr];
474
- if (this._hasField(key, field)) {
475
- delete this.cache[key].value[field];
476
- retVal++;
477
- }
478
- }
479
- }
480
- return this._handleCallback(callback, retVal);
481
- }
482
- /**
483
- *
484
- *
485
- * @param {string} key
486
- * @param {Function} [callback]
487
- * @returns {*}
488
- * @memberof MemoryCache
489
- */
490
- hlen(key, callback) {
491
- const retVal = this.hkeys(key).length;
492
- return this._handleCallback(callback, retVal);
493
- }
494
- /**
495
- *
496
- *
497
- * @param {string} key
498
- * @param {string} field
499
- * @param {*} value
500
- * @param {Function} [callback]
501
- * @returns {*}
502
- * @memberof MemoryCache
503
- */
504
- hincrby(key, field, value, callback) {
505
- let retVal;
506
- try {
507
- retVal = this._addToField(key, field, value, false);
508
- }
509
- catch (err) {
510
- return this._handleCallback(callback, null, err);
511
- }
512
- return this._handleCallback(callback, retVal);
513
- }
514
- /**
515
- *
516
- *
517
- * @param {string} key
518
- * @param {Function} [callback]
519
- * @returns {*}
520
- * @memberof MemoryCache
521
- */
522
- hgetall(key, callback) {
523
- let retVals = {};
524
- if (this._hasKey(key)) {
525
- this._testType(key, 'hash', true, callback);
526
- retVals = this._getKey(key);
527
- }
528
- return this._handleCallback(callback, retVals);
529
- }
530
- /**
531
- *
532
- *
533
- * @param {string} key
534
- * @param {Function} [callback]
535
- * @returns {*}
536
- * @memberof MemoryCache
537
- */
538
- hkeys(key, callback) {
539
- let retVals = [];
540
- if (this._hasKey(key)) {
541
- this._testType(key, 'hash', true, callback);
542
- retVals = Object.keys(this._getKey(key));
543
- }
544
- return this._handleCallback(callback, retVals);
545
- }
546
- /**
547
- *
548
- *
549
- * @param {string} key
550
- * @param {Function} [callback]
551
- * @returns {*}
552
- * @memberof MemoryCache
553
- */
554
- hvals(key, callback) {
555
- let retVals = [];
556
- if (this._hasKey(key)) {
557
- this._testType(key, 'hash', true, callback);
558
- retVals = Object.values(this._getKey(key));
559
- }
560
- return this._handleCallback(callback, retVals);
561
- }
562
- // ---------------------------------------
563
- // Lists (Array / Queue / Stack)
564
- // ---------------------------------------
565
- /**
566
- *
567
- *
568
- * @param {string} key
569
- * @param {Function} [callback]
570
- * @returns {*}
571
- * @memberof MemoryCache
572
- */
573
- llen(key, callback) {
574
- let retVal = 0;
575
- if (this._hasKey(key)) {
576
- this._testType(key, 'list', true, callback);
577
- retVal = this._getKey(key).length || 0;
578
- }
579
- return this._handleCallback(callback, retVal);
580
- }
581
- /**
582
- *
583
- *
584
- * @param {string} key
585
- * @param {(string | number)} value
586
- * @param {Function} [callback]
587
- * @returns {*}
588
- * @memberof MemoryCache
589
- */
590
- rpush(key, value, callback) {
591
- let retVal = 0;
592
- if (this._hasKey(key)) {
593
- this._testType(key, 'list', true, callback);
594
- }
595
- else {
596
- this.cache[key] = this._makeKey([], 'list');
597
- }
598
- const val = this._getKey(key);
599
- val.push(value);
600
- this._setKey(key, val);
601
- retVal = val.length;
602
- return this._handleCallback(callback, retVal);
603
- }
604
- /**
605
- *
606
- *
607
- * @param {string} key
608
- * @param {(string | number)} value
609
- * @param {Function} [callback]
610
- * @returns {*}
611
- * @memberof MemoryCache
612
- */
613
- lpush(key, value, callback) {
614
- let retVal = 0;
615
- if (this._hasKey(key)) {
616
- this._testType(key, 'list', true, callback);
617
- }
618
- else {
619
- this.cache[key] = this._makeKey([], 'list');
620
- }
621
- const val = this._getKey(key);
622
- val.splice(0, 0, value);
623
- this._setKey(key, val);
624
- retVal = val.length;
625
- return this._handleCallback(callback, retVal);
626
- }
627
- /**
628
- *
629
- *
630
- * @param {string} key
631
- * @param {Function} [callback]
632
- * @returns {*}
633
- * @memberof MemoryCache
634
- */
635
- lpop(key, callback) {
636
- let retVal = null;
637
- if (this._hasKey(key)) {
638
- this._testType(key, 'list', true, callback);
639
- const val = this._getKey(key);
640
- retVal = val.shift();
641
- this._setKey(key, val);
642
- }
643
- return this._handleCallback(callback, retVal);
644
- }
645
- /**
646
- *
647
- *
648
- * @param {string} key
649
- * @param {Function} [callback]
650
- * @returns {*}
651
- * @memberof MemoryCache
652
- */
653
- rpop(key, callback) {
654
- let retVal = null;
655
- if (this._hasKey(key)) {
656
- this._testType(key, 'list', true, callback);
657
- const val = this._getKey(key);
658
- retVal = val.pop();
659
- this._setKey(key, val);
660
- }
661
- return this._handleCallback(callback, retVal);
662
- }
663
- /**
664
- *
665
- *
666
- * @param {string} key
667
- * @param {number} start
668
- * @param {number} stop
669
- * @param {Function} [callback]
670
- * @returns {*}
671
- * @memberof MemoryCache
672
- */
673
- lrange(key, start, stop, callback) {
674
- const retVal = [];
675
- if (this._hasKey(key)) {
676
- this._testType(key, 'list', true, callback);
677
- const val = this._getKey(key);
678
- const length = val.length;
679
- if (stop < 0) {
680
- stop = length + stop;
681
- }
682
- if (start < 0) {
683
- start = length + start;
684
- }
685
- if (start < 0) {
686
- start = 0;
687
- }
688
- if (stop >= length) {
689
- stop = length - 1;
690
- }
691
- if (stop >= 0 && stop >= start) {
692
- const size = stop - start + 1;
693
- for (let itr = start; itr < size; itr++) {
694
- retVal.push(val[itr]);
695
- }
696
- }
697
- }
698
- return this._handleCallback(callback, retVal);
699
- }
700
- // ---------------------------------------
701
- // ## Sets (Unique Lists)##
702
- // ---------------------------------------
703
- /**
704
- *
705
- *
706
- * @param {string} key
707
- * @param {...any[]} members
708
- * @returns {*}
709
- * @memberof MemoryCache
710
- */
711
- sadd(key, ...members) {
712
- let retVal = 0;
713
- const callback = this._retrieveCallback(members);
714
- if (this._hasKey(key)) {
715
- this._testType(key, 'set', true, callback);
716
- }
717
- else {
718
- this.cache[key] = this._makeKey([], 'set');
719
- }
720
- const val = this._getKey(key);
721
- const length = val.length;
722
- const nval = lodash.union(val, members);
723
- const newlength = nval.length;
724
- retVal = newlength - length;
725
- this._setKey(key, nval);
726
- return this._handleCallback(callback, retVal);
727
- }
728
- /**
729
- *
730
- *
731
- * @param {string} key
732
- * @param {Function} [callback]
733
- * @returns {*}
734
- * @memberof MemoryCache
735
- */
736
- scard(key, callback) {
737
- let retVal = 0;
738
- if (this._hasKey(key)) {
739
- this._testType(key, 'set', true, callback);
740
- retVal = this._getKey(key).length;
741
- }
742
- return this._handleCallback(callback, retVal);
743
- }
744
- /**
745
- *
746
- *
747
- * @param {string} key
748
- * @param {string} member
749
- * @param {Function} [callback]
750
- * @returns {*}
751
- * @memberof MemoryCache
752
- */
753
- sismember(key, member, callback) {
754
- let retVal = 0;
755
- if (this._hasKey(key)) {
756
- this._testType(key, 'set', true, callback);
757
- const val = this._getKey(key);
758
- if (val.includes(member)) {
759
- retVal = 1;
760
- }
761
- }
762
- return this._handleCallback(callback, retVal);
763
- }
764
- /**
765
- *
766
- *
767
- * @param {string} key
768
- * @param {Function} [callback]
769
- * @returns {*}
770
- * @memberof MemoryCache
771
- */
772
- smembers(key, callback) {
773
- let retVal = [];
774
- if (this._hasKey(key)) {
775
- this._testType(key, 'set', true, callback);
776
- retVal = this._getKey(key);
777
- }
778
- return this._handleCallback(callback, retVal);
779
- }
780
- /**
781
- *
782
- *
783
- * @param {string} key
784
- * @param {number} [count]
785
- * @param {Function} [callback]
786
- * @returns {*}
787
- * @memberof MemoryCache
788
- */
789
- spop(key, count, callback) {
790
- let retVal = null;
791
- count = count || 1;
792
- if (isNaN(count)) {
793
- return this._handleCallback(callback, null, messages.noint);
794
- }
795
- if (this._hasKey(key)) {
796
- retVal = [];
797
- this._testType(key, 'set', true, callback);
798
- const val = this._getKey(key);
799
- const length = val.length;
800
- count = count > length ? length : count;
801
- for (let itr = 0; itr < count; itr++) {
802
- retVal.push(val.pop());
803
- }
804
- }
805
- return this._handleCallback(callback, retVal);
806
- }
807
- /**
808
- *
809
- *
810
- * @param {string} key
811
- * @param {...any[]} members
812
- * @returns {*}
813
- * @memberof MemoryCache
814
- */
815
- srem(key, ...members) {
816
- let retVal = 0;
817
- const callback = this._retrieveCallback(members);
818
- if (this._hasKey(key)) {
819
- this._testType(key, 'set', true, callback);
820
- const val = this._getKey(key);
821
- for (const index in members) {
822
- if (members.hasOwnProperty(index)) {
823
- const member = members[index];
824
- const idx = val.indexOf(member);
825
- if (idx !== -1) {
826
- val.splice(idx, 1);
827
- retVal++;
828
- }
829
- }
830
- }
831
- this._setKey(key, val);
832
- }
833
- return this._handleCallback(callback, retVal);
834
- }
835
- /**
836
- *
837
- *
838
- * @param {string} sourcekey
839
- * @param {string} destkey
840
- * @param {string} member
841
- * @param {Function} [callback]
842
- * @returns {*}
843
- * @memberof MemoryCache
844
- */
845
- smove(sourcekey, destkey, member, callback) {
846
- let retVal = 0;
847
- if (this._hasKey(sourcekey)) {
848
- this._testType(sourcekey, 'set', true, callback);
849
- const val = this._getKey(sourcekey);
850
- const idx = val.indexOf(member);
851
- if (idx !== -1) {
852
- this.sadd(destkey, member);
853
- val.splice(idx, 1);
854
- retVal = 1;
855
- }
856
- }
857
- return this._handleCallback(callback, retVal);
858
- }
859
- // ---------------------------------------
860
- // ## Transactions (Atomic) ##
861
- // ---------------------------------------
862
- // TODO: Transaction Queues watch and unwatch
863
- // https://redis.io/topics/transactions
864
- // This can be accomplished by temporarily swapping this.cache to a temporary copy of the current statement
865
- // holding and then using __.merge on actual this.cache with the temp storage.
866
- discard(callback, silent) {
867
- // Clear the queue mode, drain the queue, empty the watch list
868
- if (this.multiMode) {
869
- this.cache = this.databases[this.currentDBIndex];
870
- this.multiMode = false;
871
- this.responseMessages = [];
872
- }
873
- else if (!silent) {
874
- return this._handleCallback(callback, null, messages.nomultidiscard);
875
- }
876
- return this._handleCallback(callback, messages.ok);
877
- }
878
- // ---------------------------------------
879
- // ## Internal - Key ##
880
- // ---------------------------------------
881
- /**
882
- *
883
- *
884
- * @param {string} key
885
- * @param {Function} [callback]
886
- * @returns {*}
887
- * @memberof MemoryCache
888
- */
889
- pttl(key, callback) {
890
- let retVal = -2;
891
- if (this._hasKey(key)) {
892
- if (!lodash.isNil(this.cache[key].timeout)) {
893
- retVal = this.cache[key].timeout - Date.now();
894
- // Prevent unexpected errors if the actual ttl just happens to be -2 or -1
895
- if (retVal < 0 && retVal > -3) {
896
- retVal = -3;
897
- }
898
- }
899
- else {
900
- retVal = -1;
901
- }
902
- }
903
- return this._handleCallback(callback, retVal);
904
- }
905
- /**
906
- *
907
- *
908
- * @private
909
- * @param {string} key
910
- * @param {Function} [callback]
911
- * @returns {*}
912
- * @memberof MemoryCache
913
- */
914
- persist(key, callback) {
915
- let retVal = 0;
916
- if (this._hasKey(key)) {
917
- if (!lodash.isNil(this._key(key).timeout)) {
918
- this._key(key).timeout = null;
919
- retVal = 1;
920
- }
921
- }
922
- return this._handleCallback(callback, retVal);
923
- }
924
- /**
925
- *
926
- *
927
- * @private
928
- * @param {string} key
929
- * @returns {*} {boolean}
930
- * @memberof MemoryCache
931
- */
932
- _hasKey(key) {
933
- return this.cache.hasOwnProperty(key);
934
- }
935
- /**
936
- *
937
- *
938
- * @private
939
- * @param {*} value
940
- * @param {string} type
941
- * @param {number} timeout
942
- * @returns {*}
943
- * @memberof MemoryCache
944
- */
945
- _makeKey(value, type, timeout) {
946
- return { value: value, type: type, timeout: timeout || null, lastAccess: Date.now() };
947
- }
948
- /**
949
- *
950
- *
951
- * @private
952
- * @param {string} key
953
- * @returns {*}
954
- * @memberof MemoryCache
955
- */
956
- _key(key) {
957
- this.cache[key].lastAccess = Date.now();
958
- return this.cache[key];
959
- }
960
- /**
961
- *
962
- *
963
- * @private
964
- * @param {string} key
965
- * @param {number} amount
966
- * @param {Function} [callback]
967
- * @returns {*}
968
- * @memberof MemoryCache
969
- */
970
- _addToKey(key, amount, callback) {
971
- let keyValue = 0;
972
- if (isNaN(amount) || lodash.isNil(amount)) {
973
- return this._handleCallback(callback, null, messages.noint);
974
- }
975
- if (this._hasKey(key)) {
976
- this._testType(key, 'string', true, callback);
977
- keyValue = parseInt(this._getKey(key));
978
- if (isNaN(keyValue) || lodash.isNil(keyValue)) {
979
- return this._handleCallback(callback, null, messages.noint);
980
- }
981
- }
982
- else {
983
- this.cache[key] = this._makeKey('0', 'string');
984
- }
985
- const val = keyValue + amount;
986
- this._setKey(key, val.toString());
987
- return val;
988
- }
989
- /**
990
- *
991
- *
992
- * @private
993
- * @param {string} key
994
- * @param {string} type
995
- * @param {boolean} [throwError]
996
- * @param {Function} [callback]
997
- * @returns {*}
998
- * @memberof MemoryCache
999
- */
1000
- _testType(key, type, throwError, callback) {
1001
- throwError = !!throwError;
1002
- const keyType = this._key(key).type;
1003
- if (keyType !== type) {
1004
- if (throwError) {
1005
- return this._handleCallback(callback, null, messages.wrongTypeOp);
1006
- }
1007
- return false;
1008
- }
1009
- return true;
1010
- }
1011
- /**
1012
- *
1013
- *
1014
- * @private
1015
- * @param {string} key
1016
- * @returns {*}
1017
- * @memberof MemoryCache
1018
- */
1019
- _getKey(key) {
1020
- const _key = this._key(key) || {};
1021
- if (_key.timeout && _key.timeout <= Date.now()) {
1022
- this.del(key);
1023
- return null;
1024
- }
1025
- return _key.value;
1026
- }
1027
- /**
1028
- *
1029
- *
1030
- * @private
1031
- * @param {string} key
1032
- * @param {(number | string)} value
1033
- * @memberof MemoryCache
1034
- */
1035
- _setKey(key, value) {
1036
- this.cache[key].value = value;
1037
- this.cache[key].lastAccess = Date.now();
1038
- }
1039
- /**
1040
- *
1041
- *
1042
- * @private
1043
- * @param {string} key
1044
- * @param {string} field
1045
- * @param {number} [amount]
1046
- * @param {boolean} [useFloat]
1047
- * @param {Function} [callback]
1048
- * @returns {*}
1049
- * @memberof MemoryCache
1050
- */
1051
- _addToField(key, field, amount, useFloat, callback) {
1052
- useFloat = useFloat || false;
1053
- let fieldValue = useFloat ? 0.0 : 0;
1054
- let value = 0;
1055
- if (isNaN(amount) || lodash.isNil(amount)) {
1056
- return this._handleCallback(callback, null, useFloat ? messages.nofloat : messages.noint);
1057
- }
1058
- if (this._hasKey(key)) {
1059
- this._testType(key, 'hash', true, callback);
1060
- if (this._hasField(key, field)) {
1061
- value = this._getField(key, field);
1062
- }
1063
- }
1064
- else {
1065
- this.cache[key] = this._makeKey({}, 'hash');
1066
- }
1067
- fieldValue = useFloat ? parseFloat(`${value}`) : parseInt(`${value}`);
1068
- amount = useFloat ? parseFloat(`${amount}`) : parseInt(`${amount}`);
1069
- if (isNaN(fieldValue) || lodash.isNil(fieldValue)) {
1070
- return this._handleCallback(callback, null, useFloat ? messages.nofloat : messages.noint);
1071
- }
1072
- fieldValue += amount;
1073
- this._setField(key, field, fieldValue.toString());
1074
- return fieldValue;
1075
- }
1076
- /**
1077
- *
1078
- *
1079
- * @private
1080
- * @param {string} key
1081
- * @param {string} field
1082
- * @returns {*}
1083
- * @memberof MemoryCache
1084
- */
1085
- _getField(key, field) {
1086
- return this._getKey(key)[field];
1087
- }
1088
- /**
1089
- *
1090
- *
1091
- * @private
1092
- * @param {string} key
1093
- * @param {string} field
1094
- * @returns {*} {boolean}
1095
- * @memberof MemoryCache
1096
- */
1097
- _hasField(key, field) {
1098
- let retVal = false;
1099
- if (key && field) {
1100
- const ky = this._getKey(key);
1101
- if (ky) {
1102
- retVal = ky.hasOwnProperty(field);
1103
- }
1104
- }
1105
- return retVal;
1106
- }
1107
- /**
1108
- *
1109
- *
1110
- * @param {string} key
1111
- * @param {string} field
1112
- * @param {*} value
1113
- * @memberof MemoryCache
1114
- */
1115
- _setField(key, field, value) {
1116
- this._getKey(key)[field] = value;
1117
- }
1118
- /**
1119
- *
1120
- *
1121
- * @private
1122
- * @param {Function} [callback]
1123
- * @param {(any)} [message]
1124
- * @param {*} [error]
1125
- * @param {boolean} [nolog]
1126
- * @returns {*}
1127
- * @memberof MemoryCache
1128
- */
1129
- _handleCallback(callback, message, error, nolog) {
1130
- let err = error;
1131
- let msg = message;
1132
- nolog = lodash.isNil(nolog) ? true : nolog;
1133
- if (nolog) {
1134
- err = this._logReturn(error);
1135
- msg = this._logReturn(message);
1136
- }
1137
- if (typeof callback === 'function') {
1138
- callback(err, msg);
1139
- return;
1140
- }
1141
- if (err) {
1142
- throw new Error(err);
1143
- }
1144
- return msg;
1145
- }
1146
- _logReturn(message) {
1147
- if (!lodash.isUndefined(message)) {
1148
- if (this.multiMode) {
1149
- if (!lodash.isNil(this.responseMessages)) {
1150
- this.responseMessages.push(message);
1151
- if (message === messages.ok) {
1152
- message = messages.queued;
1153
- }
1154
- }
1155
- }
1156
- return message;
1157
- }
1158
- return;
1159
- }
1160
- /**
1161
- *
1162
- *
1163
- * @private
1164
- * @param {any[]} [params]
1165
- * @returns {*}
1166
- * @memberof MemoryCache
1167
- */
1168
- _retrieveCallback(params) {
1169
- if (Array.isArray(params) && params.length > 0 && typeof params[params.length - 1] === 'function') {
1170
- return params.pop();
1171
- }
1172
- return;
1173
- }
36
+ /*
37
+ * @Description:
38
+ * @Usage:
39
+ * @Author: richen
40
+ * @Date: 2021-12-02 11:03:20
41
+ * @LastEditTime: 2023-12-20 19:04:29
42
+ */
43
+ /**
44
+ *
45
+ *
46
+ * @enum {number}
47
+ */
48
+ var messages;
49
+ (function (messages) {
50
+ messages["ok"] = "OK";
51
+ messages["queued"] = "QUEUED";
52
+ messages["pong"] = "PONG";
53
+ messages["noint"] = "ERR value is not an integer or out of range";
54
+ messages["nofloat"] = "ERR value is not an float or out of range";
55
+ messages["nokey"] = "ERR no such key";
56
+ messages["nomultiinmulti"] = "ERR MULTI calls can not be nested";
57
+ messages["nomultiexec"] = "ERR EXEC without MULTI";
58
+ messages["nomultidiscard"] = "ERR DISCARD without MULTI";
59
+ messages["busykey"] = "ERR target key name is busy";
60
+ messages["syntax"] = "ERR syntax error";
61
+ messages["unsupported"] = "MemoryCache does not support that operation";
62
+ messages["wrongTypeOp"] = "WRONGTYPE Operation against a key holding the wrong kind of value";
63
+ messages["wrongPayload"] = "DUMP payload version or checksum are wrong";
64
+ messages["wrongArgCount"] = "ERR wrong number of arguments for '%0' command";
65
+ messages["bitopnotWrongCount"] = "ERR BITOP NOT must be called with a single source key";
66
+ messages["indexOutOfRange"] = "ERR index out of range";
67
+ messages["invalidLexRange"] = "ERR min or max not valid string range item";
68
+ messages["invalidDBIndex"] = "ERR invalid DB index";
69
+ messages["invalidDBIndexNX"] = "ERR invalid DB index, '%0' does not exist";
70
+ messages["mutuallyExclusiveNXXX"] = "ERR XX and NX options at the same time are not compatible";
71
+ })(messages || (messages = {}));
72
+ class MemoryCache extends events.EventEmitter {
73
+ databases = Object.create({});
74
+ options;
75
+ currentDBIndex;
76
+ connected;
77
+ lastSave;
78
+ multiMode;
79
+ cache;
80
+ responseMessages;
81
+ /**
82
+ * Creates an instance of MemoryCache.
83
+ * @param {*} options
84
+ * @memberof MemoryCache
85
+ */
86
+ constructor(options) {
87
+ super();
88
+ this.options = { ...{ database: "0" }, ...options };
89
+ this.currentDBIndex = 0;
90
+ this.connected = false;
91
+ this.lastSave = Date.now();
92
+ this.multiMode = false;
93
+ }
94
+ /**
95
+ *
96
+ *
97
+ * @returns {*}
98
+ * @memberof MemoryCache
99
+ */
100
+ createClient() {
101
+ this.databases[this.options.database] = Object.create({});
102
+ this.cache = this.databases[this.options.database];
103
+ this.connected = true;
104
+ // exit multi mode if we are in it
105
+ this.discard(null, true);
106
+ this.emit('connect');
107
+ this.emit('ready');
108
+ return this;
109
+ }
110
+ /**
111
+ *
112
+ *
113
+ * @returns {*}
114
+ * @memberof MemoryCache
115
+ */
116
+ quit() {
117
+ this.connected = false;
118
+ // exit multi mode if we are in it
119
+ this.discard(null, true);
120
+ this.emit('end');
121
+ return this;
122
+ }
123
+ /**
124
+ *
125
+ *
126
+ * @returns {*}
127
+ * @memberof MemoryCache
128
+ */
129
+ end() {
130
+ return this.quit();
131
+ }
132
+ /**
133
+ *
134
+ *
135
+ * @param {string} message
136
+ * @param {Function} [callback]
137
+ * @returns {*}
138
+ * @memberof MemoryCache
139
+ */
140
+ echo(message, callback) {
141
+ return this._handleCallback(callback, message);
142
+ }
143
+ /**
144
+ *
145
+ *
146
+ * @param {string} message
147
+ * @param {Function} [callback]
148
+ * @returns {*}
149
+ * @memberof MemoryCache
150
+ */
151
+ ping(message, callback) {
152
+ message = message || messages.pong;
153
+ return this._handleCallback(callback, message);
154
+ }
155
+ /**
156
+ *
157
+ *
158
+ * @param {string} password
159
+ * @param {Function} [callback]
160
+ * @returns {*}
161
+ * @memberof MemoryCache
162
+ */
163
+ auth(password, callback) {
164
+ return this._handleCallback(callback, messages.ok);
165
+ }
166
+ /**
167
+ *
168
+ *
169
+ * @param {number} dbIndex
170
+ * @param {Function} [callback]
171
+ * @returns {*}
172
+ * @memberof MemoryCache
173
+ */
174
+ select(dbIndex, callback) {
175
+ if (!helper__namespace.isNumber(dbIndex)) {
176
+ return this._handleCallback(callback, null, messages.invalidDBIndex);
177
+ }
178
+ if (!this.databases.hasOwnProperty(dbIndex)) {
179
+ this.databases[dbIndex] = Object.create({});
180
+ }
181
+ this.multiMode = false;
182
+ this.currentDBIndex = dbIndex;
183
+ this.cache = this.databases[dbIndex];
184
+ return this._handleCallback(callback, messages.ok);
185
+ }
186
+ // ---------------------------------------
187
+ // Keys
188
+ // ---------------------------------------
189
+ get(key, callback) {
190
+ let retVal = null;
191
+ if (this._hasKey(key)) {
192
+ this._testType(key, 'string', true, callback);
193
+ retVal = this._getKey(key);
194
+ }
195
+ return this._handleCallback(callback, retVal);
196
+ }
197
+ /**
198
+ * set(key, value, ttl, pttl, notexist, onlyexist, callback)
199
+ *
200
+ * @param {string} key
201
+ * @param {(string | number)} value
202
+ * @param {...any[]} params
203
+ * @returns {*}
204
+ * @memberof MemoryCache
205
+ */
206
+ set(key, value, ...params) {
207
+ const retVal = null;
208
+ params = lodash.flatten(params);
209
+ const callback = this._retrieveCallback(params);
210
+ let ttl, pttl, notexist, onlyexist;
211
+ // parse parameters
212
+ while (params.length > 0) {
213
+ const param = params.shift();
214
+ switch (param.toString().toLowerCase()) {
215
+ case 'nx':
216
+ notexist = true;
217
+ break;
218
+ case 'xx':
219
+ onlyexist = true;
220
+ break;
221
+ case 'ex':
222
+ if (params.length === 0) {
223
+ return this._handleCallback(callback, null, messages.syntax);
224
+ }
225
+ ttl = parseInt(params.shift());
226
+ if (isNaN(ttl)) {
227
+ return this._handleCallback(callback, null, messages.noint);
228
+ }
229
+ break;
230
+ case 'px':
231
+ if (params.length === 0) {
232
+ return this._handleCallback(callback, null, messages.syntax);
233
+ }
234
+ pttl = parseInt(params.shift());
235
+ if (isNaN(pttl)) {
236
+ return this._handleCallback(callback, null, messages.noint);
237
+ }
238
+ break;
239
+ default:
240
+ return this._handleCallback(callback, null, messages.syntax);
241
+ }
242
+ }
243
+ if (!lodash.isNil(ttl) && !lodash.isNil(pttl)) {
244
+ return this._handleCallback(callback, null, messages.syntax);
245
+ }
246
+ if (notexist && onlyexist) {
247
+ return this._handleCallback(callback, null, messages.syntax);
248
+ }
249
+ pttl = pttl || ttl * 1000 || null;
250
+ if (!lodash.isNil(pttl)) {
251
+ pttl = Date.now() + pttl;
252
+ }
253
+ if (this._hasKey(key)) {
254
+ this._testType(key, 'string', true, callback);
255
+ if (notexist) {
256
+ return this._handleCallback(callback, retVal);
257
+ }
258
+ }
259
+ else if (onlyexist) {
260
+ return this._handleCallback(callback, retVal);
261
+ }
262
+ this.cache[key] = this._makeKey(value.toString(), 'string', pttl);
263
+ return this._handleCallback(callback, messages.ok);
264
+ }
265
+ /**
266
+ *
267
+ *
268
+ * @param {string} key
269
+ * @param {Function} [callback]
270
+ * @returns {*}
271
+ * @memberof MemoryCache
272
+ */
273
+ ttl(key, callback) {
274
+ let retVal = this.pttl(key);
275
+ if (retVal >= 0 || retVal <= -3) {
276
+ retVal = Math.floor(retVal / 1000);
277
+ }
278
+ return this._handleCallback(callback, retVal);
279
+ }
280
+ /**
281
+ *
282
+ *
283
+ * @param {string} key
284
+ * @param {number} seconds
285
+ * @param {Function} [callback]
286
+ * @returns {*}
287
+ * @memberof MemoryCache
288
+ */
289
+ expire(key, seconds, callback) {
290
+ let retVal = 0;
291
+ if (this._hasKey(key)) {
292
+ this.cache[key].timeout = Date.now() + seconds * 1000;
293
+ retVal = 1;
294
+ }
295
+ return this._handleCallback(callback, retVal);
296
+ }
297
+ /**
298
+ *
299
+ *
300
+ * @param {...any[]} keys
301
+ * @returns {*}
302
+ * @memberof MemoryCache
303
+ */
304
+ del(...keys) {
305
+ let retVal = 0;
306
+ const callback = this._retrieveCallback(keys);
307
+ // Flatten the array in case an array was passed
308
+ keys = lodash.flatten(keys);
309
+ for (let itr = 0; itr < keys.length; itr++) {
310
+ const key = keys[itr];
311
+ if (this._hasKey(key)) {
312
+ delete this.cache[key];
313
+ retVal++;
314
+ }
315
+ }
316
+ return this._handleCallback(callback, retVal);
317
+ }
318
+ /**
319
+ *
320
+ *
321
+ * @param {...any[]} keys
322
+ * @returns {*}
323
+ * @memberof MemoryCache
324
+ */
325
+ exists(...keys) {
326
+ let retVal = 0;
327
+ const callback = this._retrieveCallback(keys);
328
+ for (let itr = 0; itr < keys.length; itr++) {
329
+ const key = keys[itr];
330
+ if (this._hasKey(key)) {
331
+ retVal++;
332
+ }
333
+ }
334
+ return this._handleCallback(callback, retVal);
335
+ }
336
+ /**
337
+ *
338
+ *
339
+ * @param {string} key
340
+ * @param {Function} [callback]
341
+ * @returns {*}
342
+ * @memberof MemoryCache
343
+ */
344
+ incr(key, callback) {
345
+ let retVal = null;
346
+ try {
347
+ retVal = this._addToKey(key, 1);
348
+ }
349
+ catch (err) {
350
+ return this._handleCallback(callback, null, err);
351
+ }
352
+ return this._handleCallback(callback, retVal);
353
+ }
354
+ /**
355
+ *
356
+ *
357
+ * @param {string} key
358
+ * @param {number} amount
359
+ * @param {Function} [callback]
360
+ * @returns {*}
361
+ * @memberof MemoryCache
362
+ */
363
+ incrby(key, amount, callback) {
364
+ let retVal = null;
365
+ try {
366
+ retVal = this._addToKey(key, amount);
367
+ }
368
+ catch (err) {
369
+ return this._handleCallback(callback, null, err);
370
+ }
371
+ return this._handleCallback(callback, retVal);
372
+ }
373
+ /**
374
+ *
375
+ *
376
+ * @param {string} key
377
+ * @param {Function} [callback]
378
+ * @returns {*}
379
+ * @memberof MemoryCache
380
+ */
381
+ decr(key, callback) {
382
+ let retVal = null;
383
+ try {
384
+ retVal = this._addToKey(key, -1);
385
+ }
386
+ catch (err) {
387
+ return this._handleCallback(callback, null, err);
388
+ }
389
+ return this._handleCallback(callback, retVal);
390
+ }
391
+ /**
392
+ *
393
+ *
394
+ * @param {string} key
395
+ * @param {number} amount
396
+ * @param {Function} [callback]
397
+ * @returns {*}
398
+ * @memberof MemoryCache
399
+ */
400
+ decrby(key, amount, callback) {
401
+ let retVal = null;
402
+ try {
403
+ retVal = this._addToKey(key, -amount);
404
+ }
405
+ catch (err) {
406
+ return this._handleCallback(callback, null, err);
407
+ }
408
+ return this._handleCallback(callback, retVal);
409
+ }
410
+ // ---------------------------------------
411
+ // ## Hash ##
412
+ // ---------------------------------------
413
+ hset(key, field, value, callback) {
414
+ let retVal = 0;
415
+ if (this._hasKey(key)) {
416
+ this._testType(key, 'hash', true, callback);
417
+ }
418
+ else {
419
+ this.cache[key] = this._makeKey({}, 'hash');
420
+ }
421
+ if (!this._hasField(key, field)) {
422
+ retVal = 1;
423
+ }
424
+ this._setField(key, field, value.toString());
425
+ this.persist(key);
426
+ return this._handleCallback(callback, retVal);
427
+ }
428
+ /**
429
+ *
430
+ *
431
+ * @param {string} key
432
+ * @param {string} field
433
+ * @param {Function} [callback]
434
+ * @returns {*}
435
+ * @memberof MemoryCache
436
+ */
437
+ hget(key, field, callback) {
438
+ let retVal = null;
439
+ if (this._hasKey(key)) {
440
+ this._testType(key, 'hash', true, callback);
441
+ if (this._hasField(key, field)) {
442
+ retVal = this._getKey(key)[field];
443
+ }
444
+ }
445
+ return this._handleCallback(callback, retVal);
446
+ }
447
+ /**
448
+ *
449
+ *
450
+ * @param {string} key
451
+ * @param {string} field
452
+ * @param {Function} [callback]
453
+ * @returns {*}
454
+ * @memberof MemoryCache
455
+ */
456
+ hexists(key, field, callback) {
457
+ let retVal = 0;
458
+ if (this._hasKey(key)) {
459
+ this._testType(key, 'hash', true, callback);
460
+ if (this._hasField(key, field)) {
461
+ retVal = 1;
462
+ }
463
+ }
464
+ return this._handleCallback(callback, retVal);
465
+ }
466
+ /**
467
+ *
468
+ *
469
+ * @param {string} key
470
+ * @param {...any[]} fields
471
+ * @returns {*}
472
+ * @memberof MemoryCache
473
+ */
474
+ hdel(key, ...fields) {
475
+ let retVal = 0;
476
+ const callback = this._retrieveCallback(fields);
477
+ if (this._hasKey(key)) {
478
+ this._testType(key, 'hash', true, callback);
479
+ for (let itr = 0; itr < fields.length; itr++) {
480
+ const field = fields[itr];
481
+ if (this._hasField(key, field)) {
482
+ delete this.cache[key].value[field];
483
+ retVal++;
484
+ }
485
+ }
486
+ }
487
+ return this._handleCallback(callback, retVal);
488
+ }
489
+ /**
490
+ *
491
+ *
492
+ * @param {string} key
493
+ * @param {Function} [callback]
494
+ * @returns {*}
495
+ * @memberof MemoryCache
496
+ */
497
+ hlen(key, callback) {
498
+ const retVal = this.hkeys(key).length;
499
+ return this._handleCallback(callback, retVal);
500
+ }
501
+ /**
502
+ *
503
+ *
504
+ * @param {string} key
505
+ * @param {string} field
506
+ * @param {*} value
507
+ * @param {Function} [callback]
508
+ * @returns {*}
509
+ * @memberof MemoryCache
510
+ */
511
+ hincrby(key, field, value, callback) {
512
+ let retVal;
513
+ try {
514
+ retVal = this._addToField(key, field, value, false);
515
+ }
516
+ catch (err) {
517
+ return this._handleCallback(callback, null, err);
518
+ }
519
+ return this._handleCallback(callback, retVal);
520
+ }
521
+ /**
522
+ *
523
+ *
524
+ * @param {string} key
525
+ * @param {Function} [callback]
526
+ * @returns {*}
527
+ * @memberof MemoryCache
528
+ */
529
+ hgetall(key, callback) {
530
+ let retVals = {};
531
+ if (this._hasKey(key)) {
532
+ this._testType(key, 'hash', true, callback);
533
+ retVals = this._getKey(key);
534
+ }
535
+ return this._handleCallback(callback, retVals);
536
+ }
537
+ /**
538
+ *
539
+ *
540
+ * @param {string} key
541
+ * @param {Function} [callback]
542
+ * @returns {*}
543
+ * @memberof MemoryCache
544
+ */
545
+ hkeys(key, callback) {
546
+ let retVals = [];
547
+ if (this._hasKey(key)) {
548
+ this._testType(key, 'hash', true, callback);
549
+ retVals = Object.keys(this._getKey(key));
550
+ }
551
+ return this._handleCallback(callback, retVals);
552
+ }
553
+ /**
554
+ *
555
+ *
556
+ * @param {string} key
557
+ * @param {Function} [callback]
558
+ * @returns {*}
559
+ * @memberof MemoryCache
560
+ */
561
+ hvals(key, callback) {
562
+ let retVals = [];
563
+ if (this._hasKey(key)) {
564
+ this._testType(key, 'hash', true, callback);
565
+ retVals = Object.values(this._getKey(key));
566
+ }
567
+ return this._handleCallback(callback, retVals);
568
+ }
569
+ // ---------------------------------------
570
+ // Lists (Array / Queue / Stack)
571
+ // ---------------------------------------
572
+ /**
573
+ *
574
+ *
575
+ * @param {string} key
576
+ * @param {Function} [callback]
577
+ * @returns {*}
578
+ * @memberof MemoryCache
579
+ */
580
+ llen(key, callback) {
581
+ let retVal = 0;
582
+ if (this._hasKey(key)) {
583
+ this._testType(key, 'list', true, callback);
584
+ retVal = this._getKey(key).length || 0;
585
+ }
586
+ return this._handleCallback(callback, retVal);
587
+ }
588
+ /**
589
+ *
590
+ *
591
+ * @param {string} key
592
+ * @param {(string | number)} value
593
+ * @param {Function} [callback]
594
+ * @returns {*}
595
+ * @memberof MemoryCache
596
+ */
597
+ rpush(key, value, callback) {
598
+ let retVal = 0;
599
+ if (this._hasKey(key)) {
600
+ this._testType(key, 'list', true, callback);
601
+ }
602
+ else {
603
+ this.cache[key] = this._makeKey([], 'list');
604
+ }
605
+ const val = this._getKey(key);
606
+ val.push(value);
607
+ this._setKey(key, val);
608
+ retVal = val.length;
609
+ return this._handleCallback(callback, retVal);
610
+ }
611
+ /**
612
+ *
613
+ *
614
+ * @param {string} key
615
+ * @param {(string | number)} value
616
+ * @param {Function} [callback]
617
+ * @returns {*}
618
+ * @memberof MemoryCache
619
+ */
620
+ lpush(key, value, callback) {
621
+ let retVal = 0;
622
+ if (this._hasKey(key)) {
623
+ this._testType(key, 'list', true, callback);
624
+ }
625
+ else {
626
+ this.cache[key] = this._makeKey([], 'list');
627
+ }
628
+ const val = this._getKey(key);
629
+ val.splice(0, 0, value);
630
+ this._setKey(key, val);
631
+ retVal = val.length;
632
+ return this._handleCallback(callback, retVal);
633
+ }
634
+ /**
635
+ *
636
+ *
637
+ * @param {string} key
638
+ * @param {Function} [callback]
639
+ * @returns {*}
640
+ * @memberof MemoryCache
641
+ */
642
+ lpop(key, callback) {
643
+ let retVal = null;
644
+ if (this._hasKey(key)) {
645
+ this._testType(key, 'list', true, callback);
646
+ const val = this._getKey(key);
647
+ retVal = val.shift();
648
+ this._setKey(key, val);
649
+ }
650
+ return this._handleCallback(callback, retVal);
651
+ }
652
+ /**
653
+ *
654
+ *
655
+ * @param {string} key
656
+ * @param {Function} [callback]
657
+ * @returns {*}
658
+ * @memberof MemoryCache
659
+ */
660
+ rpop(key, callback) {
661
+ let retVal = null;
662
+ if (this._hasKey(key)) {
663
+ this._testType(key, 'list', true, callback);
664
+ const val = this._getKey(key);
665
+ retVal = val.pop();
666
+ this._setKey(key, val);
667
+ }
668
+ return this._handleCallback(callback, retVal);
669
+ }
670
+ /**
671
+ *
672
+ *
673
+ * @param {string} key
674
+ * @param {number} start
675
+ * @param {number} stop
676
+ * @param {Function} [callback]
677
+ * @returns {*}
678
+ * @memberof MemoryCache
679
+ */
680
+ lrange(key, start, stop, callback) {
681
+ const retVal = [];
682
+ if (this._hasKey(key)) {
683
+ this._testType(key, 'list', true, callback);
684
+ const val = this._getKey(key);
685
+ const length = val.length;
686
+ if (stop < 0) {
687
+ stop = length + stop;
688
+ }
689
+ if (start < 0) {
690
+ start = length + start;
691
+ }
692
+ if (start < 0) {
693
+ start = 0;
694
+ }
695
+ if (stop >= length) {
696
+ stop = length - 1;
697
+ }
698
+ if (stop >= 0 && stop >= start) {
699
+ const size = stop - start + 1;
700
+ for (let itr = start; itr < size; itr++) {
701
+ retVal.push(val[itr]);
702
+ }
703
+ }
704
+ }
705
+ return this._handleCallback(callback, retVal);
706
+ }
707
+ // ---------------------------------------
708
+ // ## Sets (Unique Lists)##
709
+ // ---------------------------------------
710
+ /**
711
+ *
712
+ *
713
+ * @param {string} key
714
+ * @param {...any[]} members
715
+ * @returns {*}
716
+ * @memberof MemoryCache
717
+ */
718
+ sadd(key, ...members) {
719
+ let retVal = 0;
720
+ const callback = this._retrieveCallback(members);
721
+ if (this._hasKey(key)) {
722
+ this._testType(key, 'set', true, callback);
723
+ }
724
+ else {
725
+ this.cache[key] = this._makeKey([], 'set');
726
+ }
727
+ const val = this._getKey(key);
728
+ const length = val.length;
729
+ const nval = lodash.union(val, members);
730
+ const newlength = nval.length;
731
+ retVal = newlength - length;
732
+ this._setKey(key, nval);
733
+ return this._handleCallback(callback, retVal);
734
+ }
735
+ /**
736
+ *
737
+ *
738
+ * @param {string} key
739
+ * @param {Function} [callback]
740
+ * @returns {*}
741
+ * @memberof MemoryCache
742
+ */
743
+ scard(key, callback) {
744
+ let retVal = 0;
745
+ if (this._hasKey(key)) {
746
+ this._testType(key, 'set', true, callback);
747
+ retVal = this._getKey(key).length;
748
+ }
749
+ return this._handleCallback(callback, retVal);
750
+ }
751
+ /**
752
+ *
753
+ *
754
+ * @param {string} key
755
+ * @param {string} member
756
+ * @param {Function} [callback]
757
+ * @returns {*}
758
+ * @memberof MemoryCache
759
+ */
760
+ sismember(key, member, callback) {
761
+ let retVal = 0;
762
+ if (this._hasKey(key)) {
763
+ this._testType(key, 'set', true, callback);
764
+ const val = this._getKey(key);
765
+ if (val.includes(member)) {
766
+ retVal = 1;
767
+ }
768
+ }
769
+ return this._handleCallback(callback, retVal);
770
+ }
771
+ /**
772
+ *
773
+ *
774
+ * @param {string} key
775
+ * @param {Function} [callback]
776
+ * @returns {*}
777
+ * @memberof MemoryCache
778
+ */
779
+ smembers(key, callback) {
780
+ let retVal = [];
781
+ if (this._hasKey(key)) {
782
+ this._testType(key, 'set', true, callback);
783
+ retVal = this._getKey(key);
784
+ }
785
+ return this._handleCallback(callback, retVal);
786
+ }
787
+ /**
788
+ *
789
+ *
790
+ * @param {string} key
791
+ * @param {number} [count]
792
+ * @param {Function} [callback]
793
+ * @returns {*}
794
+ * @memberof MemoryCache
795
+ */
796
+ spop(key, count, callback) {
797
+ let retVal = null;
798
+ count = count || 1;
799
+ if (isNaN(count)) {
800
+ return this._handleCallback(callback, null, messages.noint);
801
+ }
802
+ if (this._hasKey(key)) {
803
+ retVal = [];
804
+ this._testType(key, 'set', true, callback);
805
+ const val = this._getKey(key);
806
+ const length = val.length;
807
+ count = count > length ? length : count;
808
+ for (let itr = 0; itr < count; itr++) {
809
+ retVal.push(val.pop());
810
+ }
811
+ }
812
+ return this._handleCallback(callback, retVal);
813
+ }
814
+ /**
815
+ *
816
+ *
817
+ * @param {string} key
818
+ * @param {...any[]} members
819
+ * @returns {*}
820
+ * @memberof MemoryCache
821
+ */
822
+ srem(key, ...members) {
823
+ let retVal = 0;
824
+ const callback = this._retrieveCallback(members);
825
+ if (this._hasKey(key)) {
826
+ this._testType(key, 'set', true, callback);
827
+ const val = this._getKey(key);
828
+ for (const index in members) {
829
+ if (members.hasOwnProperty(index)) {
830
+ const member = members[index];
831
+ const idx = val.indexOf(member);
832
+ if (idx !== -1) {
833
+ val.splice(idx, 1);
834
+ retVal++;
835
+ }
836
+ }
837
+ }
838
+ this._setKey(key, val);
839
+ }
840
+ return this._handleCallback(callback, retVal);
841
+ }
842
+ /**
843
+ *
844
+ *
845
+ * @param {string} sourcekey
846
+ * @param {string} destkey
847
+ * @param {string} member
848
+ * @param {Function} [callback]
849
+ * @returns {*}
850
+ * @memberof MemoryCache
851
+ */
852
+ smove(sourcekey, destkey, member, callback) {
853
+ let retVal = 0;
854
+ if (this._hasKey(sourcekey)) {
855
+ this._testType(sourcekey, 'set', true, callback);
856
+ const val = this._getKey(sourcekey);
857
+ const idx = val.indexOf(member);
858
+ if (idx !== -1) {
859
+ this.sadd(destkey, member);
860
+ val.splice(idx, 1);
861
+ retVal = 1;
862
+ }
863
+ }
864
+ return this._handleCallback(callback, retVal);
865
+ }
866
+ // ---------------------------------------
867
+ // ## Transactions (Atomic) ##
868
+ // ---------------------------------------
869
+ // TODO: Transaction Queues watch and unwatch
870
+ // https://redis.io/topics/transactions
871
+ // This can be accomplished by temporarily swapping this.cache to a temporary copy of the current statement
872
+ // holding and then using __.merge on actual this.cache with the temp storage.
873
+ discard(callback, silent) {
874
+ // Clear the queue mode, drain the queue, empty the watch list
875
+ if (this.multiMode) {
876
+ this.cache = this.databases[this.currentDBIndex];
877
+ this.multiMode = false;
878
+ this.responseMessages = [];
879
+ }
880
+ else if (!silent) {
881
+ return this._handleCallback(callback, null, messages.nomultidiscard);
882
+ }
883
+ return this._handleCallback(callback, messages.ok);
884
+ }
885
+ // ---------------------------------------
886
+ // ## Internal - Key ##
887
+ // ---------------------------------------
888
+ /**
889
+ *
890
+ *
891
+ * @param {string} key
892
+ * @param {Function} [callback]
893
+ * @returns {*}
894
+ * @memberof MemoryCache
895
+ */
896
+ pttl(key, callback) {
897
+ let retVal = -2;
898
+ if (this._hasKey(key)) {
899
+ if (!lodash.isNil(this.cache[key].timeout)) {
900
+ retVal = this.cache[key].timeout - Date.now();
901
+ // Prevent unexpected errors if the actual ttl just happens to be -2 or -1
902
+ if (retVal < 0 && retVal > -3) {
903
+ retVal = -3;
904
+ }
905
+ }
906
+ else {
907
+ retVal = -1;
908
+ }
909
+ }
910
+ return this._handleCallback(callback, retVal);
911
+ }
912
+ /**
913
+ *
914
+ *
915
+ * @private
916
+ * @param {string} key
917
+ * @param {Function} [callback]
918
+ * @returns {*}
919
+ * @memberof MemoryCache
920
+ */
921
+ persist(key, callback) {
922
+ let retVal = 0;
923
+ if (this._hasKey(key)) {
924
+ if (!lodash.isNil(this._key(key).timeout)) {
925
+ this._key(key).timeout = null;
926
+ retVal = 1;
927
+ }
928
+ }
929
+ return this._handleCallback(callback, retVal);
930
+ }
931
+ /**
932
+ *
933
+ *
934
+ * @private
935
+ * @param {string} key
936
+ * @returns {*} {boolean}
937
+ * @memberof MemoryCache
938
+ */
939
+ _hasKey(key) {
940
+ return this.cache.hasOwnProperty(key);
941
+ }
942
+ /**
943
+ *
944
+ *
945
+ * @private
946
+ * @param {*} value
947
+ * @param {string} type
948
+ * @param {number} timeout
949
+ * @returns {*}
950
+ * @memberof MemoryCache
951
+ */
952
+ _makeKey(value, type, timeout) {
953
+ return { value: value, type: type, timeout: timeout || null, lastAccess: Date.now() };
954
+ }
955
+ /**
956
+ *
957
+ *
958
+ * @private
959
+ * @param {string} key
960
+ * @returns {*}
961
+ * @memberof MemoryCache
962
+ */
963
+ _key(key) {
964
+ this.cache[key].lastAccess = Date.now();
965
+ return this.cache[key];
966
+ }
967
+ /**
968
+ *
969
+ *
970
+ * @private
971
+ * @param {string} key
972
+ * @param {number} amount
973
+ * @param {Function} [callback]
974
+ * @returns {*}
975
+ * @memberof MemoryCache
976
+ */
977
+ _addToKey(key, amount, callback) {
978
+ let keyValue = 0;
979
+ if (isNaN(amount) || lodash.isNil(amount)) {
980
+ return this._handleCallback(callback, null, messages.noint);
981
+ }
982
+ if (this._hasKey(key)) {
983
+ this._testType(key, 'string', true, callback);
984
+ keyValue = parseInt(this._getKey(key));
985
+ if (isNaN(keyValue) || lodash.isNil(keyValue)) {
986
+ return this._handleCallback(callback, null, messages.noint);
987
+ }
988
+ }
989
+ else {
990
+ this.cache[key] = this._makeKey('0', 'string');
991
+ }
992
+ const val = keyValue + amount;
993
+ this._setKey(key, val.toString());
994
+ return val;
995
+ }
996
+ /**
997
+ *
998
+ *
999
+ * @private
1000
+ * @param {string} key
1001
+ * @param {string} type
1002
+ * @param {boolean} [throwError]
1003
+ * @param {Function} [callback]
1004
+ * @returns {*}
1005
+ * @memberof MemoryCache
1006
+ */
1007
+ _testType(key, type, throwError, callback) {
1008
+ throwError = !!throwError;
1009
+ const keyType = this._key(key).type;
1010
+ if (keyType !== type) {
1011
+ if (throwError) {
1012
+ return this._handleCallback(callback, null, messages.wrongTypeOp);
1013
+ }
1014
+ return false;
1015
+ }
1016
+ return true;
1017
+ }
1018
+ /**
1019
+ *
1020
+ *
1021
+ * @private
1022
+ * @param {string} key
1023
+ * @returns {*}
1024
+ * @memberof MemoryCache
1025
+ */
1026
+ _getKey(key) {
1027
+ const _key = this._key(key) || {};
1028
+ if (_key.timeout && _key.timeout <= Date.now()) {
1029
+ this.del(key);
1030
+ return null;
1031
+ }
1032
+ return _key.value;
1033
+ }
1034
+ /**
1035
+ *
1036
+ *
1037
+ * @private
1038
+ * @param {string} key
1039
+ * @param {(number | string)} value
1040
+ * @memberof MemoryCache
1041
+ */
1042
+ _setKey(key, value) {
1043
+ this.cache[key].value = value;
1044
+ this.cache[key].lastAccess = Date.now();
1045
+ }
1046
+ /**
1047
+ *
1048
+ *
1049
+ * @private
1050
+ * @param {string} key
1051
+ * @param {string} field
1052
+ * @param {number} [amount]
1053
+ * @param {boolean} [useFloat]
1054
+ * @param {Function} [callback]
1055
+ * @returns {*}
1056
+ * @memberof MemoryCache
1057
+ */
1058
+ _addToField(key, field, amount, useFloat, callback) {
1059
+ useFloat = useFloat || false;
1060
+ let fieldValue = useFloat ? 0.0 : 0;
1061
+ let value = 0;
1062
+ if (isNaN(amount) || lodash.isNil(amount)) {
1063
+ return this._handleCallback(callback, null, useFloat ? messages.nofloat : messages.noint);
1064
+ }
1065
+ if (this._hasKey(key)) {
1066
+ this._testType(key, 'hash', true, callback);
1067
+ if (this._hasField(key, field)) {
1068
+ value = this._getField(key, field);
1069
+ }
1070
+ }
1071
+ else {
1072
+ this.cache[key] = this._makeKey({}, 'hash');
1073
+ }
1074
+ fieldValue = useFloat ? parseFloat(`${value}`) : parseInt(`${value}`);
1075
+ amount = useFloat ? parseFloat(`${amount}`) : parseInt(`${amount}`);
1076
+ if (isNaN(fieldValue) || lodash.isNil(fieldValue)) {
1077
+ return this._handleCallback(callback, null, useFloat ? messages.nofloat : messages.noint);
1078
+ }
1079
+ fieldValue += amount;
1080
+ this._setField(key, field, fieldValue.toString());
1081
+ return fieldValue;
1082
+ }
1083
+ /**
1084
+ *
1085
+ *
1086
+ * @private
1087
+ * @param {string} key
1088
+ * @param {string} field
1089
+ * @returns {*}
1090
+ * @memberof MemoryCache
1091
+ */
1092
+ _getField(key, field) {
1093
+ return this._getKey(key)[field];
1094
+ }
1095
+ /**
1096
+ *
1097
+ *
1098
+ * @private
1099
+ * @param {string} key
1100
+ * @param {string} field
1101
+ * @returns {*} {boolean}
1102
+ * @memberof MemoryCache
1103
+ */
1104
+ _hasField(key, field) {
1105
+ let retVal = false;
1106
+ if (key && field) {
1107
+ const ky = this._getKey(key);
1108
+ if (ky) {
1109
+ retVal = ky.hasOwnProperty(field);
1110
+ }
1111
+ }
1112
+ return retVal;
1113
+ }
1114
+ /**
1115
+ *
1116
+ *
1117
+ * @param {string} key
1118
+ * @param {string} field
1119
+ * @param {*} value
1120
+ * @memberof MemoryCache
1121
+ */
1122
+ _setField(key, field, value) {
1123
+ this._getKey(key)[field] = value;
1124
+ }
1125
+ /**
1126
+ *
1127
+ *
1128
+ * @private
1129
+ * @param {Function} [callback]
1130
+ * @param {(any)} [message]
1131
+ * @param {*} [error]
1132
+ * @param {boolean} [nolog]
1133
+ * @returns {*}
1134
+ * @memberof MemoryCache
1135
+ */
1136
+ _handleCallback(callback, message, error, nolog) {
1137
+ let err = error;
1138
+ let msg = message;
1139
+ nolog = lodash.isNil(nolog) ? true : nolog;
1140
+ if (nolog) {
1141
+ err = this._logReturn(error);
1142
+ msg = this._logReturn(message);
1143
+ }
1144
+ if (typeof callback === 'function') {
1145
+ callback(err, msg);
1146
+ return;
1147
+ }
1148
+ if (err) {
1149
+ throw new Error(err);
1150
+ }
1151
+ return msg;
1152
+ }
1153
+ _logReturn(message) {
1154
+ if (!lodash.isUndefined(message)) {
1155
+ if (this.multiMode) {
1156
+ if (!lodash.isNil(this.responseMessages)) {
1157
+ this.responseMessages.push(message);
1158
+ if (message === messages.ok) {
1159
+ message = messages.queued;
1160
+ }
1161
+ }
1162
+ }
1163
+ return message;
1164
+ }
1165
+ return;
1166
+ }
1167
+ /**
1168
+ *
1169
+ *
1170
+ * @private
1171
+ * @param {any[]} [params]
1172
+ * @returns {*}
1173
+ * @memberof MemoryCache
1174
+ */
1175
+ _retrieveCallback(params) {
1176
+ if (Array.isArray(params) && params.length > 0 && typeof params[params.length - 1] === 'function') {
1177
+ return params.pop();
1178
+ }
1179
+ return;
1180
+ }
1174
1181
  }
1175
1182
 
1176
- /*
1177
- * @Description:
1178
- * @Usage:
1179
- * @Author: richen
1180
- * @Date: 2021-06-29 19:07:57
1181
- * @LastEditTime: 2023-02-18 23:52:47
1182
- */
1183
- class MemoryStore {
1184
- /**
1185
- * Creates an instance of MemoryStore.
1186
- * @param {MemoryStoreOpt} options
1187
- * @memberof MemoryStore
1188
- */
1189
- constructor(options) {
1190
- this.options = options;
1191
- this.client = null;
1192
- }
1193
- /**
1194
- * getConnection
1195
- *
1196
- * @returns {*}
1197
- * @memberof MemoryStore
1198
- */
1199
- getConnection() {
1200
- if (!this.pool) {
1201
- this.pool = new MemoryCache({
1202
- database: this.options.db
1203
- });
1204
- }
1205
- if (!this.client) {
1206
- this.client = this.pool.createClient();
1207
- this.client.status = "ready";
1208
- }
1209
- return this.client;
1210
- }
1211
- /**
1212
- * close
1213
- *
1214
- * @returns {*} {Promise<void>}
1215
- * @memberof MemoryStore
1216
- */
1217
- async close() {
1218
- this.client.end();
1219
- this.client = null;
1220
- }
1221
- /**
1222
- * release
1223
- *
1224
- * @param {*} conn
1225
- * @returns {*} {Promise<void>}
1226
- * @memberof MemoryStore
1227
- */
1228
- async release(conn) {
1229
- return;
1230
- }
1231
- /**
1232
- * defineCommand
1233
- *
1234
- * @param {string} name
1235
- * @param {*} scripts
1236
- * @memberof MemoryStore
1237
- */
1238
- async defineCommand(name, scripts) {
1239
- throw new Error(messages.unsupported);
1240
- }
1241
- /**
1242
- * get and compare value
1243
- *
1244
- * @param {string} name
1245
- * @param {(string | number)} value
1246
- * @returns {*} {Promise<any>}
1247
- * @memberof MemoryStore
1248
- */
1249
- async getCompare(name, value) {
1250
- const client = this.getConnection();
1251
- const val = client.get(`${this.options.keyPrefix}${name}`);
1252
- if (!val) {
1253
- return 0;
1254
- }
1255
- else if (val == value) {
1256
- return client.del(`${this.options.keyPrefix}${name}`);
1257
- }
1258
- else {
1259
- return -1;
1260
- }
1261
- }
1183
+ /*
1184
+ * @Description:
1185
+ * @Usage:
1186
+ * @Author: richen
1187
+ * @Date: 2021-06-29 19:07:57
1188
+ * @LastEditTime: 2023-02-18 23:52:47
1189
+ */
1190
+ class MemoryStore {
1191
+ client;
1192
+ pool;
1193
+ options;
1194
+ /**
1195
+ * Creates an instance of MemoryStore.
1196
+ * @param {MemoryStoreOpt} options
1197
+ * @memberof MemoryStore
1198
+ */
1199
+ constructor(options) {
1200
+ this.options = options;
1201
+ this.client = null;
1202
+ }
1203
+ /**
1204
+ * getConnection
1205
+ *
1206
+ * @returns {*}
1207
+ * @memberof MemoryStore
1208
+ */
1209
+ getConnection() {
1210
+ if (!this.pool) {
1211
+ this.pool = new MemoryCache({
1212
+ database: this.options.db
1213
+ });
1214
+ }
1215
+ if (!this.client) {
1216
+ this.client = this.pool.createClient();
1217
+ this.client.status = "ready";
1218
+ }
1219
+ return this.client;
1220
+ }
1221
+ /**
1222
+ * close
1223
+ *
1224
+ * @returns {*} {Promise<void>}
1225
+ * @memberof MemoryStore
1226
+ */
1227
+ async close() {
1228
+ this.client.end();
1229
+ this.client = null;
1230
+ }
1231
+ /**
1232
+ * release
1233
+ *
1234
+ * @param {*} _conn
1235
+ * @returns {*} {Promise<void>}
1236
+ * @memberof MemoryStore
1237
+ */
1238
+ async release(_conn) {
1239
+ return;
1240
+ }
1241
+ /**
1242
+ * defineCommand
1243
+ *
1244
+ * @param {string} _name
1245
+ * @param {*} _scripts
1246
+ * @memberof MemoryStore
1247
+ */
1248
+ async defineCommand(_name, _scripts) {
1249
+ throw new Error(messages.unsupported);
1250
+ }
1251
+ /**
1252
+ * get and compare value
1253
+ *
1254
+ * @param {string} name
1255
+ * @param {(string | number)} value
1256
+ * @returns {*} {Promise<any>}
1257
+ * @memberof MemoryStore
1258
+ */
1259
+ async getCompare(name, value) {
1260
+ const client = this.getConnection();
1261
+ const val = client.get(`${this.options.keyPrefix}${name}`);
1262
+ if (!val) {
1263
+ return 0;
1264
+ }
1265
+ else if (val == value) {
1266
+ return client.del(`${this.options.keyPrefix}${name}`);
1267
+ }
1268
+ else {
1269
+ return -1;
1270
+ }
1271
+ }
1262
1272
  }
1263
1273
 
1264
- /*
1265
- * @Author: richen
1266
- * @Date: 2020-11-30 15:56:08
1267
- * @LastEditors: Please set LastEditors
1268
- * @LastEditTime: 2023-02-19 00:02:09
1269
- * @License: BSD (3-Clause)
1270
- * @Copyright (c) - <richenlin(at)gmail.com>
1271
- */
1272
- /**
1273
- *
1274
- *
1275
- * @export
1276
- * @class RedisStore
1277
- */
1278
- class RedisStore {
1279
- /**
1280
- * Creates an instance of RedisStore.
1281
- * @param {RedisStoreOpt} options
1282
- * @memberof RedisStore
1283
- */
1284
- constructor(options) {
1285
- this.options = this.parseOpt(options);
1286
- this.pool = null;
1287
- }
1288
- // parseOpt
1289
- parseOpt(options) {
1290
- const opt = {
1291
- type: options.type,
1292
- host: options.host || '127.0.0.1',
1293
- port: options.port || 3306,
1294
- username: options.username || "",
1295
- password: options.password || "",
1296
- db: options.db || 0,
1297
- timeout: options.timeout,
1298
- keyPrefix: options.keyPrefix || '',
1299
- poolSize: options.poolSize || 10,
1300
- connectTimeout: options.connectTimeout || 500,
1301
- };
1302
- if (helper__namespace.isArray(options.host)) {
1303
- const hosts = [];
1304
- for (let i = 0; i < options.host.length; i++) {
1305
- const h = options.host[i];
1306
- if (!helper__namespace.isEmpty(options.host[i])) {
1307
- let p;
1308
- if (helper__namespace.isArray(options.port)) {
1309
- p = options.port[i];
1310
- }
1311
- else {
1312
- p = options.port || 6379;
1313
- }
1314
- hosts.push({
1315
- host: h,
1316
- port: helper__namespace.toNumber(p),
1317
- });
1318
- }
1319
- }
1320
- // sentinel
1321
- if (!helper__namespace.isEmpty(options.name)) {
1322
- opt.host = "";
1323
- opt.port = null;
1324
- opt.sentinels = [...hosts];
1325
- opt.sentinelUsername = options.username;
1326
- opt.sentinelPassword = options.password;
1327
- }
1328
- else {
1329
- // cluster
1330
- opt.host = "";
1331
- opt.port = null;
1332
- opt.clusters = [...hosts];
1333
- }
1334
- }
1335
- return opt;
1336
- }
1337
- /**
1338
- * create connection by native
1339
- *
1340
- * @param {number} [connNum=0]
1341
- * @returns {*} {Promise<Redis | Cluster>}
1342
- * @memberof RedisStore
1343
- */
1344
- async connect(connNum = 0) {
1345
- if (this.client && this.client.status === 'ready') {
1346
- return this.client;
1347
- }
1348
- const defer = helper__namespace.getDefer();
1349
- let connection;
1350
- if (!helper__namespace.isEmpty(this.options.clusters)) {
1351
- connection = new ioredis.Cluster([...this.options.clusters], { redisOptions: this.options });
1352
- }
1353
- else {
1354
- connection = new ioredis.Redis(this.options);
1355
- }
1356
- // 去除prefix, 防止重复
1357
- this.options.keyPrefix = "";
1358
- connection.on('end', () => {
1359
- if (connNum < 3) {
1360
- connNum++;
1361
- defer.resolve(this.connect(connNum));
1362
- }
1363
- else {
1364
- this.close();
1365
- defer.reject('redis connection end');
1366
- }
1367
- });
1368
- connection.on('ready', () => {
1369
- this.client = connection;
1370
- defer.resolve(connection);
1371
- });
1372
- return defer.promise;
1373
- }
1374
- /**
1375
- * get connection from pool
1376
- *
1377
- * @returns {*}
1378
- * @memberof RedisStore
1379
- */
1380
- getConnection() {
1381
- if (!this.pool || !this.pool.acquire) {
1382
- const factory = {
1383
- create: () => {
1384
- return this.connect();
1385
- },
1386
- destroy: () => {
1387
- return this.close();
1388
- },
1389
- validate: (resource) => {
1390
- return Promise.resolve(resource.status === 'ready');
1391
- }
1392
- };
1393
- this.pool = genericPool.createPool(factory, {
1394
- max: this.options.poolSize || 10,
1395
- min: 2 // minimum size of the pool
1396
- });
1397
- this.pool.on('factoryCreateError', function (err) {
1398
- koatty_logger.DefaultLogger.Error(err);
1399
- });
1400
- this.pool.on('factoryDestroyError', function (err) {
1401
- koatty_logger.DefaultLogger.Error(err);
1402
- });
1403
- }
1404
- return this.pool.acquire();
1405
- }
1406
- /**
1407
- * close connection
1408
- *
1409
- * @returns {*}
1410
- * @memberof RedisStore
1411
- */
1412
- async close() {
1413
- this.client.disconnect();
1414
- this.client = null;
1415
- this.pool.destroy(this.client);
1416
- this.pool = null;
1417
- return;
1418
- }
1419
- /**
1420
- *
1421
- *
1422
- * @param {*} conn
1423
- * @returns {*}
1424
- * @memberof RedisStore
1425
- */
1426
- async release(conn) {
1427
- if (this.pool.isBorrowedResource(conn)) {
1428
- return this.pool.release(conn);
1429
- }
1430
- return Promise.resolve();
1431
- }
1432
- /**
1433
- * defineCommand
1434
- *
1435
- * @param {string} name
1436
- * @param {{ numberOfKeys?: number; lua?: string; }} scripts
1437
- * @returns {*}
1438
- * @memberof RedisStore
1439
- */
1440
- async defineCommand(name, scripts) {
1441
- const conn = await this.getConnection();
1442
- if (!conn[name]) {
1443
- conn.defineCommand(name, scripts);
1444
- }
1445
- return conn;
1446
- }
1447
- /**
1448
- * get and compare value
1449
- *
1450
- * @param {string} name
1451
- * @param {(string | number)} value
1452
- * @returns {*} {Promise<any>}
1453
- * @memberof RedisStore
1454
- */
1455
- async getCompare(name, value) {
1456
- let conn;
1457
- try {
1458
- conn = await this.defineCommand("getCompare", {
1459
- numberOfKeys: 1,
1460
- lua: `
1461
- local remote_value = redis.call("get",KEYS[1])
1462
-
1463
- if (not remote_value) then
1464
- return 0
1465
- elseif (remote_value == ARGV[1]) then
1466
- return redis.call("del",KEYS[1])
1467
- else
1468
- return -1
1469
- end
1470
- `
1471
- });
1472
- return conn.getCompare(name, value);
1473
- }
1474
- catch (error) {
1475
- throw error;
1476
- }
1477
- finally {
1478
- this.release(conn);
1479
- }
1480
- }
1274
+ /*
1275
+ * @Author: richen
1276
+ * @Date: 2020-11-30 15:56:08
1277
+ * @LastEditors: Please set LastEditors
1278
+ * @LastEditTime: 2023-02-19 00:02:09
1279
+ * @License: BSD (3-Clause)
1280
+ * @Copyright (c) - <richenlin(at)gmail.com>
1281
+ */
1282
+ /**
1283
+ *
1284
+ *
1285
+ * @export
1286
+ * @class RedisStore
1287
+ */
1288
+ class RedisStore {
1289
+ options;
1290
+ pool;
1291
+ client;
1292
+ /**
1293
+ * Creates an instance of RedisStore.
1294
+ * @param {RedisStoreOpt} options
1295
+ * @memberof RedisStore
1296
+ */
1297
+ constructor(options) {
1298
+ this.options = this.parseOpt(options);
1299
+ this.pool = null;
1300
+ }
1301
+ // parseOpt
1302
+ parseOpt(options) {
1303
+ const opt = {
1304
+ type: options.type,
1305
+ host: options.host || '127.0.0.1',
1306
+ port: options.port || 3306,
1307
+ username: options.username || "",
1308
+ password: options.password || "",
1309
+ db: options.db || 0,
1310
+ timeout: options.timeout,
1311
+ keyPrefix: options.keyPrefix || '',
1312
+ poolSize: options.poolSize || 10,
1313
+ connectTimeout: options.connectTimeout || 500,
1314
+ };
1315
+ if (helper__namespace.isArray(options.host)) {
1316
+ const hosts = [];
1317
+ for (let i = 0; i < options.host.length; i++) {
1318
+ const h = options.host[i];
1319
+ if (!helper__namespace.isEmpty(options.host[i])) {
1320
+ let p;
1321
+ if (helper__namespace.isArray(options.port)) {
1322
+ p = options.port[i];
1323
+ }
1324
+ else {
1325
+ p = options.port || 6379;
1326
+ }
1327
+ hosts.push({
1328
+ host: h,
1329
+ port: helper__namespace.toNumber(p),
1330
+ });
1331
+ }
1332
+ }
1333
+ // sentinel
1334
+ if (!helper__namespace.isEmpty(options.name)) {
1335
+ opt.host = "";
1336
+ opt.port = null;
1337
+ opt.sentinels = [...hosts];
1338
+ opt.sentinelUsername = options.username;
1339
+ opt.sentinelPassword = options.password;
1340
+ }
1341
+ else {
1342
+ // cluster
1343
+ opt.host = "";
1344
+ opt.port = null;
1345
+ opt.clusters = [...hosts];
1346
+ }
1347
+ }
1348
+ return opt;
1349
+ }
1350
+ /**
1351
+ * create connection by native
1352
+ *
1353
+ * @param {number} [connNum=0]
1354
+ * @returns {*} {Promise<Redis | Cluster>}
1355
+ * @memberof RedisStore
1356
+ */
1357
+ async connect(connNum = 0) {
1358
+ if (this.client && this.client.status === 'ready') {
1359
+ return this.client;
1360
+ }
1361
+ const defer = helper__namespace.getDefer();
1362
+ let connection;
1363
+ if (!helper__namespace.isEmpty(this.options.clusters)) {
1364
+ connection = new ioredis.Cluster([...this.options.clusters], { redisOptions: this.options });
1365
+ }
1366
+ else {
1367
+ connection = new ioredis.Redis(this.options);
1368
+ }
1369
+ // 去除prefix, 防止重复
1370
+ this.options.keyPrefix = "";
1371
+ connection.on('end', () => {
1372
+ if (connNum < 3) {
1373
+ connNum++;
1374
+ defer.resolve(this.connect(connNum));
1375
+ }
1376
+ else {
1377
+ this.close();
1378
+ defer.reject('redis connection end');
1379
+ }
1380
+ });
1381
+ connection.on('ready', () => {
1382
+ this.client = connection;
1383
+ defer.resolve(connection);
1384
+ });
1385
+ return defer.promise;
1386
+ }
1387
+ /**
1388
+ * get connection from pool
1389
+ *
1390
+ * @returns {*}
1391
+ * @memberof RedisStore
1392
+ */
1393
+ getConnection() {
1394
+ if (!this.pool || !this.pool.acquire) {
1395
+ const factory = {
1396
+ create: () => {
1397
+ return this.connect();
1398
+ },
1399
+ destroy: () => {
1400
+ return this.close();
1401
+ },
1402
+ validate: (resource) => {
1403
+ return Promise.resolve(resource.status === 'ready');
1404
+ }
1405
+ };
1406
+ this.pool = genericPool.createPool(factory, {
1407
+ max: this.options.poolSize || 10, // maximum size of the pool
1408
+ min: 2 // minimum size of the pool
1409
+ });
1410
+ this.pool.on('factoryCreateError', function (err) {
1411
+ koatty_logger.DefaultLogger.Error(err);
1412
+ });
1413
+ this.pool.on('factoryDestroyError', function (err) {
1414
+ koatty_logger.DefaultLogger.Error(err);
1415
+ });
1416
+ }
1417
+ return this.pool.acquire();
1418
+ }
1419
+ /**
1420
+ * close connection
1421
+ *
1422
+ * @returns {*}
1423
+ * @memberof RedisStore
1424
+ */
1425
+ async close() {
1426
+ this.client.disconnect();
1427
+ this.client = null;
1428
+ this.pool.destroy(this.client);
1429
+ this.pool = null;
1430
+ return;
1431
+ }
1432
+ /**
1433
+ *
1434
+ *
1435
+ * @param {*} conn
1436
+ * @returns {*}
1437
+ * @memberof RedisStore
1438
+ */
1439
+ async release(conn) {
1440
+ if (this.pool.isBorrowedResource(conn)) {
1441
+ return this.pool.release(conn);
1442
+ }
1443
+ return Promise.resolve();
1444
+ }
1445
+ /**
1446
+ * defineCommand
1447
+ *
1448
+ * @param {string} name
1449
+ * @param {{ numberOfKeys?: number; lua?: string; }} scripts
1450
+ * @returns {*}
1451
+ * @memberof RedisStore
1452
+ */
1453
+ async defineCommand(name, scripts) {
1454
+ const conn = await this.getConnection();
1455
+ if (!conn[name]) {
1456
+ conn.defineCommand(name, scripts);
1457
+ }
1458
+ return conn;
1459
+ }
1460
+ /**
1461
+ * get and compare value
1462
+ *
1463
+ * @param {string} name
1464
+ * @param {(string | number)} value
1465
+ * @returns {*} {Promise<any>}
1466
+ * @memberof RedisStore
1467
+ */
1468
+ async getCompare(name, value) {
1469
+ let conn;
1470
+ try {
1471
+ conn = await this.defineCommand("getCompare", {
1472
+ numberOfKeys: 1,
1473
+ lua: `
1474
+ local remote_value = redis.call("get",KEYS[1])
1475
+
1476
+ if (not remote_value) then
1477
+ return 0
1478
+ elseif (remote_value == ARGV[1]) then
1479
+ return redis.call("del",KEYS[1])
1480
+ else
1481
+ return -1
1482
+ end
1483
+ `
1484
+ });
1485
+ return conn.getCompare(name, value);
1486
+ }
1487
+ catch (error) {
1488
+ throw error;
1489
+ }
1490
+ finally {
1491
+ this.release(conn);
1492
+ }
1493
+ }
1481
1494
  }
1482
1495
 
1483
- /*
1484
- * @Description:
1485
- * @Usage:
1486
- * @Author: richen
1487
- * @Date: 2021-12-02 15:26:55
1488
- * @LastEditTime: 2023-02-19 01:03:59
1489
- */
1490
- const defaultOptions = {
1491
- type: 'memory',
1492
- host: '',
1493
- port: 0,
1494
- keyPrefix: 'Koatty',
1495
- timeout: 600,
1496
- poolSize: 10,
1497
- connectTimeout: 500,
1498
- db: 0
1499
- };
1500
- /**
1501
- *
1502
- *
1503
- * @export
1504
- * @class Store
1505
- */
1506
- class CacheStore {
1507
- /**
1508
- * Creates an instance of CacheStore.
1509
- * @param {StoreOptions} options
1510
- * @memberof CacheStore
1511
- */
1512
- constructor(options) {
1513
- this.options = { ...defaultOptions, ...options };
1514
- this.client = null;
1515
- switch (options.type) {
1516
- case "redis":
1517
- this.client = new RedisStore(options);
1518
- break;
1519
- case "memory":
1520
- default:
1521
- this.client = new MemoryStore(options);
1522
- break;
1523
- }
1524
- }
1525
- /**
1526
- *
1527
- *
1528
- * @static
1529
- * @returns
1530
- */
1531
- static getInstance(options) {
1532
- if (this.instance) {
1533
- return this.instance;
1534
- }
1535
- this.instance = new CacheStore(options);
1536
- return this.instance;
1537
- }
1538
- getConnection() {
1539
- return this.client.getConnection();
1540
- }
1541
- close() {
1542
- return this.client.close();
1543
- }
1544
- release(conn) {
1545
- return this.client.release(conn);
1546
- }
1547
- defineCommand(name, scripts) {
1548
- return this.client.defineCommand(name, scripts);
1549
- }
1550
- getCompare(name, value) {
1551
- return this.client.getCompare(name, value);
1552
- }
1553
- /**
1554
- * handler for native client
1555
- *
1556
- * @param {string} name
1557
- * @param {any[]} data
1558
- * @returns {*}
1559
- * @memberof RedisStore
1560
- */
1561
- async wrap(name, data) {
1562
- let conn;
1563
- try {
1564
- conn = await this.getConnection();
1565
- const res = await conn[name](...data);
1566
- return res;
1567
- }
1568
- catch (err) {
1569
- throw err;
1570
- }
1571
- finally {
1572
- this.release(conn);
1573
- }
1574
- }
1575
- /**
1576
- * 字符串获取
1577
- * @param name
1578
- */
1579
- get(name) {
1580
- return this.wrap('get', [`${this.options.keyPrefix || ""}${name}`]);
1581
- }
1582
- /**
1583
- * 字符串写入
1584
- * @param name
1585
- * @param value
1586
- * @param timeout
1587
- * @returns {Promise}
1588
- */
1589
- set(name, value, timeout) {
1590
- if (typeof timeout !== 'number') {
1591
- timeout = this.options.timeout;
1592
- }
1593
- return this.wrap('set', [`${this.options.keyPrefix || ""}${name}`, value, 'ex', timeout]);
1594
- }
1595
- /**
1596
- * 以秒为单位,返回给定 key 的剩余生存时间
1597
- * @param name
1598
- * @returns {*}
1599
- */
1600
- ttl(name) {
1601
- return this.wrap('ttl', [`${this.options.keyPrefix || ""}${name}`]);
1602
- }
1603
- /**
1604
- * 设置key超时属性
1605
- * @param name
1606
- * @param timeout
1607
- */
1608
- expire(name, timeout) {
1609
- return this.wrap('expire', [`${this.options.keyPrefix || ""}${name}`, timeout]);
1610
- }
1611
- /**
1612
- * 删除key
1613
- * @param name
1614
- */
1615
- rm(name) {
1616
- return this.wrap('del', [`${this.options.keyPrefix || ""}${name}`]);
1617
- }
1618
- /**
1619
- *
1620
- *
1621
- * @param {*} name
1622
- * @returns
1623
- */
1624
- del(name) {
1625
- return this.wrap('del', [`${this.options.keyPrefix || ""}${name}`]);
1626
- }
1627
- /**
1628
- * 判断key是否存在
1629
- * @param name
1630
- */
1631
- exists(name) {
1632
- return this.wrap('exists', [`${this.options.keyPrefix || ""}${name}`]);
1633
- }
1634
- /**
1635
- * 自增
1636
- * @param name
1637
- */
1638
- incr(name) {
1639
- return this.wrap('incr', [`${this.options.keyPrefix || ""}${name}`]);
1640
- }
1641
- /**
1642
- * 自减
1643
- * @param name
1644
- * @returns {*}
1645
- */
1646
- decr(name) {
1647
- return this.wrap('decr', [`${this.options.keyPrefix || ""}${name}`]);
1648
- }
1649
- /**
1650
- * key 所储存的值增加增量
1651
- * @param name
1652
- * @param incr
1653
- * @returns {*}
1654
- */
1655
- incrby(name, incr = 1) {
1656
- return this.wrap('incrby', [`${this.options.keyPrefix || ""}${name}`, incr]);
1657
- }
1658
- /**
1659
- * key 所储存的值减去减量
1660
- *
1661
- * @param {any} name
1662
- * @param {any} decr
1663
- */
1664
- decrby(name, decr = 1) {
1665
- return this.wrap('decrby', [`${this.options.keyPrefix || ""}${name}`, decr]);
1666
- }
1667
- /**
1668
- * 哈希写入
1669
- * @param name
1670
- * @param key
1671
- * @param value
1672
- * @param timeout
1673
- */
1674
- hset(name, key, value, timeout) {
1675
- const setP = [this.wrap('hset', [`${this.options.keyPrefix || ""}${name}`, key, value])];
1676
- if (typeof timeout !== 'number') {
1677
- timeout = this.options.timeout;
1678
- }
1679
- setP.push(this.set(`${name}:${key}_ex`, 1, timeout));
1680
- return Promise.all(setP);
1681
- }
1682
- /**
1683
- * 哈希获取
1684
- * @param name
1685
- * @param key
1686
- * @returns {*}
1687
- */
1688
- hget(name, key) {
1689
- const setP = [this.get(`${name}:${key}_ex`)];
1690
- setP.push(this.wrap('hget', [`${this.options.keyPrefix || ""}${name}`, key]));
1691
- return Promise.all(setP).then(dataArr => {
1692
- if (dataArr[0] === null) {
1693
- this.hdel(name, key);
1694
- return null;
1695
- }
1696
- return dataArr[1] || null;
1697
- });
1698
- }
1699
- /**
1700
- * 查看哈希表 hashKey 中,给定域 key 是否存在
1701
- * @param name
1702
- * @param key
1703
- * @returns {*}
1704
- */
1705
- hexists(name, key) {
1706
- const setP = [this.get(`${name}:${key}_ex`)];
1707
- setP.push(this.wrap('hexists', [`${this.options.keyPrefix || ""}${name}`, key]));
1708
- return Promise.all(setP).then(dataArr => {
1709
- if (dataArr[0] === null) {
1710
- this.hdel(name, key);
1711
- return 0;
1712
- }
1713
- return dataArr[1] || 0;
1714
- });
1715
- }
1716
- /**
1717
- * 哈希删除
1718
- * @param name
1719
- * @param key
1720
- * @returns {*}
1721
- */
1722
- hdel(name, key) {
1723
- const setP = [this.del(`${name}:${key}_ex`)];
1724
- setP.push(this.wrap('hdel', [`${this.options.keyPrefix || ""}${name}`, key]));
1725
- return Promise.all(setP);
1726
- }
1727
- /**
1728
- * 返回哈希表 key 中域的数量
1729
- * @param name
1730
- * @returns {*}
1731
- */
1732
- hlen(name) {
1733
- return this.wrap('hlen', [`${this.options.keyPrefix || ""}${name}`]);
1734
- }
1735
- /**
1736
- * 给哈希表指定key,增加increment
1737
- * @param name
1738
- * @param key
1739
- * @param incr
1740
- * @returns {*}
1741
- */
1742
- hincrby(name, key, incr = 1) {
1743
- return this.wrap('hincrby', [`${this.options.keyPrefix || ""}${name}`, key, incr]);
1744
- }
1745
- /**
1746
- * 返回哈希表所有key-value
1747
- * @param name
1748
- * @returns {*}
1749
- */
1750
- hgetall(name) {
1751
- return this.wrap('hgetall', [`${this.options.keyPrefix || ""}${name}`]);
1752
- }
1753
- /**
1754
- * 返回哈希表所有key
1755
- * @param name
1756
- * @returns {*}
1757
- */
1758
- hkeys(name) {
1759
- return this.wrap('hkeys', [`${this.options.keyPrefix || ""}${name}`]);
1760
- }
1761
- /**
1762
- * 返回哈希表所有value
1763
- * @param name
1764
- * @returns {*}
1765
- */
1766
- hvals(name) {
1767
- return this.wrap('hvals', [`${this.options.keyPrefix || ""}${name}`]);
1768
- }
1769
- /**
1770
- * 判断列表长度,若不存在则表示为空
1771
- * @param name
1772
- * @returns {*}
1773
- */
1774
- llen(name) {
1775
- return this.wrap('llen', [`${this.options.keyPrefix || ""}${name}`]);
1776
- }
1777
- /**
1778
- * 将值插入列表表尾
1779
- * @param name
1780
- * @param value
1781
- * @returns {*}
1782
- */
1783
- rpush(name, value) {
1784
- return this.wrap('rpush', [`${this.options.keyPrefix || ""}${name}`, value]);
1785
- }
1786
- /**
1787
- *
1788
- *
1789
- * @param {string} name
1790
- * @param {(string | number)} value
1791
- * @returns {*}
1792
- * @memberof RedisStore
1793
- */
1794
- lpush(name, value) {
1795
- return this.wrap('lpush', [`${this.options.keyPrefix || ""}${name}`, value]);
1796
- }
1797
- /**
1798
- * 将列表表头取出,并去除
1799
- * @param name
1800
- * @returns {*}
1801
- */
1802
- lpop(name) {
1803
- return this.wrap('lpop', [`${this.options.keyPrefix || ""}${name}`]);
1804
- }
1805
- /**
1806
- *
1807
- *
1808
- * @param {string} name
1809
- * @returns {*}
1810
- * @memberof RedisStore
1811
- */
1812
- rpop(name) {
1813
- return this.wrap('rpop', [`${this.options.keyPrefix || ""}${name}`]);
1814
- }
1815
- /**
1816
- * 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定
1817
- * @param name
1818
- * @param start
1819
- * @param stop
1820
- * @returns {*}
1821
- */
1822
- lrange(name, start, stop) {
1823
- return this.wrap('lrange', [`${this.options.keyPrefix || ""}${name}`, start, stop]);
1824
- }
1825
- /**
1826
- * 集合新增
1827
- * @param name
1828
- * @param value
1829
- * @param timeout
1830
- * @returns {*}
1831
- */
1832
- sadd(name, value, timeout) {
1833
- const setP = [this.wrap('sadd', [`${this.options.keyPrefix || ""}${name}`, value])];
1834
- if (typeof timeout !== 'number') {
1835
- setP.push(this.wrap('expire', [`${this.options.keyPrefix || ""}${name}`, timeout]));
1836
- }
1837
- return Promise.all(setP);
1838
- }
1839
- /**
1840
- * 返回集合的基数(集合中元素的数量)
1841
- * @param name
1842
- * @returns {*}
1843
- */
1844
- scard(name) {
1845
- return this.wrap('scard', [`${this.options.keyPrefix || ""}${name}`]);
1846
- }
1847
- /**
1848
- * 判断 member 元素是否集合的成员
1849
- * @param name
1850
- * @param key
1851
- * @returns {*}
1852
- */
1853
- sismember(name, key) {
1854
- return this.wrap('sismember', [`${this.options.keyPrefix || ""}${name}`, key]);
1855
- }
1856
- /**
1857
- * 返回集合中的所有成员
1858
- * @param name
1859
- * @returns {*}
1860
- */
1861
- smembers(name) {
1862
- return this.wrap('smembers', [`${this.options.keyPrefix || ""}${name}`]);
1863
- }
1864
- /**
1865
- * 移除并返回集合中的一个随机元素
1866
- * @param name
1867
- * @returns {*}
1868
- */
1869
- spop(name) {
1870
- return this.wrap('spop', [`${this.options.keyPrefix || ""}${name}`]);
1871
- }
1872
- /**
1873
- * 移除集合 key 中的一个 member 元素
1874
- * @param name
1875
- * @param key
1876
- * @returns {*}
1877
- */
1878
- srem(name, key) {
1879
- return this.wrap('srem', [`${this.options.keyPrefix || ""}${name}`, key]);
1880
- }
1881
- /**
1882
- * member 元素从 source 集合移动到 destination 集合
1883
- * @param source
1884
- * @param destination
1885
- * @param member
1886
- * @returns {*}
1887
- */
1888
- smove(source, destination, member) {
1889
- return this.wrap('smove', [`${this.options.keyPrefix || ""}${source}`, `${this.options.keyPrefix}${destination}`, member]);
1890
- }
1496
+ /*
1497
+ * @Description:
1498
+ * @Usage:
1499
+ * @Author: richen
1500
+ * @Date: 2021-12-02 15:26:55
1501
+ * @LastEditTime: 2024-11-07 14:27:25
1502
+ */
1503
+ const defaultOptions = {
1504
+ type: 'memory', // memory | redis
1505
+ host: '',
1506
+ port: 0,
1507
+ keyPrefix: 'Koatty',
1508
+ timeout: 600,
1509
+ poolSize: 10,
1510
+ connectTimeout: 500,
1511
+ db: 0
1512
+ };
1513
+ /**
1514
+ *
1515
+ *
1516
+ * @export
1517
+ * @class Store
1518
+ */
1519
+ class CacheStore {
1520
+ client;
1521
+ options;
1522
+ static instance;
1523
+ /**
1524
+ * Creates an instance of CacheStore.
1525
+ * @param {StoreOptions} options
1526
+ * @memberof CacheStore
1527
+ */
1528
+ constructor(options) {
1529
+ this.options = options ? { ...defaultOptions, ...options } : defaultOptions;
1530
+ this.client = null;
1531
+ switch (this.options.type) {
1532
+ case "redis":
1533
+ this.client = new RedisStore(this.options);
1534
+ break;
1535
+ case "memory":
1536
+ default:
1537
+ this.client = new MemoryStore(this.options);
1538
+ break;
1539
+ }
1540
+ }
1541
+ /**
1542
+ *
1543
+ *
1544
+ * @static
1545
+ * @returns
1546
+ */
1547
+ static getInstance(options) {
1548
+ if (this.instance) {
1549
+ return this.instance;
1550
+ }
1551
+ this.instance = new CacheStore(options);
1552
+ return this.instance;
1553
+ }
1554
+ getConnection() {
1555
+ return this.client.getConnection();
1556
+ }
1557
+ close() {
1558
+ return this.client.close();
1559
+ }
1560
+ release(conn) {
1561
+ return this.client.release(conn);
1562
+ }
1563
+ defineCommand(name, scripts) {
1564
+ return this.client.defineCommand(name, scripts);
1565
+ }
1566
+ getCompare(name, value) {
1567
+ return this.client.getCompare(name, value);
1568
+ }
1569
+ /**
1570
+ * handler for native client
1571
+ *
1572
+ * @param {string} name
1573
+ * @param {any[]} data
1574
+ * @returns {*}
1575
+ * @memberof RedisStore
1576
+ */
1577
+ async wrap(name, data) {
1578
+ let conn;
1579
+ try {
1580
+ conn = await this.getConnection();
1581
+ const res = await conn[name](...data);
1582
+ return res;
1583
+ }
1584
+ catch (err) {
1585
+ throw err;
1586
+ }
1587
+ finally {
1588
+ this.release(conn);
1589
+ }
1590
+ }
1591
+ /**
1592
+ * 字符串获取
1593
+ * @param name
1594
+ */
1595
+ get(name) {
1596
+ return this.wrap('get', [`${this.options.keyPrefix || ""}${name}`]);
1597
+ }
1598
+ /**
1599
+ * 字符串写入
1600
+ * @param name
1601
+ * @param value
1602
+ * @param timeout
1603
+ * @returns {Promise}
1604
+ */
1605
+ set(name, value, timeout) {
1606
+ if (typeof timeout !== 'number') {
1607
+ timeout = this.options.timeout;
1608
+ }
1609
+ return this.wrap('set', [`${this.options.keyPrefix || ""}${name}`, value, 'ex', timeout]);
1610
+ }
1611
+ /**
1612
+ * 以秒为单位,返回给定 key 的剩余生存时间
1613
+ * @param name
1614
+ * @returns {*}
1615
+ */
1616
+ ttl(name) {
1617
+ return this.wrap('ttl', [`${this.options.keyPrefix || ""}${name}`]);
1618
+ }
1619
+ /**
1620
+ * 设置key超时属性
1621
+ * @param name
1622
+ * @param timeout
1623
+ */
1624
+ expire(name, timeout) {
1625
+ return this.wrap('expire', [`${this.options.keyPrefix || ""}${name}`, timeout]);
1626
+ }
1627
+ /**
1628
+ * 删除key
1629
+ * @param name
1630
+ */
1631
+ rm(name) {
1632
+ return this.wrap('del', [`${this.options.keyPrefix || ""}${name}`]);
1633
+ }
1634
+ /**
1635
+ *
1636
+ *
1637
+ * @param {*} name
1638
+ * @returns
1639
+ */
1640
+ del(name) {
1641
+ return this.wrap('del', [`${this.options.keyPrefix || ""}${name}`]);
1642
+ }
1643
+ /**
1644
+ * 判断key是否存在
1645
+ * @param name
1646
+ */
1647
+ exists(name) {
1648
+ return this.wrap('exists', [`${this.options.keyPrefix || ""}${name}`]);
1649
+ }
1650
+ /**
1651
+ * 自增
1652
+ * @param name
1653
+ */
1654
+ incr(name) {
1655
+ return this.wrap('incr', [`${this.options.keyPrefix || ""}${name}`]);
1656
+ }
1657
+ /**
1658
+ * 自减
1659
+ * @param name
1660
+ * @returns {*}
1661
+ */
1662
+ decr(name) {
1663
+ return this.wrap('decr', [`${this.options.keyPrefix || ""}${name}`]);
1664
+ }
1665
+ /**
1666
+ * key 所储存的值增加增量
1667
+ * @param name
1668
+ * @param incr
1669
+ * @returns {*}
1670
+ */
1671
+ incrby(name, incr = 1) {
1672
+ return this.wrap('incrby', [`${this.options.keyPrefix || ""}${name}`, incr]);
1673
+ }
1674
+ /**
1675
+ * key 所储存的值减去减量
1676
+ *
1677
+ * @param {any} name
1678
+ * @param {any} decr
1679
+ */
1680
+ decrby(name, decr = 1) {
1681
+ return this.wrap('decrby', [`${this.options.keyPrefix || ""}${name}`, decr]);
1682
+ }
1683
+ /**
1684
+ * 哈希写入
1685
+ * @param name
1686
+ * @param key
1687
+ * @param value
1688
+ * @param timeout
1689
+ */
1690
+ hset(name, key, value, timeout) {
1691
+ const setP = [this.wrap('hset', [`${this.options.keyPrefix || ""}${name}`, key, value])];
1692
+ if (typeof timeout !== 'number') {
1693
+ timeout = this.options.timeout;
1694
+ }
1695
+ setP.push(this.set(`${name}:${key}_ex`, 1, timeout));
1696
+ return Promise.all(setP);
1697
+ }
1698
+ /**
1699
+ * 哈希获取
1700
+ * @param name
1701
+ * @param key
1702
+ * @returns {*}
1703
+ */
1704
+ hget(name, key) {
1705
+ const setP = [this.get(`${name}:${key}_ex`)];
1706
+ setP.push(this.wrap('hget', [`${this.options.keyPrefix || ""}${name}`, key]));
1707
+ return Promise.all(setP).then(dataArr => {
1708
+ if (dataArr[0] === null) {
1709
+ this.hdel(name, key);
1710
+ return null;
1711
+ }
1712
+ return dataArr[1] || null;
1713
+ });
1714
+ }
1715
+ /**
1716
+ * 查看哈希表 hashKey 中,给定域 key 是否存在
1717
+ * @param name
1718
+ * @param key
1719
+ * @returns {*}
1720
+ */
1721
+ hexists(name, key) {
1722
+ const setP = [this.get(`${name}:${key}_ex`)];
1723
+ setP.push(this.wrap('hexists', [`${this.options.keyPrefix || ""}${name}`, key]));
1724
+ return Promise.all(setP).then(dataArr => {
1725
+ if (dataArr[0] === null) {
1726
+ this.hdel(name, key);
1727
+ return 0;
1728
+ }
1729
+ return dataArr[1] || 0;
1730
+ });
1731
+ }
1732
+ /**
1733
+ * 哈希删除
1734
+ * @param name
1735
+ * @param key
1736
+ * @returns {*}
1737
+ */
1738
+ hdel(name, key) {
1739
+ const setP = [this.del(`${name}:${key}_ex`)];
1740
+ setP.push(this.wrap('hdel', [`${this.options.keyPrefix || ""}${name}`, key]));
1741
+ return Promise.all(setP);
1742
+ }
1743
+ /**
1744
+ * 返回哈希表 key 中域的数量
1745
+ * @param name
1746
+ * @returns {*}
1747
+ */
1748
+ hlen(name) {
1749
+ return this.wrap('hlen', [`${this.options.keyPrefix || ""}${name}`]);
1750
+ }
1751
+ /**
1752
+ * 给哈希表指定key,增加increment
1753
+ * @param name
1754
+ * @param key
1755
+ * @param incr
1756
+ * @returns {*}
1757
+ */
1758
+ hincrby(name, key, incr = 1) {
1759
+ return this.wrap('hincrby', [`${this.options.keyPrefix || ""}${name}`, key, incr]);
1760
+ }
1761
+ /**
1762
+ * 返回哈希表所有key-value
1763
+ * @param name
1764
+ * @returns {*}
1765
+ */
1766
+ hgetall(name) {
1767
+ return this.wrap('hgetall', [`${this.options.keyPrefix || ""}${name}`]);
1768
+ }
1769
+ /**
1770
+ * 返回哈希表所有key
1771
+ * @param name
1772
+ * @returns {*}
1773
+ */
1774
+ hkeys(name) {
1775
+ return this.wrap('hkeys', [`${this.options.keyPrefix || ""}${name}`]);
1776
+ }
1777
+ /**
1778
+ * 返回哈希表所有value
1779
+ * @param name
1780
+ * @returns {*}
1781
+ */
1782
+ hvals(name) {
1783
+ return this.wrap('hvals', [`${this.options.keyPrefix || ""}${name}`]);
1784
+ }
1785
+ /**
1786
+ * 判断列表长度,若不存在则表示为空
1787
+ * @param name
1788
+ * @returns {*}
1789
+ */
1790
+ llen(name) {
1791
+ return this.wrap('llen', [`${this.options.keyPrefix || ""}${name}`]);
1792
+ }
1793
+ /**
1794
+ * 将值插入列表表尾
1795
+ * @param name
1796
+ * @param value
1797
+ * @returns {*}
1798
+ */
1799
+ rpush(name, value) {
1800
+ return this.wrap('rpush', [`${this.options.keyPrefix || ""}${name}`, value]);
1801
+ }
1802
+ /**
1803
+ *
1804
+ *
1805
+ * @param {string} name
1806
+ * @param {(string | number)} value
1807
+ * @returns {*}
1808
+ * @memberof RedisStore
1809
+ */
1810
+ lpush(name, value) {
1811
+ return this.wrap('lpush', [`${this.options.keyPrefix || ""}${name}`, value]);
1812
+ }
1813
+ /**
1814
+ * 将列表表头取出,并去除
1815
+ * @param name
1816
+ * @returns {*}
1817
+ */
1818
+ lpop(name) {
1819
+ return this.wrap('lpop', [`${this.options.keyPrefix || ""}${name}`]);
1820
+ }
1821
+ /**
1822
+ *
1823
+ *
1824
+ * @param {string} name
1825
+ * @returns {*}
1826
+ * @memberof RedisStore
1827
+ */
1828
+ rpop(name) {
1829
+ return this.wrap('rpop', [`${this.options.keyPrefix || ""}${name}`]);
1830
+ }
1831
+ /**
1832
+ * 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定
1833
+ * @param name
1834
+ * @param start
1835
+ * @param stop
1836
+ * @returns {*}
1837
+ */
1838
+ lrange(name, start, stop) {
1839
+ return this.wrap('lrange', [`${this.options.keyPrefix || ""}${name}`, start, stop]);
1840
+ }
1841
+ /**
1842
+ * 集合新增
1843
+ * @param name
1844
+ * @param value
1845
+ * @param timeout
1846
+ * @returns {*}
1847
+ */
1848
+ sadd(name, value, timeout) {
1849
+ const setP = [this.wrap('sadd', [`${this.options.keyPrefix || ""}${name}`, value])];
1850
+ if (typeof timeout !== 'number') {
1851
+ setP.push(this.wrap('expire', [`${this.options.keyPrefix || ""}${name}`, timeout]));
1852
+ }
1853
+ return Promise.all(setP);
1854
+ }
1855
+ /**
1856
+ * 返回集合的基数(集合中元素的数量)
1857
+ * @param name
1858
+ * @returns {*}
1859
+ */
1860
+ scard(name) {
1861
+ return this.wrap('scard', [`${this.options.keyPrefix || ""}${name}`]);
1862
+ }
1863
+ /**
1864
+ * 判断 member 元素是否集合的成员
1865
+ * @param name
1866
+ * @param key
1867
+ * @returns {*}
1868
+ */
1869
+ sismember(name, key) {
1870
+ return this.wrap('sismember', [`${this.options.keyPrefix || ""}${name}`, key]);
1871
+ }
1872
+ /**
1873
+ * 返回集合中的所有成员
1874
+ * @param name
1875
+ * @returns {*}
1876
+ */
1877
+ smembers(name) {
1878
+ return this.wrap('smembers', [`${this.options.keyPrefix || ""}${name}`]);
1879
+ }
1880
+ /**
1881
+ * 移除并返回集合中的一个随机元素
1882
+ * @param name
1883
+ * @returns {*}
1884
+ */
1885
+ spop(name) {
1886
+ return this.wrap('spop', [`${this.options.keyPrefix || ""}${name}`]);
1887
+ }
1888
+ /**
1889
+ * 移除集合 key 中的一个 member 元素
1890
+ * @param name
1891
+ * @param key
1892
+ * @returns {*}
1893
+ */
1894
+ srem(name, key) {
1895
+ return this.wrap('srem', [`${this.options.keyPrefix || ""}${name}`, key]);
1896
+ }
1897
+ /**
1898
+ * member 元素从 source 集合移动到 destination 集合
1899
+ * @param source
1900
+ * @param destination
1901
+ * @param member
1902
+ * @returns {*}
1903
+ */
1904
+ smove(source, destination, member) {
1905
+ return this.wrap('smove', [`${this.options.keyPrefix || ""}${source}`, `${this.options.keyPrefix}${destination}`, member]);
1906
+ }
1891
1907
  }
1892
1908
 
1893
1909
  exports.CacheStore = CacheStore;