ts-cache-mongoose 2.0.0 → 2.2.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.d.cts CHANGED
@@ -1,17 +1,59 @@
1
1
  import { Mongoose } from 'mongoose';
2
2
  import { RedisOptions } from 'ioredis';
3
3
 
4
- type CacheTTL = number | string;
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
+
5
43
  type CacheData = Record<string, unknown> | Record<string, unknown>[] | unknown[] | number | undefined;
6
44
  type CacheOptions = {
7
45
  engine: 'memory' | 'redis';
8
46
  engineOptions?: RedisOptions;
9
- defaultTTL?: CacheTTL;
47
+ defaultTTL?: Duration;
10
48
  debug?: boolean;
49
+ onError?: (error: Error) => void;
50
+ maxEntries?: number;
51
+ maxBytes?: number;
52
+ sizeCalculation?: (value: CacheData) => number;
11
53
  };
12
54
  interface CacheEngine {
13
55
  get: (key: string) => Promise<CacheData> | CacheData;
14
- set: (key: string, value: CacheData, ttl?: CacheTTL) => Promise<void> | void;
56
+ set: (key: string, value: CacheData, ttl?: Duration) => Promise<void> | void;
15
57
  del: (key: string) => Promise<void> | void;
16
58
  clear: () => Promise<void> | void;
17
59
  close: () => Promise<void> | void;
@@ -19,11 +61,11 @@ interface CacheEngine {
19
61
 
20
62
  declare module 'mongoose' {
21
63
  interface Query<ResultType, DocType, THelpers, RawDocType> {
22
- cache: (this: Query<ResultType, DocType, THelpers, RawDocType>, ttl?: CacheTTL, customKey?: string) => this;
64
+ cache: (this: Query<ResultType, DocType, THelpers, RawDocType>, ttl?: Duration, customKey?: string) => this;
23
65
  _key: string | null;
24
66
  getCacheKey: (this: Query<ResultType, DocType, THelpers, RawDocType>) => string;
25
- _ttl: CacheTTL | null;
26
- getCacheTTL: (this: Query<ResultType, DocType, THelpers, RawDocType>) => CacheTTL | null;
67
+ _ttl: Duration | null;
68
+ getDuration: (this: Query<ResultType, DocType, THelpers, RawDocType>) => Duration | null;
27
69
  op?: string;
28
70
  _path?: unknown;
29
71
  _fields?: unknown;
@@ -31,11 +73,11 @@ declare module 'mongoose' {
31
73
  _conditions?: unknown;
32
74
  }
33
75
  interface Aggregate<ResultType> {
34
- cache: (this: Aggregate<ResultType>, ttl?: CacheTTL, customKey?: string) => this;
76
+ cache: (this: Aggregate<ResultType>, ttl?: Duration, customKey?: string) => this;
35
77
  _key: string | null;
36
78
  getCacheKey: (this: Aggregate<ResultType>) => string;
37
- _ttl: CacheTTL | null;
38
- getCacheTTL: (this: Aggregate<ResultType>) => CacheTTL | null;
79
+ _ttl: Duration | null;
80
+ getDuration: (this: Aggregate<ResultType>) => Duration | null;
39
81
  }
40
82
  }
41
83
  declare class CacheMongoose {
@@ -48,5 +90,5 @@ declare class CacheMongoose {
48
90
  }
49
91
 
50
92
  export { CacheMongoose as default };
51
- export type { CacheData, CacheEngine, CacheOptions, CacheTTL };
93
+ export type { CacheData, CacheEngine, CacheOptions, Duration };
52
94
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","sources":["../src/types.ts","../src/index.ts"],"mappings":";;;AAEM,KAAM,QAAQ;AAEd,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;;;ACTtB;;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":[]}
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;;sBAEH,KAAK;;;8BAGG,SAAS;;AAG/B,UAAW,WAAW;0BACJ,OAAO,CAAC,SAAS,IAAI,SAAS;8BAC1B,SAAS,QAAQ,QAAQ,KAAK,OAAO;0BACzC,OAAO;iBAChB,OAAO;iBACP,OAAO;;;ACdtB;;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,17 +1,59 @@
1
1
  import { Mongoose } from 'mongoose';
2
2
  import { RedisOptions } from 'ioredis';
3
3
 
4
- type CacheTTL = number | string;
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
+
5
43
  type CacheData = Record<string, unknown> | Record<string, unknown>[] | unknown[] | number | undefined;
6
44
  type CacheOptions = {
7
45
  engine: 'memory' | 'redis';
8
46
  engineOptions?: RedisOptions;
9
- defaultTTL?: CacheTTL;
47
+ defaultTTL?: Duration;
10
48
  debug?: boolean;
49
+ onError?: (error: Error) => void;
50
+ maxEntries?: number;
51
+ maxBytes?: number;
52
+ sizeCalculation?: (value: CacheData) => number;
11
53
  };
12
54
  interface CacheEngine {
13
55
  get: (key: string) => Promise<CacheData> | CacheData;
14
- set: (key: string, value: CacheData, ttl?: CacheTTL) => Promise<void> | void;
56
+ set: (key: string, value: CacheData, ttl?: Duration) => Promise<void> | void;
15
57
  del: (key: string) => Promise<void> | void;
16
58
  clear: () => Promise<void> | void;
17
59
  close: () => Promise<void> | void;
@@ -19,11 +61,11 @@ interface CacheEngine {
19
61
 
20
62
  declare module 'mongoose' {
21
63
  interface Query<ResultType, DocType, THelpers, RawDocType> {
22
- cache: (this: Query<ResultType, DocType, THelpers, RawDocType>, ttl?: CacheTTL, customKey?: string) => this;
64
+ cache: (this: Query<ResultType, DocType, THelpers, RawDocType>, ttl?: Duration, customKey?: string) => this;
23
65
  _key: string | null;
24
66
  getCacheKey: (this: Query<ResultType, DocType, THelpers, RawDocType>) => string;
25
- _ttl: CacheTTL | null;
26
- getCacheTTL: (this: Query<ResultType, DocType, THelpers, RawDocType>) => CacheTTL | null;
67
+ _ttl: Duration | null;
68
+ getDuration: (this: Query<ResultType, DocType, THelpers, RawDocType>) => Duration | null;
27
69
  op?: string;
28
70
  _path?: unknown;
29
71
  _fields?: unknown;
@@ -31,11 +73,11 @@ declare module 'mongoose' {
31
73
  _conditions?: unknown;
32
74
  }
33
75
  interface Aggregate<ResultType> {
34
- cache: (this: Aggregate<ResultType>, ttl?: CacheTTL, customKey?: string) => this;
76
+ cache: (this: Aggregate<ResultType>, ttl?: Duration, customKey?: string) => this;
35
77
  _key: string | null;
36
78
  getCacheKey: (this: Aggregate<ResultType>) => string;
37
- _ttl: CacheTTL | null;
38
- getCacheTTL: (this: Aggregate<ResultType>) => CacheTTL | null;
79
+ _ttl: Duration | null;
80
+ getDuration: (this: Aggregate<ResultType>) => Duration | null;
39
81
  }
40
82
  }
41
83
  declare class CacheMongoose {
@@ -48,5 +90,5 @@ declare class CacheMongoose {
48
90
  }
49
91
 
50
92
  export { CacheMongoose as default };
51
- export type { CacheData, CacheEngine, CacheOptions, CacheTTL };
93
+ export type { CacheData, CacheEngine, CacheOptions, Duration };
52
94
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sources":["../src/types.ts","../src/index.ts"],"mappings":";;;AAEM,KAAM,QAAQ;AAEd,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;;;ACTtB;;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":[]}
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;;sBAEH,KAAK;;;8BAGG,SAAS;;AAG/B,UAAW,WAAW;0BACJ,OAAO,CAAC,SAAS,IAAI,SAAS;8BAC1B,SAAS,QAAQ,QAAQ,KAAK,OAAO;0BACzC,OAAO;iBAChB,OAAO;iBACP,OAAO;;;ACdtB;;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,3 +1,4 @@
1
+ import { serialize } from 'node:v8';
1
2
  import { EJSON } from 'bson';
2
3
  import IORedis from 'ioredis';
3
4
  import mongoose from 'mongoose';
@@ -9,89 +10,119 @@ const h = m * 60;
9
10
  const d = h * 24;
10
11
  const w = d * 7;
11
12
  const y = d * 365.25;
12
- const RE = /^(-?(?:\d+)?\.?\d+)\s*(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i;
13
+ const mo = y / 12;
13
14
  const UNITS = {
14
- years: y,
15
- year: y,
16
- yrs: y,
17
- yr: y,
18
- y,
19
- weeks: w,
20
- week: w,
21
- w,
22
- days: d,
23
- day: d,
24
- d,
25
- hours: h,
26
- hour: h,
27
- hrs: h,
28
- hr: h,
29
- h,
30
- minutes: m,
31
- minute: m,
32
- mins: m,
33
- min: m,
34
- m,
15
+ milliseconds: 1,
16
+ millisecond: 1,
17
+ msecs: 1,
18
+ msec: 1,
19
+ ms: 1,
35
20
  seconds: s,
36
21
  second: s,
37
22
  secs: s,
38
23
  sec: s,
39
24
  s,
40
- milliseconds: 1,
41
- millisecond: 1,
42
- msecs: 1,
43
- msec: 1,
44
- ms: 1
25
+ minutes: m,
26
+ minute: m,
27
+ mins: m,
28
+ min: m,
29
+ m,
30
+ hours: h,
31
+ hour: h,
32
+ hrs: h,
33
+ hr: h,
34
+ h,
35
+ days: d,
36
+ day: d,
37
+ d,
38
+ weeks: w,
39
+ week: w,
40
+ w,
41
+ months: mo,
42
+ month: mo,
43
+ mo,
44
+ years: y,
45
+ year: y,
46
+ yrs: y,
47
+ yr: y,
48
+ y
45
49
  };
50
+ const unitPattern = Object.keys(UNITS).sort((a, b) => b.length - a.length).join("|");
51
+ const RE = new RegExp(String.raw`^(-?(?:\d+)?\.?\d+)\s*(${unitPattern})?$`, "i");
46
52
  const ms = (val) => {
47
53
  const str = String(val);
48
- if (str.length > 100) return 0;
54
+ if (str.length > 100) return Number.NaN;
49
55
  const match = RE.exec(str);
50
- if (!match) return 0;
56
+ if (!match) return Number.NaN;
51
57
  const n = Number.parseFloat(match[1] ?? "");
52
58
  const type = (match[2] ?? "ms").toLowerCase();
53
59
  return n * (UNITS[type] ?? 0);
54
60
  };
55
61
 
56
- var __typeError$3 = (msg) => {
57
- throw TypeError(msg);
58
- };
59
- var __accessCheck$3 = (obj, member, msg) => member.has(obj) || __typeError$3("Cannot " + msg);
60
- var __privateGet$3 = (obj, member, getter) => (__accessCheck$3(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
61
- var __privateAdd$3 = (obj, member, value) => member.has(obj) ? __typeError$3("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
62
- var __privateSet$3 = (obj, member, value, setter) => (__accessCheck$3(obj, member, "write to private field"), member.set(obj, value), value);
63
- var _cache;
62
+ const defaultSizer = (value) => serialize(value).byteLength;
64
63
  class MemoryCacheEngine {
65
- constructor() {
66
- __privateAdd$3(this, _cache);
67
- __privateSet$3(this, _cache, /* @__PURE__ */ new Map());
64
+ #cache;
65
+ #maxEntries;
66
+ #maxBytes;
67
+ #sizeOf;
68
+ #totalBytes;
69
+ constructor(options) {
70
+ this.#cache = /* @__PURE__ */ new Map();
71
+ this.#maxEntries = options?.maxEntries != null && options.maxEntries > 0 ? options.maxEntries : Number.POSITIVE_INFINITY;
72
+ this.#maxBytes = options?.maxBytes != null && options.maxBytes > 0 ? options.maxBytes : Number.POSITIVE_INFINITY;
73
+ this.#sizeOf = options?.sizeCalculation ?? defaultSizer;
74
+ this.#totalBytes = 0;
75
+ }
76
+ get totalBytes() {
77
+ return this.#totalBytes;
78
+ }
79
+ get size() {
80
+ return this.#cache.size;
68
81
  }
69
82
  get(key) {
70
- const item = __privateGet$3(this, _cache).get(key);
71
- if (!item || item.expiresAt < Date.now()) {
72
- this.del(key);
83
+ const item = this.#cache.get(key);
84
+ if (!item) return void 0;
85
+ if (item.expiresAt < Date.now()) {
86
+ this.#cache.delete(key);
87
+ this.#totalBytes -= item.bytes;
73
88
  return void 0;
74
89
  }
90
+ this.#cache.delete(key);
91
+ this.#cache.set(key, item);
75
92
  return item.value;
76
93
  }
77
94
  set(key, value, ttl) {
78
- const givenTTL = typeof ttl === "string" ? ms(ttl) : ttl;
95
+ const givenTTL = ttl == null ? void 0 : ms(ttl);
79
96
  const actualTTL = givenTTL ?? Number.POSITIVE_INFINITY;
80
- __privateGet$3(this, _cache).set(key, {
81
- value,
82
- expiresAt: Date.now() + actualTTL
83
- });
97
+ const existing = this.#cache.get(key);
98
+ if (existing) {
99
+ this.#cache.delete(key);
100
+ this.#totalBytes -= existing.bytes;
101
+ }
102
+ const bytes = this.#sizeOf(value);
103
+ this.#cache.set(key, { value, expiresAt: Date.now() + actualTTL, bytes });
104
+ this.#totalBytes += bytes;
105
+ while ((this.#cache.size > this.#maxEntries || this.#totalBytes > this.#maxBytes) && this.#cache.size > 1) {
106
+ const oldestKey = this.#cache.keys().next().value;
107
+ if (oldestKey === void 0 || oldestKey === key) break;
108
+ const oldest = this.#cache.get(oldestKey);
109
+ this.#cache.delete(oldestKey);
110
+ if (oldest) this.#totalBytes -= oldest.bytes;
111
+ }
84
112
  }
85
113
  del(key) {
86
- __privateGet$3(this, _cache).delete(key);
114
+ const item = this.#cache.get(key);
115
+ if (!item) return;
116
+ this.#cache.delete(key);
117
+ this.#totalBytes -= item.bytes;
87
118
  }
88
119
  clear() {
89
- __privateGet$3(this, _cache).clear();
120
+ this.#cache.clear();
121
+ this.#totalBytes = 0;
90
122
  }
91
123
  close() {
92
124
  }
93
125
  }
94
- _cache = new WeakMap();
95
126
 
96
127
  const isMongooseLessThan7 = Number.parseInt(mongoose.version, 10) < 7;
97
128
  const convertToObject = (value) => {
@@ -106,120 +137,120 @@ const convertToObject = (value) => {
106
137
  return value;
107
138
  };
108
139
 
109
- var __typeError$2 = (msg) => {
110
- throw TypeError(msg);
111
- };
112
- var __accessCheck$2 = (obj, member, msg) => member.has(obj) || __typeError$2("Cannot " + msg);
113
- var __privateGet$2 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
114
- 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);
115
- var __privateSet$2 = (obj, member, value, setter) => (__accessCheck$2(obj, member, "write to private field"), member.set(obj, value), value);
116
- var _client;
117
140
  class RedisCacheEngine {
118
- constructor(options) {
119
- __privateAdd$2(this, _client);
141
+ #client;
142
+ #onError;
143
+ constructor(options, onError) {
120
144
  options.keyPrefix ??= "cache-mongoose:";
121
- __privateSet$2(this, _client, new IORedis(options));
145
+ this.#client = new IORedis(options);
146
+ this.#onError = onError;
122
147
  }
123
148
  async get(key) {
124
149
  try {
125
- const value = await __privateGet$2(this, _client).get(key);
150
+ const value = await this.#client.get(key);
126
151
  if (value === null) {
127
152
  return void 0;
128
153
  }
129
154
  return EJSON.parse(value);
130
155
  } catch (err) {
131
- console.error(err);
156
+ this.#onError(err);
132
157
  return void 0;
133
158
  }
134
159
  }
135
160
  async set(key, value, ttl) {
136
161
  try {
137
- const givenTTL = typeof ttl === "string" ? ms(ttl) : ttl;
162
+ const converted = convertToObject(value);
163
+ if (converted === void 0) {
164
+ return;
165
+ }
166
+ const givenTTL = ttl == null ? void 0 : ms(ttl);
138
167
  const actualTTL = givenTTL ?? Number.POSITIVE_INFINITY;
139
- const serializedValue = EJSON.stringify(convertToObject(value));
140
- await __privateGet$2(this, _client).setex(key, Math.ceil(actualTTL / 1e3), serializedValue);
168
+ const serializedValue = EJSON.stringify(converted);
169
+ await this.#client.setex(key, Math.ceil(actualTTL / 1e3), serializedValue);
141
170
  } catch (err) {
142
- console.error(err);
171
+ this.#onError(err);
143
172
  }
144
173
  }
145
174
  async del(key) {
146
- await __privateGet$2(this, _client).del(key);
175
+ await this.#client.del(key);
147
176
  }
148
177
  async clear() {
149
- await __privateGet$2(this, _client).flushdb();
178
+ await this.#client.flushdb();
150
179
  }
151
180
  async close() {
152
- await __privateGet$2(this, _client).quit();
181
+ await this.#client.quit();
153
182
  }
154
183
  }
155
- _client = new WeakMap();
156
184
 
157
- var __typeError$1 = (msg) => {
158
- throw TypeError(msg);
159
- };
160
- var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
161
- var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
162
- 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);
163
- var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
164
- var _engine, _defaultTTL, _debug, _engines;
165
185
  class Cache {
186
+ #engine;
187
+ #defaultTTL;
188
+ #debug;
189
+ #onError;
190
+ #engines = ["memory", "redis"];
166
191
  constructor(cacheOptions) {
167
- __privateAdd$1(this, _engine);
168
- __privateAdd$1(this, _defaultTTL);
169
- __privateAdd$1(this, _debug);
170
- __privateAdd$1(this, _engines, ["memory", "redis"]);
171
- if (!__privateGet$1(this, _engines).includes(cacheOptions.engine)) {
192
+ if (!this.#engines.includes(cacheOptions.engine)) {
172
193
  throw new Error(`Invalid engine name: ${cacheOptions.engine}`);
173
194
  }
174
195
  if (cacheOptions.engine === "redis" && !cacheOptions.engineOptions) {
175
196
  throw new Error(`Engine options are required for ${cacheOptions.engine} engine`);
176
197
  }
177
198
  cacheOptions.defaultTTL ??= "1 minute";
178
- __privateSet$1(this, _defaultTTL, typeof cacheOptions.defaultTTL === "string" ? ms(cacheOptions.defaultTTL) : cacheOptions.defaultTTL);
199
+ this.#defaultTTL = ms(cacheOptions.defaultTTL);
200
+ this.#onError = cacheOptions.onError ?? console.error;
179
201
  if (cacheOptions.engine === "redis" && cacheOptions.engineOptions) {
180
- __privateSet$1(this, _engine, new RedisCacheEngine(cacheOptions.engineOptions));
202
+ this.#engine = new RedisCacheEngine(cacheOptions.engineOptions, this.#onError);
181
203
  }
182
204
  if (cacheOptions.engine === "memory") {
183
- __privateSet$1(this, _engine, new MemoryCacheEngine());
205
+ this.#engine = new MemoryCacheEngine({
206
+ maxEntries: cacheOptions.maxEntries,
207
+ maxBytes: cacheOptions.maxBytes,
208
+ sizeCalculation: cacheOptions.sizeCalculation
209
+ });
184
210
  }
185
- __privateSet$1(this, _debug, cacheOptions.debug === true);
211
+ this.#debug = cacheOptions.debug === true;
212
+ }
213
+ get onError() {
214
+ return this.#onError;
186
215
  }
187
216
  async get(key) {
188
- const cacheEntry = await __privateGet$1(this, _engine).get(key);
189
- if (__privateGet$1(this, _debug)) {
217
+ const cacheEntry = await this.#engine.get(key);
218
+ if (this.#debug) {
190
219
  const cacheHit = cacheEntry == null ? "MISS" : "HIT";
191
220
  console.log(`[ts-cache-mongoose] GET '${key}' - ${cacheHit}`);
192
221
  }
193
222
  return cacheEntry;
194
223
  }
195
224
  async set(key, value, ttl) {
196
- const givenTTL = typeof ttl === "string" ? ms(ttl) : ttl;
197
- const actualTTL = givenTTL ?? __privateGet$1(this, _defaultTTL);
198
- await __privateGet$1(this, _engine).set(key, value, actualTTL);
199
- if (__privateGet$1(this, _debug)) {
225
+ const givenTTL = ttl == null ? null : ms(ttl);
226
+ const actualTTL = givenTTL ?? this.#defaultTTL;
227
+ if (Number.isNaN(actualTTL) || actualTTL <= 0) {
228
+ if (this.#debug) {
229
+ console.log(`[ts-cache-mongoose] SET '${key}' - skipped (non-positive ttl: ${String(actualTTL)} ms)`);
230
+ }
231
+ return;
232
+ }
233
+ await this.#engine.set(key, value, actualTTL);
234
+ if (this.#debug) {
200
235
  console.log(`[ts-cache-mongoose] SET '${key}' - ttl: ${actualTTL.toFixed(0)} ms`);
201
236
  }
202
237
  }
203
238
  async del(key) {
204
- await __privateGet$1(this, _engine).del(key);
205
- if (__privateGet$1(this, _debug)) {
239
+ await this.#engine.del(key);
240
+ if (this.#debug) {
206
241
  console.log(`[ts-cache-mongoose] DEL '${key}'`);
207
242
  }
208
243
  }
209
244
  async clear() {
210
- await __privateGet$1(this, _engine).clear();
211
- if (__privateGet$1(this, _debug)) {
245
+ await this.#engine.clear();
246
+ if (this.#debug) {
212
247
  console.log("[ts-cache-mongoose] CLEAR");
213
248
  }
214
249
  }
215
250
  async close() {
216
- return __privateGet$1(this, _engine).close();
251
+ return this.#engine.close();
217
252
  }
218
253
  }
219
- _engine = new WeakMap();
220
- _defaultTTL = new WeakMap();
221
- _debug = new WeakMap();
222
- _engines = new WeakMap();
223
254
 
224
255
  const isPlainObject = (value) => {
225
256
  if (typeof value !== "object" || value === null) return false;
@@ -271,7 +302,7 @@ function extendAggregate(mongoose, cache) {
271
302
  pipeline: this.pipeline()
272
303
  });
273
304
  };
274
- mongoose.Aggregate.prototype.getCacheTTL = function() {
305
+ mongoose.Aggregate.prototype.getDuration = function() {
275
306
  return this._ttl;
276
307
  };
277
308
  mongoose.Aggregate.prototype.cache = function(ttl, customKey) {
@@ -280,20 +311,20 @@ function extendAggregate(mongoose, cache) {
280
311
  return this;
281
312
  };
282
313
  mongoose.Aggregate.prototype.exec = async function(...args) {
283
- if (!Object.prototype.hasOwnProperty.call(this, "_ttl")) {
314
+ if (!Object.hasOwn(this, "_ttl")) {
284
315
  return mongooseExec.apply(this, args);
285
316
  }
286
317
  const key = this.getCacheKey();
287
- const ttl = this.getCacheTTL();
318
+ const ttl = this.getDuration();
288
319
  const resultCache = await cache.get(key).catch((err) => {
289
- console.error(err);
320
+ cache.onError(err);
290
321
  });
291
322
  if (resultCache) {
292
323
  return resultCache;
293
324
  }
294
325
  const result = await mongooseExec.call(this);
295
326
  await cache.set(key, result, ttl).catch((err) => {
296
- console.error(err);
327
+ cache.onError(err);
297
328
  });
298
329
  return result;
299
330
  };
@@ -320,7 +351,7 @@ function extendQuery(mongoose, cache) {
320
351
  _conditions: this._conditions
321
352
  });
322
353
  };
323
- mongoose.Query.prototype.getCacheTTL = function() {
354
+ mongoose.Query.prototype.getDuration = function() {
324
355
  return this._ttl;
325
356
  };
326
357
  mongoose.Query.prototype.cache = function(ttl, customKey) {
@@ -329,17 +360,17 @@ function extendQuery(mongoose, cache) {
329
360
  return this;
330
361
  };
331
362
  mongoose.Query.prototype.exec = async function(...args) {
332
- if (!Object.prototype.hasOwnProperty.call(this, "_ttl")) {
363
+ if (!Object.hasOwn(this, "_ttl")) {
333
364
  return mongooseExec.apply(this, args);
334
365
  }
335
366
  const key = this.getCacheKey();
336
- const ttl = this.getCacheTTL();
367
+ const ttl = this.getDuration();
337
368
  const mongooseOptions = this.mongooseOptions();
338
369
  const isCount = this.op?.includes("count") ?? false;
339
370
  const isDistinct = this.op === "distinct";
340
371
  const model = this.model.modelName;
341
372
  const resultCache = await cache.get(key).catch((err) => {
342
- console.error(err);
373
+ cache.onError(err);
343
374
  });
344
375
  if (resultCache) {
345
376
  if (isCount || isDistinct || mongooseOptions.lean) {
@@ -355,32 +386,26 @@ function extendQuery(mongoose, cache) {
355
386
  }
356
387
  const result = await mongooseExec.call(this);
357
388
  await cache.set(key, result, ttl).catch((err) => {
358
- console.error(err);
389
+ cache.onError(err);
359
390
  });
360
391
  return result;
361
392
  };
362
393
  }
363
394
 
364
- var __typeError = (msg) => {
365
- throw TypeError(msg);
366
- };
367
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
368
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
369
- 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);
370
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
371
- var _instance;
372
- const _CacheMongoose = class _CacheMongoose {
395
+ class CacheMongoose {
396
+ static #instance;
397
+ cache;
373
398
  constructor() {
374
399
  }
375
400
  static init(mongoose, cacheOptions) {
376
- if (!__privateGet(_CacheMongoose, _instance)) {
377
- __privateSet(_CacheMongoose, _instance, new _CacheMongoose());
378
- __privateGet(_CacheMongoose, _instance).cache = new Cache(cacheOptions);
379
- const cache = __privateGet(_CacheMongoose, _instance).cache;
401
+ if (!CacheMongoose.#instance) {
402
+ CacheMongoose.#instance = new CacheMongoose();
403
+ CacheMongoose.#instance.cache = new Cache(cacheOptions);
404
+ const cache = CacheMongoose.#instance.cache;
380
405
  extendQuery(mongoose, cache);
381
406
  extendAggregate(mongoose, cache);
382
407
  }
383
- return __privateGet(_CacheMongoose, _instance);
408
+ return CacheMongoose.#instance;
384
409
  }
385
410
  async clear(customKey) {
386
411
  if (customKey == null) {
@@ -392,9 +417,6 @@ const _CacheMongoose = class _CacheMongoose {
392
417
  async close() {
393
418
  await this.cache.close();
394
419
  }
395
- };
396
- _instance = new WeakMap();
397
- __privateAdd(_CacheMongoose, _instance);
398
- let CacheMongoose = _CacheMongoose;
420
+ }
399
421
 
400
422
  export { CacheMongoose as default };