@akinon/next 1.93.0-snapshot-ZERO-3586-20250827125222 → 1.93.0-snapshot-ZERO-3586-20250827132644

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-20250827125222
3
+ ## 1.93.0-snapshot-ZERO-3586-20250827132644
4
4
 
5
5
  ### Minor Changes
6
6
 
@@ -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
@@ -46,6 +46,9 @@ export const getFlatPageData = ({
46
46
  return Cache.wrap(
47
47
  CacheKey.FlatPage(pk),
48
48
  locale,
49
- getFlatPageDataHandler(pk, locale, currency, headers)
49
+ getFlatPageDataHandler(pk, locale, currency, headers),
50
+ {
51
+ compressed: true
52
+ }
50
53
  );
51
54
  };
@@ -43,6 +43,9 @@ export const getFormData = ({
43
43
  return Cache.wrap(
44
44
  CacheKey.Form(pk),
45
45
  locale,
46
- getFormDataHandler(pk, locale, currency, headers)
46
+ getFormDataHandler(pk, locale, currency, headers),
47
+ {
48
+ compressed: true
49
+ }
47
50
  );
48
51
  };
@@ -46,6 +46,9 @@ export const getLandingPageData = ({
46
46
  return Cache.wrap(
47
47
  CacheKey.LandingPage(pk),
48
48
  locale,
49
- getLandingPageHandler(pk, locale, currency, headers)
49
+ getLandingPageHandler(pk, locale, currency, headers),
50
+ {
51
+ compressed: true
52
+ }
50
53
  );
51
54
  };
@@ -43,6 +43,9 @@ export const getSeoData = async (
43
43
  return Cache.wrap(
44
44
  CacheKey.Seo(url),
45
45
  locale,
46
- getSeoDataHandler({ url, locale, currency, headers })
46
+ getSeoDataHandler({ url, locale, currency, headers }),
47
+ {
48
+ compressed: true
49
+ }
47
50
  );
48
51
  };
@@ -44,6 +44,9 @@ export const getWidgetData = async <T>({
44
44
  CacheKey.Widget(slug),
45
45
  locale,
46
46
  getWidgetDataHandler(slug, locale, currency, headers),
47
- cacheOptions
47
+ {
48
+ compressed: true,
49
+ ...cacheOptions
50
+ }
48
51
  );
49
52
  };
package/lib/cache.ts CHANGED
@@ -10,7 +10,12 @@ let isZstdInitialized = false;
10
10
 
11
11
  const initZstd = async () => {
12
12
  if (!isZstdInitialized) {
13
- await zstd.init();
13
+ try {
14
+ await zstd.init();
15
+ } catch (error) {
16
+ logger.error('Failed to initialize zstd compression', { error });
17
+ throw new Error('ZSTD initialization failed');
18
+ }
14
19
  isZstdInitialized = true;
15
20
  }
16
21
  };
@@ -204,7 +209,8 @@ export class Cache {
204
209
 
205
210
  const defaultOptions: CacheOptions = {
206
211
  cache: true,
207
- expire: Settings.redis.defaultExpirationTime
212
+ expire: Settings.redis.defaultExpirationTime,
213
+ compressed: process.env.CACHE_COMPRESSION_ENABLED !== 'false'
208
214
  };
209
215
 
210
216
  const _options = Object.assign(defaultOptions, options);
@@ -282,7 +288,7 @@ export class Cache {
282
288
  await fetch(Cache.PROXY_URL, {
283
289
  method,
284
290
  headers: {
285
- authorization: process.env.CACHE_SECRET
291
+ authorization: process.env.CACHE_SECRET || ''
286
292
  },
287
293
  body
288
294
  })
@@ -383,30 +389,50 @@ export class Cache {
383
389
  });
384
390
  }
385
391
 
386
- await initZstd();
387
- const compressed = Buffer.from(
388
- zstd.compress(new Uint8Array(Buffer.from(serializedValue, 'utf8')), 3)
389
- );
392
+ try {
393
+ await initZstd();
394
+ const compressed = Buffer.from(
395
+ zstd.compress(new Uint8Array(Buffer.from(serializedValue, 'utf8')), 3)
396
+ );
390
397
 
391
- const compressedBase64 = compressed.toString('base64');
398
+ const compressedBase64 = compressed.toString('base64');
392
399
 
393
- if (expire) {
394
- await client.set(key, compressedBase64, { EX: expire });
395
- } else {
396
- await client.set(key, compressedBase64);
397
- }
400
+ if (expire) {
401
+ await client.set(key, compressedBase64, { EX: expire });
402
+ } else {
403
+ await client.set(key, compressedBase64);
404
+ }
398
405
 
399
- success = true;
400
- const compressionRatio = (
401
- (1 - compressed.length / serializedValue.length) *
402
- 100
403
- ).toFixed(2);
404
- logger.debug('Redis setCompressed success', {
405
- key,
406
- originalSize: serializedValue.length,
407
- compressedSize: compressed.length,
408
- compressionRatio: `${compressionRatio}%`
409
- });
406
+ success = true;
407
+ const compressionRatio = (
408
+ (1 - compressed.length / serializedValue.length) *
409
+ 100
410
+ ).toFixed(2);
411
+ logger.debug('Redis setCompressed success', {
412
+ key,
413
+ originalSize: serializedValue.length,
414
+ compressedSize: compressed.length,
415
+ compressionRatio: `${compressionRatio}%`
416
+ });
417
+ } catch (compressionError) {
418
+ // If compression fails, fallback to uncompressed storage
419
+ logger.warn('Compression failed, storing uncompressed', {
420
+ key,
421
+ error: compressionError
422
+ });
423
+
424
+ if (expire) {
425
+ await client.set(key, serializedValue, { EX: expire });
426
+ } else {
427
+ await client.set(key, serializedValue);
428
+ }
429
+
430
+ success = true;
431
+ logger.debug('Redis set success (uncompressed fallback)', {
432
+ key,
433
+ size: serializedValue.length
434
+ });
435
+ }
410
436
  } catch (error) {
411
437
  logger.error('Redis setCompressed error', { key, error });
412
438
  success = false;
@@ -438,10 +464,9 @@ export class Cache {
438
464
  if (compressed) {
439
465
  const compressedBuffer = Buffer.from(compressed, 'base64');
440
466
 
441
- await initZstd();
442
-
443
467
  let decompressed: Buffer;
444
468
  try {
469
+ await initZstd();
445
470
  decompressed = Buffer.from(
446
471
  zstd.decompress(new Uint8Array(compressedBuffer))
447
472
  );
@@ -452,29 +477,46 @@ export class Cache {
452
477
  );
453
478
 
454
479
  try {
455
- const { gunzip } = await import('zlib');
456
- const { promisify } = await import('util');
457
- const gunzipAsync = promisify(gunzip);
458
- decompressed = await gunzipAsync(compressedBuffer as any);
459
- logger.debug('Successfully decompressed with gzip fallback', {
460
- key
461
- });
462
- } catch (gzipError) {
463
- logger.debug('Gzip fallback also failed, trying raw JSON parse', {
464
- key
465
- });
480
+ // Try if it's actually uncompressed JSON (from fallback in setCompressed)
481
+ const rawString = compressed;
482
+ const parsedData = JSON.parse(rawString);
483
+ logger.debug(
484
+ 'Data was stored uncompressed (fallback), returning raw JSON',
485
+ {
486
+ key
487
+ }
488
+ );
489
+ return parsedData;
490
+ } catch (jsonError) {
466
491
  try {
467
- const rawString = compressedBuffer.toString('utf8');
468
- JSON.parse(rawString);
469
- return JSON.parse(rawString);
470
- } catch (jsonError) {
471
- logger.error('All decompression methods failed', {
472
- key,
473
- error,
474
- gzipError,
475
- jsonError
492
+ const { gunzip } = await import('zlib');
493
+ const { promisify } = await import('util');
494
+ const gunzipAsync = promisify(gunzip);
495
+ decompressed = await gunzipAsync(compressedBuffer as any);
496
+ logger.debug('Successfully decompressed with gzip fallback', {
497
+ key
476
498
  });
477
- throw error;
499
+ } catch (gzipError) {
500
+ logger.debug(
501
+ 'All fallback methods failed, trying base64 decoded JSON',
502
+ {
503
+ key
504
+ }
505
+ );
506
+ try {
507
+ const rawString = compressedBuffer.toString('utf8');
508
+ const parsedData = JSON.parse(rawString);
509
+ return parsedData;
510
+ } catch (finalError) {
511
+ logger.error('All decompression methods failed', {
512
+ key,
513
+ error,
514
+ jsonError,
515
+ gzipError,
516
+ finalError
517
+ });
518
+ return null;
519
+ }
478
520
  }
479
521
  }
480
522
  }
@@ -53,7 +53,8 @@ const resolvePrettyUrl = async (
53
53
  locale,
54
54
  resolvePrettyUrlHandler(pathname, ip),
55
55
  {
56
- useProxy: true
56
+ useProxy: true,
57
+ compressed: true
57
58
  }
58
59
  );
59
60
  };
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-20250827125222",
4
+ "version": "1.93.0-snapshot-ZERO-3586-20250827132644",
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-20250827125222",
38
+ "@akinon/eslint-plugin-projectzero": "1.93.0-snapshot-ZERO-3586-20250827132644",
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,18 @@ const defaultConfig = {
57
57
  }, {}),
58
58
  translations: false
59
59
  };
60
+
61
+
62
+ config.experiments = {
63
+ ...config.experiments,
64
+ asyncWebAssembly: true
65
+ };
66
+
67
+ config.module.rules.push({
68
+ test: /\.wasm$/,
69
+ type: 'webassembly/async'
70
+ });
71
+
60
72
  return config;
61
73
  },
62
74
  sentry: {