ts-cache-mongoose 1.7.7 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -66
- package/biome.json +1 -1
- package/dist/index.cjs +140 -93
- package/dist/index.d.cts +48 -11
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +48 -11
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +140 -93
- package/dist/nest/index.cjs +113 -0
- package/dist/nest/index.d.cts +40 -0
- package/dist/nest/index.d.cts.map +1 -0
- package/dist/nest/index.d.mts +40 -0
- package/dist/nest/index.d.mts.map +1 -0
- package/dist/nest/index.mjs +110 -0
- package/package.json +44 -22
- package/src/cache/Cache.ts +5 -5
- package/src/cache/engine/MemoryCacheEngine.ts +4 -4
- package/src/cache/engine/RedisCacheEngine.ts +4 -4
- package/src/extend/aggregate.ts +5 -6
- package/src/extend/query.ts +5 -6
- package/src/index.ts +7 -7
- package/src/key.ts +2 -2
- package/src/ms.ts +66 -0
- package/src/nest/cache.module.ts +79 -0
- package/src/nest/cache.service.ts +37 -0
- package/src/nest/index.ts +4 -0
- package/src/nest/interfaces.ts +17 -0
- package/src/sort-keys.ts +38 -0
- package/src/types.ts +4 -4
- package/src/version.ts +1 -2
- package/tests/ms.test.ts +113 -0
- package/tests/nest.test.ts +158 -0
- package/tests/sort-keys.test.ts +80 -0
- package/tsconfig.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,18 +1,55 @@
|
|
|
1
1
|
import { Mongoose } from 'mongoose';
|
|
2
2
|
import { RedisOptions } from 'ioredis';
|
|
3
|
-
import { StringValue } from 'ms';
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
declare const UNITS: {
|
|
5
|
+
readonly milliseconds: 1;
|
|
6
|
+
readonly millisecond: 1;
|
|
7
|
+
readonly msecs: 1;
|
|
8
|
+
readonly msec: 1;
|
|
9
|
+
readonly ms: 1;
|
|
10
|
+
readonly seconds: 1000;
|
|
11
|
+
readonly second: 1000;
|
|
12
|
+
readonly secs: 1000;
|
|
13
|
+
readonly sec: 1000;
|
|
14
|
+
readonly s: 1000;
|
|
15
|
+
readonly minutes: number;
|
|
16
|
+
readonly minute: number;
|
|
17
|
+
readonly mins: number;
|
|
18
|
+
readonly min: number;
|
|
19
|
+
readonly m: number;
|
|
20
|
+
readonly hours: number;
|
|
21
|
+
readonly hour: number;
|
|
22
|
+
readonly hrs: number;
|
|
23
|
+
readonly hr: number;
|
|
24
|
+
readonly h: number;
|
|
25
|
+
readonly days: number;
|
|
26
|
+
readonly day: number;
|
|
27
|
+
readonly d: number;
|
|
28
|
+
readonly weeks: number;
|
|
29
|
+
readonly week: number;
|
|
30
|
+
readonly w: number;
|
|
31
|
+
readonly months: number;
|
|
32
|
+
readonly month: number;
|
|
33
|
+
readonly mo: number;
|
|
34
|
+
readonly years: number;
|
|
35
|
+
readonly year: number;
|
|
36
|
+
readonly yrs: number;
|
|
37
|
+
readonly yr: number;
|
|
38
|
+
readonly y: number;
|
|
39
|
+
};
|
|
40
|
+
type Unit = keyof typeof UNITS;
|
|
41
|
+
type Duration = number | `${number}` | `${number}${Unit}` | `${number} ${Unit}`;
|
|
42
|
+
|
|
6
43
|
type CacheData = Record<string, unknown> | Record<string, unknown>[] | unknown[] | number | undefined;
|
|
7
44
|
type CacheOptions = {
|
|
8
45
|
engine: 'memory' | 'redis';
|
|
9
46
|
engineOptions?: RedisOptions;
|
|
10
|
-
defaultTTL?:
|
|
47
|
+
defaultTTL?: Duration;
|
|
11
48
|
debug?: boolean;
|
|
12
49
|
};
|
|
13
50
|
interface CacheEngine {
|
|
14
51
|
get: (key: string) => Promise<CacheData> | CacheData;
|
|
15
|
-
set: (key: string, value: CacheData, ttl?:
|
|
52
|
+
set: (key: string, value: CacheData, ttl?: Duration) => Promise<void> | void;
|
|
16
53
|
del: (key: string) => Promise<void> | void;
|
|
17
54
|
clear: () => Promise<void> | void;
|
|
18
55
|
close: () => Promise<void> | void;
|
|
@@ -20,11 +57,11 @@ interface CacheEngine {
|
|
|
20
57
|
|
|
21
58
|
declare module 'mongoose' {
|
|
22
59
|
interface Query<ResultType, DocType, THelpers, RawDocType> {
|
|
23
|
-
cache: (this: Query<ResultType, DocType, THelpers, RawDocType>, ttl?:
|
|
60
|
+
cache: (this: Query<ResultType, DocType, THelpers, RawDocType>, ttl?: Duration, customKey?: string) => this;
|
|
24
61
|
_key: string | null;
|
|
25
62
|
getCacheKey: (this: Query<ResultType, DocType, THelpers, RawDocType>) => string;
|
|
26
|
-
_ttl:
|
|
27
|
-
|
|
63
|
+
_ttl: Duration | null;
|
|
64
|
+
getDuration: (this: Query<ResultType, DocType, THelpers, RawDocType>) => Duration | null;
|
|
28
65
|
op?: string;
|
|
29
66
|
_path?: unknown;
|
|
30
67
|
_fields?: unknown;
|
|
@@ -32,11 +69,11 @@ declare module 'mongoose' {
|
|
|
32
69
|
_conditions?: unknown;
|
|
33
70
|
}
|
|
34
71
|
interface Aggregate<ResultType> {
|
|
35
|
-
cache: (this: Aggregate<ResultType>, ttl?:
|
|
72
|
+
cache: (this: Aggregate<ResultType>, ttl?: Duration, customKey?: string) => this;
|
|
36
73
|
_key: string | null;
|
|
37
74
|
getCacheKey: (this: Aggregate<ResultType>) => string;
|
|
38
|
-
_ttl:
|
|
39
|
-
|
|
75
|
+
_ttl: Duration | null;
|
|
76
|
+
getDuration: (this: Aggregate<ResultType>) => Duration | null;
|
|
40
77
|
}
|
|
41
78
|
}
|
|
42
79
|
declare class CacheMongoose {
|
|
@@ -49,5 +86,5 @@ declare class CacheMongoose {
|
|
|
49
86
|
}
|
|
50
87
|
|
|
51
88
|
export { CacheMongoose as default };
|
|
52
|
-
export type { CacheData, CacheEngine, CacheOptions,
|
|
89
|
+
export type { CacheData, CacheEngine, CacheOptions, Duration };
|
|
53
90
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sources":["../src/types.ts","../src/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.cts","sources":["../src/ms.ts","../src/types.ts","../src/index.ts"],"mappings":";;;AAQA,cAAa,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCZ,KAAM,IAAI,gBAAgB,KAAK;AAE/B,KAAM,QAAQ,sCAAsC,IAAI,kBAAkB,IAAI;;AC1C9E,KAAM,SAAS,GAAG,MAAM,oBAAoB,MAAM;AAElD,KAAM,YAAY;;oBAEN,YAAY;iBACf,QAAQ;;;AAIjB,UAAW,WAAW;0BACJ,OAAO,CAAC,SAAS,IAAI,SAAS;8BAC1B,SAAS,QAAQ,QAAQ,KAAK,OAAO;0BACzC,OAAO;iBAChB,OAAO;iBACP,OAAO;;;ACVtB;;8EAE0E,QAAQ;;;cAGxE,QAAQ;iFAC2D,QAAQ;;;;;;;;mDAStC,QAAQ;;;cAG7C,QAAQ;sDACgC,QAAQ;;;AAI1D,cAAM,aAAa;;;;0BAQY,QAAQ,gBAAgB,YAAY,GAAG,aAAa;+BAczC,OAAO;aAQzB,OAAO","names":[]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,18 +1,55 @@
|
|
|
1
1
|
import { Mongoose } from 'mongoose';
|
|
2
2
|
import { RedisOptions } from 'ioredis';
|
|
3
|
-
import { StringValue } from 'ms';
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
declare const UNITS: {
|
|
5
|
+
readonly milliseconds: 1;
|
|
6
|
+
readonly millisecond: 1;
|
|
7
|
+
readonly msecs: 1;
|
|
8
|
+
readonly msec: 1;
|
|
9
|
+
readonly ms: 1;
|
|
10
|
+
readonly seconds: 1000;
|
|
11
|
+
readonly second: 1000;
|
|
12
|
+
readonly secs: 1000;
|
|
13
|
+
readonly sec: 1000;
|
|
14
|
+
readonly s: 1000;
|
|
15
|
+
readonly minutes: number;
|
|
16
|
+
readonly minute: number;
|
|
17
|
+
readonly mins: number;
|
|
18
|
+
readonly min: number;
|
|
19
|
+
readonly m: number;
|
|
20
|
+
readonly hours: number;
|
|
21
|
+
readonly hour: number;
|
|
22
|
+
readonly hrs: number;
|
|
23
|
+
readonly hr: number;
|
|
24
|
+
readonly h: number;
|
|
25
|
+
readonly days: number;
|
|
26
|
+
readonly day: number;
|
|
27
|
+
readonly d: number;
|
|
28
|
+
readonly weeks: number;
|
|
29
|
+
readonly week: number;
|
|
30
|
+
readonly w: number;
|
|
31
|
+
readonly months: number;
|
|
32
|
+
readonly month: number;
|
|
33
|
+
readonly mo: number;
|
|
34
|
+
readonly years: number;
|
|
35
|
+
readonly year: number;
|
|
36
|
+
readonly yrs: number;
|
|
37
|
+
readonly yr: number;
|
|
38
|
+
readonly y: number;
|
|
39
|
+
};
|
|
40
|
+
type Unit = keyof typeof UNITS;
|
|
41
|
+
type Duration = number | `${number}` | `${number}${Unit}` | `${number} ${Unit}`;
|
|
42
|
+
|
|
6
43
|
type CacheData = Record<string, unknown> | Record<string, unknown>[] | unknown[] | number | undefined;
|
|
7
44
|
type CacheOptions = {
|
|
8
45
|
engine: 'memory' | 'redis';
|
|
9
46
|
engineOptions?: RedisOptions;
|
|
10
|
-
defaultTTL?:
|
|
47
|
+
defaultTTL?: Duration;
|
|
11
48
|
debug?: boolean;
|
|
12
49
|
};
|
|
13
50
|
interface CacheEngine {
|
|
14
51
|
get: (key: string) => Promise<CacheData> | CacheData;
|
|
15
|
-
set: (key: string, value: CacheData, ttl?:
|
|
52
|
+
set: (key: string, value: CacheData, ttl?: Duration) => Promise<void> | void;
|
|
16
53
|
del: (key: string) => Promise<void> | void;
|
|
17
54
|
clear: () => Promise<void> | void;
|
|
18
55
|
close: () => Promise<void> | void;
|
|
@@ -20,11 +57,11 @@ interface CacheEngine {
|
|
|
20
57
|
|
|
21
58
|
declare module 'mongoose' {
|
|
22
59
|
interface Query<ResultType, DocType, THelpers, RawDocType> {
|
|
23
|
-
cache: (this: Query<ResultType, DocType, THelpers, RawDocType>, ttl?:
|
|
60
|
+
cache: (this: Query<ResultType, DocType, THelpers, RawDocType>, ttl?: Duration, customKey?: string) => this;
|
|
24
61
|
_key: string | null;
|
|
25
62
|
getCacheKey: (this: Query<ResultType, DocType, THelpers, RawDocType>) => string;
|
|
26
|
-
_ttl:
|
|
27
|
-
|
|
63
|
+
_ttl: Duration | null;
|
|
64
|
+
getDuration: (this: Query<ResultType, DocType, THelpers, RawDocType>) => Duration | null;
|
|
28
65
|
op?: string;
|
|
29
66
|
_path?: unknown;
|
|
30
67
|
_fields?: unknown;
|
|
@@ -32,11 +69,11 @@ declare module 'mongoose' {
|
|
|
32
69
|
_conditions?: unknown;
|
|
33
70
|
}
|
|
34
71
|
interface Aggregate<ResultType> {
|
|
35
|
-
cache: (this: Aggregate<ResultType>, ttl?:
|
|
72
|
+
cache: (this: Aggregate<ResultType>, ttl?: Duration, customKey?: string) => this;
|
|
36
73
|
_key: string | null;
|
|
37
74
|
getCacheKey: (this: Aggregate<ResultType>) => string;
|
|
38
|
-
_ttl:
|
|
39
|
-
|
|
75
|
+
_ttl: Duration | null;
|
|
76
|
+
getDuration: (this: Aggregate<ResultType>) => Duration | null;
|
|
40
77
|
}
|
|
41
78
|
}
|
|
42
79
|
declare class CacheMongoose {
|
|
@@ -49,5 +86,5 @@ declare class CacheMongoose {
|
|
|
49
86
|
}
|
|
50
87
|
|
|
51
88
|
export { CacheMongoose as default };
|
|
52
|
-
export type { CacheData, CacheEngine, CacheOptions,
|
|
89
|
+
export type { CacheData, CacheEngine, CacheOptions, Duration };
|
|
53
90
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sources":["../src/types.ts","../src/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","sources":["../src/ms.ts","../src/types.ts","../src/index.ts"],"mappings":";;;AAQA,cAAa,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCZ,KAAM,IAAI,gBAAgB,KAAK;AAE/B,KAAM,QAAQ,sCAAsC,IAAI,kBAAkB,IAAI;;AC1C9E,KAAM,SAAS,GAAG,MAAM,oBAAoB,MAAM;AAElD,KAAM,YAAY;;oBAEN,YAAY;iBACf,QAAQ;;;AAIjB,UAAW,WAAW;0BACJ,OAAO,CAAC,SAAS,IAAI,SAAS;8BAC1B,SAAS,QAAQ,QAAQ,KAAK,OAAO;0BACzC,OAAO;iBAChB,OAAO;iBACP,OAAO;;;ACVtB;;8EAE0E,QAAQ;;;cAGxE,QAAQ;iFAC2D,QAAQ;;;;;;;;mDAStC,QAAQ;;;cAG7C,QAAQ;sDACgC,QAAQ;;;AAI1D,cAAM,aAAa;;;;0BAQY,QAAQ,gBAAgB,YAAY,GAAG,aAAa;+BAczC,OAAO;aAQzB,OAAO","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,26 +1,70 @@
|
|
|
1
|
-
import ms from 'ms';
|
|
2
1
|
import { EJSON } from 'bson';
|
|
3
2
|
import IORedis from 'ioredis';
|
|
4
3
|
import mongoose from 'mongoose';
|
|
5
|
-
import { satisfies } from 'semver';
|
|
6
4
|
import { createHash } from 'node:crypto';
|
|
7
|
-
import sortKeys from 'sort-keys';
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
const s = 1e3;
|
|
7
|
+
const m = s * 60;
|
|
8
|
+
const h = m * 60;
|
|
9
|
+
const d = h * 24;
|
|
10
|
+
const w = d * 7;
|
|
11
|
+
const y = d * 365.25;
|
|
12
|
+
const mo = y / 12;
|
|
13
|
+
const UNITS = {
|
|
14
|
+
milliseconds: 1,
|
|
15
|
+
millisecond: 1,
|
|
16
|
+
msecs: 1,
|
|
17
|
+
msec: 1,
|
|
18
|
+
ms: 1,
|
|
19
|
+
seconds: s,
|
|
20
|
+
second: s,
|
|
21
|
+
secs: s,
|
|
22
|
+
sec: s,
|
|
23
|
+
s,
|
|
24
|
+
minutes: m,
|
|
25
|
+
minute: m,
|
|
26
|
+
mins: m,
|
|
27
|
+
min: m,
|
|
28
|
+
m,
|
|
29
|
+
hours: h,
|
|
30
|
+
hour: h,
|
|
31
|
+
hrs: h,
|
|
32
|
+
hr: h,
|
|
33
|
+
h,
|
|
34
|
+
days: d,
|
|
35
|
+
day: d,
|
|
36
|
+
d,
|
|
37
|
+
weeks: w,
|
|
38
|
+
week: w,
|
|
39
|
+
w,
|
|
40
|
+
months: mo,
|
|
41
|
+
month: mo,
|
|
42
|
+
mo,
|
|
43
|
+
years: y,
|
|
44
|
+
year: y,
|
|
45
|
+
yrs: y,
|
|
46
|
+
yr: y,
|
|
47
|
+
y
|
|
11
48
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
49
|
+
const unitPattern = Object.keys(UNITS).sort((a, b) => b.length - a.length).join("|");
|
|
50
|
+
const RE = new RegExp(String.raw`^(-?(?:\d+)?\.?\d+)\s*(${unitPattern})?$`, "i");
|
|
51
|
+
const ms = (val) => {
|
|
52
|
+
const str = String(val);
|
|
53
|
+
if (str.length > 100) return Number.NaN;
|
|
54
|
+
const match = RE.exec(str);
|
|
55
|
+
if (!match) return Number.NaN;
|
|
56
|
+
const n = Number.parseFloat(match[1] ?? "");
|
|
57
|
+
const type = (match[2] ?? "ms").toLowerCase();
|
|
58
|
+
return n * (UNITS[type] ?? 0);
|
|
59
|
+
};
|
|
60
|
+
|
|
17
61
|
class MemoryCacheEngine {
|
|
62
|
+
#cache;
|
|
18
63
|
constructor() {
|
|
19
|
-
|
|
20
|
-
__privateSet$3(this, _cache, /* @__PURE__ */ new Map());
|
|
64
|
+
this.#cache = /* @__PURE__ */ new Map();
|
|
21
65
|
}
|
|
22
66
|
get(key) {
|
|
23
|
-
const item =
|
|
67
|
+
const item = this.#cache.get(key);
|
|
24
68
|
if (!item || item.expiresAt < Date.now()) {
|
|
25
69
|
this.del(key);
|
|
26
70
|
return void 0;
|
|
@@ -28,25 +72,24 @@ class MemoryCacheEngine {
|
|
|
28
72
|
return item.value;
|
|
29
73
|
}
|
|
30
74
|
set(key, value, ttl) {
|
|
31
|
-
const givenTTL =
|
|
75
|
+
const givenTTL = ttl == null ? void 0 : ms(ttl);
|
|
32
76
|
const actualTTL = givenTTL ?? Number.POSITIVE_INFINITY;
|
|
33
|
-
|
|
77
|
+
this.#cache.set(key, {
|
|
34
78
|
value,
|
|
35
79
|
expiresAt: Date.now() + actualTTL
|
|
36
80
|
});
|
|
37
81
|
}
|
|
38
82
|
del(key) {
|
|
39
|
-
|
|
83
|
+
this.#cache.delete(key);
|
|
40
84
|
}
|
|
41
85
|
clear() {
|
|
42
|
-
|
|
86
|
+
this.#cache.clear();
|
|
43
87
|
}
|
|
44
88
|
close() {
|
|
45
89
|
}
|
|
46
90
|
}
|
|
47
|
-
_cache = new WeakMap();
|
|
48
91
|
|
|
49
|
-
const isMongooseLessThan7 =
|
|
92
|
+
const isMongooseLessThan7 = Number.parseInt(mongoose.version, 10) < 7;
|
|
50
93
|
const convertToObject = (value) => {
|
|
51
94
|
if (isMongooseLessThan7) {
|
|
52
95
|
if (value != null && typeof value === "object" && !Array.isArray(value) && value.toObject) {
|
|
@@ -59,23 +102,15 @@ const convertToObject = (value) => {
|
|
|
59
102
|
return value;
|
|
60
103
|
};
|
|
61
104
|
|
|
62
|
-
var __typeError$2 = (msg) => {
|
|
63
|
-
throw TypeError(msg);
|
|
64
|
-
};
|
|
65
|
-
var __accessCheck$2 = (obj, member, msg) => member.has(obj) || __typeError$2("Cannot " + msg);
|
|
66
|
-
var __privateGet$2 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
67
|
-
var __privateAdd$2 = (obj, member, value) => member.has(obj) ? __typeError$2("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
68
|
-
var __privateSet$2 = (obj, member, value, setter) => (__accessCheck$2(obj, member, "write to private field"), member.set(obj, value), value);
|
|
69
|
-
var _client;
|
|
70
105
|
class RedisCacheEngine {
|
|
106
|
+
#client;
|
|
71
107
|
constructor(options) {
|
|
72
|
-
__privateAdd$2(this, _client);
|
|
73
108
|
options.keyPrefix ??= "cache-mongoose:";
|
|
74
|
-
|
|
109
|
+
this.#client = new IORedis(options);
|
|
75
110
|
}
|
|
76
111
|
async get(key) {
|
|
77
112
|
try {
|
|
78
|
-
const value = await
|
|
113
|
+
const value = await this.#client.get(key);
|
|
79
114
|
if (value === null) {
|
|
80
115
|
return void 0;
|
|
81
116
|
}
|
|
@@ -87,95 +122,116 @@ class RedisCacheEngine {
|
|
|
87
122
|
}
|
|
88
123
|
async set(key, value, ttl) {
|
|
89
124
|
try {
|
|
90
|
-
const givenTTL =
|
|
125
|
+
const givenTTL = ttl == null ? void 0 : ms(ttl);
|
|
91
126
|
const actualTTL = givenTTL ?? Number.POSITIVE_INFINITY;
|
|
92
127
|
const serializedValue = EJSON.stringify(convertToObject(value));
|
|
93
|
-
await
|
|
128
|
+
await this.#client.setex(key, Math.ceil(actualTTL / 1e3), serializedValue);
|
|
94
129
|
} catch (err) {
|
|
95
130
|
console.error(err);
|
|
96
131
|
}
|
|
97
132
|
}
|
|
98
133
|
async del(key) {
|
|
99
|
-
await
|
|
134
|
+
await this.#client.del(key);
|
|
100
135
|
}
|
|
101
136
|
async clear() {
|
|
102
|
-
await
|
|
137
|
+
await this.#client.flushdb();
|
|
103
138
|
}
|
|
104
139
|
async close() {
|
|
105
|
-
await
|
|
140
|
+
await this.#client.quit();
|
|
106
141
|
}
|
|
107
142
|
}
|
|
108
|
-
_client = new WeakMap();
|
|
109
143
|
|
|
110
|
-
var __typeError$1 = (msg) => {
|
|
111
|
-
throw TypeError(msg);
|
|
112
|
-
};
|
|
113
|
-
var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
|
|
114
|
-
var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
115
|
-
var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
116
|
-
var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
|
|
117
|
-
var _engine, _defaultTTL, _debug, _engines;
|
|
118
144
|
class Cache {
|
|
145
|
+
#engine;
|
|
146
|
+
#defaultTTL;
|
|
147
|
+
#debug;
|
|
148
|
+
#engines = ["memory", "redis"];
|
|
119
149
|
constructor(cacheOptions) {
|
|
120
|
-
|
|
121
|
-
__privateAdd$1(this, _defaultTTL);
|
|
122
|
-
__privateAdd$1(this, _debug);
|
|
123
|
-
__privateAdd$1(this, _engines, ["memory", "redis"]);
|
|
124
|
-
if (!__privateGet$1(this, _engines).includes(cacheOptions.engine)) {
|
|
150
|
+
if (!this.#engines.includes(cacheOptions.engine)) {
|
|
125
151
|
throw new Error(`Invalid engine name: ${cacheOptions.engine}`);
|
|
126
152
|
}
|
|
127
153
|
if (cacheOptions.engine === "redis" && !cacheOptions.engineOptions) {
|
|
128
154
|
throw new Error(`Engine options are required for ${cacheOptions.engine} engine`);
|
|
129
155
|
}
|
|
130
156
|
cacheOptions.defaultTTL ??= "1 minute";
|
|
131
|
-
|
|
157
|
+
this.#defaultTTL = ms(cacheOptions.defaultTTL);
|
|
132
158
|
if (cacheOptions.engine === "redis" && cacheOptions.engineOptions) {
|
|
133
|
-
|
|
159
|
+
this.#engine = new RedisCacheEngine(cacheOptions.engineOptions);
|
|
134
160
|
}
|
|
135
161
|
if (cacheOptions.engine === "memory") {
|
|
136
|
-
|
|
162
|
+
this.#engine = new MemoryCacheEngine();
|
|
137
163
|
}
|
|
138
|
-
|
|
164
|
+
this.#debug = cacheOptions.debug === true;
|
|
139
165
|
}
|
|
140
166
|
async get(key) {
|
|
141
|
-
const cacheEntry = await
|
|
142
|
-
if (
|
|
167
|
+
const cacheEntry = await this.#engine.get(key);
|
|
168
|
+
if (this.#debug) {
|
|
143
169
|
const cacheHit = cacheEntry == null ? "MISS" : "HIT";
|
|
144
170
|
console.log(`[ts-cache-mongoose] GET '${key}' - ${cacheHit}`);
|
|
145
171
|
}
|
|
146
172
|
return cacheEntry;
|
|
147
173
|
}
|
|
148
174
|
async set(key, value, ttl) {
|
|
149
|
-
const givenTTL =
|
|
150
|
-
const actualTTL = givenTTL ??
|
|
151
|
-
await
|
|
152
|
-
if (
|
|
175
|
+
const givenTTL = ttl == null ? null : ms(ttl);
|
|
176
|
+
const actualTTL = givenTTL ?? this.#defaultTTL;
|
|
177
|
+
await this.#engine.set(key, value, actualTTL);
|
|
178
|
+
if (this.#debug) {
|
|
153
179
|
console.log(`[ts-cache-mongoose] SET '${key}' - ttl: ${actualTTL.toFixed(0)} ms`);
|
|
154
180
|
}
|
|
155
181
|
}
|
|
156
182
|
async del(key) {
|
|
157
|
-
await
|
|
158
|
-
if (
|
|
183
|
+
await this.#engine.del(key);
|
|
184
|
+
if (this.#debug) {
|
|
159
185
|
console.log(`[ts-cache-mongoose] DEL '${key}'`);
|
|
160
186
|
}
|
|
161
187
|
}
|
|
162
188
|
async clear() {
|
|
163
|
-
await
|
|
164
|
-
if (
|
|
189
|
+
await this.#engine.clear();
|
|
190
|
+
if (this.#debug) {
|
|
165
191
|
console.log("[ts-cache-mongoose] CLEAR");
|
|
166
192
|
}
|
|
167
193
|
}
|
|
168
194
|
async close() {
|
|
169
|
-
return
|
|
195
|
+
return this.#engine.close();
|
|
170
196
|
}
|
|
171
197
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
198
|
+
|
|
199
|
+
const isPlainObject = (value) => {
|
|
200
|
+
if (typeof value !== "object" || value === null) return false;
|
|
201
|
+
const proto = Object.getPrototypeOf(value);
|
|
202
|
+
return proto === Object.prototype || proto === null;
|
|
203
|
+
};
|
|
204
|
+
const sortKeys = (input) => {
|
|
205
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
206
|
+
const sortObject = (obj) => {
|
|
207
|
+
if (seen.has(obj)) return obj;
|
|
208
|
+
seen.add(obj);
|
|
209
|
+
const sorted = {};
|
|
210
|
+
for (const key of Object.keys(obj).sort((a, b) => a.localeCompare(b))) {
|
|
211
|
+
const value = obj[key];
|
|
212
|
+
if (Array.isArray(value)) {
|
|
213
|
+
sorted[key] = sortArray(value);
|
|
214
|
+
} else if (isPlainObject(value)) {
|
|
215
|
+
sorted[key] = sortObject(value);
|
|
216
|
+
} else {
|
|
217
|
+
sorted[key] = value;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return sorted;
|
|
221
|
+
};
|
|
222
|
+
const sortArray = (arr) => {
|
|
223
|
+
return arr.map((item) => {
|
|
224
|
+
if (Array.isArray(item)) return sortArray(item);
|
|
225
|
+
if (isPlainObject(item)) return sortObject(item);
|
|
226
|
+
return item;
|
|
227
|
+
});
|
|
228
|
+
};
|
|
229
|
+
if (Array.isArray(input)) return sortArray(input);
|
|
230
|
+
return sortObject(input);
|
|
231
|
+
};
|
|
176
232
|
|
|
177
233
|
function getKey(data) {
|
|
178
|
-
const sortedObj = sortKeys(data
|
|
234
|
+
const sortedObj = sortKeys(data);
|
|
179
235
|
const sortedStr = JSON.stringify(sortedObj, (_, val) => {
|
|
180
236
|
return val instanceof RegExp ? String(val) : val;
|
|
181
237
|
});
|
|
@@ -190,7 +246,7 @@ function extendAggregate(mongoose, cache) {
|
|
|
190
246
|
pipeline: this.pipeline()
|
|
191
247
|
});
|
|
192
248
|
};
|
|
193
|
-
mongoose.Aggregate.prototype.
|
|
249
|
+
mongoose.Aggregate.prototype.getDuration = function() {
|
|
194
250
|
return this._ttl;
|
|
195
251
|
};
|
|
196
252
|
mongoose.Aggregate.prototype.cache = function(ttl, customKey) {
|
|
@@ -199,11 +255,11 @@ function extendAggregate(mongoose, cache) {
|
|
|
199
255
|
return this;
|
|
200
256
|
};
|
|
201
257
|
mongoose.Aggregate.prototype.exec = async function(...args) {
|
|
202
|
-
if (!Object.
|
|
258
|
+
if (!Object.hasOwn(this, "_ttl")) {
|
|
203
259
|
return mongooseExec.apply(this, args);
|
|
204
260
|
}
|
|
205
261
|
const key = this.getCacheKey();
|
|
206
|
-
const ttl = this.
|
|
262
|
+
const ttl = this.getDuration();
|
|
207
263
|
const resultCache = await cache.get(key).catch((err) => {
|
|
208
264
|
console.error(err);
|
|
209
265
|
});
|
|
@@ -239,7 +295,7 @@ function extendQuery(mongoose, cache) {
|
|
|
239
295
|
_conditions: this._conditions
|
|
240
296
|
});
|
|
241
297
|
};
|
|
242
|
-
mongoose.Query.prototype.
|
|
298
|
+
mongoose.Query.prototype.getDuration = function() {
|
|
243
299
|
return this._ttl;
|
|
244
300
|
};
|
|
245
301
|
mongoose.Query.prototype.cache = function(ttl, customKey) {
|
|
@@ -248,11 +304,11 @@ function extendQuery(mongoose, cache) {
|
|
|
248
304
|
return this;
|
|
249
305
|
};
|
|
250
306
|
mongoose.Query.prototype.exec = async function(...args) {
|
|
251
|
-
if (!Object.
|
|
307
|
+
if (!Object.hasOwn(this, "_ttl")) {
|
|
252
308
|
return mongooseExec.apply(this, args);
|
|
253
309
|
}
|
|
254
310
|
const key = this.getCacheKey();
|
|
255
|
-
const ttl = this.
|
|
311
|
+
const ttl = this.getDuration();
|
|
256
312
|
const mongooseOptions = this.mongooseOptions();
|
|
257
313
|
const isCount = this.op?.includes("count") ?? false;
|
|
258
314
|
const isDistinct = this.op === "distinct";
|
|
@@ -280,26 +336,20 @@ function extendQuery(mongoose, cache) {
|
|
|
280
336
|
};
|
|
281
337
|
}
|
|
282
338
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
287
|
-
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
288
|
-
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
289
|
-
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
|
|
290
|
-
var _instance;
|
|
291
|
-
const _CacheMongoose = class _CacheMongoose {
|
|
339
|
+
class CacheMongoose {
|
|
340
|
+
static #instance;
|
|
341
|
+
cache;
|
|
292
342
|
constructor() {
|
|
293
343
|
}
|
|
294
344
|
static init(mongoose, cacheOptions) {
|
|
295
|
-
if (!
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const cache =
|
|
345
|
+
if (!CacheMongoose.#instance) {
|
|
346
|
+
CacheMongoose.#instance = new CacheMongoose();
|
|
347
|
+
CacheMongoose.#instance.cache = new Cache(cacheOptions);
|
|
348
|
+
const cache = CacheMongoose.#instance.cache;
|
|
299
349
|
extendQuery(mongoose, cache);
|
|
300
350
|
extendAggregate(mongoose, cache);
|
|
301
351
|
}
|
|
302
|
-
return
|
|
352
|
+
return CacheMongoose.#instance;
|
|
303
353
|
}
|
|
304
354
|
async clear(customKey) {
|
|
305
355
|
if (customKey == null) {
|
|
@@ -311,9 +361,6 @@ const _CacheMongoose = class _CacheMongoose {
|
|
|
311
361
|
async close() {
|
|
312
362
|
await this.cache.close();
|
|
313
363
|
}
|
|
314
|
-
}
|
|
315
|
-
_instance = new WeakMap();
|
|
316
|
-
__privateAdd(_CacheMongoose, _instance);
|
|
317
|
-
let CacheMongoose = _CacheMongoose;
|
|
364
|
+
}
|
|
318
365
|
|
|
319
366
|
export { CacheMongoose as default };
|