@pluslabs/utils 0.2.1 → 0.3.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.
@@ -0,0 +1,42 @@
1
+ declare class CacheKey {
2
+ private key;
3
+ /**
4
+ * The time to live for the cache key in seconds
5
+ */
6
+ ttl: number;
7
+ constructor(prefix: string, ...args: string[]);
8
+ setTtl(ttl: number): this;
9
+ add(...values: (string | number | boolean)[]): this;
10
+ get(): string;
11
+ }
12
+ type CacheKeysManagerOptions<R extends Record<string, readonly string[]>> = {
13
+ registry: R;
14
+ namespace: string;
15
+ redisClient?: {
16
+ get<T = string>(key: string): Promise<T | null>;
17
+ set<T = string>(key: string, value: T, options: {
18
+ ex: number;
19
+ }): Promise<void>;
20
+ del(key: string): Promise<void>;
21
+ [key: string]: any;
22
+ };
23
+ };
24
+ /**
25
+ * Creates a cache keys manager
26
+ * @param options - The options for the cache keys manager
27
+ * @param options.registry - The registry of cache keys
28
+ * @param options.namespace - The namespace for the cache keys
29
+ * @param options.redisClient - The redis client to use for the cache keys manager
30
+ * @returns The cache keys manager
31
+ */
32
+ declare function createCacheKeysManager<R extends Record<string, readonly string[]>>(options: CacheKeysManagerOptions<R>): {
33
+ getCacheKey: <K extends keyof R, V extends R[K][number], Args extends (string | number | boolean)[]>(root: K, node: V, ...identifiers: Args) => CacheKey;
34
+ invalidateCacheKey: <K_1 extends keyof R, V_1 extends R[K_1][number], Args_1 extends (string | number | boolean)[]>(root: K_1, key: V_1, ...identifiers: Args_1) => Promise<void>;
35
+ getCachedData: <T, K_2 extends keyof R, V_2 extends R[K_2][number]>(options: {
36
+ cacheKey: string | (() => [K_2, V_2, ...(string | number | boolean)[]]);
37
+ queryFn: () => Promise<T | null>;
38
+ ttl?: number | undefined;
39
+ }) => Promise<T | null>;
40
+ };
41
+ export default createCacheKeysManager;
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cache/index.ts"],"names":[],"mappings":"AAEA,cAAM,QAAQ;IACV,OAAO,CAAC,GAAG,CAAW;IAEtB;;OAEG;IACI,GAAG,EAAE,MAAM,CAAe;gBAErB,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE;IAI7C,MAAM,CAAC,GAAG,EAAE,MAAM;IAKlB,GAAG,CAAC,GAAG,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE;IAK5C,GAAG;CAGN;AAED,KAAK,uBAAuB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,IAAI;IACxE,QAAQ,EAAE,CAAC,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE;QACV,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAChD,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACtB,CAAC;CACL,CAAC;AAEF;;;;;;;GAOG;AACH,iBAAS,sBAAsB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,EACvE,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC;;wKAqBO,QAAQ,IAAI,CAAC;;;;;;EA0F1D;AAED,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,118 @@
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 DEFAULT_TTL = 10 * 60; // 10 minutes
13
+ class CacheKey {
14
+ constructor(prefix, ...args) {
15
+ var _a, _b;
16
+ /**
17
+ * The time to live for the cache key in seconds
18
+ */
19
+ this.ttl = DEFAULT_TTL;
20
+ this.key = [prefix, (_b = (_a = process.env.NODE_ENV) === null || _a === void 0 ? void 0 : _a.substring(0, 4)) !== null && _b !== void 0 ? _b : 'dev', ...args];
21
+ }
22
+ setTtl(ttl) {
23
+ this.ttl = ttl;
24
+ return this;
25
+ }
26
+ add(...values) {
27
+ this.key.push(...((values === null || values === void 0 ? void 0 : values.map((value) => { var _a; return (_a = value === null || value === void 0 ? void 0 : value.toString()) !== null && _a !== void 0 ? _a : value; })) || []));
28
+ return this;
29
+ }
30
+ get() {
31
+ return this.key.join(':');
32
+ }
33
+ }
34
+ /**
35
+ * Creates a cache keys manager
36
+ * @param options - The options for the cache keys manager
37
+ * @param options.registry - The registry of cache keys
38
+ * @param options.namespace - The namespace for the cache keys
39
+ * @param options.redisClient - The redis client to use for the cache keys manager
40
+ * @returns The cache keys manager
41
+ */
42
+ function createCacheKeysManager(options) {
43
+ const { registry, namespace, redisClient } = options;
44
+ function getCacheKey(root, node, ...identifiers) {
45
+ return new CacheKey(namespace, root.toString(), node, ...((identifiers === null || identifiers === void 0 ? void 0 : identifiers.map((arg) => { var _a; return (_a = arg === null || arg === void 0 ? void 0 : arg.toString()) !== null && _a !== void 0 ? _a : arg; })) || []));
46
+ }
47
+ function invalidateCacheKey(root, key, ...identifiers) {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ const cacheKey = getCacheKey(root, key, ...identifiers);
50
+ if (process.env.NODE_ENV !== 'production' && !redisClient) {
51
+ console.warn('[Cache Keys Manager] You tried to invalidate a cache key with no redis client');
52
+ return;
53
+ }
54
+ yield (redisClient === null || redisClient === void 0 ? void 0 : redisClient.del(cacheKey.get()));
55
+ });
56
+ }
57
+ function getCachedData(options) {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ const { cacheKey, queryFn, ttl = DEFAULT_TTL } = options;
60
+ let cacheKeyString;
61
+ if (typeof cacheKey === 'string') {
62
+ cacheKeyString = cacheKey;
63
+ }
64
+ else {
65
+ const keyTuple = cacheKey();
66
+ cacheKeyString = getCacheKey(keyTuple[0], keyTuple[1], ...keyTuple.slice(2)).get();
67
+ }
68
+ try {
69
+ // Check cache first
70
+ const cachedData = yield (redisClient === null || redisClient === void 0 ? void 0 : redisClient.get(cacheKeyString));
71
+ if (cachedData) {
72
+ return cachedData;
73
+ }
74
+ }
75
+ catch (error) {
76
+ console.error({
77
+ error,
78
+ cacheKey: cacheKeyString,
79
+ message: 'Redis error, falling back to database'
80
+ });
81
+ }
82
+ // If not in cache or Redis error, get from database
83
+ try {
84
+ const data = yield queryFn();
85
+ if (!data) {
86
+ return null;
87
+ }
88
+ // Try to cache the result, but don't fail if Redis is down
89
+ try {
90
+ yield (redisClient === null || redisClient === void 0 ? void 0 : redisClient.set(cacheKeyString, data, { ex: ttl }));
91
+ }
92
+ catch (error) {
93
+ console.error({
94
+ error,
95
+ cacheKey: cacheKeyString,
96
+ message: 'Failed to cache data, but continuing with database result'
97
+ });
98
+ }
99
+ return data;
100
+ }
101
+ catch (error) {
102
+ console.error({
103
+ error,
104
+ cacheKey: cacheKeyString,
105
+ message: 'Database query failed'
106
+ });
107
+ return null;
108
+ }
109
+ });
110
+ }
111
+ return {
112
+ getCacheKey,
113
+ invalidateCacheKey,
114
+ getCachedData
115
+ };
116
+ }
117
+ exports.default = createCacheKeysManager;
118
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cache/index.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ type ProactiveRequestData = {
4
4
  client_id: string;
5
5
  client_phone_number: string;
6
6
  };
7
- declare const gpt: {
7
+ export declare const gpt: {
8
8
  extension: {
9
9
  /**
10
10
  * Send a proactive request to MagicGPT extension
@@ -14,5 +14,5 @@ declare const gpt: {
14
14
  proactiveRequest: (source: string, data: ProactiveRequestData) => void;
15
15
  };
16
16
  };
17
- export default gpt;
17
+ export {};
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/gpt/index.ts"],"names":[],"mappings":"AAAA,KAAK,oBAAoB,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,QAAA,MAAM,GAAG;;QAED;;;;WAIG;mCACwB,MAAM,QAAQ,oBAAoB;;CAmBpE,CAAC;AAEF,eAAe,GAAG,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/gpt/index.ts"],"names":[],"mappings":"AAAA,KAAK,oBAAoB,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,eAAO,MAAM,GAAG;;QAER;;;;WAIG;mCACwB,MAAM,QAAQ,oBAAoB;;CAmBpE,CAAC"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const gpt = {
3
+ exports.gpt = void 0;
4
+ exports.gpt = {
4
5
  extension: {
5
6
  /**
6
7
  * Send a proactive request to MagicGPT extension
@@ -23,5 +24,4 @@ const gpt = {
23
24
  }
24
25
  }
25
26
  };
26
- exports.default = gpt;
27
27
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/gpt/index.ts"],"names":[],"mappings":";;AAOA,MAAM,GAAG,GAAG;IACR,SAAS,EAAE;QACP;;;;WAIG;QACH,gBAAgB,EAAE,CAAC,MAAc,EAAE,IAA0B,EAAE,EAAE;YAC7D,MAAM,CAAC,WAAW,CACd,IAAI,CAAC,SAAS,CAAC;gBACX,MAAM,EAAE,mBAAmB;gBAC3B,IAAI,EAAE,IAAI,CACN,IAAI,CAAC,SAAS,CAAC;oBACX,MAAM;oBACN,IAAI,EAAE;wBACF,UAAU,EAAE,IAAI,CAAC,UAAU;wBAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;wBAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;wBACzB,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;qBAChD;iBACJ,CAAC,CACL;aACJ,CAAC,CACL,CAAC;QACN,CAAC;KACJ;CACJ,CAAC;AAEF,kBAAe,GAAG,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/gpt/index.ts"],"names":[],"mappings":";;;AAOa,QAAA,GAAG,GAAG;IACf,SAAS,EAAE;QACP;;;;WAIG;QACH,gBAAgB,EAAE,CAAC,MAAc,EAAE,IAA0B,EAAE,EAAE;YAC7D,MAAM,CAAC,WAAW,CACd,IAAI,CAAC,SAAS,CAAC;gBACX,MAAM,EAAE,mBAAmB;gBAC3B,IAAI,EAAE,IAAI,CACN,IAAI,CAAC,SAAS,CAAC;oBACX,MAAM;oBACN,IAAI,EAAE;wBACF,UAAU,EAAE,IAAI,CAAC,UAAU;wBAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;wBAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;wBACzB,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;qBAChD;iBACJ,CAAC,CACL;aACJ,CAAC,CACL,CAAC;QACN,CAAC;KACJ;CACJ,CAAC"}
@@ -1,4 +1,6 @@
1
- import gpt from './gpt';
2
- export { gpt };
1
+ import * as gpt from './gpt';
2
+ import createCacheKeysManager from './cache';
3
3
  export * from './stamp';
4
+ export * from './cache';
5
+ export { gpt, createCacheKeysManager };
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,OAAO,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,CAAC;AAEf,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,sBAAsB,MAAM,SAAS,CAAC;AAE7C,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAExB,OAAO,EAAE,GAAG,EAAE,sBAAsB,EAAE,CAAC"}
@@ -10,6 +10,18 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
10
10
  if (k2 === undefined) k2 = k;
11
11
  o[k2] = m[k];
12
12
  }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
13
25
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
26
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
27
  };
@@ -17,8 +29,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
29
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
30
  };
19
31
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.gpt = void 0;
21
- const gpt_1 = __importDefault(require("./gpt"));
22
- exports.gpt = gpt_1.default;
32
+ exports.createCacheKeysManager = exports.gpt = void 0;
33
+ const gpt = __importStar(require("./gpt"));
34
+ exports.gpt = gpt;
35
+ const cache_1 = __importDefault(require("./cache"));
36
+ exports.createCacheKeysManager = cache_1.default;
23
37
  __exportStar(require("./stamp"), exports);
38
+ __exportStar(require("./cache"), exports);
24
39
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,gDAAwB;AACf,cADF,aAAG,CACE;AAEZ,0CAAwB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAMpB,kBAAG;AALZ,oDAA6C;AAK/B,iCALP,eAAsB,CAKO;AAHpC,0CAAwB;AACxB,0CAAwB"}
@@ -0,0 +1,42 @@
1
+ declare class CacheKey {
2
+ private key;
3
+ /**
4
+ * The time to live for the cache key in seconds
5
+ */
6
+ ttl: number;
7
+ constructor(prefix: string, ...args: string[]);
8
+ setTtl(ttl: number): this;
9
+ add(...values: (string | number | boolean)[]): this;
10
+ get(): string;
11
+ }
12
+ type CacheKeysManagerOptions<R extends Record<string, readonly string[]>> = {
13
+ registry: R;
14
+ namespace: string;
15
+ redisClient?: {
16
+ get<T = string>(key: string): Promise<T | null>;
17
+ set<T = string>(key: string, value: T, options: {
18
+ ex: number;
19
+ }): Promise<void>;
20
+ del(key: string): Promise<void>;
21
+ [key: string]: any;
22
+ };
23
+ };
24
+ /**
25
+ * Creates a cache keys manager
26
+ * @param options - The options for the cache keys manager
27
+ * @param options.registry - The registry of cache keys
28
+ * @param options.namespace - The namespace for the cache keys
29
+ * @param options.redisClient - The redis client to use for the cache keys manager
30
+ * @returns The cache keys manager
31
+ */
32
+ declare function createCacheKeysManager<R extends Record<string, readonly string[]>>(options: CacheKeysManagerOptions<R>): {
33
+ getCacheKey: <K extends keyof R, V extends R[K][number], Args extends (string | number | boolean)[]>(root: K, node: V, ...identifiers: Args) => CacheKey;
34
+ invalidateCacheKey: <K_1 extends keyof R, V_1 extends R[K_1][number], Args_1 extends (string | number | boolean)[]>(root: K_1, key: V_1, ...identifiers: Args_1) => Promise<void>;
35
+ getCachedData: <T, K_2 extends keyof R, V_2 extends R[K_2][number]>(options: {
36
+ cacheKey: string | (() => [K_2, V_2, ...(string | number | boolean)[]]);
37
+ queryFn: () => Promise<T | null>;
38
+ ttl?: number | undefined;
39
+ }) => Promise<T | null>;
40
+ };
41
+ export default createCacheKeysManager;
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cache/index.ts"],"names":[],"mappings":"AAEA,cAAM,QAAQ;IACV,OAAO,CAAC,GAAG,CAAW;IAEtB;;OAEG;IACI,GAAG,EAAE,MAAM,CAAe;gBAErB,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE;IAI7C,MAAM,CAAC,GAAG,EAAE,MAAM;IAKlB,GAAG,CAAC,GAAG,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE;IAK5C,GAAG;CAGN;AAED,KAAK,uBAAuB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,IAAI;IACxE,QAAQ,EAAE,CAAC,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE;QACV,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAChD,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACtB,CAAC;CACL,CAAC;AAEF;;;;;;;GAOG;AACH,iBAAS,sBAAsB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,EACvE,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC;;wKAqBO,QAAQ,IAAI,CAAC;;;;;;EA0F1D;AAED,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,116 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ const DEFAULT_TTL = 10 * 60; // 10 minutes
11
+ class CacheKey {
12
+ constructor(prefix, ...args) {
13
+ var _a, _b;
14
+ /**
15
+ * The time to live for the cache key in seconds
16
+ */
17
+ this.ttl = DEFAULT_TTL;
18
+ this.key = [prefix, (_b = (_a = process.env.NODE_ENV) === null || _a === void 0 ? void 0 : _a.substring(0, 4)) !== null && _b !== void 0 ? _b : 'dev', ...args];
19
+ }
20
+ setTtl(ttl) {
21
+ this.ttl = ttl;
22
+ return this;
23
+ }
24
+ add(...values) {
25
+ this.key.push(...((values === null || values === void 0 ? void 0 : values.map((value) => { var _a; return (_a = value === null || value === void 0 ? void 0 : value.toString()) !== null && _a !== void 0 ? _a : value; })) || []));
26
+ return this;
27
+ }
28
+ get() {
29
+ return this.key.join(':');
30
+ }
31
+ }
32
+ /**
33
+ * Creates a cache keys manager
34
+ * @param options - The options for the cache keys manager
35
+ * @param options.registry - The registry of cache keys
36
+ * @param options.namespace - The namespace for the cache keys
37
+ * @param options.redisClient - The redis client to use for the cache keys manager
38
+ * @returns The cache keys manager
39
+ */
40
+ function createCacheKeysManager(options) {
41
+ const { registry, namespace, redisClient } = options;
42
+ function getCacheKey(root, node, ...identifiers) {
43
+ return new CacheKey(namespace, root.toString(), node, ...((identifiers === null || identifiers === void 0 ? void 0 : identifiers.map((arg) => { var _a; return (_a = arg === null || arg === void 0 ? void 0 : arg.toString()) !== null && _a !== void 0 ? _a : arg; })) || []));
44
+ }
45
+ function invalidateCacheKey(root, key, ...identifiers) {
46
+ return __awaiter(this, void 0, void 0, function* () {
47
+ const cacheKey = getCacheKey(root, key, ...identifiers);
48
+ if (process.env.NODE_ENV !== 'production' && !redisClient) {
49
+ console.warn('[Cache Keys Manager] You tried to invalidate a cache key with no redis client');
50
+ return;
51
+ }
52
+ yield (redisClient === null || redisClient === void 0 ? void 0 : redisClient.del(cacheKey.get()));
53
+ });
54
+ }
55
+ function getCachedData(options) {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ const { cacheKey, queryFn, ttl = DEFAULT_TTL } = options;
58
+ let cacheKeyString;
59
+ if (typeof cacheKey === 'string') {
60
+ cacheKeyString = cacheKey;
61
+ }
62
+ else {
63
+ const keyTuple = cacheKey();
64
+ cacheKeyString = getCacheKey(keyTuple[0], keyTuple[1], ...keyTuple.slice(2)).get();
65
+ }
66
+ try {
67
+ // Check cache first
68
+ const cachedData = yield (redisClient === null || redisClient === void 0 ? void 0 : redisClient.get(cacheKeyString));
69
+ if (cachedData) {
70
+ return cachedData;
71
+ }
72
+ }
73
+ catch (error) {
74
+ console.error({
75
+ error,
76
+ cacheKey: cacheKeyString,
77
+ message: 'Redis error, falling back to database'
78
+ });
79
+ }
80
+ // If not in cache or Redis error, get from database
81
+ try {
82
+ const data = yield queryFn();
83
+ if (!data) {
84
+ return null;
85
+ }
86
+ // Try to cache the result, but don't fail if Redis is down
87
+ try {
88
+ yield (redisClient === null || redisClient === void 0 ? void 0 : redisClient.set(cacheKeyString, data, { ex: ttl }));
89
+ }
90
+ catch (error) {
91
+ console.error({
92
+ error,
93
+ cacheKey: cacheKeyString,
94
+ message: 'Failed to cache data, but continuing with database result'
95
+ });
96
+ }
97
+ return data;
98
+ }
99
+ catch (error) {
100
+ console.error({
101
+ error,
102
+ cacheKey: cacheKeyString,
103
+ message: 'Database query failed'
104
+ });
105
+ return null;
106
+ }
107
+ });
108
+ }
109
+ return {
110
+ getCacheKey,
111
+ invalidateCacheKey,
112
+ getCachedData
113
+ };
114
+ }
115
+ export default createCacheKeysManager;
116
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cache/index.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ type ProactiveRequestData = {
4
4
  client_id: string;
5
5
  client_phone_number: string;
6
6
  };
7
- declare const gpt: {
7
+ export declare const gpt: {
8
8
  extension: {
9
9
  /**
10
10
  * Send a proactive request to MagicGPT extension
@@ -14,5 +14,5 @@ declare const gpt: {
14
14
  proactiveRequest: (source: string, data: ProactiveRequestData) => void;
15
15
  };
16
16
  };
17
- export default gpt;
17
+ export {};
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/gpt/index.ts"],"names":[],"mappings":"AAAA,KAAK,oBAAoB,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,QAAA,MAAM,GAAG;;QAED;;;;WAIG;mCACwB,MAAM,QAAQ,oBAAoB;;CAmBpE,CAAC;AAEF,eAAe,GAAG,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/gpt/index.ts"],"names":[],"mappings":"AAAA,KAAK,oBAAoB,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,eAAO,MAAM,GAAG;;QAER;;;;WAIG;mCACwB,MAAM,QAAQ,oBAAoB;;CAmBpE,CAAC"}
@@ -1,4 +1,4 @@
1
- const gpt = {
1
+ export const gpt = {
2
2
  extension: {
3
3
  /**
4
4
  * Send a proactive request to MagicGPT extension
@@ -21,5 +21,4 @@ const gpt = {
21
21
  }
22
22
  }
23
23
  };
24
- export default gpt;
25
24
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/gpt/index.ts"],"names":[],"mappings":"AAOA,MAAM,GAAG,GAAG;IACR,SAAS,EAAE;QACP;;;;WAIG;QACH,gBAAgB,EAAE,CAAC,MAAc,EAAE,IAA0B,EAAE,EAAE;YAC7D,MAAM,CAAC,WAAW,CACd,IAAI,CAAC,SAAS,CAAC;gBACX,MAAM,EAAE,mBAAmB;gBAC3B,IAAI,EAAE,IAAI,CACN,IAAI,CAAC,SAAS,CAAC;oBACX,MAAM;oBACN,IAAI,EAAE;wBACF,UAAU,EAAE,IAAI,CAAC,UAAU;wBAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;wBAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;wBACzB,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;qBAChD;iBACJ,CAAC,CACL;aACJ,CAAC,CACL,CAAC;QACN,CAAC;KACJ;CACJ,CAAC;AAEF,eAAe,GAAG,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/gpt/index.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,GAAG,GAAG;IACf,SAAS,EAAE;QACP;;;;WAIG;QACH,gBAAgB,EAAE,CAAC,MAAc,EAAE,IAA0B,EAAE,EAAE;YAC7D,MAAM,CAAC,WAAW,CACd,IAAI,CAAC,SAAS,CAAC;gBACX,MAAM,EAAE,mBAAmB;gBAC3B,IAAI,EAAE,IAAI,CACN,IAAI,CAAC,SAAS,CAAC;oBACX,MAAM;oBACN,IAAI,EAAE;wBACF,UAAU,EAAE,IAAI,CAAC,UAAU;wBAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;wBAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;wBACzB,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;qBAChD;iBACJ,CAAC,CACL;aACJ,CAAC,CACL,CAAC;QACN,CAAC;KACJ;CACJ,CAAC"}
@@ -1,4 +1,6 @@
1
- import gpt from './gpt';
2
- export { gpt };
1
+ import * as gpt from './gpt';
2
+ import createCacheKeysManager from './cache';
3
3
  export * from './stamp';
4
+ export * from './cache';
5
+ export { gpt, createCacheKeysManager };
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,OAAO,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,CAAC;AAEf,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,sBAAsB,MAAM,SAAS,CAAC;AAE7C,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAExB,OAAO,EAAE,GAAG,EAAE,sBAAsB,EAAE,CAAC"}
@@ -1,4 +1,6 @@
1
- import gpt from './gpt';
2
- export { gpt };
1
+ import * as gpt from './gpt';
2
+ import createCacheKeysManager from './cache';
3
3
  export * from './stamp';
4
+ export * from './cache';
5
+ export { gpt, createCacheKeysManager };
4
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,OAAO,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,CAAC;AAEf,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,sBAAsB,MAAM,SAAS,CAAC;AAE7C,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAExB,OAAO,EAAE,GAAG,EAAE,sBAAsB,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluslabs/utils",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "A set of utilities used across projects",
5
5
  "keywords": [
6
6
  "javascript",
@@ -0,0 +1,163 @@
1
+ const DEFAULT_TTL = 10 * 60; // 10 minutes
2
+
3
+ class CacheKey {
4
+ private key: string[];
5
+
6
+ /**
7
+ * The time to live for the cache key in seconds
8
+ */
9
+ public ttl: number = DEFAULT_TTL;
10
+
11
+ constructor(prefix: string, ...args: string[]) {
12
+ this.key = [prefix, process.env.NODE_ENV?.substring(0, 4) ?? 'dev', ...args];
13
+ }
14
+
15
+ setTtl(ttl: number) {
16
+ this.ttl = ttl;
17
+ return this;
18
+ }
19
+
20
+ add(...values: (string | number | boolean)[]) {
21
+ this.key.push(...(values?.map((value) => value?.toString() ?? value) || []));
22
+ return this;
23
+ }
24
+
25
+ get() {
26
+ return this.key.join(':');
27
+ }
28
+ }
29
+
30
+ type CacheKeysManagerOptions<R extends Record<string, readonly string[]>> = {
31
+ registry: R;
32
+ namespace: string;
33
+ redisClient?: {
34
+ get<T = string>(key: string): Promise<T | null>;
35
+ set<T = string>(key: string, value: T, options: { ex: number }): Promise<void>;
36
+ del(key: string): Promise<void>;
37
+ [key: string]: any;
38
+ };
39
+ };
40
+
41
+ /**
42
+ * Creates a cache keys manager
43
+ * @param options - The options for the cache keys manager
44
+ * @param options.registry - The registry of cache keys
45
+ * @param options.namespace - The namespace for the cache keys
46
+ * @param options.redisClient - The redis client to use for the cache keys manager
47
+ * @returns The cache keys manager
48
+ */
49
+ function createCacheKeysManager<R extends Record<string, readonly string[]>>(
50
+ options: CacheKeysManagerOptions<R>
51
+ ) {
52
+ const { registry, namespace, redisClient } = options;
53
+
54
+ function getCacheKey<
55
+ K extends keyof R,
56
+ V extends R[K][number],
57
+ Args extends (string | number | boolean)[]
58
+ >(root: K, node: V, ...identifiers: Args) {
59
+ return new CacheKey(
60
+ namespace,
61
+ root.toString(),
62
+ node,
63
+ ...(identifiers?.map((arg) => arg?.toString() ?? arg) || [])
64
+ );
65
+ }
66
+
67
+ async function invalidateCacheKey<
68
+ K extends keyof R,
69
+ V extends R[K][number],
70
+ Args extends (string | number | boolean)[]
71
+ >(root: K, key: V, ...identifiers: Args): Promise<void> {
72
+ const cacheKey = getCacheKey(root, key, ...identifiers);
73
+
74
+ if (process.env.NODE_ENV !== 'production' && !redisClient) {
75
+ console.warn(
76
+ '[Cache Keys Manager] You tried to invalidate a cache key with no redis client'
77
+ );
78
+ return;
79
+ }
80
+
81
+ await redisClient?.del(cacheKey.get());
82
+ }
83
+
84
+ type CacheKeyTuple<K extends keyof R, V extends R[K][number]> = [
85
+ K,
86
+ V,
87
+ ...(string | number | boolean)[]
88
+ ];
89
+
90
+ async function getCachedData<T, K extends keyof R, V extends R[K][number]>(options: {
91
+ cacheKey: string | (() => CacheKeyTuple<K, V>);
92
+ queryFn: () => Promise<T | null>;
93
+ ttl?: number;
94
+ }): Promise<T | null> {
95
+ const { cacheKey, queryFn, ttl = DEFAULT_TTL } = options;
96
+
97
+ let cacheKeyString;
98
+
99
+ if (typeof cacheKey === 'string') {
100
+ cacheKeyString = cacheKey;
101
+ } else {
102
+ const keyTuple = cacheKey() as CacheKeyTuple<K, V>;
103
+ cacheKeyString = getCacheKey(
104
+ keyTuple[0],
105
+ keyTuple[1],
106
+ ...(keyTuple.slice(2) as (string | number | boolean)[])
107
+ ).get();
108
+ }
109
+
110
+ try {
111
+ // Check cache first
112
+ const cachedData = await redisClient?.get<T>(cacheKeyString);
113
+
114
+ if (cachedData) {
115
+ return cachedData as T;
116
+ }
117
+ } catch (error: any) {
118
+ console.error({
119
+ error,
120
+ cacheKey: cacheKeyString,
121
+ message: 'Redis error, falling back to database'
122
+ });
123
+ }
124
+
125
+ // If not in cache or Redis error, get from database
126
+ try {
127
+ const data = await queryFn();
128
+
129
+ if (!data) {
130
+ return null;
131
+ }
132
+
133
+ // Try to cache the result, but don't fail if Redis is down
134
+ try {
135
+ await redisClient?.set(cacheKeyString, data, { ex: ttl });
136
+ } catch (error: any) {
137
+ console.error({
138
+ error,
139
+ cacheKey: cacheKeyString,
140
+ message: 'Failed to cache data, but continuing with database result'
141
+ });
142
+ }
143
+
144
+ return data;
145
+ } catch (error: any) {
146
+ console.error({
147
+ error,
148
+ cacheKey: cacheKeyString,
149
+ message: 'Database query failed'
150
+ });
151
+
152
+ return null;
153
+ }
154
+ }
155
+
156
+ return {
157
+ getCacheKey,
158
+ invalidateCacheKey,
159
+ getCachedData
160
+ };
161
+ }
162
+
163
+ export default createCacheKeysManager;
package/src/gpt/index.ts CHANGED
@@ -5,7 +5,7 @@ type ProactiveRequestData = {
5
5
  client_phone_number: string;
6
6
  };
7
7
 
8
- const gpt = {
8
+ export const gpt = {
9
9
  extension: {
10
10
  /**
11
11
  * Send a proactive request to MagicGPT extension
@@ -32,5 +32,3 @@ const gpt = {
32
32
  }
33
33
  }
34
34
  };
35
-
36
- export default gpt;
package/src/index.ts CHANGED
@@ -1,4 +1,7 @@
1
- import gpt from './gpt';
2
- export { gpt };
1
+ import * as gpt from './gpt';
2
+ import createCacheKeysManager from './cache';
3
3
 
4
4
  export * from './stamp';
5
+ export * from './cache';
6
+
7
+ export { gpt, createCacheKeysManager };