@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,698 @@
1
+ import { describe, it, expect, beforeEach } from 'bun:test'
2
+ import { ThemeStore, themeStore, themeStoreComputed } from '../themeStore'
3
+
4
+ describe('ThemeStore - Heavy Load Tests', () => {
5
+ let store: ThemeStore
6
+
7
+ const getThemeStore = () => store.theme as any
8
+
9
+ beforeEach(() => {
10
+ store = new ThemeStore()
11
+ })
12
+
13
+ describe('basic functionality', () => {
14
+ it('should handle theme management', () => {
15
+ const mockTheme = {
16
+ colors: { primary: '#007bff' },
17
+ spacing: { small: '8px' }
18
+ }
19
+
20
+ store.setTheme(mockTheme)
21
+ expect(getThemeStore()).toEqual(mockTheme)
22
+ })
23
+
24
+ it('should handle color scheme management', () => {
25
+ store.setColorScheme('dark')
26
+ expect(store.colorScheme).toBe('dark')
27
+ })
28
+ })
29
+
30
+ describe('stress tests - massive data operations', () => {
31
+ it('should handle thousands of theme updates without performance degradation', () => {
32
+ const iterations = 10000
33
+ const startTime = performance.now()
34
+
35
+ for (let i = 0; i < iterations; i++) {
36
+ const theme = {
37
+ colors: {
38
+ primary: `#${i.toString(16).padStart(6, '0')}`,
39
+ secondary: `#${(i * 2).toString(16).padStart(6, '0')}`,
40
+ background: `#${(i * 3).toString(16).padStart(6, '0')}`,
41
+ surface: `#${(i * 4).toString(16).padStart(6, '0')}`,
42
+ text: `#${(i * 5).toString(16).padStart(6, '0')}`
43
+ },
44
+ spacing: {
45
+ xs: `${i}px`,
46
+ sm: `${i * 2}px`,
47
+ md: `${i * 4}px`,
48
+ lg: `${i * 8}px`,
49
+ xl: `${i * 16}px`
50
+ },
51
+ typography: {
52
+ fontSize: `${i}px`,
53
+ fontWeight: i % 900,
54
+ lineHeight: i / 100
55
+ },
56
+ iteration: i
57
+ }
58
+
59
+ store.setTheme(theme)
60
+
61
+ // Verify state is correctly updated every 1000 iterations
62
+ if (i % 1000 === 0) {
63
+ expect(getThemeStore()?.iteration).toBe(i)
64
+ }
65
+ }
66
+
67
+ const endTime = performance.now()
68
+ const executionTime = endTime - startTime
69
+
70
+ // Should complete within reasonable time (adjust threshold as needed)
71
+ expect(executionTime).toBeLessThan(5000) // 5 seconds
72
+ expect(getThemeStore()?.iteration).toBe(iterations - 1)
73
+
74
+ console.log(`Theme updates: ${iterations} operations in ${executionTime.toFixed(2)}ms`)
75
+ })
76
+
77
+ it('should handle massive color schemes with deep nesting', () => {
78
+ const colorSchemes = {}
79
+ const schemeCount = 1000
80
+ const colorsPerScheme = 100
81
+
82
+ // Generate massive color schemes
83
+ for (let scheme = 0; scheme < schemeCount; scheme++) {
84
+ const colors = {}
85
+ for (let color = 0; color < colorsPerScheme; color++) {
86
+ colors[`color_${color}`] = {
87
+ primary: `#${(scheme * color).toString(16).padStart(6, '0')}`,
88
+ variants: {
89
+ light: `#${(scheme * color + 100000).toString(16).padStart(6, '0')}`,
90
+ dark: `#${(scheme * color + 200000).toString(16).padStart(6, '0')}`,
91
+ medium: `#${(scheme * color + 300000).toString(16).padStart(6, '0')}`
92
+ },
93
+ states: {
94
+ hover: `#${(scheme * color + 400000).toString(16).padStart(6, '0')}`,
95
+ active: `#${(scheme * color + 500000).toString(16).padStart(6, '0')}`,
96
+ disabled: `#${(scheme * color + 600000).toString(16).padStart(6, '0')}`,
97
+ focus: `#${(scheme * color + 700000).toString(16).padStart(6, '0')}`
98
+ }
99
+ }
100
+ }
101
+ colorSchemes[`scheme_${scheme}`] = colors
102
+ }
103
+
104
+ const startTime = performance.now()
105
+ store.setAlternateColorsScheme(colorSchemes)
106
+ const endTime = performance.now()
107
+
108
+ expect(Object.keys(store.alternateColorsScheme)).toHaveLength(schemeCount)
109
+ expect(Object.keys(store.alternateColorsScheme.scheme_0)).toHaveLength(colorsPerScheme)
110
+
111
+ console.log(`Color schemes: ${schemeCount} schemes with ${colorsPerScheme} colors each in ${(endTime - startTime).toFixed(2)}ms`)
112
+ })
113
+
114
+ it('should handle rapid color scheme injections and ejections', () => {
115
+ const operations = 5000
116
+ const startTime = performance.now()
117
+
118
+ // Initial base scheme
119
+ store.setAlternateColorsScheme({
120
+ base: {
121
+ primary: '#000000',
122
+ secondary: '#111111',
123
+ tertiary: '#222222'
124
+ }
125
+ })
126
+
127
+ for (let i = 0; i < operations; i++) {
128
+ const schemeName = `scheme_${i}`
129
+ const colors = {
130
+ primary: `#${i.toString(16).padStart(6, '0')}`,
131
+ accent: `#${(i * 2).toString(16).padStart(6, '0')}`,
132
+ background: `#${(i * 3).toString(16).padStart(6, '0')}`,
133
+ customColor: `#${(i * 4).toString(16).padStart(6, '0')}`
134
+ }
135
+
136
+ // Inject scheme
137
+ const injected = store.injectColorScheme(schemeName, colors)
138
+ expect(injected[schemeName]).toBeDefined()
139
+ expect(injected[schemeName].primary).toBe(colors.primary)
140
+ expect(injected[schemeName].secondary).toBe('#111111') // inherited
141
+
142
+ // Every 10th operation, eject some schemes
143
+ if (i % 10 === 0 && i > 0) {
144
+ const toEject = `scheme_${i - 5}`
145
+ store.ejectColorScheme(toEject)
146
+ expect(store.alternateColorsScheme[toEject]).toBeUndefined()
147
+ }
148
+ }
149
+
150
+ const endTime = performance.now()
151
+ const executionTime = endTime - startTime
152
+
153
+ expect(executionTime).toBeLessThan(3000) // Should be fast
154
+ console.log(`Color scheme operations: ${operations} inject/eject operations in ${executionTime.toFixed(2)}ms`)
155
+ })
156
+
157
+ it('should handle massive variants with complex structures', () => {
158
+ const componentCount = 500
159
+ const variantsPerComponent = 50
160
+ const variants = {}
161
+
162
+ for (let comp = 0; comp < componentCount; comp++) {
163
+ const componentVariants = {}
164
+ for (let variant = 0; variant < variantsPerComponent; variant++) {
165
+ componentVariants[`variant_${variant}`] = {
166
+ className: `comp-${comp}-var-${variant}`,
167
+ styles: {
168
+ color: `#${(comp * variant).toString(16).padStart(6, '0')}`,
169
+ backgroundColor: `#${(comp + variant).toString(16).padStart(6, '0')}`,
170
+ fontSize: `${comp + variant}px`,
171
+ padding: `${variant}px ${comp}px`,
172
+ margin: `${comp * variant}px`,
173
+ borderRadius: `${variant / 2}px`,
174
+ transform: `rotate(${variant}deg) scale(${1 + comp / 100})`,
175
+ boxShadow: `${variant}px ${comp}px ${comp + variant}px rgba(${comp}, ${variant}, ${comp + variant}, 0.${variant})`
176
+ },
177
+ states: {
178
+ hover: { opacity: 0.8 + (variant / 100) },
179
+ active: { transform: `scale(${1 + variant / 1000})` },
180
+ disabled: { opacity: 0.5 },
181
+ focus: { outline: `${variant}px solid #${comp.toString(16).padStart(6, '0')}` }
182
+ }
183
+ }
184
+ }
185
+ variants[`component_${comp}`] = componentVariants
186
+ }
187
+
188
+ const startTime = performance.now()
189
+ store.setVariants(variants)
190
+ const endTime = performance.now()
191
+
192
+ expect(Object.keys(store.variants)).toHaveLength(componentCount)
193
+ // @ts-ignore
194
+ expect(Object.keys(store.variants.component_0)).toHaveLength(variantsPerComponent)
195
+
196
+ console.log(`Variants: ${componentCount} components with ${variantsPerComponent} variants each in ${(endTime - startTime).toFixed(2)}ms`)
197
+ })
198
+ })
199
+
200
+ describe('concurrent operations stress test', () => {
201
+ it('should handle simultaneous theme, color scheme, and variants updates', () => {
202
+ const iterations = 2000
203
+ const startTime = performance.now()
204
+
205
+ for (let i = 0; i < iterations; i++) {
206
+ // Simultaneous updates
207
+ store.setTheme({
208
+ colors: { primary: `#${i.toString(16).padStart(6, '0')}` },
209
+ iteration: i
210
+ })
211
+
212
+ store.setColorScheme(`scheme_${i % 50}`)
213
+
214
+ store.setVariants({
215
+ [`component_${i}`]: {
216
+ [`variant_${i}`]: {
217
+ className: `test-${i}`,
218
+ styles: { color: `#${i.toString(16).padStart(6, '0')}` }
219
+ }
220
+ }
221
+ })
222
+
223
+ store.injectColorScheme(`dynamic_${i % 100}`, {
224
+ primary: `#${(i * 2).toString(16).padStart(6, '0')}`,
225
+ secondary: `#${(i * 3).toString(16).padStart(6, '0')}`
226
+ })
227
+
228
+ // Verify consistency every 200 iterations
229
+ if (i % 200 === 0) {
230
+ expect(getThemeStore()?.iteration).toBe(i)
231
+ expect(store.colorScheme).toBe(`scheme_${i % 50}`)
232
+ expect(store.variants[`component_${i}`]).toBeDefined()
233
+ }
234
+ }
235
+
236
+ const endTime = performance.now()
237
+ const executionTime = endTime - startTime
238
+
239
+ expect(executionTime).toBeLessThan(10000) // 10 seconds
240
+ expect(getThemeStore()?.iteration).toBe(iterations - 1)
241
+
242
+ console.log(`Concurrent operations: ${iterations * 4} total operations in ${executionTime.toFixed(2)}ms`)
243
+ })
244
+ })
245
+
246
+ describe('function storage and execution stress tests', () => {
247
+ it('should handle thousands of stored functions with complex computations', () => {
248
+ const functionCount = 5000
249
+ const theme = {
250
+ colors: {},
251
+ spacing: {},
252
+ calculators: {},
253
+ transformers: {},
254
+ validators: {}
255
+ }
256
+
257
+ const startTime = performance.now()
258
+
259
+ // Store various types of functions
260
+ for (let i = 0; i < functionCount; i++) {
261
+ // Simple calculators
262
+ theme.calculators[`calc_${i}`] = (value) => value * (i + 1)
263
+
264
+ // Complex transformers
265
+ theme.transformers[`transform_${i}`] = (input) => {
266
+ return {
267
+ scaled: input * Math.pow(2, i % 10),
268
+ offset: input + (i * 3.14159),
269
+ computed: Math.sin(input + i) * 100,
270
+ conditional: input > i ? input * 2 : input / 2,
271
+ recursive: i > 0 ? theme.calculators[`calc_${i - 1}`]?.(input) || input : input
272
+ }
273
+ }
274
+
275
+ // Spacing functions
276
+ theme.spacing[`space_${i}`] = (multiplier = 1) => `${i * 8 * multiplier}px`
277
+
278
+ // Color functions
279
+ theme.colors[`color_${i}`] = (opacity = 1) => {
280
+ const r = (i * 37) % 256
281
+ const g = (i * 73) % 256
282
+ const b = (i * 113) % 256
283
+ return `rgba(${r}, ${g}, ${b}, ${opacity})`
284
+ }
285
+
286
+ // Validators
287
+ theme.validators[`validate_${i}`] = (value) => {
288
+ return value !== null &&
289
+ value !== undefined &&
290
+ (typeof value === 'number' ? value >= i : value.length >= i % 10)
291
+ }
292
+ }
293
+
294
+ store.setTheme(theme)
295
+ const setTime = performance.now()
296
+
297
+ // Execute all functions to test performance
298
+ let executionResults = 0
299
+ const executeStartTime = performance.now()
300
+
301
+ for (let i = 0; i < functionCount; i++) {
302
+ const testValue = i * 2.5
303
+
304
+ // Execute calculators
305
+ const calcResult = getThemeStore()?.calculators[`calc_${i}`]?.(testValue)
306
+ if (calcResult) executionResults++
307
+
308
+ // Execute transformers
309
+ const transformResult = getThemeStore()?.transformers[`transform_${i}`]?.(testValue)
310
+ if (transformResult?.scaled) executionResults++
311
+
312
+ // Execute spacing functions
313
+ const spacingResult = getThemeStore()?.spacing[`space_${i}`]?.(2)
314
+ if (spacingResult?.includes('px')) executionResults++
315
+
316
+ // Execute color functions
317
+ const colorResult = getThemeStore()?.colors[`color_${i}`]?.(0.8)
318
+ if (colorResult?.includes('rgba')) executionResults++
319
+
320
+ // Execute validators
321
+ const validatorResult = getThemeStore()?.validators[`validate_${i}`]?.(testValue)
322
+ if (typeof validatorResult === 'boolean') executionResults++
323
+
324
+ // Test some complex chaining every 100 iterations
325
+ if (i % 100 === 0) {
326
+ const chainResult = getThemeStore()?.transformers[`transform_${i}`]?.(
327
+ getThemeStore()?.calculators[`calc_${i}`]?.(testValue) || 0
328
+ )
329
+ if (chainResult) executionResults++
330
+ }
331
+ }
332
+
333
+ const executeEndTime = performance.now()
334
+ const totalTime = executeEndTime - startTime
335
+
336
+ expect(executionResults).toBeGreaterThan(functionCount * 4) // At least 4 successful executions per function
337
+ expect(totalTime).toBeLessThan(15000) // Should handle massive function storage/execution
338
+
339
+ console.log(`Function storage: ${functionCount} functions stored in ${(setTime - startTime).toFixed(2)}ms`)
340
+ console.log(`Function execution: ${executionResults} executions in ${(executeEndTime - executeStartTime).toFixed(2)}ms`)
341
+ console.log(`Total function test: ${totalTime.toFixed(2)}ms`)
342
+ })
343
+
344
+ it('should handle recursive and nested function calls', () => {
345
+ const depth = 100
346
+ const iterations = 1000
347
+
348
+ // Create deeply nested function chains
349
+ const theme = {
350
+ fibonacci: {},
351
+ factorial: {},
352
+ compose: {},
353
+ pipeline: {}
354
+ }
355
+
356
+ // Fibonacci functions
357
+ for (let i = 0; i < depth; i++) {
358
+ theme.fibonacci[`fib_${i}`] = (n) => {
359
+ if (n <= 1) return n
360
+ if (i > 0 && theme.fibonacci[`fib_${i - 1}`]) {
361
+ return theme.fibonacci[`fib_${i - 1}`](n - 1) + theme.fibonacci[`fib_${i - 1}`](n - 2)
362
+ }
363
+ return n
364
+ }
365
+ }
366
+
367
+ // Factorial chains
368
+ for (let i = 0; i < depth; i++) {
369
+ theme.factorial[`fact_${i}`] = (n) => {
370
+ if (n <= 1) return 1
371
+ const prevFact = theme.factorial[`fact_${Math.max(0, i - 1)}`]
372
+ return prevFact ? n * prevFact(n - 1) : n
373
+ }
374
+ }
375
+
376
+ // Function composition
377
+ for (let i = 0; i < depth; i++) {
378
+ theme.compose[`comp_${i}`] = (value) => {
379
+ let result = value
380
+ for (let j = 0; j <= i && j < 10; j++) {
381
+ result = Math.sqrt(Math.abs(result * (j + 1)))
382
+ }
383
+ return result
384
+ }
385
+ }
386
+
387
+ // Pipeline functions
388
+ for (let i = 0; i < depth; i++) {
389
+ theme.pipeline[`pipe_${i}`] = (input) => {
390
+ const steps = [
391
+ (x) => x * 2,
392
+ (x) => x + i,
393
+ (x) => Math.pow(x, 1.5),
394
+ (x) => x % 1000,
395
+ (x) => theme.compose[`comp_${Math.min(i, depth - 1)}`]?.(x) || x
396
+ ]
397
+ return steps.reduce((acc, fn) => fn(acc), input)
398
+ }
399
+ }
400
+
401
+ store.setTheme(theme)
402
+
403
+ const startTime = performance.now()
404
+ let successfulExecutions = 0
405
+
406
+ // Execute nested functions
407
+ for (let i = 0; i < iterations; i++) {
408
+ const testValue = i % 20
409
+
410
+ try {
411
+ // Test fibonacci (limited to avoid stack overflow)
412
+ const fibResult = getThemeStore()?.fibonacci[`fib_${i % 10}`]?.(testValue % 10)
413
+ if (typeof fibResult === 'number') successfulExecutions++
414
+
415
+ // Test factorial
416
+ const factResult = getThemeStore()?.factorial[`fact_${i % depth}`]?.(testValue % 8)
417
+ if (typeof factResult === 'number') successfulExecutions++
418
+
419
+ // Test composition
420
+ const compResult = getThemeStore()?.compose[`comp_${i % depth}`]?.(testValue + 1)
421
+ if (typeof compResult === 'number') successfulExecutions++
422
+
423
+ // Test pipeline
424
+ const pipeResult = getThemeStore()?.pipeline[`pipe_${i % depth}`]?.(testValue)
425
+ if (typeof pipeResult === 'number') successfulExecutions++
426
+
427
+ // Test chained execution
428
+ if (i % 50 === 0) {
429
+ const chainedResult = getThemeStore()?.pipeline[`pipe_${i % depth}`]?.(
430
+ getThemeStore()?.compose[`comp_${i % depth}`]?.(testValue) || 0
431
+ )
432
+ if (typeof chainedResult === 'number') successfulExecutions++
433
+ }
434
+ } catch (error) {
435
+ // Some recursion might fail, that's ok
436
+ }
437
+ }
438
+
439
+ const endTime = performance.now()
440
+ const executionTime = endTime - startTime
441
+
442
+ expect(successfulExecutions).toBeGreaterThan(iterations * 3) // Most executions should succeed
443
+ expect(executionTime).toBeLessThan(10000)
444
+
445
+ console.log(`Recursive functions: ${depth} depth, ${iterations} iterations, ${successfulExecutions} successful executions in ${executionTime.toFixed(2)}ms`)
446
+ })
447
+
448
+ it('should handle function factories and dynamic function generation', () => {
449
+ const factoryCount = 1000
450
+ const generatedPerFactory = 10
451
+
452
+ const theme = {
453
+ factories: {},
454
+ generated: {},
455
+ dynamicComputed: {}
456
+ }
457
+
458
+ const startTime = performance.now()
459
+
460
+ // Create function factories
461
+ for (let i = 0; i < factoryCount; i++) {
462
+ theme.factories[`factory_${i}`] = (config) => {
463
+ return {
464
+ calculator: (value) => value * (config.multiplier || 1) + (config.offset || 0),
465
+ validator: (value) => value >= (config.min || 0) && value <= (config.max || 1000),
466
+ transformer: (value) => ({
467
+ original: value,
468
+ scaled: value * (config.scale || 1),
469
+ formatted: `${config.prefix || ''}${value}${config.suffix || ''}`,
470
+ computed: Math.pow(value, config.power || 1)
471
+ }),
472
+ composer: (...fns) => (value) => fns.reduce((acc, fn) => fn(acc), value)
473
+ }
474
+ }
475
+
476
+ // Generate functions using factories
477
+ for (let j = 0; j < generatedPerFactory; j++) {
478
+ const config = {
479
+ multiplier: i + j,
480
+ offset: j * 10,
481
+ scale: 1 + (j / 10),
482
+ min: i,
483
+ max: i * 100,
484
+ prefix: `gen_${i}_`,
485
+ suffix: `_${j}`,
486
+ power: 1 + (j / 5)
487
+ }
488
+
489
+ const generatedFunctions = theme.factories[`factory_${i}`](config)
490
+ theme.generated[`gen_${i}_${j}`] = generatedFunctions
491
+
492
+ // Create dynamic computed values
493
+ theme.dynamicComputed[`comp_${i}_${j}`] = (input) => {
494
+ const calc = generatedFunctions.calculator(input)
495
+ const valid = generatedFunctions.validator(calc)
496
+ const transform = generatedFunctions.transformer(calc)
497
+
498
+ return {
499
+ calculated: calc,
500
+ isValid: valid,
501
+ transformed: transform,
502
+ final: valid ? transform.computed : 0
503
+ }
504
+ }
505
+ }
506
+ }
507
+
508
+ store.setTheme(theme)
509
+ const creationTime = performance.now()
510
+
511
+ // Execute generated functions
512
+ let executionCount = 0
513
+ const executionStartTime = performance.now()
514
+
515
+ for (let i = 0; i < factoryCount; i++) {
516
+ for (let j = 0; j < generatedPerFactory; j++) {
517
+ const testValue = (i + j) * 1.5
518
+
519
+ try {
520
+ // Test generated functions
521
+ const generated = getThemeStore()?.generated[`gen_${i}_${j}`]
522
+ if (generated) {
523
+ const calcResult = generated.calculator(testValue)
524
+ const validResult = generated.validator(calcResult)
525
+ const transformResult = generated.transformer(testValue)
526
+
527
+ if (typeof calcResult === 'number') executionCount++
528
+ if (typeof validResult === 'boolean') executionCount++
529
+ if (transformResult?.original === testValue) executionCount++
530
+ }
531
+
532
+ // Test dynamic computed
533
+ const dynamicResult = getThemeStore()?.dynamicComputed[`comp_${i}_${j}`]?.(testValue)
534
+ if (dynamicResult?.calculated !== undefined) executionCount++
535
+
536
+ } catch (error) {
537
+ // Some executions might fail
538
+ }
539
+
540
+ // Test function composition every 100 iterations
541
+ if ((i * generatedPerFactory + j) % 100 === 0) {
542
+ try {
543
+ const generated = getThemeStore()?.generated[`gen_${i}_${j}`]
544
+ if (generated?.composer) {
545
+ const composed = generated.composer(
546
+ (x) => x * 2,
547
+ (x) => x + 10,
548
+ generated.calculator
549
+ )(testValue)
550
+ if (typeof composed === 'number') executionCount++
551
+ }
552
+ } catch (error) {
553
+ // Composition might fail
554
+ }
555
+ }
556
+ }
557
+ }
558
+
559
+ const executionEndTime = performance.now()
560
+ const totalTime = executionEndTime - startTime
561
+
562
+ const expectedOperations = factoryCount * generatedPerFactory * 3 // At least 3 operations per generated function
563
+ expect(executionCount).toBeGreaterThan(expectedOperations * 0.8) // 80% success rate minimum
564
+ expect(totalTime).toBeLessThan(20000) // 20 seconds max
565
+
566
+ console.log(`Function factories: ${factoryCount} factories generating ${factoryCount * generatedPerFactory} functions`)
567
+ console.log(`Creation time: ${(creationTime - startTime).toFixed(2)}ms`)
568
+ console.log(`Execution time: ${(executionEndTime - executionStartTime).toFixed(2)}ms`)
569
+ console.log(`Total operations: ${executionCount} in ${totalTime.toFixed(2)}ms`)
570
+ })
571
+ })
572
+
573
+ describe('memory pressure and cleanup', () => {
574
+ it('should handle massive data without memory leaks', () => {
575
+ const hugeSets = 10
576
+ const itemsPerSet = 1000
577
+
578
+ for (let set = 0; set < hugeSets; set++) {
579
+ // Create massive theme
580
+ const hugeTheme = {
581
+ colors: {},
582
+ spacing: {},
583
+ typography: {},
584
+ components: {}
585
+ }
586
+
587
+ for (let i = 0; i < itemsPerSet; i++) {
588
+ hugeTheme.colors[`color_${i}`] = `#${i.toString(16).padStart(6, '0')}`
589
+ hugeTheme.spacing[`space_${i}`] = `${i}px`
590
+ hugeTheme.typography[`font_${i}`] = `${i}px`
591
+ hugeTheme.components[`comp_${i}`] = {
592
+ styles: { margin: `${i}px` },
593
+ variants: Array.from({ length: 10 }, (_, j) => `variant_${j}`)
594
+ }
595
+ }
596
+
597
+ store.setTheme(hugeTheme)
598
+
599
+ // Create massive color schemes
600
+ const hugeColorSchemes = {}
601
+ for (let i = 0; i < itemsPerSet; i++) {
602
+ const scheme = {}
603
+ for (let j = 0; j < 50; j++) {
604
+ scheme[`color_${j}`] = `#${(i * j).toString(16).padStart(6, '0')}`
605
+ }
606
+ hugeColorSchemes[`scheme_${set}_${i}`] = scheme
607
+ }
608
+
609
+ store.setAlternateColorsScheme(hugeColorSchemes)
610
+
611
+ // Verify data is accessible
612
+ expect(Object.keys(getThemeStore()?.colors || {})).toHaveLength(itemsPerSet)
613
+ expect(Object.keys(store.alternateColorsScheme)).toHaveLength(itemsPerSet)
614
+ }
615
+
616
+ // Final verification
617
+ expect(getThemeStore()).toBeDefined()
618
+ expect(Object.keys(store.alternateColorsScheme)).toHaveLength(itemsPerSet)
619
+
620
+ console.log(`Memory test: Handled ${hugeSets} sets of ${itemsPerSet} items each`)
621
+ })
622
+ })
623
+
624
+ describe('computed store performance under heavy load', () => {
625
+ it('should maintain reactivity with rapid updates', () => {
626
+ const updates = 3000
627
+ const startTime = performance.now()
628
+ const computedValues = []
629
+
630
+ for (let i = 0; i < updates; i++) {
631
+ themeStore.setTheme({
632
+ colors: { primary: `#${i.toString(16).padStart(6, '0')}` },
633
+ iteration: i
634
+ })
635
+ themeStore.setColorScheme(`scheme_${i % 100}`)
636
+
637
+ const computed = themeStoreComputed.get() as any
638
+ computedValues.push(computed)
639
+
640
+ // Verify computed values every 500 iterations
641
+ if (i % 500 === 0) {
642
+ expect(computed.theme?.iteration).toBe(i)
643
+ expect(computed.colorScheme).toBe(`scheme_${i % 100}`)
644
+ }
645
+ }
646
+
647
+ const endTime = performance.now()
648
+ const executionTime = endTime - startTime
649
+
650
+ expect(computedValues).toHaveLength(updates)
651
+ expect(executionTime).toBeLessThan(8000) // 8 seconds
652
+
653
+ // Verify final state
654
+ const finalComputed = themeStoreComputed.get() as any
655
+ expect(finalComputed.theme?.iteration).toBe(updates - 1)
656
+ expect(finalComputed.colorScheme).toBe(`scheme_${(updates - 1) % 100}`)
657
+
658
+ console.log(`Computed reactivity: ${updates} updates with computed reads in ${executionTime.toFixed(2)}ms`)
659
+ })
660
+
661
+ it('should handle multiple subscribers without performance degradation', () => {
662
+ const subscribers = []
663
+ const subscribeCount = 100
664
+ const updates = 1000
665
+
666
+ // Create multiple subscribers
667
+ for (let i = 0; i < subscribeCount; i++) {
668
+ const unsubscribe = themeStoreComputed.subscribe((value: any) => {
669
+ // Simulate some work
670
+ if (value.theme?.iteration && value.theme.iteration % 100 === 0) {
671
+ // Do something with the value
672
+ expect(value).toBeDefined()
673
+ }
674
+ })
675
+ subscribers.push(unsubscribe)
676
+ }
677
+
678
+ const startTime = performance.now()
679
+
680
+ // Make updates that should trigger all subscribers
681
+ for (let i = 0; i < updates; i++) {
682
+ themeStore.setTheme({
683
+ colors: { primary: `#${i.toString(16).padStart(6, '0')}` },
684
+ iteration: i
685
+ })
686
+ }
687
+
688
+ const endTime = performance.now()
689
+ const executionTime = endTime - startTime
690
+
691
+ // Cleanup subscribers
692
+ subscribers.forEach(unsubscribe => unsubscribe())
693
+
694
+ expect(executionTime).toBeLessThan(5000) // Should handle multiple subscribers efficiently
695
+ console.log(`Multiple subscribers: ${subscribeCount} subscribers with ${updates} updates in ${executionTime.toFixed(2)}ms`)
696
+ })
697
+ })
698
+ })