@akinon/next 1.96.0-rc.56 → 1.96.0-snapshot-ZERO-35861-20250908151109
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/CHANGELOG.md +41 -1244
- package/__tests__/next-config.test.ts +10 -1
- package/api/cache.ts +39 -5
- package/components/accordion.tsx +5 -20
- package/components/file-input.tsx +3 -65
- package/components/input.tsx +0 -2
- package/components/link.tsx +12 -16
- package/components/modal.tsx +16 -32
- package/components/plugin-module.tsx +3 -30
- package/data/client/checkout.ts +4 -5
- package/data/server/category.ts +32 -50
- package/data/server/flatpage.ts +16 -17
- package/data/server/form.ts +4 -1
- package/data/server/landingpage.ts +12 -16
- package/data/server/list.ts +15 -24
- package/data/server/menu.ts +5 -2
- package/data/server/product.ts +41 -67
- package/data/server/special-page.ts +12 -16
- package/data/server/widget.ts +4 -1
- package/data/urls.ts +1 -5
- package/hocs/server/with-segment-defaults.tsx +2 -5
- package/hooks/use-localization.ts +3 -2
- package/jest.config.js +1 -7
- package/lib/cache-handler.mjs +365 -87
- package/lib/cache.ts +252 -25
- package/middlewares/complete-gpay.ts +1 -2
- package/middlewares/complete-masterpass.ts +1 -2
- package/middlewares/default.ts +13 -50
- package/middlewares/locale.ts +1 -9
- package/middlewares/pretty-url.ts +2 -1
- package/middlewares/redirection-payment.ts +1 -2
- package/middlewares/saved-card-redirection.ts +1 -2
- package/middlewares/three-d-redirection.ts +1 -2
- package/middlewares/url-redirection.ts +14 -8
- package/package.json +4 -3
- package/plugins.d.ts +0 -8
- package/plugins.js +1 -3
- package/redux/middlewares/checkout.ts +1 -5
- package/types/commerce/order.ts +0 -1
- package/types/index.ts +2 -34
- package/utils/app-fetch.ts +2 -7
- package/utils/redirect.ts +6 -31
- package/with-pz-config.js +5 -1
- package/__tests__/redirect.test.ts +0 -319
- package/api/image-proxy.ts +0 -75
- package/api/similar-product-list.ts +0 -84
- package/api/similar-products.ts +0 -120
- package/data/server/basket.ts +0 -72
- package/utils/redirect-ignore.ts +0 -35
package/lib/cache-handler.mjs
CHANGED
|
@@ -3,7 +3,261 @@ import createLruHandler from '@neshca/cache-handler/local-lru';
|
|
|
3
3
|
import createRedisHandler from '@neshca/cache-handler/redis-strings';
|
|
4
4
|
import { createClient } from 'redis';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
let zstd;
|
|
7
|
+
|
|
8
|
+
(async () => {
|
|
9
|
+
try {
|
|
10
|
+
const { compress, decompress } = await import('@mongodb-js/zstd');
|
|
11
|
+
zstd = { compress, decompress, type: 'native' };
|
|
12
|
+
} catch (_) {
|
|
13
|
+
zstd = false;
|
|
14
|
+
}
|
|
15
|
+
})();
|
|
16
|
+
|
|
17
|
+
const getZstd = () => {
|
|
18
|
+
return zstd;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const compressValue = async (value) => {
|
|
22
|
+
try {
|
|
23
|
+
if (value && typeof value === 'object' && value.value !== undefined) {
|
|
24
|
+
const nestedValue = value.value;
|
|
25
|
+
const serializedNestedValue =
|
|
26
|
+
typeof nestedValue === 'string'
|
|
27
|
+
? nestedValue
|
|
28
|
+
: JSON.stringify(nestedValue);
|
|
29
|
+
const originalSize = Buffer.byteLength(serializedNestedValue, 'utf8');
|
|
30
|
+
|
|
31
|
+
if (originalSize < 1024) {
|
|
32
|
+
const result = {
|
|
33
|
+
...value,
|
|
34
|
+
tags: Array.isArray(value.tags) ? value.tags : []
|
|
35
|
+
};
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const zstdLib = getZstd();
|
|
40
|
+
let compressed;
|
|
41
|
+
|
|
42
|
+
if (zstdLib && zstdLib !== false) {
|
|
43
|
+
const inputBuffer = Buffer.from(serializedNestedValue, 'utf8');
|
|
44
|
+
|
|
45
|
+
if (
|
|
46
|
+
typeof zstdLib.compress === 'function' &&
|
|
47
|
+
zstdLib.compress.constructor.name === 'AsyncFunction'
|
|
48
|
+
) {
|
|
49
|
+
compressed = await zstdLib.compress(inputBuffer, 3);
|
|
50
|
+
} else {
|
|
51
|
+
compressed = zstdLib.compress(inputBuffer, 3);
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
return {
|
|
55
|
+
...value,
|
|
56
|
+
tags: Array.isArray(value.tags) ? value.tags : []
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const compressedBase64 = Buffer.from(compressed).toString('base64');
|
|
61
|
+
|
|
62
|
+
const result = {
|
|
63
|
+
...value,
|
|
64
|
+
tags: Array.isArray(value.tags) ? value.tags : [],
|
|
65
|
+
lifespan: {
|
|
66
|
+
...value.lifespan,
|
|
67
|
+
expireAge: value.lifespan?.revalidate || value.lifespan?.expireAge,
|
|
68
|
+
expireAt:
|
|
69
|
+
value.lifespan?.lastModifiedAt && value.lifespan?.revalidate
|
|
70
|
+
? value.lifespan.lastModifiedAt + value.lifespan.revalidate
|
|
71
|
+
: value.lifespan?.expireAt
|
|
72
|
+
},
|
|
73
|
+
value: {
|
|
74
|
+
__compressed: true,
|
|
75
|
+
__method: 'zstd',
|
|
76
|
+
__originalSize: originalSize,
|
|
77
|
+
__compressedSize: compressed.length,
|
|
78
|
+
__data: compressedBase64
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const serializedValue =
|
|
86
|
+
typeof value === 'string' ? value : JSON.stringify(value);
|
|
87
|
+
const originalSize = Buffer.byteLength(serializedValue, 'utf8');
|
|
88
|
+
|
|
89
|
+
if (originalSize < 1024) {
|
|
90
|
+
if (
|
|
91
|
+
value &&
|
|
92
|
+
typeof value === 'object' &&
|
|
93
|
+
value.lastModified === undefined &&
|
|
94
|
+
value.lifespan === undefined &&
|
|
95
|
+
value.value === undefined
|
|
96
|
+
) {
|
|
97
|
+
return {
|
|
98
|
+
...value,
|
|
99
|
+
tags: value.tags || [],
|
|
100
|
+
lastModified: Date.now(),
|
|
101
|
+
lifespan: {
|
|
102
|
+
expireAt: Math.floor(Date.now() / 1000) + 3600
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
if (
|
|
107
|
+
value &&
|
|
108
|
+
typeof value === 'object' &&
|
|
109
|
+
value.lifespan &&
|
|
110
|
+
value.lifespan.revalidate
|
|
111
|
+
) {
|
|
112
|
+
return {
|
|
113
|
+
...value,
|
|
114
|
+
lifespan: {
|
|
115
|
+
...value.lifespan,
|
|
116
|
+
expireAge: value.lifespan.revalidate,
|
|
117
|
+
expireAt:
|
|
118
|
+
value.lifespan.lastModifiedAt && value.lifespan.revalidate
|
|
119
|
+
? value.lifespan.lastModifiedAt + value.lifespan.revalidate
|
|
120
|
+
: value.lifespan.expireAt
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return value;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const zstdLib = getZstd();
|
|
128
|
+
let compressed;
|
|
129
|
+
|
|
130
|
+
if (zstdLib && zstdLib !== false) {
|
|
131
|
+
const inputBuffer = Buffer.from(serializedValue, 'utf8');
|
|
132
|
+
|
|
133
|
+
if (
|
|
134
|
+
typeof zstdLib.compress === 'function' &&
|
|
135
|
+
zstdLib.compress.constructor.name === 'AsyncFunction'
|
|
136
|
+
) {
|
|
137
|
+
compressed = await zstdLib.compress(inputBuffer, 3);
|
|
138
|
+
} else {
|
|
139
|
+
compressed = zstdLib.compress(inputBuffer, 3);
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
if (
|
|
143
|
+
value &&
|
|
144
|
+
typeof value === 'object' &&
|
|
145
|
+
value.lastModified === undefined &&
|
|
146
|
+
value.lifespan === undefined &&
|
|
147
|
+
value.value === undefined
|
|
148
|
+
) {
|
|
149
|
+
return {
|
|
150
|
+
...value,
|
|
151
|
+
tags: value.tags || [],
|
|
152
|
+
lastModified: Date.now(),
|
|
153
|
+
lifespan: {
|
|
154
|
+
expireAt: Math.floor(Date.now() / 1000) + 3600
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
return value;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const compressedBase64 = Buffer.from(compressed).toString('base64');
|
|
162
|
+
|
|
163
|
+
const compressedResult = {
|
|
164
|
+
__compressed: true,
|
|
165
|
+
__method: 'zstd',
|
|
166
|
+
__originalSize: originalSize,
|
|
167
|
+
__compressedSize: compressed.length,
|
|
168
|
+
__data: compressedBase64,
|
|
169
|
+
tags: [],
|
|
170
|
+
lastModified: Date.now(),
|
|
171
|
+
lifespan: { expireAt: Math.floor(Date.now() / 1000) + 3600 }
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
return compressedResult;
|
|
175
|
+
} catch (_) {
|
|
176
|
+
return value;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const decompressValue = async (compressedData) => {
|
|
181
|
+
try {
|
|
182
|
+
if (
|
|
183
|
+
compressedData &&
|
|
184
|
+
typeof compressedData === 'object' &&
|
|
185
|
+
compressedData.value &&
|
|
186
|
+
typeof compressedData.value === 'object' &&
|
|
187
|
+
compressedData.value.__compressed
|
|
188
|
+
) {
|
|
189
|
+
const compressedNestedValue = compressedData.value;
|
|
190
|
+
const compressedBuffer = Buffer.from(
|
|
191
|
+
compressedNestedValue.__data,
|
|
192
|
+
'base64'
|
|
193
|
+
);
|
|
194
|
+
let decompressed;
|
|
195
|
+
|
|
196
|
+
if (compressedNestedValue.__method === 'zstd') {
|
|
197
|
+
const zstdLib = getZstd();
|
|
198
|
+
if (zstdLib && zstdLib !== false) {
|
|
199
|
+
if (
|
|
200
|
+
typeof zstdLib.decompress === 'function' &&
|
|
201
|
+
zstdLib.decompress.constructor.name === 'AsyncFunction'
|
|
202
|
+
) {
|
|
203
|
+
const decompressedBuffer = await zstdLib.decompress(
|
|
204
|
+
compressedBuffer
|
|
205
|
+
);
|
|
206
|
+
decompressed = decompressedBuffer.toString('utf8');
|
|
207
|
+
} else {
|
|
208
|
+
decompressed = zstdLib
|
|
209
|
+
.decompress(compressedBuffer)
|
|
210
|
+
.toString('utf8');
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
throw new Error('zstd not available for decompression');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
...compressedData,
|
|
219
|
+
value: JSON.parse(decompressed)
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (
|
|
224
|
+
compressedData &&
|
|
225
|
+
typeof compressedData === 'object' &&
|
|
226
|
+
compressedData.__compressed
|
|
227
|
+
) {
|
|
228
|
+
const compressedBuffer = Buffer.from(compressedData.__data, 'base64');
|
|
229
|
+
let decompressed;
|
|
230
|
+
|
|
231
|
+
if (compressedData.__method === 'zstd') {
|
|
232
|
+
const zstdLib = getZstd();
|
|
233
|
+
if (zstdLib && zstdLib !== false) {
|
|
234
|
+
if (
|
|
235
|
+
typeof zstdLib.decompress === 'function' &&
|
|
236
|
+
zstdLib.decompress.constructor.name === 'AsyncFunction'
|
|
237
|
+
) {
|
|
238
|
+
const decompressedBuffer = await zstdLib.decompress(
|
|
239
|
+
compressedBuffer
|
|
240
|
+
);
|
|
241
|
+
decompressed = decompressedBuffer.toString('utf8');
|
|
242
|
+
} else {
|
|
243
|
+
decompressed = zstdLib
|
|
244
|
+
.decompress(compressedBuffer)
|
|
245
|
+
.toString('utf8');
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
throw new Error('zstd not available for decompression');
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return JSON.parse(decompressed);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return compressedData;
|
|
256
|
+
} catch (error) {
|
|
257
|
+
return compressedData;
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
|
|
7
261
|
const CACHE_CONFIG = {
|
|
8
262
|
lru: {
|
|
9
263
|
maxItemCount: 2000
|
|
@@ -22,7 +276,6 @@ const CACHE_CONFIG = {
|
|
|
22
276
|
version: process.env.ACC_APP_VERSION || ''
|
|
23
277
|
};
|
|
24
278
|
|
|
25
|
-
// Use global to persist across module reloads in development
|
|
26
279
|
const globalForRedis = global;
|
|
27
280
|
if (!globalForRedis.redisClient) {
|
|
28
281
|
globalForRedis.redisClient = null;
|
|
@@ -31,42 +284,22 @@ if (!globalForRedis.redisClient) {
|
|
|
31
284
|
globalForRedis.connectionAttempts = 0;
|
|
32
285
|
}
|
|
33
286
|
|
|
34
|
-
// Logging configuration
|
|
35
|
-
const debugValue = process.env.NEXT_PRIVATE_DEBUG_CACHE;
|
|
36
|
-
const debug = debugValue === 'true' || debugValue === '1';
|
|
37
|
-
|
|
38
|
-
let console_log;
|
|
39
|
-
if (debug) {
|
|
40
|
-
// eslint-disable-next-line no-console
|
|
41
|
-
console_log = (...args) => console.log('[Cache Handler]', ...args);
|
|
42
|
-
} else {
|
|
43
|
-
console_log = () => {};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
287
|
async function getRedisClient() {
|
|
47
|
-
// If client exists and is ready, return it
|
|
48
288
|
if (globalForRedis.redisClient?.isReady) {
|
|
49
|
-
console_log('Reusing existing Redis connection');
|
|
50
289
|
return globalForRedis.redisClient;
|
|
51
290
|
}
|
|
52
291
|
|
|
53
|
-
// If we're already connecting, wait a bit and retry
|
|
54
292
|
if (globalForRedis.isConnecting) {
|
|
55
293
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
56
294
|
return getRedisClient();
|
|
57
295
|
}
|
|
58
296
|
|
|
59
|
-
// Start new connection
|
|
60
297
|
globalForRedis.isConnecting = true;
|
|
61
298
|
globalForRedis.connectionAttempts++;
|
|
62
299
|
|
|
63
300
|
try {
|
|
64
301
|
const redisUrl = `redis://${CACHE_CONFIG.host}:${CACHE_CONFIG.port}/${CACHE_CONFIG.bucket}`;
|
|
65
302
|
|
|
66
|
-
if (globalForRedis.connectionAttempts === 1) {
|
|
67
|
-
console_log('Creating Redis connection:', redisUrl);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
303
|
const redisClient = createClient({
|
|
71
304
|
url: redisUrl,
|
|
72
305
|
socket: {
|
|
@@ -87,7 +320,6 @@ async function getRedisClient() {
|
|
|
87
320
|
});
|
|
88
321
|
|
|
89
322
|
redisClient.on('error', (error) => {
|
|
90
|
-
// Only log the first connection error to avoid spam
|
|
91
323
|
if (!globalForRedis.hasLoggedConnectionError) {
|
|
92
324
|
if (error.code === 'ECONNREFUSED') {
|
|
93
325
|
console.warn(
|
|
@@ -101,12 +333,10 @@ async function getRedisClient() {
|
|
|
101
333
|
});
|
|
102
334
|
|
|
103
335
|
redisClient.on('connect', () => {
|
|
104
|
-
console_log('Redis connected');
|
|
105
336
|
globalForRedis.hasLoggedConnectionError = false;
|
|
106
337
|
});
|
|
107
338
|
|
|
108
339
|
redisClient.on('ready', () => {
|
|
109
|
-
console_log('Redis ready');
|
|
110
340
|
globalForRedis.hasLoggedConnectionError = false;
|
|
111
341
|
});
|
|
112
342
|
|
|
@@ -115,16 +345,6 @@ async function getRedisClient() {
|
|
|
115
345
|
return redisClient;
|
|
116
346
|
} catch (error) {
|
|
117
347
|
if (!globalForRedis.hasLoggedConnectionError) {
|
|
118
|
-
if (error.code === 'ECONNREFUSED') {
|
|
119
|
-
console.warn(
|
|
120
|
-
'[Cache Handler] Could not connect to Redis - using local cache only'
|
|
121
|
-
);
|
|
122
|
-
} else {
|
|
123
|
-
console.error(
|
|
124
|
-
'[Cache Handler] Failed to connect to Redis:',
|
|
125
|
-
error.message
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
348
|
globalForRedis.hasLoggedConnectionError = true;
|
|
129
349
|
}
|
|
130
350
|
globalForRedis.redisClient = null;
|
|
@@ -135,13 +355,10 @@ async function getRedisClient() {
|
|
|
135
355
|
}
|
|
136
356
|
|
|
137
357
|
CacheHandler.onCreation(async () => {
|
|
138
|
-
console_log('Initializing cache handlers...');
|
|
139
|
-
|
|
140
358
|
let client;
|
|
141
359
|
try {
|
|
142
360
|
client = await getRedisClient();
|
|
143
361
|
} catch (error) {
|
|
144
|
-
// Error already logged in getRedisClient, just return local handler
|
|
145
362
|
return {
|
|
146
363
|
handlers: [createLruHandler(CACHE_CONFIG.lru)]
|
|
147
364
|
};
|
|
@@ -150,98 +367,161 @@ CacheHandler.onCreation(async () => {
|
|
|
150
367
|
const redisHandler = createRedisHandler({
|
|
151
368
|
client,
|
|
152
369
|
timeoutMs: CACHE_CONFIG.redis.timeoutMs,
|
|
153
|
-
keyExpirationStrategy: '
|
|
370
|
+
keyExpirationStrategy: 'EXPIREAT'
|
|
154
371
|
});
|
|
155
372
|
|
|
156
373
|
const localHandler = createLruHandler(CACHE_CONFIG.lru);
|
|
157
374
|
|
|
158
|
-
|
|
159
|
-
const versionPrefix =
|
|
160
|
-
|
|
161
|
-
// Create optimized functions for each scenario
|
|
162
|
-
const versionKeyString = versionPrefix
|
|
163
|
-
? (key) => `${versionPrefix}${key}`
|
|
164
|
-
: (key) => key;
|
|
375
|
+
const CACHE_VERSION = 'v2';
|
|
376
|
+
const versionPrefix = `${CACHE_VERSION}_`;
|
|
165
377
|
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
378
|
+
const versionKeyString = (key) => `${versionPrefix}${key}`;
|
|
379
|
+
const versionKeyObject = (key) => ({
|
|
380
|
+
...key,
|
|
381
|
+
key: `${versionPrefix}${key.key}`
|
|
382
|
+
});
|
|
169
383
|
|
|
170
|
-
// Main version key function that routes to optimized paths
|
|
171
384
|
const versionKey = (key) => {
|
|
172
385
|
return typeof key === 'string'
|
|
173
386
|
? versionKeyString(key)
|
|
174
387
|
: versionKeyObject(key);
|
|
175
388
|
};
|
|
176
389
|
|
|
177
|
-
// Create a custom handler that checks local first, then Redis
|
|
178
390
|
const customHandler = {
|
|
179
391
|
name: 'custom-local-then-redis',
|
|
180
392
|
get: async (key, context) => {
|
|
181
393
|
const vKey = versionKey(key);
|
|
182
|
-
console_log(
|
|
183
|
-
'GET called for key:',
|
|
184
|
-
typeof vKey === 'string' ? vKey : vKey?.key
|
|
185
|
-
);
|
|
186
394
|
|
|
187
|
-
// Check local cache first
|
|
188
|
-
console_log('Checking local cache...');
|
|
189
395
|
const localResult = await localHandler.get(vKey, context);
|
|
190
396
|
|
|
191
397
|
if (localResult) {
|
|
192
|
-
|
|
398
|
+
if (
|
|
399
|
+
localResult &&
|
|
400
|
+
typeof localResult === 'object' &&
|
|
401
|
+
(localResult.__compressed ||
|
|
402
|
+
(localResult.value && localResult.value.__compressed) ||
|
|
403
|
+
localResult.compressed !== undefined)
|
|
404
|
+
) {
|
|
405
|
+
try {
|
|
406
|
+
const decompressed = await decompressValue(localResult);
|
|
407
|
+
return typeof decompressed === 'string'
|
|
408
|
+
? JSON.parse(decompressed)
|
|
409
|
+
: decompressed;
|
|
410
|
+
} catch (_) {
|
|
411
|
+
return localResult;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
193
415
|
return localResult;
|
|
194
416
|
}
|
|
195
417
|
|
|
196
|
-
console_log('Not found in local, checking Redis...');
|
|
197
418
|
try {
|
|
198
419
|
const redisResult = await redisHandler.get(vKey, context);
|
|
199
420
|
|
|
200
421
|
if (redisResult) {
|
|
201
|
-
|
|
202
|
-
|
|
422
|
+
let finalResult = redisResult;
|
|
423
|
+
|
|
424
|
+
if (typeof redisResult === 'string') {
|
|
425
|
+
try {
|
|
426
|
+
finalResult = JSON.parse(redisResult);
|
|
427
|
+
} catch (parseError) {
|
|
428
|
+
finalResult = redisResult;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (
|
|
433
|
+
finalResult &&
|
|
434
|
+
typeof finalResult === 'object' &&
|
|
435
|
+
(finalResult.__compressed ||
|
|
436
|
+
(finalResult.value && finalResult.value.__compressed) ||
|
|
437
|
+
finalResult.compressed !== undefined)
|
|
438
|
+
) {
|
|
439
|
+
try {
|
|
440
|
+
const decompressed = await decompressValue(finalResult);
|
|
441
|
+
finalResult =
|
|
442
|
+
typeof decompressed === 'string'
|
|
443
|
+
? JSON.parse(decompressed)
|
|
444
|
+
: decompressed;
|
|
445
|
+
} catch (_) {
|
|
446
|
+
return finalResult;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
203
450
|
try {
|
|
204
|
-
await localHandler.set(vKey,
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
console_log('Failed to sync to local:', error.message);
|
|
451
|
+
await localHandler.set(vKey, finalResult, context);
|
|
452
|
+
} catch (_) {
|
|
453
|
+
return finalResult;
|
|
208
454
|
}
|
|
209
|
-
return
|
|
455
|
+
return finalResult;
|
|
210
456
|
}
|
|
211
|
-
} catch (
|
|
212
|
-
|
|
457
|
+
} catch (_) {
|
|
458
|
+
return undefined;
|
|
213
459
|
}
|
|
214
460
|
|
|
215
|
-
console_log('Not found in any cache');
|
|
216
461
|
return undefined;
|
|
217
462
|
},
|
|
218
463
|
set: async (key, value, context) => {
|
|
219
464
|
const vKey = versionKey(key);
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
465
|
+
|
|
466
|
+
let compressedValue;
|
|
467
|
+
let shouldUseCompressed = false;
|
|
468
|
+
|
|
469
|
+
try {
|
|
470
|
+
compressedValue = await compressValue(value);
|
|
471
|
+
|
|
472
|
+
shouldUseCompressed =
|
|
473
|
+
compressedValue !== value &&
|
|
474
|
+
(compressedValue?.__compressed ||
|
|
475
|
+
compressedValue?.value?.__compressed);
|
|
476
|
+
} catch (error) {
|
|
477
|
+
compressedValue = value;
|
|
478
|
+
shouldUseCompressed = false;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
let redisSetResult;
|
|
482
|
+
|
|
483
|
+
if (shouldUseCompressed) {
|
|
484
|
+
try {
|
|
485
|
+
await redisHandler.set(vKey, compressedValue, context);
|
|
486
|
+
|
|
487
|
+
redisSetResult = { status: 'fulfilled' };
|
|
488
|
+
} catch (compressionError) {
|
|
489
|
+
try {
|
|
490
|
+
await redisHandler.set(vKey, value, context);
|
|
491
|
+
|
|
492
|
+
redisSetResult = { status: 'fulfilled' };
|
|
493
|
+
} catch (fallbackError) {
|
|
494
|
+
redisSetResult = { status: 'rejected', reason: fallbackError };
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
} else {
|
|
498
|
+
try {
|
|
499
|
+
await redisHandler.set(vKey, value, context);
|
|
500
|
+
redisSetResult = { status: 'fulfilled' };
|
|
501
|
+
} catch (error) {
|
|
502
|
+
redisSetResult = { status: 'rejected', reason: error };
|
|
503
|
+
return redisSetResult;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
let localSetResult;
|
|
508
|
+
try {
|
|
509
|
+
await localHandler.set(vKey, value, context);
|
|
510
|
+
localSetResult = { status: 'fulfilled' };
|
|
511
|
+
} catch (error) {
|
|
512
|
+
localSetResult = { status: 'rejected', reason: error };
|
|
513
|
+
return localSetResult;
|
|
514
|
+
}
|
|
231
515
|
},
|
|
232
516
|
delete: async (key, context) => {
|
|
233
517
|
const vKey = versionKey(key);
|
|
234
|
-
|
|
235
|
-
'DELETE called for key:',
|
|
236
|
-
typeof vKey === 'string' ? vKey : vKey?.key
|
|
237
|
-
);
|
|
518
|
+
|
|
238
519
|
await Promise.allSettled([
|
|
239
520
|
localHandler.delete?.(vKey, context),
|
|
240
521
|
redisHandler.delete?.(vKey, context)
|
|
241
522
|
]);
|
|
242
523
|
},
|
|
243
524
|
revalidateTag: async (tags, context) => {
|
|
244
|
-
console_log('REVALIDATE_TAG called for tags:', tags);
|
|
245
525
|
await Promise.allSettled([
|
|
246
526
|
localHandler.revalidateTag?.(tags, context),
|
|
247
527
|
redisHandler.revalidateTag?.(tags, context)
|
|
@@ -249,8 +529,6 @@ CacheHandler.onCreation(async () => {
|
|
|
249
529
|
}
|
|
250
530
|
};
|
|
251
531
|
|
|
252
|
-
console_log('[Cache Handler] Handlers initialized successfully');
|
|
253
|
-
|
|
254
532
|
return {
|
|
255
533
|
handlers: [customHandler]
|
|
256
534
|
};
|