@codeleap/styles 5.8.2 → 5.8.3

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.
Files changed (69) hide show
  1. package/package.json +9 -15
  2. package/package.json.bak +8 -14
  3. package/src/classes/Cacher.ts +169 -0
  4. package/src/classes/StaleControl.ts +125 -0
  5. package/src/classes/StyleCache.ts +116 -0
  6. package/src/classes/StylePersistor.ts +62 -0
  7. package/src/{lib → classes}/StyleRegistry.ts +7 -12
  8. package/src/classes/index.ts +2 -0
  9. package/src/classes/tests/Cache.spec.ts +371 -0
  10. package/src/classes/tests/StaleControl.spec.ts +175 -0
  11. package/src/classes/tests/StyleCache.spec.ts +452 -0
  12. package/src/classes/tests/StylePersistor.spec.ts +231 -0
  13. package/src/{lib/constants.ts → constants.ts} +1 -0
  14. package/src/hooks/index.ts +4 -0
  15. package/src/hooks/tests/useCompositionStyles.spec.ts +107 -0
  16. package/src/hooks/tests/useStyleObserver.spec.ts +89 -0
  17. package/src/hooks/useCompositionStyles.ts +33 -0
  18. package/src/hooks/useNestedStylesByKey.ts +13 -0
  19. package/src/hooks/useStyleObserver.ts +19 -0
  20. package/src/hooks/useTheme.ts +16 -0
  21. package/src/index.ts +9 -5
  22. package/src/lib/createStyles.ts +10 -1
  23. package/src/lib/createTheme.ts +22 -13
  24. package/src/lib/index.ts +1 -10
  25. package/src/lib/tests/createStyles.spec.ts +151 -0
  26. package/src/tests/colors/baseColors.ts +166 -0
  27. package/src/tests/colors/darkMode.ts +232 -0
  28. package/src/tests/colors/lightMode.ts +285 -0
  29. package/src/tests/measures.ts +31 -0
  30. package/src/tests/theme.ts +58 -0
  31. package/src/theme/generateColorScheme.ts +53 -0
  32. package/src/theme/index.ts +3 -0
  33. package/src/theme/tests/generateColorScheme.spec.ts +118 -0
  34. package/src/theme/tests/themeStore.spec.ts +698 -0
  35. package/src/theme/tests/validateTheme.spec.ts +173 -0
  36. package/src/{lib → theme}/themeStore.ts +68 -3
  37. package/src/{lib → theme}/validateTheme.ts +13 -0
  38. package/src/tools/colors.ts +83 -39
  39. package/src/tools/deepClone.ts +10 -0
  40. package/src/tools/deepmerge.ts +10 -0
  41. package/src/{lib → tools}/hashKey.ts +7 -0
  42. package/src/tools/index.ts +6 -1
  43. package/src/tools/minifier.ts +38 -0
  44. package/src/tools/tests/colors.spec.ts +233 -0
  45. package/src/tools/tests/deepClone.spec.ts +102 -0
  46. package/src/tools/tests/deepmerge.spec.ts +155 -0
  47. package/src/tools/tests/hashKey.spec.ts +69 -0
  48. package/src/tools/tests/minifier.spec.ts +173 -0
  49. package/src/types/store.ts +2 -2
  50. package/src/types/style.ts +3 -3
  51. package/src/types/theme.ts +4 -4
  52. package/src/{lib/utils.ts → utils.ts} +3 -3
  53. package/src/{lib → variants}/borderCreator.ts +2 -2
  54. package/src/{lib → variants}/createAppVariants.ts +1 -1
  55. package/src/{lib → variants}/dynamicVariants.ts +1 -1
  56. package/src/variants/index.ts +6 -0
  57. package/src/{lib → variants}/spacing.ts +37 -24
  58. package/src/variants/tests/borderCreator.spec.ts +180 -0
  59. package/src/variants/tests/dynamicVariants.spec.ts +194 -0
  60. package/src/variants/tests/spacing.spec.ts +177 -0
  61. package/src/lib/Cacher.ts +0 -112
  62. package/src/lib/StaleControl.ts +0 -73
  63. package/src/lib/StyleCache.ts +0 -81
  64. package/src/lib/StylePersistor.ts +0 -28
  65. package/src/lib/hooks.ts +0 -64
  66. package/src/lib/minifier.ts +0 -20
  67. /package/src/{lib → tools}/multiplierProperty.ts +0 -0
  68. /package/src/{lib → variants}/defaultVariants.ts +0 -0
  69. /package/src/{lib → variants}/mediaQuery.ts +0 -0
@@ -0,0 +1,173 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+ import { validateTheme } from '../validateTheme'
3
+
4
+ describe('validateTheme', () => {
5
+ test('should merge baseColors into colors', () => {
6
+ const theme: any = {
7
+ baseColors: {
8
+ primary: '#000000',
9
+ secondary: '#ffffff',
10
+ },
11
+ colors: {
12
+ background: '#f0f0f0',
13
+ text: '#333333',
14
+ },
15
+ }
16
+
17
+ const result = validateTheme(theme)
18
+
19
+ expect(result.colors).toEqual({
20
+ primary: '#000000',
21
+ secondary: '#ffffff',
22
+ background: '#f0f0f0',
23
+ text: '#333333',
24
+ })
25
+ })
26
+
27
+ test('should validate and merge alternate color schemes', () => {
28
+ const theme: any = {
29
+ baseColors: {
30
+ primary: '#000000',
31
+ secondary: '#ffffff',
32
+ },
33
+ colors: {
34
+ background: '#f0f0f0',
35
+ text: '#333333',
36
+ },
37
+ alternateColors: {
38
+ dark: {
39
+ background: '#1a1a1a',
40
+ text: '#ffffff',
41
+ },
42
+ },
43
+ }
44
+
45
+ const result = validateTheme(theme)
46
+
47
+ expect(result.alternateColors.dark).toEqual({
48
+ primary: '#000000',
49
+ secondary: '#ffffff',
50
+ background: '#1a1a1a',
51
+ text: '#ffffff',
52
+ })
53
+ })
54
+
55
+ test('should throw error when alternate scheme is missing required colors', () => {
56
+ const theme: any = {
57
+ baseColors: {
58
+ primary: '#000000',
59
+ },
60
+ colors: {
61
+ background: '#f0f0f0',
62
+ text: '#333333',
63
+ },
64
+ alternateColors: {
65
+ dark: {
66
+ background: '#1a1a1a',
67
+ // Missing 'text' color
68
+ },
69
+ },
70
+ }
71
+
72
+ expect(() => validateTheme(theme)).toThrow(
73
+ 'Alternate color scheme dark is missing color text'
74
+ )
75
+ })
76
+
77
+ test('should handle theme without alternateColors', () => {
78
+ const theme: any = {
79
+ baseColors: {
80
+ primary: '#000000',
81
+ },
82
+ colors: {
83
+ background: '#f0f0f0',
84
+ },
85
+ }
86
+
87
+ const result = validateTheme(theme)
88
+
89
+ expect(result.colors).toEqual({
90
+ primary: '#000000',
91
+ background: '#f0f0f0',
92
+ })
93
+ expect(result.alternateColors).toEqual({})
94
+ })
95
+
96
+ test('should handle empty baseColors', () => {
97
+ const theme: any = {
98
+ baseColors: {},
99
+ colors: {
100
+ background: '#f0f0f0',
101
+ text: '#333333',
102
+ },
103
+ alternateColors: {
104
+ dark: {
105
+ background: '#1a1a1a',
106
+ text: '#ffffff',
107
+ },
108
+ },
109
+ }
110
+
111
+ const result = validateTheme(theme)
112
+
113
+ expect(result.colors).toEqual({
114
+ background: '#f0f0f0',
115
+ text: '#333333',
116
+ })
117
+ expect(result.alternateColors.dark).toEqual({
118
+ background: '#1a1a1a',
119
+ text: '#ffffff',
120
+ })
121
+ })
122
+
123
+ test('should handle multiple alternate color schemes', () => {
124
+ const theme: any = {
125
+ baseColors: {
126
+ primary: '#000000',
127
+ },
128
+ colors: {
129
+ background: '#f0f0f0',
130
+ text: '#333333',
131
+ },
132
+ alternateColors: {
133
+ dark: {
134
+ background: '#1a1a1a',
135
+ text: '#ffffff',
136
+ },
137
+ light: {
138
+ background: '#ffffff',
139
+ text: '#000000',
140
+ },
141
+ },
142
+ }
143
+
144
+ const result = validateTheme(theme)
145
+
146
+ expect(Object.keys(result.alternateColors)).toEqual(['dark', 'light'])
147
+ expect(result.alternateColors.dark).toEqual({
148
+ primary: '#000000',
149
+ background: '#1a1a1a',
150
+ text: '#ffffff',
151
+ })
152
+ expect(result.alternateColors.light).toEqual({
153
+ primary: '#000000',
154
+ background: '#ffffff',
155
+ text: '#000000',
156
+ })
157
+ })
158
+
159
+ test('should preserve all original theme properties', () => {
160
+ const theme: any = {
161
+ baseColors: { primary: '#000000' },
162
+ colors: { background: '#f0f0f0' },
163
+ alternateColors: { dark: { background: '#1a1a1a' } },
164
+ name: 'test-theme',
165
+ fontSize: { sm: '12px', md: '16px' },
166
+ }
167
+
168
+ const result = validateTheme(theme)
169
+
170
+ expect(result.name).toBe('test-theme')
171
+ expect(result.fontSize).toEqual({ sm: '12px', md: '16px' })
172
+ })
173
+ })
@@ -1,12 +1,19 @@
1
1
  import { AppTheme, ColorMap, IAppVariants, ITheme, Theme } from '../types'
2
2
  import { map, computed, atom } from 'nanostores'
3
3
 
4
+ /**
5
+ * Theme state interface containing theme and color scheme information.
6
+ */
4
7
  export type ThemeState = {
5
8
  theme: AppTheme<Theme> | null
6
9
  colorScheme: string | null
7
10
  }
8
11
 
9
- class ThemeStore {
12
+ /**
13
+ * Global theme store that manages application theme, color schemes, and variants.
14
+ * Uses nanostores for reactive state management.
15
+ */
16
+ export class ThemeStore {
10
17
  private readonly alternateColorsSchemeStore = map<{ [key: string]: ColorMap }>({})
11
18
 
12
19
  public readonly colorSchemeStore = atom<string | null>(null)
@@ -15,44 +22,84 @@ class ThemeStore {
15
22
 
16
23
  public readonly variantsStore = map<IAppVariants>({})
17
24
 
25
+ /**
26
+ * Gets the current theme.
27
+ * @returns {ITheme | null} Current theme or null if not set
28
+ */
18
29
  get theme() {
19
30
  return this.themeStore.get()
20
31
  }
21
32
 
33
+ /**
34
+ * Gets the current theme with typed interface.
35
+ * @returns {AppTheme<Theme>} Current theme cast to AppTheme type
36
+ */
22
37
  get themeTyped() {
23
38
  return this.themeStore.get() as unknown as AppTheme<Theme>
24
39
  }
25
40
 
41
+ /**
42
+ * Gets the current color scheme name.
43
+ * @returns {string | null} Current color scheme name or null if not set
44
+ */
26
45
  get colorScheme() {
27
46
  return this.colorSchemeStore.get()
28
47
  }
29
48
 
49
+ /**
50
+ * Gets the current variants configuration.
51
+ * @returns {IAppVariants} Current variants object
52
+ */
30
53
  get variants() {
31
54
  return this.variantsStore.get()
32
55
  }
33
56
 
57
+ /**
58
+ * Gets all alternate color schemes.
59
+ * @returns {{ [key: string]: ColorMap }} Object containing all alternate color schemes
60
+ */
34
61
  get alternateColorsScheme() {
35
62
  return this.alternateColorsSchemeStore.get() ?? {}
36
63
  }
37
64
 
65
+ /**
66
+ * Sets the variants configuration.
67
+ * @template T
68
+ * @param {T} variants - Variants configuration to set
69
+ */
38
70
  setVariants<T>(variants: T) {
39
71
  this.variantsStore.set(variants as unknown as IAppVariants)
40
72
  }
41
73
 
74
+ /**
75
+ * Sets the current color scheme.
76
+ * @param {string} colorScheme - Color scheme name to set
77
+ */
42
78
  setColorScheme(colorScheme: string) {
43
79
  this.colorSchemeStore.set(colorScheme)
44
80
  }
45
81
 
82
+ /**
83
+ * Sets the current theme.
84
+ * @param {ITheme} theme - Theme object to set
85
+ */
46
86
  setTheme(theme: ITheme) {
47
87
  this.themeStore.set(theme)
48
88
  }
49
89
 
90
+ /**
91
+ * Sets all alternate color schemes.
92
+ * @param {{ [key: string]: ColorMap }} colors - Object containing color schemes
93
+ */
50
94
  setAlternateColorsScheme(colors: { [key: string]: ColorMap }) {
51
95
  this.alternateColorsSchemeStore.set(colors)
52
96
  }
53
97
 
54
- // utils
55
-
98
+ /**
99
+ * Gets the base color scheme colors (first available scheme).
100
+ * @private
101
+ * @returns {ColorMap} Base color scheme colors
102
+ */
56
103
  private getBaseSchemeColors(): ColorMap {
57
104
  const alternateColors = this.alternateColorsScheme ?? {}
58
105
  const colorSchemeKeys = Object.keys(alternateColors)
@@ -64,6 +111,12 @@ class ThemeStore {
64
111
  return alternateColors[colorSchemeKeys[0]] ?? {}
65
112
  }
66
113
 
114
+ /**
115
+ * Injects a new color scheme, merging with base scheme colors.
116
+ * @param {string} name - Name of the color scheme
117
+ * @param {ColorMap} colors - Color map to inject
118
+ * @returns {{ [key: string]: ColorMap }} Updated alternate colors object
119
+ */
67
120
  injectColorScheme(name: string, colors: ColorMap) {
68
121
  const baseSchemeColors = this.getBaseSchemeColors()
69
122
  const currentAlternateColors = this.alternateColorsScheme ?? {}
@@ -82,6 +135,11 @@ class ThemeStore {
82
135
  return alternateColors
83
136
  }
84
137
 
138
+ /**
139
+ * Removes a color scheme by name.
140
+ * @param {string} name - Name of the color scheme to remove
141
+ * @returns {{ [key: string]: ColorMap }} Updated alternate colors object
142
+ */
85
143
  ejectColorScheme(name:string) {
86
144
  const currentAlternateColors = this.alternateColorsScheme ?? {}
87
145
 
@@ -95,8 +153,15 @@ class ThemeStore {
95
153
  }
96
154
  }
97
155
 
156
+ /**
157
+ * Global theme store instance.
158
+ */
98
159
  export const themeStore = new ThemeStore()
99
160
 
161
+ /**
162
+ * Computed store that combines theme and color scheme for reactive updates.
163
+ * @returns {ThemeState} Combined theme state with theme and colorScheme
164
+ */
100
165
  export const themeStoreComputed = computed([
101
166
  themeStore.themeStore,
102
167
  themeStore.colorSchemeStore,
@@ -1,5 +1,18 @@
1
1
  import { Theme } from '../types/theme'
2
2
 
3
+ /**
4
+ * Validates and normalizes a theme object.
5
+ * Ensures all alternate color schemes include the same keys as `colors`,
6
+ * and merges `baseColors` into `colors` and `alternateColors`.
7
+ *
8
+ * @template T extends Theme
9
+ * @param {T} theme - The theme to validate.
10
+ * @throws {Error} If an alternate scheme is missing a required color.
11
+ * @returns {T & {
12
+ * alternateColors: Record<string, Record<string, string>>,
13
+ * colors: Record<string, string>
14
+ * }} The validated theme with merged colors.
15
+ */
3
16
  export function validateTheme<T extends Theme>(theme: T) {
4
17
  const baseColors = theme.baseColors
5
18
 
@@ -1,5 +1,9 @@
1
- import { ColorMap } from '../types'
2
-
1
+ /**
2
+ * Converts a hex color to HSL format.
3
+ *
4
+ * @param {string} hex - Hex color string (e.g., '#ff5733')
5
+ * @returns {object} HSL object with h (0-360), s (0-100), l (0-100)
6
+ */
3
7
  export function hexToHSL(hex: string) {
4
8
  const r = parseInt(hex.slice(1, 3), 16) / 255
5
9
  const g = parseInt(hex.slice(3, 5), 16) / 255
@@ -26,6 +30,14 @@ export function hexToHSL(hex: string) {
26
30
  }
27
31
  }
28
32
 
33
+ /**
34
+ * Converts HSL values to hex color format.
35
+ *
36
+ * @param {number} h - Hue (0-360)
37
+ * @param {number} s - Saturation (0-100)
38
+ * @param {number} l - Lightness (0-100)
39
+ * @returns {string} Hex color string
40
+ */
29
41
  export function hslToHex(h: number, s: number, l: number): string {
30
42
  s /= 100
31
43
  l /= 100
@@ -37,6 +49,12 @@ export function hslToHex(h: number, s: number, l: number): string {
37
49
  return `#${[f(0), f(8), f(4)].map(x => x.toString(16).padStart(2, '0')).join('')}`
38
50
  }
39
51
 
52
+ /**
53
+ * Converts a hex color to RGB format.
54
+ *
55
+ * @param {string} hex - Hex color string (e.g., '#ff5733')
56
+ * @returns {object} RGB object with r, g, b values (0-255)
57
+ */
40
58
  export function hexToRGB(hex: string) {
41
59
  const r = parseInt(hex.slice(1, 3), 16)
42
60
  const g = parseInt(hex.slice(3, 5), 16)
@@ -44,6 +62,14 @@ export function hexToRGB(hex: string) {
44
62
  return { r, g, b }
45
63
  }
46
64
 
65
+ /**
66
+ * Converts HSL values to RGB format.
67
+ *
68
+ * @param {number} h - Hue (0-360)
69
+ * @param {number} s - Saturation (0-100)
70
+ * @param {number} l - Lightness (0-100)
71
+ * @returns {object} RGB object with r, g, b values (0-255)
72
+ */
47
73
  export function hslToRGB(h: number, s: number, l: number) {
48
74
  s /= 100
49
75
  l /= 100
@@ -59,47 +85,56 @@ export function hslToRGB(h: number, s: number, l: number) {
59
85
  }
60
86
  }
61
87
 
62
- const lightnesses = [95, 85, 75, 60, 45, 30, 27, 21, 16, 10]
63
-
64
- const defaultLightnessMap = Object.fromEntries(
65
- lightnesses.map((l, i) => {
66
- const step = ((i + 1) * 100).toString()
67
- return [step, l]
68
- }),
69
- )
70
-
71
- const alphas = [0.05, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90]
72
-
73
- const defaultAlphasMap = Object.fromEntries(
74
- alphas.map((a, i) => {
75
- const step = ((i + 1) * 100).toString()
76
- return [step, a]
77
- }),
78
- )
79
-
80
- export function generateColorScheme(
81
- anchorHex: string,
82
- prefix = 'primary',
83
- lightnesses:typeof defaultLightnessMap = defaultLightnessMap,
84
- alphas: typeof defaultAlphasMap = defaultAlphasMap,
85
- ): ColorMap {
86
- const { h, s } = hexToHSL(anchorHex)
87
- const baseRGB = hexToRGB(anchorHex)
88
-
89
- const scheme: ColorMap = {}
90
-
91
- Object.entries(lightnesses).forEach(([step, lightness]) => {
92
- const rgb = hslToRGB(h, s, lightness)
93
- scheme[`${prefix}Solid${step}`] = `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 1.00)`
94
- })
88
+ /**
89
+ * Converts RGB values to HSL format.
90
+ *
91
+ * @param {object} rgb - RGB object with r, g, b values (0-255)
92
+ * @returns {object} HSL object with h (0-360), s (0-100), l (0-100)
93
+ */
94
+ export function rgbToHSL(rgb: { r: number; g: number; b: number }): { h: number; s: number; l: number } {
95
+ const r = rgb.r / 255
96
+ const g = rgb.g / 255
97
+ const b = rgb.b / 255
98
+
99
+ const max = Math.max(r, g, b)
100
+ const min = Math.min(r, g, b)
101
+ let h = 0
102
+ let s = 0
103
+ const l = (max + min) / 2
95
104
 
96
- Object.entries(alphas).forEach(([step, alpha]) => {
97
- scheme[`${prefix}Transparent${step}`] = `rgba(${baseRGB.r}, ${baseRGB.g}, ${baseRGB.b}, ${alpha.toFixed(2)})`
98
- })
105
+ if (max !== min) {
106
+ const d = max - min
107
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min)
108
+
109
+ switch (max) {
110
+ case r:
111
+ h = (g - b) / d + (g < b ? 6 : 0)
112
+ break
113
+ case g:
114
+ h = (b - r) / d + 2
115
+ break
116
+ case b:
117
+ h = (r - g) / d + 4
118
+ break
119
+ }
120
+
121
+ h /= 6
122
+ }
99
123
 
100
- return scheme
124
+ return {
125
+ h: Math.round(h * 360),
126
+ s: Math.round(s * 100),
127
+ l: Math.round(l * 100)
128
+ }
101
129
  }
102
130
 
131
+ /**
132
+ * Calculates the relative luminance of an RGB color.
133
+ * Uses the WCAG formula for accessibility calculations.
134
+ *
135
+ * @param {object} rgb - RGB object with r, g, b values (0-255)
136
+ * @returns {number} Luminance value (0-1)
137
+ */
103
138
  export function getLuminance({ r, g, b }: { r: number; g: number; b: number }): number {
104
139
  const [R, G, B] = [r, g, b].map(c => {
105
140
  const channel = c / 255
@@ -111,6 +146,15 @@ export function getLuminance({ r, g, b }: { r: number; g: number; b: number }):
111
146
  return 0.2126 * R + 0.7152 * G + 0.0722 * B
112
147
  }
113
148
 
149
+ /**
150
+ * Determines the best text color (dark or light) for a given background.
151
+ * Uses luminance calculation for optimal contrast.
152
+ *
153
+ * @param {string} backgroundHex - Background hex color
154
+ * @param {string} darkColor - Dark text color option
155
+ * @param {string} lightColor - Light text color option
156
+ * @returns {string} Recommended text color
157
+ */
114
158
  export function getTextColor(backgroundHex: string, darkColor = 'black', lightColor = 'white'): string {
115
159
  const rgb = hexToRGB(backgroundHex)
116
160
  const luminance = getLuminance(rgb)
@@ -0,0 +1,10 @@
1
+ import rfdc from 'rfdc'
2
+
3
+ /**
4
+ * Creates a deep clone of any JavaScript object or value.
5
+ * Uses rfdc (Really Fast Deep Clone) for optimal performance.
6
+ *
7
+ * @param {T} obj - The object or value to clone
8
+ * @returns {T} A deep copy of the input
9
+ */
10
+ export const deepClone = rfdc()
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Deep merge constructor from Fastify's optimized implementation.
3
+ * Returns a merge function that recursively merges objects with high performance.
4
+ * By default, arrays are concatenated and objects are deeply merged.
5
+ *
6
+ * @example
7
+ * const merger = deepmerge()
8
+ * const result = merger(target, source)
9
+ */
10
+ export { default as deepmerge } from '@fastify/deepmerge'
@@ -3,6 +3,13 @@ import { sha256 } from 'js-sha256'
3
3
  const styleKey = '@styles-version'
4
4
  const version = require('../../package.json')?.version
5
5
 
6
+ /**
7
+ * Generates a SHA-256 hash from an array with automatic version injection.
8
+ * Appends package version to the array for cache invalidation purposes.
9
+ *
10
+ * @param {Array<any>} value - Array to be hashed
11
+ * @returns {string} SHA-256 hash string
12
+ */
6
13
  export const hashKey = (value: Array<any>): string => {
7
14
  value.push({ [styleKey]: version })
8
15
 
@@ -1 +1,6 @@
1
- export * as colorTools from './colors'
1
+ export * as colorTools from './colors'
2
+ export * from './hashKey'
3
+ export * from './minifier'
4
+ export * from './multiplierProperty'
5
+ export * from './deepClone'
6
+ export * from './deepmerge'
@@ -0,0 +1,38 @@
1
+ import { compressToBase64, decompressFromBase64 } from 'lz-string'
2
+
3
+ /**
4
+ * Compresses any value to a Base64 string using LZ compression.
5
+ * Returns the original value if falsy.
6
+ *
7
+ * @param {any} value - Value to compress
8
+ * @returns {string|any} Compressed Base64 string or original falsy value
9
+ */
10
+ export function compress(value: any): any {
11
+ if (!value) return value
12
+
13
+ return compressToBase64(JSON.stringify(value))
14
+ }
15
+
16
+ /**
17
+ * Decompresses a Base64 string back to its original value.
18
+ * Returns the original value if falsy.
19
+ *
20
+ * @param {any} value - Compressed Base64 string to decompress
21
+ * @returns {any} Original decompressed value or original falsy value
22
+ */
23
+ export function decompress(value: any): any {
24
+ if (!value) return value
25
+
26
+ const decoded = decompressFromBase64(value)
27
+
28
+ return JSON.parse(decoded)
29
+ }
30
+
31
+ /**
32
+ * Utility object containing compress and decompress functions.
33
+ * Useful for data compression/decompression operations.
34
+ */
35
+ export const minifier = {
36
+ compress,
37
+ decompress,
38
+ }