cds-caching 0.3.3 → 1.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.
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Manages basic cache operations with statistics tracking
3
+ */
4
+ class BasicOperations {
5
+ constructor(cache, keyManager, tagResolver, statistics) {
6
+ this.cache = cache;
7
+ this.keyManager = keyManager;
8
+ this.tagResolver = tagResolver;
9
+ this.statistics = statistics;
10
+ }
11
+
12
+ /**
13
+ * Set a value in the cache
14
+ * @param {string|object} key - the key to set
15
+ * @param {any} value - the value to cache
16
+ * @param {object} options - cache options
17
+ * @returns {Promise<void>}
18
+ */
19
+ async set(key, value, options = {}) {
20
+ const wrappedValue = {
21
+ value,
22
+ tags: this.tagResolver.resolveTags(options.tags, value, options.params) || [],
23
+ timestamp: Date.now()
24
+ };
25
+ const createdKey = this.keyManager.createKey(key, {}, options.key);
26
+ await this.cache.send('SET', {
27
+ key: createdKey,
28
+ value: wrappedValue,
29
+ ttl: options.ttl || 0
30
+ });
31
+
32
+ const metadata = {
33
+ dataType: 'Operation',
34
+ operation: 'SET',
35
+ operationType: 'BASIC',
36
+ metadata: JSON.stringify({ key: createdKey, ttl: options.ttl || 0 }),
37
+ cacheOptions: JSON.stringify(options)
38
+ };
39
+ this.statistics.recordNativeSet(createdKey, metadata);
40
+ }
41
+
42
+ /**
43
+ * Get a value from the cache
44
+ * @param {string|object} key - the key to get
45
+ * @returns {Promise<any>} - the cached value
46
+ */
47
+ async get(key) {
48
+ const createdKey = this.keyManager.createKey(key);
49
+ const wrappedValue = await this.cache.send('GET', {
50
+ key: createdKey
51
+ });
52
+
53
+ // Record the native get operation
54
+ const metadata = {
55
+ dataType: 'Operation',
56
+ operation: 'GET',
57
+ operationType: 'BASIC',
58
+ metadata: JSON.stringify({ key: createdKey })
59
+ };
60
+ const isHit = wrappedValue !== undefined && wrappedValue !== null;
61
+ this.statistics.recordNativeGet(createdKey, isHit, metadata);
62
+
63
+ return wrappedValue?.value;
64
+ }
65
+
66
+ /**
67
+ * Check if a key exists in the cache
68
+ * @param {string|object} key - the key to check
69
+ * @returns {Promise<boolean>} - whether the key exists
70
+ */
71
+ async has(key) {
72
+ const createdKey = this.keyManager.createKey(key);
73
+ try {
74
+ return await this.cache.cache.has(createdKey);
75
+ } catch (error) {
76
+ if (this.cache.options.throwOnErrors) {
77
+ throw error;
78
+ } else {
79
+ return false; // We don't want to throw errors here
80
+ }
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Delete a key from the cache
86
+ * @param {string|object} key - the key to delete
87
+ * @returns {Promise<boolean>} - whether the key was deleted
88
+ */
89
+ async delete(key) {
90
+ const createdKey = this.keyManager.createKey(key);
91
+ const result = await this.cache.send('DELETE', {
92
+ key: createdKey
93
+ });
94
+
95
+ // Record the native delete operation
96
+ const metadata = {
97
+ dataType: 'Operation',
98
+ operation: 'DELETE',
99
+ operationType: 'BASIC',
100
+ metadata: JSON.stringify({ key: createdKey })
101
+ };
102
+ this.statistics.recordNativeDelete(createdKey, metadata);
103
+
104
+ return result;
105
+ }
106
+
107
+ /**
108
+ * Clear all cache entries
109
+ * @returns {Promise<void>}
110
+ */
111
+ async clear() {
112
+ await this.cache.send('CLEAR', {
113
+ deleteAll: true
114
+ });
115
+
116
+ // Record the native clear operation
117
+ const metadata = {
118
+ dataType: 'Operation',
119
+ operation: 'CLEAR',
120
+ operationType: 'BASIC',
121
+ metadata: JSON.stringify({ cache: this.cache.name })
122
+ };
123
+ this.statistics.recordNativeClear(metadata);
124
+
125
+ }
126
+
127
+ /**
128
+ * Delete all keys that have a specific tag
129
+ * @param {string} tag - the tag to match
130
+ * @returns {Promise<void>}
131
+ */
132
+ async deleteByTag(tag) {
133
+ for await (const [key, wrappedValue] of this.iterator()) {
134
+ if (wrappedValue?.tags?.includes(tag)) {
135
+ await this.delete(key);
136
+ }
137
+ }
138
+
139
+ // Record the native deleteByTag operation
140
+ const metadata = {
141
+ dataType: 'Operation',
142
+ operation: 'DELETE_BY_TAG',
143
+ operationType: 'BASIC',
144
+ metadata: JSON.stringify({ tag: tag, cache: this.cache.name })
145
+ };
146
+ this.statistics.recordNativeDeleteByTag(tag, metadata);
147
+
148
+ }
149
+
150
+ /**
151
+ * Get metadata for a key
152
+ * @param {string|object} key - the key to get metadata for
153
+ * @returns {Promise<object|null>} - the metadata or null if not found
154
+ */
155
+ async metadata(key) {
156
+ const createdKey = this.keyManager.createKey(key);
157
+ const wrappedValue = await this.cache.send('GET', {
158
+ key: createdKey
159
+ });
160
+ if (!wrappedValue) return null;
161
+
162
+ const { value, ...metadata } = wrappedValue;
163
+ return metadata;
164
+ }
165
+
166
+ /**
167
+ * Get tags for a key
168
+ * @param {string|object} key - the key to get tags for
169
+ * @returns {Promise<string[]>} - the tags
170
+ */
171
+ async tags(key) {
172
+ const createdKey = this.keyManager.createKey(key);
173
+ const wrappedValue = await this.cache.send('GET', {
174
+ key: createdKey
175
+ });
176
+ return wrappedValue?.tags || [];
177
+ }
178
+
179
+ /**
180
+ * Get a raw value from the cache without statistics tracking
181
+ * @param {string|object} key - the key to get
182
+ * @returns {Promise<any>} - the raw cached value
183
+ */
184
+ async getRaw(key) {
185
+ const createdKey = this.keyManager.createKey(key);
186
+ const wrappedValue = await this.cache.send('GET', {
187
+ key: createdKey
188
+ });
189
+ return wrappedValue?.value;
190
+ }
191
+
192
+ /**
193
+ * Iterator for all cache entries
194
+ * @returns {AsyncIterator} - iterator for cache entries
195
+ */
196
+ async *iterator() {
197
+ for await (const [key, value] of this.cache.cache.iterator()) {
198
+ if (typeof value === "string") {
199
+ try {
200
+ yield [key, JSON.parse(value)];
201
+ } catch (error) {
202
+ yield [key, value];
203
+ }
204
+ } else {
205
+ yield [key, value];
206
+ }
207
+ }
208
+ }
209
+ }
210
+
211
+ module.exports = BasicOperations;