@platformatic/next 2.20.0 → 2.21.0-alpha.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.
@@ -44,18 +44,25 @@ export class CacheHandler {
44
44
  #subprefix
45
45
  #maxTTL
46
46
 
47
- constructor () {
48
- this.#logger = this.#createLogger()
49
- this.#config = globalThis.platformatic.config.cache
50
- this.#store = getConnection(this.#config.url)
51
- this.#maxTTL = this.#config.maxTTL
52
- this.#subprefix = this.#getSubprefix()
47
+ constructor (options) {
48
+ options ??= {}
49
+
50
+ this.#config = options.config ?? globalThis.platformatic?.config?.cache
51
+
52
+ if (!this.#config) {
53
+ throw new Error('Please provide a valid configuration.')
54
+ }
55
+
56
+ this.#logger = options.logger ?? this.#createLogger()
57
+ this.#store = options.store ?? getConnection(this.#config.url)
58
+ this.#maxTTL = options.maxTTL ?? this.#config.maxTTL ?? 86_400
59
+ this.#subprefix = options.subprefix ?? this.#getSubprefix()
53
60
  }
54
61
 
55
- async get (cacheKey) {
62
+ async get (cacheKey, isRedisKey) {
56
63
  this.#logger.trace({ key: cacheKey }, 'get')
57
64
 
58
- const key = this.#keyFor(cacheKey, sections.values)
65
+ const key = isRedisKey ? cacheKey : this.#keyFor(cacheKey, sections.values)
59
66
 
60
67
  let rawValue
61
68
  try {
@@ -96,12 +103,13 @@ export class CacheHandler {
96
103
  return value
97
104
  }
98
105
 
99
- async set (cacheKey, value, { tags, revalidate }) {
106
+ async set (cacheKey, value, { tags, revalidate }, isRedisKey) {
100
107
  this.#logger.trace({ key: cacheKey, value, tags, revalidate }, 'set')
101
108
 
109
+ const key = isRedisKey ? cacheKey : this.#keyFor(cacheKey, sections.values)
110
+
102
111
  try {
103
112
  // Compute the parameters to save
104
- const key = this.#keyFor(cacheKey, sections.values)
105
113
  const data = this.#serialize({ value, tags, lastModified: Date.now(), revalidate, maxTTL: this.#maxTTL })
106
114
  const expire = Math.min(revalidate, this.#maxTTL)
107
115
 
@@ -131,6 +139,56 @@ export class CacheHandler {
131
139
  }
132
140
  }
133
141
 
142
+ async remove (cacheKey, isRedisKey) {
143
+ this.#logger.trace({ key: cacheKey }, 'remove')
144
+
145
+ const key = isRedisKey ? cacheKey : this.#keyFor(cacheKey, sections.values)
146
+
147
+ let rawValue
148
+ try {
149
+ rawValue = await this.#store.get(key)
150
+
151
+ if (!rawValue) {
152
+ return
153
+ }
154
+ } catch (e) {
155
+ this.#logger.error({ err: ensureLoggableError(e) }, 'Cannot read cache value from Valkey')
156
+ throw new Error('Cannot read cache value from Valkey', { cause: e })
157
+ }
158
+
159
+ let value
160
+ try {
161
+ value = this.#deserialize(rawValue)
162
+ } catch (e) {
163
+ this.#logger.error({ err: ensureLoggableError(e) }, 'Cannot deserialize cache value from Valkey')
164
+
165
+ // Avoid useless reads the next time
166
+ // Note that since the value was unserializable, we don't know its tags and thus
167
+ // we cannot remove it from the tags sets. TTL will take care of them.
168
+ await this.#store.del(key)
169
+
170
+ throw new Error('Cannot deserialize cache value from Valkey', { cause: e })
171
+ }
172
+
173
+ try {
174
+ const promises = []
175
+ promises.push(this.#store.del(key))
176
+
177
+ if (Array.isArray(value.tags)) {
178
+ for (const tag of value.tags) {
179
+ const tagsKey = this.#keyFor(tag, sections.tags)
180
+ this.#store.srem(tagsKey, key, 'gt')
181
+ }
182
+ }
183
+
184
+ // Execute all the operations
185
+ await Promise.all(promises)
186
+ } catch (e) {
187
+ this.#logger.error({ err: ensureLoggableError(e) }, 'Cannot remove cache value from Valkey')
188
+ throw new Error('Cannot remove cache value from Valkey', { cause: e })
189
+ }
190
+ }
191
+
134
192
  async revalidateTag (tags) {
135
193
  this.#logger.trace({ tags }, 'revalidateTag')
136
194
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/next",
3
- "version": "2.20.0",
3
+ "version": "2.21.0-alpha.1",
4
4
  "description": "Platformatic Next.js Stackable",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -23,9 +23,9 @@
23
23
  "iovalkey": "^0.2.1",
24
24
  "msgpackr": "^1.11.2",
25
25
  "semver": "^7.6.3",
26
- "@platformatic/basic": "2.20.0",
27
- "@platformatic/utils": "2.20.0",
28
- "@platformatic/config": "2.20.0"
26
+ "@platformatic/basic": "2.21.0-alpha.1",
27
+ "@platformatic/config": "2.21.0-alpha.1",
28
+ "@platformatic/utils": "2.21.0-alpha.1"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@fastify/reply-from": "^11.0.0",
@@ -41,8 +41,8 @@
41
41
  "react-dom": "^18.3.1",
42
42
  "typescript": "^5.5.4",
43
43
  "ws": "^8.18.0",
44
- "@platformatic/composer": "2.20.0",
45
- "@platformatic/service": "2.20.0"
44
+ "@platformatic/composer": "2.21.0-alpha.1",
45
+ "@platformatic/service": "2.21.0-alpha.1"
46
46
  },
47
47
  "scripts": {
48
48
  "test": "npm run lint && borp --concurrency=1 --no-timeout",
package/schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://schemas.platformatic.dev/@platformatic/next/2.20.0.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/next/2.21.0-alpha.1.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "title": "Platformatic Next.js Stackable",
5
5
  "type": "object",