@cwcss/crosswind 0.1.5 → 0.1.6

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 (86) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +390 -0
  3. package/dist/build.d.ts +24 -0
  4. package/dist/config.d.ts +5 -0
  5. package/dist/generator.d.ts +31 -0
  6. package/dist/index.d.ts +10 -0
  7. package/dist/index.js +12798 -0
  8. package/dist/parser.d.ts +42 -0
  9. package/dist/plugin.d.ts +22 -0
  10. package/dist/preflight-forms.d.ts +5 -0
  11. package/dist/preflight.d.ts +2 -0
  12. package/dist/rules-advanced.d.ts +27 -0
  13. package/dist/rules-effects.d.ts +25 -0
  14. package/dist/rules-forms.d.ts +7 -0
  15. package/dist/rules-grid.d.ts +13 -0
  16. package/dist/rules-interactivity.d.ts +41 -0
  17. package/dist/rules-layout.d.ts +26 -0
  18. package/dist/rules-transforms.d.ts +33 -0
  19. package/dist/rules-typography.d.ts +41 -0
  20. package/dist/rules.d.ts +39 -0
  21. package/dist/scanner.d.ts +18 -0
  22. package/dist/transformer-compile-class.d.ts +37 -0
  23. package/{src/types.ts → dist/types.d.ts} +17 -86
  24. package/package.json +1 -1
  25. package/PLUGIN.md +0 -235
  26. package/benchmark/framework-comparison.bench.ts +0 -850
  27. package/bin/cli.ts +0 -365
  28. package/bin/crosswind +0 -0
  29. package/bin/headwind +0 -0
  30. package/build.ts +0 -8
  31. package/crosswind.config.ts +0 -9
  32. package/example/comprehensive.html +0 -70
  33. package/example/index.html +0 -21
  34. package/example/output.css +0 -236
  35. package/examples/plugin/README.md +0 -112
  36. package/examples/plugin/build.ts +0 -32
  37. package/examples/plugin/src/index.html +0 -34
  38. package/examples/plugin/src/index.ts +0 -7
  39. package/headwind +0 -2
  40. package/src/build.ts +0 -101
  41. package/src/config.ts +0 -529
  42. package/src/generator.ts +0 -2173
  43. package/src/index.ts +0 -10
  44. package/src/parser.ts +0 -1471
  45. package/src/plugin.ts +0 -118
  46. package/src/preflight-forms.ts +0 -229
  47. package/src/preflight.ts +0 -388
  48. package/src/rules-advanced.ts +0 -477
  49. package/src/rules-effects.ts +0 -461
  50. package/src/rules-forms.ts +0 -103
  51. package/src/rules-grid.ts +0 -241
  52. package/src/rules-interactivity.ts +0 -525
  53. package/src/rules-layout.ts +0 -385
  54. package/src/rules-transforms.ts +0 -412
  55. package/src/rules-typography.ts +0 -486
  56. package/src/rules.ts +0 -809
  57. package/src/scanner.ts +0 -84
  58. package/src/transformer-compile-class.ts +0 -275
  59. package/test/advanced-features.test.ts +0 -911
  60. package/test/arbitrary.test.ts +0 -396
  61. package/test/attributify.test.ts +0 -592
  62. package/test/bracket-syntax.test.ts +0 -1133
  63. package/test/build.test.ts +0 -99
  64. package/test/colors.test.ts +0 -934
  65. package/test/flexbox.test.ts +0 -669
  66. package/test/generator.test.ts +0 -597
  67. package/test/grid.test.ts +0 -584
  68. package/test/layout.test.ts +0 -404
  69. package/test/modifiers.test.ts +0 -417
  70. package/test/parser.test.ts +0 -564
  71. package/test/performance-regression.test.ts +0 -376
  72. package/test/performance.test.ts +0 -568
  73. package/test/plugin.test.ts +0 -160
  74. package/test/scanner.test.ts +0 -94
  75. package/test/sizing.test.ts +0 -481
  76. package/test/spacing.test.ts +0 -394
  77. package/test/transformer-compile-class.test.ts +0 -287
  78. package/test/transforms.test.ts +0 -448
  79. package/test/typography.test.ts +0 -632
  80. package/test/variants-form-states.test.ts +0 -225
  81. package/test/variants-group-peer.test.ts +0 -66
  82. package/test/variants-media.test.ts +0 -213
  83. package/test/variants-positional.test.ts +0 -58
  84. package/test/variants-pseudo-elements.test.ts +0 -47
  85. package/test/variants-state.test.ts +0 -62
  86. package/tsconfig.json +0 -18
@@ -1,376 +0,0 @@
1
- import { beforeEach, describe, expect, it } from 'bun:test'
2
- import { CSSGenerator } from '../src/generator'
3
- import { defaultConfig } from '../src/config'
4
-
5
- /**
6
- * Performance Regression Tests
7
- *
8
- * These tests ensure we maintain our PERFECT 10/10 benchmark performance.
9
- * Each test has a threshold based on our current performance numbers with generous margins.
10
- * If performance degrades significantly, these tests will fail.
11
- *
12
- * NOTE: These tests use performance.now() for measurements, which has different characteristics
13
- * than the Mitata benchmarking tool used in benchmark.test.ts. The thresholds here are set
14
- * based on actual measured values with 2-3x safety margins.
15
- *
16
- * Current Performance Targets (vs UnoCSS in Mitata benchmarks):
17
- * - CSS Output Generation: 77.4x faster (benchmark: 910µs vs 70.5ms)
18
- * - Duplicate Handling: 52.0x faster (benchmark: 30µs vs 1.6ms)
19
- * - Real-world Components: 24.4x faster (benchmark: 5.6µs vs 136µs)
20
- * - Arbitrary Values: 10.6x faster (benchmark: 2.5µs vs 26µs)
21
- * - Color Utilities: 5.4x faster (benchmark: 54µs vs 289µs)
22
- * - Interactive States: 3.8x faster (benchmark: 236µs vs 888µs)
23
- * - Simple Utilities: 3.5x faster (benchmark: 5µs vs 18µs)
24
- * - Complex Utilities: 2.9x faster (benchmark: 8µs vs 24µs)
25
- * - Large Scale: 1.67x faster (benchmark: 265µs vs 444µs)
26
- * - Responsive Utilities: 1.16x faster (benchmark: 542µs vs 631µs)
27
- *
28
- * Critical Optimization: Rule Ordering
29
- * The most common utilities (spacing, sizing, colors) are placed at the beginning of the
30
- * builtInRules array for O(1) lookup performance. The "Rule Ordering Performance - Critical!"
31
- * test ensures this optimization stays in place.
32
- */
33
-
34
- describe('Performance Regression Tests', () => {
35
- let gen: CSSGenerator
36
-
37
- beforeEach(() => {
38
- gen = new CSSGenerator(defaultConfig)
39
- })
40
-
41
- describe('Simple Utilities Performance', () => {
42
- it('should process 10 simple utilities within threshold', () => {
43
- const utilities = [
44
- 'w-4', 'h-4', 'p-4', 'm-4', 'text-lg',
45
- 'bg-blue-500', 'flex', 'items-center',
46
- 'justify-between', 'rounded-lg',
47
- ]
48
-
49
- const start = performance.now()
50
- for (const cls of utilities) {
51
- gen.generate(cls)
52
- }
53
- const duration = performance.now() - start
54
-
55
- // Current: ~2ms, threshold: 5ms (2.5x margin for safety)
56
- expect(duration).toBeLessThan(5) // 5ms
57
- })
58
- })
59
-
60
- describe('Complex Utilities with Variants Performance', () => {
61
- it('should process complex utilities with variants within threshold', () => {
62
- const utilities = [
63
- 'sm:w-full', 'md:w-1/2', 'lg:w-1/3',
64
- 'hover:bg-blue-600', 'focus:ring-2',
65
- 'dark:bg-gray-800', 'first:mt-0',
66
- 'last:mb-0', 'group-hover:scale-105',
67
- 'peer-focus:border-blue-500', 'motion-safe:animate-bounce',
68
- ]
69
-
70
- const start = performance.now()
71
- for (const cls of utilities) {
72
- gen.generate(cls)
73
- }
74
- const duration = performance.now() - start
75
-
76
- // Current: ~0.2ms, threshold: 1ms
77
- expect(duration).toBeLessThan(1) // 1ms
78
- })
79
- })
80
-
81
- describe('Arbitrary Values Performance', () => {
82
- it('should process arbitrary values within threshold', () => {
83
- const utilities = [
84
- 'w-[123px]',
85
- 'h-[456px]',
86
- 'text-[#ff0000]',
87
- 'p-[2rem]',
88
- 'bg-[#1a1a1a]',
89
- 'm-[10%]',
90
- 'shadow-[0_4px_6px_rgba(0,0,0,0.1)]',
91
- ]
92
-
93
- const start = performance.now()
94
- for (const cls of utilities) {
95
- gen.generate(cls)
96
- }
97
- const duration = performance.now() - start
98
-
99
- // Current: ~0.05ms, threshold: 0.2ms
100
- expect(duration).toBeLessThan(0.2) // 0.2ms
101
- })
102
- })
103
-
104
- describe('Real-world Component Classes Performance', () => {
105
- it('should process real-world component patterns within threshold', () => {
106
- const componentClasses = [
107
- 'flex items-center justify-between p-4 bg-white dark:bg-gray-800 rounded-lg shadow-md',
108
- 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4',
109
- 'text-sm font-medium text-gray-700 hover:text-gray-900',
110
- 'absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center',
111
- 'transition-all duration-200 ease-in-out hover:scale-105',
112
- 'border border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-200',
113
- ]
114
-
115
- const start = performance.now()
116
- for (const classString of componentClasses) {
117
- const classes = classString.split(/\s+/)
118
- for (const cls of classes) {
119
- gen.generate(cls)
120
- }
121
- }
122
- const duration = performance.now() - start
123
-
124
- // Current: ~0.5ms, threshold: 2ms
125
- expect(duration).toBeLessThan(2) // 2ms
126
- })
127
- })
128
-
129
- describe('Large Scale Performance', () => {
130
- it('should process 1000 utilities within threshold', () => {
131
- const largeSet: string[] = []
132
- for (let i = 0; i < 250; i++) {
133
- largeSet.push(`w-${i}`, `h-${i}`, `p-${i}`, `m-${i}`)
134
- }
135
-
136
- const start = performance.now()
137
- for (const cls of largeSet) {
138
- gen.generate(cls)
139
- }
140
- const duration = performance.now() - start
141
-
142
- // Current: ~5ms, threshold: 15ms (3x margin)
143
- expect(duration).toBeLessThan(15) // 15ms
144
- })
145
- })
146
-
147
- describe('CSS Output Generation Performance', () => {
148
- it('should generate CSS from 1000 rules within threshold', () => {
149
- const utilities: string[] = []
150
- for (let i = 0; i < 1000; i++) {
151
- utilities.push(`w-[${i}px]`)
152
- }
153
-
154
- // Generate all utilities
155
- for (const cls of utilities) {
156
- gen.generate(cls)
157
- }
158
-
159
- // Measure CSS output generation
160
- const start = performance.now()
161
- const css = gen.toCSS()
162
- const duration = performance.now() - start
163
-
164
- // Current: ~2ms, threshold: 5ms
165
- expect(duration).toBeLessThan(5) // 5ms
166
- expect(css.length).toBeGreaterThan(0)
167
- })
168
- })
169
-
170
- describe('Color Utilities Performance', () => {
171
- it('should process 240 color utilities within threshold', () => {
172
- const colors = ['blue', 'red', 'green', 'yellow', 'purple', 'pink', 'indigo', 'gray']
173
- const shades = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900']
174
- const colorUtilities: string[] = []
175
-
176
- for (const color of colors) {
177
- for (const shade of shades) {
178
- colorUtilities.push(`bg-${color}-${shade}`)
179
- colorUtilities.push(`text-${color}-${shade}`)
180
- colorUtilities.push(`border-${color}-${shade}`)
181
- }
182
- }
183
-
184
- const start = performance.now()
185
- for (const cls of colorUtilities) {
186
- gen.generate(cls)
187
- }
188
- const duration = performance.now() - start
189
-
190
- // Current: ~1ms, threshold: 3ms
191
- expect(duration).toBeLessThan(3) // 3ms
192
- })
193
- })
194
-
195
- describe('Responsive Utilities Performance', () => {
196
- it('should process 1000 responsive utilities within threshold', () => {
197
- const breakpoints = ['sm', 'md', 'lg', 'xl', '2xl']
198
- const utilities: string[] = []
199
-
200
- for (const bp of breakpoints) {
201
- for (let i = 0; i < 200; i++) {
202
- utilities.push(`${bp}:w-${i}`)
203
- }
204
- }
205
-
206
- const start = performance.now()
207
- for (const cls of utilities) {
208
- gen.generate(cls)
209
- }
210
- const duration = performance.now() - start
211
-
212
- // Current: ~4ms, threshold: 10ms
213
- expect(duration).toBeLessThan(10) // 10ms
214
- })
215
- })
216
-
217
- describe('Interactive States Performance', () => {
218
- it('should process 550 interactive state utilities within threshold', () => {
219
- const states = ['hover', 'focus', 'active', 'disabled', 'group-hover', 'peer-focus', 'first', 'last', 'odd', 'even', 'dark']
220
- const stateUtilities: string[] = []
221
-
222
- for (const state of states) {
223
- for (let i = 0; i < 50; i++) {
224
- stateUtilities.push(`${state}:bg-blue-${i}`)
225
- }
226
- }
227
-
228
- const start = performance.now()
229
- for (const cls of stateUtilities) {
230
- gen.generate(cls)
231
- }
232
- const duration = performance.now() - start
233
-
234
- // Current: ~2.5ms, threshold: 6ms
235
- expect(duration).toBeLessThan(6) // 6ms
236
- })
237
- })
238
-
239
- describe('Duplicate Handling Performance', () => {
240
- it('should handle 6000 duplicate classes efficiently', () => {
241
- const duplicates = ['w-4', 'h-4', 'p-4', 'm-4', 'text-lg', 'bg-blue-500']
242
- const manyDuplicates: string[] = []
243
-
244
- for (let i = 0; i < 1000; i++) {
245
- manyDuplicates.push(...duplicates)
246
- }
247
-
248
- const start = performance.now()
249
- for (const cls of manyDuplicates) {
250
- gen.generate(cls)
251
- }
252
- const duration = performance.now() - start
253
-
254
- // Current: ~0.12ms, threshold: 0.5ms (this should be VERY fast due to caching)
255
- expect(duration).toBeLessThan(0.5) // 0.5ms
256
- })
257
- })
258
-
259
- describe('Rule Ordering Performance - Critical!', () => {
260
- it('should match common utilities in first 3 rule checks', () => {
261
- // This test ensures our critical optimization (rule ordering) stays in place
262
- const commonUtilities = [
263
- 'w-4', // spacingRule should match first
264
- 'h-4', // sizingRule should match second
265
- 'p-4', // spacingRule should match first
266
- 'm-4', // spacingRule should match first
267
- 'bg-blue-500', // colorRule should match third
268
- 'text-white', // colorRule should match third
269
- ]
270
-
271
- const start = performance.now()
272
- for (const cls of commonUtilities) {
273
- gen.generate(cls)
274
- }
275
- const duration = performance.now() - start
276
-
277
- // These should be EXTREMELY fast (< 0.05ms for 6 classes)
278
- // because they match in the first 3 rules
279
- expect(duration).toBeLessThan(0.05) // 0.05ms
280
- })
281
- })
282
-
283
- describe('Cache Effectiveness', () => {
284
- it('should benefit from parse cache on repeated patterns', () => {
285
- const pattern = 'hover:bg-blue-500'
286
-
287
- // First pass - no cache
288
- const gen1 = new CSSGenerator(defaultConfig)
289
- const start1 = performance.now()
290
- for (let i = 0; i < 100; i++) {
291
- gen1.generate(pattern)
292
- }
293
- const duration1 = performance.now() - start1
294
-
295
- // Second pass - with cache (different generator, but parse cache is global)
296
- const gen2 = new CSSGenerator(defaultConfig)
297
- const start2 = performance.now()
298
- for (let i = 0; i < 100; i++) {
299
- gen2.generate(pattern)
300
- }
301
- const duration2 = performance.now() - start2
302
-
303
- // Second pass should be faster or equal (cache helps)
304
- // Due to class cache, second pass should be near-instant
305
- expect(duration2).toBeLessThanOrEqual(duration1)
306
- expect(duration2).toBeLessThan(0.05) // Should be < 50µs with full caching
307
- })
308
-
309
- it('should handle class cache efficiently', () => {
310
- const utilities = ['w-4', 'h-4', 'p-4', 'm-4']
311
-
312
- // Generate once
313
- for (const cls of utilities) {
314
- gen.generate(cls)
315
- }
316
-
317
- // Generate again (should hit class cache immediately)
318
- const start = performance.now()
319
- for (let i = 0; i < 1000; i++) {
320
- for (const cls of utilities) {
321
- gen.generate(cls)
322
- }
323
- }
324
- const duration = performance.now() - start
325
-
326
- // 4000 cached lookups should be fast
327
- expect(duration).toBeLessThan(1) // < 1ms for 4000 cached lookups
328
- })
329
- })
330
-
331
- describe('Memory Efficiency', () => {
332
- it('should not leak memory with large-scale generation', () => {
333
- const initialMemory = (performance as any).memory?.usedJSHeapSize || 0
334
-
335
- // Generate a lot of utilities
336
- for (let i = 0; i < 1000; i++) {
337
- gen.generate(`w-${i}`)
338
- gen.generate(`h-${i}`)
339
- gen.generate(`p-${i}`)
340
- }
341
-
342
- const finalMemory = (performance as any).memory?.usedJSHeapSize || 0
343
- const memoryIncrease = finalMemory - initialMemory
344
-
345
- // Memory increase should be reasonable (< 10MB for 3000 utilities)
346
- // Note: This is a rough estimate and may vary by environment
347
- if (initialMemory > 0) {
348
- expect(memoryIncrease).toBeLessThan(10 * 1024 * 1024) // 10MB
349
- }
350
- })
351
- })
352
-
353
- describe('Performance Regression Guards', () => {
354
- it('should maintain O(1) lookup for common utilities', () => {
355
- // Test that adding more rules doesn't slow down common utilities
356
- // This guards against someone accidentally moving rules back to the end
357
-
358
- const commonUtils = ['w-4', 'h-4', 'p-4', 'm-4', 'bg-blue-500', 'text-white']
359
-
360
- const iterations = 100
361
- const start = performance.now()
362
- for (let i = 0; i < iterations; i++) {
363
- const gen = new CSSGenerator(defaultConfig)
364
- for (const cls of commonUtils) {
365
- gen.generate(cls)
366
- }
367
- }
368
- const duration = performance.now() - start
369
- const avgPerIteration = duration / iterations
370
-
371
- // Average per iteration should be < 20µs
372
- // If someone moves rules back, this will break
373
- expect(avgPerIteration).toBeLessThan(0.02) // 20 microseconds per iteration
374
- })
375
- })
376
- })