@akinon/next 1.93.0-snapshot-ZERO-3586-20250827130920 → 1.93.0-snapshot-ZERO-3586-20250827134335
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 +4 -4
- package/lib/cache.ts +121 -46
- package/package.json +2 -2
- package/with-pz-config.js +8 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @akinon/next
|
|
2
2
|
|
|
3
|
-
## 1.93.0-snapshot-ZERO-3586-
|
|
3
|
+
## 1.93.0-snapshot-ZERO-3586-20250827134335
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
- d8be48fb: ZERO-3422: Update fetch method to use dynamic request method in wallet complete redirection middleware
|
|
20
20
|
- b55acb76: ZERO-2577: Fix pagination bug and update usePagination hook and ensure pagination controls rendering correctly
|
|
21
21
|
- f49bb74f: ZERO-3097: Add setCookie to logging in payment redirection middlewares
|
|
22
|
-
-
|
|
22
|
+
- 0ad91bbd: ZERO-3489: Improve error handling in data fetching across multiple pages and server functions
|
|
23
23
|
- 143be2b9: ZERO-3457: Crop styles are customizable and logic improved for rendering similar products modal
|
|
24
24
|
- e9541a13d: ZERO-2816: Add headers to url
|
|
25
25
|
- 9b7d0de6: ZERO-3393: Improve error handling in checkout middleware to support both object and array error formats
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
- 64699d3ff: ZERO-2761: Fix invalid import for plugin module
|
|
31
31
|
- 9f8cd3bc: ZERO-3449: AI Search Active Filters & Crop Style changes have been implemented
|
|
32
32
|
- e974d8e8: ZERO-3406: Fix rc build
|
|
33
|
-
-
|
|
33
|
+
- 89ce46fc: ZERO-3493: return 404 status code for pz-not-found pages
|
|
34
34
|
- 8645d90: ZERO-3574:Refactor redirect tests: streamline mock setup, enhance locale handling, and improve URL path resolution logic
|
|
35
35
|
- 7eb51ca9: ZERO-3424 :Update package versions
|
|
36
36
|
- c806fad7: ZERO-3422: Add Flow Payment plugin to the defined plugins list
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
- 0de55738: ZERO-3418: Update remotePatterns hostname to allow all subdomains
|
|
52
52
|
- 7e56d6b6b: ZERO-2841: Update api tagTypes
|
|
53
53
|
- dfaceffd: ZERO-3356: Add useLoyaltyAvailability hook and update checkout state management
|
|
54
|
-
-
|
|
54
|
+
- 86642cfa: ZERO-3531: Add saveSampleProducts endpoint and update URLs in checkout
|
|
55
55
|
- d99a6a7d: ZERO-3457: Fixed the settings prop and made sure everything is customizable.
|
|
56
56
|
- 9dc7298a: ZERO-3416: Refactor Accordion component to enhance props and improve styling flexibility
|
|
57
57
|
- 33377cfd: ZERO-3267: Refactor import statement for ROUTES in error-page component
|
package/lib/cache.ts
CHANGED
|
@@ -6,12 +6,21 @@ import logger from '../utils/log';
|
|
|
6
6
|
import * as zstd from '@bokuweb/zstd-wasm';
|
|
7
7
|
|
|
8
8
|
const CACHE_VERSION = 'v2';
|
|
9
|
-
let isZstdInitialized = false;
|
|
9
|
+
let isZstdInitialized: boolean | 'failed' = false;
|
|
10
10
|
|
|
11
11
|
const initZstd = async () => {
|
|
12
12
|
if (!isZstdInitialized) {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
try {
|
|
14
|
+
await zstd.init();
|
|
15
|
+
isZstdInitialized = true;
|
|
16
|
+
} catch (error) {
|
|
17
|
+
logger.warn(
|
|
18
|
+
'ZSTD compression not available, falling back to uncompressed',
|
|
19
|
+
{ error }
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
isZstdInitialized = 'failed';
|
|
23
|
+
}
|
|
15
24
|
}
|
|
16
25
|
};
|
|
17
26
|
|
|
@@ -283,7 +292,7 @@ export class Cache {
|
|
|
283
292
|
await fetch(Cache.PROXY_URL, {
|
|
284
293
|
method,
|
|
285
294
|
headers: {
|
|
286
|
-
authorization: process.env.CACHE_SECRET
|
|
295
|
+
authorization: process.env.CACHE_SECRET || ''
|
|
287
296
|
},
|
|
288
297
|
body
|
|
289
298
|
})
|
|
@@ -385,29 +394,68 @@ export class Cache {
|
|
|
385
394
|
}
|
|
386
395
|
|
|
387
396
|
await initZstd();
|
|
388
|
-
const compressed = Buffer.from(
|
|
389
|
-
zstd.compress(new Uint8Array(Buffer.from(serializedValue, 'utf8')), 3)
|
|
390
|
-
);
|
|
391
397
|
|
|
392
|
-
|
|
398
|
+
if (isZstdInitialized === 'failed') {
|
|
399
|
+
// ZSTD failed to initialize, store uncompressed
|
|
400
|
+
if (expire) {
|
|
401
|
+
await client.set(key, serializedValue, { EX: expire });
|
|
402
|
+
} else {
|
|
403
|
+
await client.set(key, serializedValue);
|
|
404
|
+
}
|
|
393
405
|
|
|
394
|
-
|
|
395
|
-
|
|
406
|
+
success = true;
|
|
407
|
+
logger.debug('Redis set success (uncompressed - ZSTD unavailable)', {
|
|
408
|
+
key,
|
|
409
|
+
size: serializedValue.length
|
|
410
|
+
});
|
|
396
411
|
} else {
|
|
397
|
-
|
|
398
|
-
|
|
412
|
+
try {
|
|
413
|
+
const compressed = Buffer.from(
|
|
414
|
+
zstd.compress(
|
|
415
|
+
new Uint8Array(Buffer.from(serializedValue, 'utf8')),
|
|
416
|
+
3
|
|
417
|
+
)
|
|
418
|
+
);
|
|
399
419
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
420
|
+
const compressedBase64 = compressed.toString('base64');
|
|
421
|
+
|
|
422
|
+
if (expire) {
|
|
423
|
+
await client.set(key, compressedBase64, { EX: expire });
|
|
424
|
+
} else {
|
|
425
|
+
await client.set(key, compressedBase64);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
success = true;
|
|
429
|
+
const compressionRatio = (
|
|
430
|
+
(1 - compressed.length / serializedValue.length) *
|
|
431
|
+
100
|
|
432
|
+
).toFixed(2);
|
|
433
|
+
logger.debug('Redis setCompressed success', {
|
|
434
|
+
key,
|
|
435
|
+
originalSize: serializedValue.length,
|
|
436
|
+
compressedSize: compressed.length,
|
|
437
|
+
compressionRatio: `${compressionRatio}%`
|
|
438
|
+
});
|
|
439
|
+
} catch (compressionError) {
|
|
440
|
+
// If compression fails, fallback to uncompressed storage
|
|
441
|
+
logger.warn('Compression failed, storing uncompressed', {
|
|
442
|
+
key,
|
|
443
|
+
error: compressionError
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
if (expire) {
|
|
447
|
+
await client.set(key, serializedValue, { EX: expire });
|
|
448
|
+
} else {
|
|
449
|
+
await client.set(key, serializedValue);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
success = true;
|
|
453
|
+
logger.debug('Redis set success (uncompressed fallback)', {
|
|
454
|
+
key,
|
|
455
|
+
size: serializedValue.length
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
}
|
|
411
459
|
} catch (error) {
|
|
412
460
|
logger.error('Redis setCompressed error', { key, error });
|
|
413
461
|
success = false;
|
|
@@ -439,10 +487,20 @@ export class Cache {
|
|
|
439
487
|
if (compressed) {
|
|
440
488
|
const compressedBuffer = Buffer.from(compressed, 'base64');
|
|
441
489
|
|
|
442
|
-
await initZstd();
|
|
443
|
-
|
|
444
490
|
let decompressed: Buffer;
|
|
445
491
|
try {
|
|
492
|
+
await initZstd();
|
|
493
|
+
|
|
494
|
+
if (isZstdInitialized === 'failed') {
|
|
495
|
+
// ZSTD not available, try direct JSON parse
|
|
496
|
+
const rawString = compressed;
|
|
497
|
+
const parsedData = JSON.parse(rawString);
|
|
498
|
+
logger.debug('Data read as uncompressed (ZSTD unavailable)', {
|
|
499
|
+
key
|
|
500
|
+
});
|
|
501
|
+
return parsedData;
|
|
502
|
+
}
|
|
503
|
+
|
|
446
504
|
decompressed = Buffer.from(
|
|
447
505
|
zstd.decompress(new Uint8Array(compressedBuffer))
|
|
448
506
|
);
|
|
@@ -453,29 +511,46 @@ export class Cache {
|
|
|
453
511
|
);
|
|
454
512
|
|
|
455
513
|
try {
|
|
456
|
-
|
|
457
|
-
const
|
|
458
|
-
const
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
514
|
+
// Try if it's actually uncompressed JSON (from fallback in setCompressed)
|
|
515
|
+
const rawString = compressed;
|
|
516
|
+
const parsedData = JSON.parse(rawString);
|
|
517
|
+
logger.debug(
|
|
518
|
+
'Data was stored uncompressed (fallback), returning raw JSON',
|
|
519
|
+
{
|
|
520
|
+
key
|
|
521
|
+
}
|
|
522
|
+
);
|
|
523
|
+
return parsedData;
|
|
524
|
+
} catch (jsonError) {
|
|
467
525
|
try {
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
logger.
|
|
473
|
-
key
|
|
474
|
-
error,
|
|
475
|
-
gzipError,
|
|
476
|
-
jsonError
|
|
526
|
+
const { gunzip } = await import('zlib');
|
|
527
|
+
const { promisify } = await import('util');
|
|
528
|
+
const gunzipAsync = promisify(gunzip);
|
|
529
|
+
decompressed = await gunzipAsync(compressedBuffer as any);
|
|
530
|
+
logger.debug('Successfully decompressed with gzip fallback', {
|
|
531
|
+
key
|
|
477
532
|
});
|
|
478
|
-
|
|
533
|
+
} catch (gzipError) {
|
|
534
|
+
logger.debug(
|
|
535
|
+
'All fallback methods failed, trying base64 decoded JSON',
|
|
536
|
+
{
|
|
537
|
+
key
|
|
538
|
+
}
|
|
539
|
+
);
|
|
540
|
+
try {
|
|
541
|
+
const rawString = compressedBuffer.toString('utf8');
|
|
542
|
+
const parsedData = JSON.parse(rawString);
|
|
543
|
+
return parsedData;
|
|
544
|
+
} catch (finalError) {
|
|
545
|
+
logger.error('All decompression methods failed', {
|
|
546
|
+
key,
|
|
547
|
+
error,
|
|
548
|
+
jsonError,
|
|
549
|
+
gzipError,
|
|
550
|
+
finalError
|
|
551
|
+
});
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
479
554
|
}
|
|
480
555
|
}
|
|
481
556
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/next",
|
|
3
3
|
"description": "Core package for Project Zero Next",
|
|
4
|
-
"version": "1.93.0-snapshot-ZERO-3586-
|
|
4
|
+
"version": "1.93.0-snapshot-ZERO-3586-20250827134335",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"set-cookie-parser": "2.6.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@akinon/eslint-plugin-projectzero": "1.93.0-snapshot-ZERO-3586-
|
|
38
|
+
"@akinon/eslint-plugin-projectzero": "1.93.0-snapshot-ZERO-3586-20250827134335",
|
|
39
39
|
"@babel/core": "7.26.10",
|
|
40
40
|
"@babel/preset-env": "7.26.9",
|
|
41
41
|
"@babel/preset-typescript": "7.27.0",
|
package/with-pz-config.js
CHANGED
|
@@ -17,7 +17,7 @@ const defaultConfig = {
|
|
|
17
17
|
{
|
|
18
18
|
protocol: 'https',
|
|
19
19
|
hostname: '**'
|
|
20
|
-
}
|
|
20
|
+
}
|
|
21
21
|
]
|
|
22
22
|
},
|
|
23
23
|
modularizeImports: {
|
|
@@ -57,6 +57,13 @@ const defaultConfig = {
|
|
|
57
57
|
}, {}),
|
|
58
58
|
translations: false
|
|
59
59
|
};
|
|
60
|
+
|
|
61
|
+
// WASM support for zstd-wasm (following official documentation)
|
|
62
|
+
config.module.rules.push({
|
|
63
|
+
test: /zstd\.wasm$/,
|
|
64
|
+
type: 'asset/resource'
|
|
65
|
+
});
|
|
66
|
+
|
|
60
67
|
return config;
|
|
61
68
|
},
|
|
62
69
|
sentry: {
|