@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @akinon/next
2
2
 
3
- ## 1.93.0-snapshot-ZERO-3586-20250827130920
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
- - 0ad91bb: ZERO-3489: Improve error handling in data fetching across multiple pages and server functions
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
- - 89ce46f: ZERO-3493: return 404 status code for pz-not-found pages
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
- - 86642cf: ZERO-3531: Add saveSampleProducts endpoint and update URLs in checkout
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
- await zstd.init();
14
- isZstdInitialized = true;
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
- const compressedBase64 = compressed.toString('base64');
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
- if (expire) {
395
- await client.set(key, compressedBase64, { EX: expire });
406
+ success = true;
407
+ logger.debug('Redis set success (uncompressed - ZSTD unavailable)', {
408
+ key,
409
+ size: serializedValue.length
410
+ });
396
411
  } else {
397
- await client.set(key, compressedBase64);
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
- success = true;
401
- const compressionRatio = (
402
- (1 - compressed.length / serializedValue.length) *
403
- 100
404
- ).toFixed(2);
405
- logger.debug('Redis setCompressed success', {
406
- key,
407
- originalSize: serializedValue.length,
408
- compressedSize: compressed.length,
409
- compressionRatio: `${compressionRatio}%`
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
- const { gunzip } = await import('zlib');
457
- const { promisify } = await import('util');
458
- const gunzipAsync = promisify(gunzip);
459
- decompressed = await gunzipAsync(compressedBuffer as any);
460
- logger.debug('Successfully decompressed with gzip fallback', {
461
- key
462
- });
463
- } catch (gzipError) {
464
- logger.debug('Gzip fallback also failed, trying raw JSON parse', {
465
- key
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 rawString = compressedBuffer.toString('utf8');
469
- JSON.parse(rawString);
470
- return JSON.parse(rawString);
471
- } catch (jsonError) {
472
- logger.error('All decompression methods failed', {
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
- throw error;
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-20250827130920",
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-20250827130920",
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: {