mvc-common-toolkit 1.44.9 → 1.45.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,122 +1,40 @@
1
- import {
2
- getVersionCacheKeyForKey,
3
- getVersionedCacheKey,
4
- } from "../pkg/key-helper";
1
+ import { SET_CACHE_POLICY } from "src/constants";
5
2
  import {
6
3
  CacheService,
7
- IPaginatedDataCache,
4
+ HashCacheService,
8
5
  PaginationResult,
9
6
  } from "../interfaces";
10
7
  import * as objectHelper from "../pkg/object-helper";
11
- import { SET_CACHE_POLICY } from "../constants";
12
- import { generateHashFromJSON } from "../pkg/hash-helper";
13
8
 
14
- export class PaginatedDataCache<T = any> implements IPaginatedDataCache<T> {
9
+ export class PaginatedDataCache {
15
10
  constructor(
16
11
  protected dataName: string,
17
- protected cacheService: CacheService
12
+ protected cacheService: CacheService & HashCacheService
18
13
  ) {}
19
14
 
20
- public generateCacheKey = (
21
- filter: Record<string, any> = {},
22
- limit = 10,
23
- offset = 0
24
- ): string => {
25
- const filterString = generateHashFromJSON(filter);
26
-
27
- return `paginated-cache:${this.dataName}:version:_version:filter:${filterString}:limit:${limit}:offset:${offset}`;
28
- };
29
-
30
- public async getCurrentVersion(): Promise<number> {
31
- const result = await this.cacheService.getNumber(
32
- getVersionCacheKeyForKey(this.generateCacheKey())
33
- );
34
-
35
- return result || 0;
36
- }
37
-
38
- public async getCachedPaginatedData(
39
- filter: Record<string, any>,
40
- limit: number,
41
- offset: number
42
- ): Promise<PaginationResult<T>> {
43
- const cacheKey = this.generateCacheKey(filter, limit, offset);
44
- const { data } = await this._fetchVersionedDataFromCache(cacheKey);
45
-
46
- return data;
15
+ protected getCacheKey(milestone: string | number, offset: number): string {
16
+ return `${this.dataName}:paginated_data`;
47
17
  }
48
18
 
49
- public async setCachedPaginatedData(
50
- filter: Record<string, any>,
19
+ public async paginateV2(
20
+ milestone: string | number,
51
21
  limit: number,
52
- offset: number,
53
- data: PaginationResult<T>,
54
- ttlInSecs = 60 * 30 // Default TTL is 30 minutes
55
- ): Promise<any> {
56
- const cacheKey = this.generateCacheKey(filter, limit, offset);
57
- const currentVersion = await this.getCurrentVersion();
58
- if (currentVersion === 0) {
59
- // If current version is 0, we need to increment it first
60
- await this.incrementCacheVersion(ttlInSecs);
61
- }
22
+ dataRefresherV2: () => Promise<PaginationResult>,
23
+ options: { expireInSecs: number } = { expireInSecs: 60 * 5 }
24
+ ): Promise<PaginationResult> {
25
+ const cacheKey = this.getCacheKey(milestone, limit);
62
26
 
63
- return this._setVersionedDataInCache(cacheKey, data, ttlInSecs);
64
- }
65
-
66
- public async _fetchVersionedDataFromCache(
67
- cacheKey: string,
68
- _overrideVersion?: number
69
- ): Promise<{ currentVersion: number; data: PaginationResult<T> | null }> {
70
- // Example: if cacheKey is 'user:123:profile', the version cache key will be 'user:123:profile:version'
71
- const currentVersion = _overrideVersion ?? (await this.getCurrentVersion());
72
- if (currentVersion === 0) {
73
- // Data is not yet set. If data is set, version should be 1
74
- return {
75
- currentVersion: 0,
76
- data: null,
77
- };
78
- }
79
-
80
- // Example: if cacheKey is 'user:123:profile' and version is 1, the versioned cache key will be 'user:123:profile:version:1'
81
- const versionedCacheKey = getVersionedCacheKey(cacheKey, currentVersion);
82
- const cachedData = await this.cacheService.get(versionedCacheKey);
83
- if (cachedData) {
84
- return {
85
- currentVersion: currentVersion,
86
- data: objectHelper.tryParseStringIntoCorrectData(cachedData),
87
- };
88
- }
89
-
90
- // No data means the cache is stale.
91
- return {
92
- currentVersion: currentVersion,
93
- data: null,
94
- };
95
- }
96
-
97
- protected async _setVersionedDataInCache(
98
- cacheKey: string,
99
- data: PaginationResult<T>,
100
- ttl: number = 60 * 30 // Default TTL is 30 minutes
101
- ): Promise<any> {
102
- const currentVersion = await this.getCurrentVersion();
27
+ const cached = await this.cacheService.get(cacheKey);
28
+ if (cached) return objectHelper.tryParseStringIntoCorrectData(cached);
103
29
 
104
- const versionedCacheKey = getVersionedCacheKey(cacheKey, currentVersion);
105
- const cacheableData =
106
- typeof data === "object" ? JSON.stringify(data) : data;
30
+ const freshData = await dataRefresherV2();
107
31
 
108
- // in case two processes try to set the same versioned cache key at the same time,
109
- // we use IF_NOT_EXISTS policy to avoid overwriting the cache
110
- return this.cacheService.set(versionedCacheKey, cacheableData, {
32
+ // Only set cache if not exists, And on set cache, also set TTL
33
+ await this.cacheService.set(cacheKey, JSON.stringify(freshData), {
111
34
  policy: SET_CACHE_POLICY.IF_NOT_EXISTS,
112
- value: ttl, // Set versioned cache key to expire in 30 minutes
35
+ value: options.expireInSecs,
113
36
  });
114
- }
115
-
116
- public async incrementCacheVersion(ttl = 60 * 60 * 24): Promise<number> {
117
- const cacheKey = this.generateCacheKey();
118
- const versionCacheKey = getVersionCacheKeyForKey(cacheKey);
119
37
 
120
- return this.cacheService.incrBy(versionCacheKey, 1);
38
+ return freshData;
121
39
  }
122
40
  }
@@ -8,6 +8,7 @@ import {
8
8
  ListCacheService,
9
9
  LuaCall,
10
10
  SetCacheOption,
11
+ SetCacheService,
11
12
  } from "../interfaces";
12
13
  import { SET_CACHE_POLICY } from "../constants";
13
14
 
@@ -16,7 +17,8 @@ export class RedisService
16
17
  CacheService,
17
18
  HashCacheService,
18
19
  ListCacheService,
19
- CacheScriptEvaluator
20
+ CacheScriptEvaluator,
21
+ SetCacheService
20
22
  {
21
23
  protected _redis: ioredis.Redis;
22
24
 
@@ -104,6 +106,18 @@ export class RedisService
104
106
  return execResult.map(([, value]) => value);
105
107
  }
106
108
 
109
+ public async sadd(key: string, ...values: string[]): Promise<number> {
110
+ return this._redis.sadd(key, ...values);
111
+ }
112
+
113
+ public async srem(key: string, ...values: string[]): Promise<number> {
114
+ return this._redis.srem(key, ...values);
115
+ }
116
+
117
+ public async scard(key: string): Promise<number> {
118
+ return this._redis.scard(key);
119
+ }
120
+
107
121
  public async eval(script: string, numberOfKeys: number, ...args: any[]) {
108
122
  return this._redis.eval(script, numberOfKeys, ...args);
109
123
  }
@@ -1,284 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- const chai_1 = require("chai");
13
- const paginated_cache_1 = require("./paginated-cache");
14
- const hash_helper_1 = require("../pkg/hash-helper");
15
- class FakeCacheService {
16
- constructor() {
17
- this._cache = {};
18
- }
19
- reset() {
20
- this._cache = {};
21
- }
22
- get(key) {
23
- return __awaiter(this, void 0, void 0, function* () {
24
- return this._cache[key];
25
- });
26
- }
27
- set(key, value, ttlInSecs) {
28
- return __awaiter(this, void 0, void 0, function* () {
29
- this._cache[key] = value;
30
- });
31
- }
32
- incrBy(key, increment) {
33
- return __awaiter(this, void 0, void 0, function* () {
34
- if (this._cache[key] === undefined) {
35
- this._cache[key] = 0;
36
- }
37
- if (typeof this._cache[key] !== "number") {
38
- throw new Error(`Value for key ${key} is not a number`);
39
- }
40
- this._cache[key] += increment;
41
- return this._cache[key];
42
- });
43
- }
44
- getNumber(key) {
45
- return __awaiter(this, void 0, void 0, function* () {
46
- const value = this._cache[key];
47
- if (value === undefined) {
48
- return null;
49
- }
50
- return typeof value === "number" ? value : Number(value);
51
- });
52
- }
53
- }
54
- var cacheService = new FakeCacheService();
55
- const paginatedDataCache = new paginated_cache_1.PaginatedDataCache("users", cacheService);
56
- describe("paginated cache", () => {
57
- beforeEach(() => {
58
- cacheService.reset();
59
- });
60
- it("should generate cache key correctly", () => {
61
- const filter = { country: "vietnam", age: 30 };
62
- const limit = 10;
63
- const offset = 100;
64
- const cacheKey = paginatedDataCache.generateCacheKey(filter, limit, offset);
65
- const filterHash = (0, hash_helper_1.generateHashFromJSON)(filter);
66
- const expectedKey = `paginated-cache:users:version:_version:filter:${filterHash}:limit:${limit}:offset:${offset}`;
67
- (0, chai_1.expect)(cacheKey).to.equal(expectedKey, "Cache key should match expected format");
68
- });
69
- it("should set and get cached paginated data successfully", () => __awaiter(void 0, void 0, void 0, function* () {
70
- const filter = { country: "vietnam", age: 30 };
71
- const limit = 10;
72
- const offset = 100;
73
- const data = {
74
- rows: [{ id: 1, name: "Andy" }],
75
- total: 1,
76
- limit,
77
- offset,
78
- };
79
- const cacheKey = paginatedDataCache.generateCacheKey(filter, limit, offset);
80
- yield paginatedDataCache.setCachedPaginatedData(filter, limit, offset, data);
81
- const currentVersion = yield paginatedDataCache.getCurrentVersion();
82
- (0, chai_1.expect)(currentVersion).to.equal(1, "Initial version should be 1");
83
- const cachedData = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset);
84
- const newVersion = yield paginatedDataCache.getCurrentVersion();
85
- (0, chai_1.expect)(newVersion).to.equal(1, "Version should still be 1");
86
- (0, chai_1.expect)(cachedData).to.deep.equal(data, "Cached data should match set data");
87
- }));
88
- it("should override existing cache with new data", () => __awaiter(void 0, void 0, void 0, function* () {
89
- const filter = { country: "vietnam", age: 30 };
90
- const limit = 10;
91
- const offset = 100;
92
- const data1 = {
93
- rows: [{ id: 1, name: "Andy" }],
94
- total: 1,
95
- limit,
96
- offset,
97
- };
98
- const data2 = {
99
- rows: [{ id: 2, name: "Bob" }],
100
- total: 1,
101
- limit,
102
- offset,
103
- };
104
- const cacheKey = paginatedDataCache.generateCacheKey(filter, limit, offset);
105
- yield paginatedDataCache.setCachedPaginatedData(filter, limit, offset, data1);
106
- const initialVersion = yield paginatedDataCache.getCurrentVersion();
107
- (0, chai_1.expect)(initialVersion).to.equal(1, "Initial version should be 1");
108
- const cachedData1 = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset);
109
- (0, chai_1.expect)(cachedData1).to.deep.equal(data1, "Initial cached data should match");
110
- yield paginatedDataCache.setCachedPaginatedData(filter, limit, offset, data2);
111
- const newVersion = yield paginatedDataCache.getCurrentVersion();
112
- (0, chai_1.expect)(newVersion).to.equal(1, "Version should still be 1 after override");
113
- const cachedData2 = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset);
114
- (0, chai_1.expect)(cachedData2).to.deep.equal(data2, "Cached data should match new data after override");
115
- }));
116
- it("should invalidate old cache when increment new version", () => __awaiter(void 0, void 0, void 0, function* () {
117
- const filter = { country: "vietnam", age: 30 };
118
- const filter2 = { country: "usa", age: 25 };
119
- const limit = 10;
120
- const offset = 100;
121
- const cacheKey = paginatedDataCache.generateCacheKey(filter, limit, offset);
122
- const data1 = {
123
- rows: [{ id: 1, name: "Andy" }],
124
- total: 1,
125
- limit,
126
- offset,
127
- };
128
- const data2 = {
129
- rows: [{ id: 2, name: "Bob" }],
130
- total: 1,
131
- limit,
132
- offset,
133
- };
134
- yield paginatedDataCache.setCachedPaginatedData(filter, limit, offset, data1);
135
- yield paginatedDataCache.setCachedPaginatedData(filter2, limit, offset, data2);
136
- const initialVersion = yield paginatedDataCache.getCurrentVersion();
137
- (0, chai_1.expect)(initialVersion).to.equal(1, "Initial version should be 1");
138
- const cachedData1 = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset);
139
- (0, chai_1.expect)(cachedData1).to.deep.equal(data1, "Initial cached data should match");
140
- const cachedData2 = yield paginatedDataCache.getCachedPaginatedData(filter2, limit, offset);
141
- (0, chai_1.expect)(cachedData2).to.deep.equal(data2, "Initial cached data2 should match");
142
- const newVersion = yield paginatedDataCache.incrementCacheVersion();
143
- (0, chai_1.expect)(newVersion).to.equal(2, "Version should be incremented to 2");
144
- const oldData1 = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset);
145
- const oldData2 = yield paginatedDataCache.getCachedPaginatedData(filter2, limit, offset);
146
- (0, chai_1.expect)(oldData1).to.be.null;
147
- (0, chai_1.expect)(oldData2).to.be.null;
148
- }));
149
- it("should give different result for different filters", () => __awaiter(void 0, void 0, void 0, function* () {
150
- const filter1 = { country: "vietnam", age: 30 };
151
- const filter2 = { country: "usa", age: 25 };
152
- const limit = 10;
153
- const offset = 100;
154
- const cacheKey1 = paginatedDataCache.generateCacheKey(filter1, limit, offset);
155
- const cacheKey2 = paginatedDataCache.generateCacheKey(filter2, limit, offset);
156
- const data1 = {
157
- rows: [{ id: 1, name: "Andy" }],
158
- total: 1,
159
- limit,
160
- offset,
161
- };
162
- const data2 = {
163
- rows: [{ id: 2, name: "Bob" }],
164
- total: 1,
165
- limit,
166
- offset,
167
- };
168
- yield paginatedDataCache.setCachedPaginatedData(filter1, limit, offset, data1);
169
- yield paginatedDataCache.setCachedPaginatedData(filter2, limit, offset, data2);
170
- const currentVersion = yield paginatedDataCache.getCurrentVersion();
171
- (0, chai_1.expect)(currentVersion).to.equal(1, "Filter2 version should be 1");
172
- const cachedData1 = yield paginatedDataCache.getCachedPaginatedData(filter1, limit, offset);
173
- const cachedData2 = yield paginatedDataCache.getCachedPaginatedData(filter2, limit, offset);
174
- (0, chai_1.expect)(cachedData1).to.deep.equal(data1, "Cached data for filter1 should match");
175
- (0, chai_1.expect)(cachedData2).to.deep.equal(data2, "Cached data for filter2 should match");
176
- }));
177
- it("should paginate data correctly", () => __awaiter(void 0, void 0, void 0, function* () {
178
- const data = [
179
- { id: 1, name: "Andy" },
180
- { id: 2, name: "Bob" },
181
- { id: 3, name: "Charlie" },
182
- { id: 4, name: "David" },
183
- { id: 5, name: "Eve" },
184
- ];
185
- const filter = { country: "vietnam", age: 30 };
186
- const limit = 2;
187
- const offset = 0;
188
- const data1 = {
189
- rows: data.slice(0, limit),
190
- total: data.length,
191
- limit,
192
- offset,
193
- };
194
- const data2 = {
195
- rows: data.slice(limit, limit * 2),
196
- total: data.length,
197
- limit,
198
- offset: limit,
199
- };
200
- yield paginatedDataCache.setCachedPaginatedData(filter, limit, offset, data1);
201
- const currentVersion = yield paginatedDataCache.getCurrentVersion();
202
- (0, chai_1.expect)(currentVersion).to.equal(1, "Initial version should be 1");
203
- const cachedData = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset);
204
- (0, chai_1.expect)(cachedData).to.deep.equal(data1, "Cached paginated data should match expected data");
205
- (0, chai_1.expect)(cachedData.rows.length).to.equal(limit, "Number of rows should match limit");
206
- const nextPage = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset + limit);
207
- (0, chai_1.expect)(nextPage).to.be.null;
208
- yield paginatedDataCache.setCachedPaginatedData(filter, limit, offset + limit, data2);
209
- const nextVersion = yield paginatedDataCache.getCurrentVersion();
210
- (0, chai_1.expect)(nextVersion).to.equal(1, "Next page version should be 1");
211
- const nextCachedData = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset + limit);
212
- (0, chai_1.expect)(nextCachedData).to.deep.equal(data2, "Next page cached data should match expected data");
213
- yield paginatedDataCache.incrementCacheVersion();
214
- const oldCachedData = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset);
215
- (0, chai_1.expect)(oldCachedData).to.be.null;
216
- const oldNextCachedData = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset + limit);
217
- (0, chai_1.expect)(oldNextCachedData).to.be.null;
218
- const newData = [
219
- { id: 1, name: "Andy" },
220
- { id: 2, name: "Bob" },
221
- { id: 3, name: "Charlie" },
222
- { id: 4, name: "David" },
223
- { id: 5, name: "Eve" },
224
- { id: 6, name: "Frank" },
225
- { id: 7, name: "Grace" },
226
- { id: 8, name: "Hank" },
227
- { id: 9, name: "Ivy" },
228
- { id: 10, name: "Jack" },
229
- ];
230
- const newData1 = {
231
- rows: newData.slice(0, limit),
232
- total: newData.length,
233
- limit,
234
- offset,
235
- };
236
- yield paginatedDataCache.setCachedPaginatedData(filter, limit, offset, newData1);
237
- const newCurrentVersion = yield paginatedDataCache.getCurrentVersion();
238
- (0, chai_1.expect)(newCurrentVersion).to.equal(2, "New version should be 2");
239
- const newCachedData = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset);
240
- (0, chai_1.expect)(newCachedData).to.deep.equal(newData1, "New cached paginated data should match expected data");
241
- }));
242
- it("should gives null if next page data is not set", () => __awaiter(void 0, void 0, void 0, function* () {
243
- const filter = { country: "vietnam", age: 30 };
244
- const limit = 2;
245
- const offset = 0;
246
- const data = [
247
- { id: 1, name: "Andy" },
248
- { id: 2, name: "Bob" },
249
- { id: 3, name: "Charlie" },
250
- { id: 4, name: "David" },
251
- { id: 5, name: "Eve" },
252
- ];
253
- yield paginatedDataCache.setCachedPaginatedData(filter, limit, offset, {
254
- rows: data.slice(0, limit),
255
- total: data.length,
256
- limit,
257
- offset,
258
- });
259
- const cachedData = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset);
260
- (0, chai_1.expect)(cachedData).to.not.be.null;
261
- (0, chai_1.expect)(cachedData.rows.length).to.equal(limit, "Should return correct number of rows");
262
- (0, chai_1.expect)(cachedData.rows[0].name).to.equal("Andy", "First row should be Andy");
263
- const nextPageData = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset + limit);
264
- (0, chai_1.expect)(nextPageData).to.be.null;
265
- yield paginatedDataCache.setCachedPaginatedData(filter, limit, offset + limit, {
266
- rows: data.slice(limit, limit * 2),
267
- total: data.length,
268
- limit,
269
- offset: limit,
270
- });
271
- const nextCachedData = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset + limit);
272
- (0, chai_1.expect)(nextCachedData).to.not.be.null;
273
- (0, chai_1.expect)(nextCachedData.rows.length).to.equal(limit, "Next page should return correct number of rows");
274
- (0, chai_1.expect)(nextCachedData.rows[0].name).to.equal("Charlie", "First row of next page should be Charlie");
275
- const version = yield paginatedDataCache.getCurrentVersion();
276
- (0, chai_1.expect)(version).to.equal(1, "Next page version should be 1");
277
- yield paginatedDataCache.incrementCacheVersion();
278
- const oldCachedData = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset);
279
- (0, chai_1.expect)(oldCachedData).to.be.null;
280
- const oldNextCachedData = yield paginatedDataCache.getCachedPaginatedData(filter, limit, offset + limit);
281
- (0, chai_1.expect)(oldNextCachedData).to.be.null;
282
- }));
283
- });
284
- //# sourceMappingURL=paginated-cache.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"paginated-cache.spec.js","sourceRoot":"","sources":["../../../src/services/paginated-cache.spec.ts"],"names":[],"mappings":"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"}