chaincss 2.0.7 → 2.1.0

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 (159) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/CODE_OF_CONDUCT.md +21 -0
  3. package/CONTRIBUTING.md +28 -0
  4. package/README.md +455 -226
  5. package/demo/demo/node_modules/caniuse-db/fulldata-json/data-2.0.json +1 -0
  6. package/demo/index.html +16 -0
  7. package/demo/package.json +20 -0
  8. package/demo/src/App.tsx +117 -0
  9. package/demo/src/chaincss-barrel.ts +9 -0
  10. package/demo/src/main.tsx +8 -0
  11. package/demo/src/styles.chain.ts +300 -0
  12. package/demo/vite.config.ts +46 -0
  13. package/dist/cli/commands/build.d.ts +0 -1
  14. package/dist/cli/commands/cache.d.ts +1 -0
  15. package/dist/cli/commands/init.d.ts +6 -3
  16. package/dist/cli/commands/timeline.d.ts +0 -1
  17. package/dist/cli/commands/watch.d.ts +0 -1
  18. package/dist/cli/index.d.ts +0 -1
  19. package/dist/cli/index.js +3213 -5296
  20. package/dist/cli/types.d.ts +51 -20
  21. package/dist/cli/utils/config-loader.d.ts +0 -1
  22. package/dist/cli/utils/file-utils.d.ts +27 -3
  23. package/dist/cli/utils/logger.d.ts +0 -1
  24. package/dist/compiler/Chain.d.ts +215 -0
  25. package/dist/compiler/animations.d.ts +76 -0
  26. package/dist/compiler/atomic-optimizer.d.ts +47 -12
  27. package/dist/compiler/breakpoints.d.ts +46 -0
  28. package/dist/compiler/btt.d.ts +36 -60
  29. package/dist/compiler/cache-manager.d.ts +58 -4
  30. package/dist/compiler/commonProps.d.ts +0 -1
  31. package/dist/compiler/content-addressable-cache.d.ts +78 -0
  32. package/dist/compiler/helpers.d.ts +54 -0
  33. package/dist/compiler/index.d.ts +16 -9
  34. package/dist/compiler/index.js +4450 -4316
  35. package/dist/compiler/prefixer.d.ts +17 -1
  36. package/dist/compiler/shorthands.d.ts +28 -0
  37. package/dist/compiler/suggestions.d.ts +43 -0
  38. package/dist/compiler/theme-contract.d.ts +16 -27
  39. package/dist/compiler/token-resolver.d.ts +69 -0
  40. package/dist/compiler/tokens.d.ts +33 -8
  41. package/dist/core/auto-detector.d.ts +34 -0
  42. package/dist/core/common-utils.d.ts +97 -0
  43. package/dist/core/compiler.d.ts +63 -23
  44. package/dist/core/constants.d.ts +137 -36
  45. package/dist/core/smart-chain.d.ts +3 -0
  46. package/dist/core/types.d.ts +122 -15
  47. package/dist/core/utils.d.ts +134 -17
  48. package/dist/index.d.ts +52 -8
  49. package/dist/index.js +7090 -5578
  50. package/dist/plugins/vite.d.ts +7 -5
  51. package/dist/plugins/vite.js +2964 -25641
  52. package/dist/plugins/webpack.d.ts +24 -1
  53. package/dist/plugins/webpack.js +209 -72
  54. package/dist/runtime/Chain.d.ts +32 -0
  55. package/dist/runtime/auto-hooks.d.ts +11 -0
  56. package/dist/runtime/hmr.d.ts +22 -2
  57. package/dist/runtime/index.d.ts +3 -2
  58. package/dist/runtime/index.js +3648 -301
  59. package/dist/runtime/injector.d.ts +39 -72
  60. package/dist/runtime/react.d.ts +17 -12
  61. package/dist/runtime/svelte.d.ts +15 -0
  62. package/dist/runtime/types.d.ts +126 -4
  63. package/dist/runtime/utils.d.ts +0 -1
  64. package/dist/runtime/vue.d.ts +34 -14
  65. package/package.json +59 -66
  66. package/src/cli/commands/build.ts +133 -0
  67. package/src/cli/commands/cache.ts +371 -0
  68. package/src/cli/commands/init.ts +230 -0
  69. package/src/cli/commands/timeline.ts +435 -0
  70. package/src/cli/commands/watch.ts +211 -0
  71. package/src/cli/index.ts +226 -0
  72. package/src/cli/types.ts +100 -0
  73. package/src/cli/utils/config-loader.ts +174 -0
  74. package/src/cli/utils/file-utils.ts +139 -0
  75. package/src/cli/utils/logger.ts +74 -0
  76. package/src/compiler/Chain.ts +831 -0
  77. package/src/compiler/animations.ts +517 -0
  78. package/src/compiler/atomic-optimizer.ts +786 -0
  79. package/src/compiler/breakpoints.ts +347 -0
  80. package/src/compiler/btt.ts +1147 -0
  81. package/src/compiler/cache-manager.ts +446 -0
  82. package/src/compiler/commonProps.ts +18 -0
  83. package/src/compiler/content-addressable-cache.ts +478 -0
  84. package/src/compiler/helpers.ts +407 -0
  85. package/src/compiler/index.ts +72 -0
  86. package/src/compiler/prefixer.ts +724 -0
  87. package/src/compiler/shorthands.ts +558 -0
  88. package/src/compiler/suggestions.ts +436 -0
  89. package/src/compiler/theme-contract.ts +197 -0
  90. package/src/compiler/token-resolver.ts +241 -0
  91. package/src/compiler/tokens.ts +612 -0
  92. package/src/core/auto-detector.ts +187 -0
  93. package/src/core/common-utils.ts +423 -0
  94. package/src/core/compiler.ts +835 -0
  95. package/src/core/constants.ts +424 -0
  96. package/src/core/index.ts +107 -0
  97. package/src/core/smart-chain.ts +163 -0
  98. package/src/core/types.ts +257 -0
  99. package/src/core/utils.ts +598 -0
  100. package/src/index.ts +208 -0
  101. package/src/plugins/vite.d.ts +316 -0
  102. package/src/plugins/vite.ts +424 -0
  103. package/src/plugins/webpack.d.ts +289 -0
  104. package/src/plugins/webpack.ts +416 -0
  105. package/src/runtime/Chain.ts +242 -0
  106. package/src/runtime/auto-hooks.tsx +127 -0
  107. package/src/runtime/auto-vue.ts +72 -0
  108. package/src/runtime/hmr.ts +212 -0
  109. package/src/runtime/index.ts +82 -0
  110. package/src/runtime/injector.ts +273 -0
  111. package/src/runtime/react.tsx +269 -0
  112. package/src/runtime/svelte.ts +15 -0
  113. package/src/runtime/types.ts +256 -0
  114. package/src/runtime/utils.ts +128 -0
  115. package/src/runtime/vite-env.d.ts +120 -0
  116. package/src/runtime/vue.ts +231 -0
  117. package/tsconfig.build.json +41 -0
  118. package/tsconfig.json +25 -0
  119. package/tsconfig.runtimes.json +18 -0
  120. package/dist/cli/cli.cjs +0 -7
  121. package/dist/cli/commands/build.d.ts.map +0 -1
  122. package/dist/cli/commands/compile.d.ts +0 -3
  123. package/dist/cli/commands/compile.d.ts.map +0 -1
  124. package/dist/cli/commands/init.d.ts.map +0 -1
  125. package/dist/cli/commands/timeline.d.ts.map +0 -1
  126. package/dist/cli/commands/watch.d.ts.map +0 -1
  127. package/dist/cli/index.d.ts.map +0 -1
  128. package/dist/cli/types.d.ts.map +0 -1
  129. package/dist/cli/utils/config-loader.d.ts.map +0 -1
  130. package/dist/cli/utils/file-utils.d.ts.map +0 -1
  131. package/dist/cli/utils/logger.d.ts.map +0 -1
  132. package/dist/compiler/atomic-optimizer.d.ts.map +0 -1
  133. package/dist/compiler/btt.d.ts.map +0 -1
  134. package/dist/compiler/cache-manager.d.ts.map +0 -1
  135. package/dist/compiler/commonProps.d.ts.map +0 -1
  136. package/dist/compiler/index.d.ts.map +0 -1
  137. package/dist/compiler/prefixer.d.ts.map +0 -1
  138. package/dist/compiler/theme-contract.d.ts.map +0 -1
  139. package/dist/compiler/tokens.d.ts.map +0 -1
  140. package/dist/compiler/types.d.ts +0 -57
  141. package/dist/compiler/types.d.ts.map +0 -1
  142. package/dist/core/compiler.d.ts.map +0 -1
  143. package/dist/core/constants.d.ts.map +0 -1
  144. package/dist/core/index.d.ts +0 -4
  145. package/dist/core/index.d.ts.map +0 -1
  146. package/dist/core/types.d.ts.map +0 -1
  147. package/dist/core/utils.d.ts.map +0 -1
  148. package/dist/index.d.ts.map +0 -1
  149. package/dist/plugins/vite.d.ts.map +0 -1
  150. package/dist/plugins/webpack.d.ts.map +0 -1
  151. package/dist/runtime/hmr.d.ts.map +0 -1
  152. package/dist/runtime/index.d.ts.map +0 -1
  153. package/dist/runtime/injector.d.ts.map +0 -1
  154. package/dist/runtime/react.d.ts.map +0 -1
  155. package/dist/runtime/react.js +0 -324
  156. package/dist/runtime/types.d.ts.map +0 -1
  157. package/dist/runtime/utils.d.ts.map +0 -1
  158. package/dist/runtime/vue.d.ts.map +0 -1
  159. package/dist/runtime/vue.js +0 -286
@@ -0,0 +1,424 @@
1
+ // chaincss/src/core/constants.ts
2
+ /**
3
+ * ChainCSS Constants
4
+ * Shared constants used across the codebase
5
+ */
6
+
7
+ import type { ChainCSSConfig } from './types.js';
8
+
9
+ // Version
10
+ export const VERSION = '2.0.0';
11
+
12
+ // Default CSS properties that should never be atomic
13
+ export const NEVER_ATOMIC_PROPERTIES = [
14
+ 'content',
15
+ 'animation',
16
+ 'animation-name',
17
+ 'animation-duration',
18
+ 'animation-timing-function',
19
+ 'animation-delay',
20
+ 'animation-iteration-count',
21
+ 'animation-direction',
22
+ 'animation-fill-mode',
23
+ 'animation-play-state',
24
+ 'transition',
25
+ 'transition-property',
26
+ 'transition-duration',
27
+ 'transition-timing-function',
28
+ 'transition-delay',
29
+ 'keyframes',
30
+ 'counter-increment',
31
+ 'counter-reset',
32
+ 'counter-set',
33
+ 'list-style',
34
+ 'list-style-type',
35
+ 'list-style-position',
36
+ 'list-style-image',
37
+ // Critical properties that should never be atomic
38
+ 'will-change',
39
+ 'backface-visibility',
40
+ 'perspective',
41
+ 'transform-style',
42
+ 'mix-blend-mode',
43
+ 'isolation',
44
+ 'contain',
45
+ 'content-visibility',
46
+ 'clip-path',
47
+ 'mask',
48
+ 'filter',
49
+ 'backdrop-filter'
50
+ ];
51
+
52
+ // Default CSS properties that should always be atomic (high reuse)
53
+ export const ALWAYS_ATOMIC_PROPERTIES = [
54
+ 'display',
55
+ 'position',
56
+ 'margin',
57
+ 'margin-top',
58
+ 'margin-right',
59
+ 'margin-bottom',
60
+ 'margin-left',
61
+ 'padding',
62
+ 'padding-top',
63
+ 'padding-right',
64
+ 'padding-bottom',
65
+ 'padding-left',
66
+ 'color',
67
+ 'background-color',
68
+ 'background',
69
+ 'border',
70
+ 'border-radius',
71
+ 'width',
72
+ 'height',
73
+ 'max-width',
74
+ 'max-height',
75
+ 'min-width',
76
+ 'min-height',
77
+ 'font-size',
78
+ 'font-weight',
79
+ 'text-align',
80
+ 'cursor',
81
+ 'opacity',
82
+ 'z-index',
83
+ 'overflow',
84
+ 'flex',
85
+ 'grid',
86
+ 'gap'
87
+ ];
88
+
89
+ // Default browsers for autoprefixer
90
+ export const DEFAULT_BROWSERS = [
91
+ '> 0.5%',
92
+ 'last 2 versions',
93
+ 'not dead',
94
+ 'Firefox ESR',
95
+ 'not ie < 11'
96
+ ];
97
+
98
+ // File extensions to process
99
+ export const SUPPORTED_EXTENSIONS = ['.chain.js', '.chain.ts'];
100
+
101
+ // Output file names
102
+ export const DEFAULT_CSS_FILENAME = 'styles.css';
103
+ export const DEFAULT_CLASS_MAP_FILENAME = 'class-map.json';
104
+ export const DEFAULT_TYPES_FILENAME = 'classes.d.ts';
105
+
106
+ // Cache configuration
107
+ export const DEFAULT_CACHE_PATH = './.chaincss-cache';
108
+ export const CACHE_VERSION = '2.0.0';
109
+
110
+ // Atomic optimizer thresholds
111
+ export const DEFAULT_ATOMIC_THRESHOLD = 2;
112
+ export const MIN_ATOMIC_THRESHOLD = 2;
113
+ export const MAX_ATOMIC_THRESHOLD = 10;
114
+
115
+ // Class name naming schemes
116
+ export const NAMING_SCHEMES = ['hash', 'readable'] as const;
117
+ export type NamingScheme = typeof NAMING_SCHEMES[number];
118
+
119
+ // Atomic optimizer modes
120
+ export const ATOMIC_MODES = ['standard', 'atomic', 'hybrid'] as const;
121
+ export type AtomicMode = typeof ATOMIC_MODES[number];
122
+
123
+ // Output strategies
124
+ export const OUTPUT_STRATEGIES = ['component-first', 'utility-first'] as const;
125
+ export type OutputStrategy = typeof OUTPUT_STRATEGIES[number];
126
+
127
+ // Prefixer modes
128
+ export const PREFIXER_MODES = ['auto', 'full', 'lightweight'] as const;
129
+ export type PrefixerMode = typeof PREFIXER_MODES[number];
130
+
131
+ // CLI exit codes
132
+ export const EXIT_CODES = {
133
+ SUCCESS: 0,
134
+ ERROR: 1,
135
+ INVALID_ARGS: 2,
136
+ FILE_NOT_FOUND: 3,
137
+ COMPILE_ERROR: 4
138
+ } as const;
139
+
140
+ // Log levels
141
+ export const LOG_LEVELS = {
142
+ DEBUG: 0,
143
+ INFO: 1,
144
+ SUCCESS: 2,
145
+ WARN: 3,
146
+ ERROR: 4,
147
+ SILENT: 5
148
+ } as const;
149
+
150
+ // Regex patterns
151
+ export const PATTERNS = {
152
+ CSS_PROPERTY: /^[a-z][a-z-]*$/,
153
+ SELECTOR: /^[.#][a-zA-Z][a-zA-Z0-9_-]*$/,
154
+ MEDIA_QUERY: /^@media\s+/,
155
+ KEYFRAMES: /^@keyframes\s+/,
156
+ TOKEN_REFERENCE: /\$([a-zA-Z0-9.-]+)/g,
157
+ HOVER_STATE: /:hover$/,
158
+ PSEUDO_CLASS: /:[a-z-]+(\([^)]+\))?$/,
159
+ CSS_VARIABLE: /^--[a-zA-Z][a-zA-Z0-9-]*$/,
160
+ SHORTHAND_PROPERTY: /^(m|p|b|bg|d|pos|w|h|max-w|max-h|min-w|min-h|rounded|border|flex|grid|gap|inset)$/,
161
+ URL_REFERENCE: /url\(['"]?([^'"()]+)['"]?\)/g,
162
+ IMPORT_STATEMENT: /@import\s+['"]([^'"]+)['"]/g,
163
+ FONT_FACE: /@font-face\s*\{/g,
164
+ STYLE_OBJECT: /(?:chain|\$)\(({[\s\S]*?})\)/g,
165
+ CHAIN_METHOD: /\.([a-zA-Z]+)\(([^)]*)\)/g,
166
+ HEX_COLOR: /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/,
167
+ RGB_COLOR: /^rgb\((\d{1,3},\s*\d{1,3},\s*\d{1,3})\)$/,
168
+ RGBA_COLOR: /^rgba\((\d{1,3},\s*\d{1,3},\s*\d{1,3},\s*(0|1|0?\.\d+))\)$/,
169
+ HSL_COLOR: /^hsl\((\d{1,3},\s*\d{1,3}%,\s*\d{1,3}%)\)$/
170
+ };
171
+
172
+ // Error messages
173
+ export const ERROR_MESSAGES = {
174
+ FILE_NOT_FOUND: (file: string) => `File not found: ${file}`,
175
+ INVALID_CONFIG: (error: string) => `Invalid configuration: ${error}`,
176
+ COMPILE_FAILED: (file: string, error: string) => `Failed to compile ${file}: ${error}`,
177
+ INVALID_SELECTOR: (selector: string) => `Invalid selector: ${selector}`,
178
+ INVALID_PROPERTY: (prop: string) => `Invalid CSS property: ${prop}`,
179
+ NO_INPUT_FILES: 'No input files found matching the patterns',
180
+ WATCH_FAILED: (error: string) => `Failed to start watch mode: ${error}`
181
+ };
182
+
183
+ // Success messages
184
+ export const SUCCESS_MESSAGES = {
185
+ COMPILE_SUCCESS: (count: number, time: number) => `Compiled ${count} file(s) in ${time}ms`,
186
+ INIT_SUCCESS: (configPath: string) => `Initialized ChainCSS config at ${configPath}`,
187
+ WATCH_STARTED: 'Watching for changes... (press Ctrl+C to stop)'
188
+ };
189
+
190
+ // Default responsive breakpoints
191
+ export const DEFAULT_BREAKPOINTS = {
192
+ sm: '(max-width: 640px)',
193
+ md: '(min-width: 641px) and (max-width: 768px)',
194
+ lg: '(min-width: 769px) and (max-width: 1024px)',
195
+ xl: '(min-width: 1025px)',
196
+ '2xl': '(min-width: 1280px)',
197
+ mobile: '(max-width: 768px)',
198
+ tablet: '(min-width: 769px) and (max-width: 1024px)',
199
+ desktop: '(min-width: 1025px)',
200
+ };
201
+
202
+ // Performance optimization constants
203
+ export const PERFORMANCE = {
204
+ MAX_CONCURRENT_COMPILATIONS: 10,
205
+ BATCH_SIZE: 20,
206
+ CACHE_PRUNE_INTERVAL_MS: 3600000, // 1 hour
207
+ CACHE_MAX_ENTRIES: 1000,
208
+ MAX_MEMORY_USAGE_MB: 512,
209
+ GC_THRESHOLD_MB: 400,
210
+ COMPILE_TIMEOUT: 30000,
211
+ FILE_WATCH_TIMEOUT: 5000,
212
+ DEBOUNCE_WRITE_MS: 100,
213
+ THROTTLE_COMPILE_MS: 50
214
+ } as const;
215
+
216
+ // Framework-specific configurations
217
+ export const FRAMEWORK_CONFIGS = {
218
+ react: {
219
+ extension: '.jsx',
220
+ componentTemplate: 'React.FC',
221
+ importReact: true,
222
+ cssInJs: false
223
+ },
224
+ vue: {
225
+ extension: '.vue',
226
+ componentTemplate: 'defineComponent',
227
+ importReact: false,
228
+ cssInJs: true
229
+ },
230
+ svelte: {
231
+ extension: '.svelte',
232
+ componentTemplate: 'script',
233
+ importReact: false,
234
+ cssInJs: true
235
+ },
236
+ solid: {
237
+ extension: '.jsx',
238
+ componentTemplate: 'Component',
239
+ importReact: false,
240
+ cssInJs: false
241
+ },
242
+ angular: {
243
+ extension: '.ts',
244
+ componentTemplate: 'Component',
245
+ importReact: false,
246
+ cssInJs: true
247
+ }
248
+ } as const;
249
+
250
+ export type Framework = keyof typeof FRAMEWORK_CONFIGS;
251
+
252
+ // Environment presets
253
+ export const ENVIRONMENT_PRESETS = {
254
+ development: {
255
+ atomic: {
256
+ naming: 'readable' as NamingScheme,
257
+ minify: false,
258
+ verbose: true,
259
+ cache: true
260
+ },
261
+ output: {
262
+ minify: false,
263
+ sourceComments: true
264
+ },
265
+ debug: true,
266
+ timeline: true,
267
+ sourceComments: true,
268
+ verbose: true
269
+ },
270
+ production: {
271
+ atomic: {
272
+ naming: 'hash' as NamingScheme,
273
+ minify: true,
274
+ verbose: false,
275
+ cache: true
276
+ },
277
+ output: {
278
+ minify: true,
279
+ sourceComments: false
280
+ },
281
+ debug: false,
282
+ timeline: false,
283
+ sourceComments: false,
284
+ verbose: false
285
+ },
286
+ test: {
287
+ atomic: {
288
+ naming: 'readable' as NamingScheme,
289
+ minify: false,
290
+ verbose: false,
291
+ cache: false
292
+ },
293
+ output: {
294
+ minify: false,
295
+ sourceComments: true
296
+ },
297
+ debug: true,
298
+ timeline: true,
299
+ sourceComments: true,
300
+ verbose: false
301
+ }
302
+ } as const;
303
+
304
+ // Validation rules
305
+ export const VALIDATION = {
306
+ MAX_SELECTOR_LENGTH: 100,
307
+ MAX_STYLE_RULES: 10000,
308
+ MAX_NESTING_DEPTH: 10,
309
+ CLASS_NAME: {
310
+ MIN_LENGTH: 1,
311
+ MAX_LENGTH: 50,
312
+ PATTERN: /^[a-zA-Z][a-zA-Z0-9_-]*$/,
313
+ RESERVED: ['chain', 'css', 'style', 'global', 'atomic']
314
+ },
315
+ PROPERTY_VALUE: {
316
+ MAX_LENGTH: 5000,
317
+ ALLOWED_UNITS: ['px', 'rem', 'em', '%', 'vw', 'vh', 'deg', 'rad', 'ms', 's']
318
+ },
319
+ BREAKPOINT: {
320
+ MIN_VALUE: 0,
321
+ MAX_VALUE: 10000,
322
+ ALLOWED_UNITS: ['px', 'rem', 'em', 'vw']
323
+ }
324
+ } as const;
325
+
326
+ // Memory management
327
+ export const MEMORY = {
328
+ CACHE_PRUNE_SIZE: 100 * 1024 * 1024, // 100MB
329
+ MAX_STRING_BUFFER: 10 * 1024 * 1024, // 10MB
330
+ BATCH_SIZE: 100,
331
+ CLEANUP_INTERVAL_MS: 300000, // 5 minutes
332
+ CACHE_CHECK_INTERVAL_MS: 60000, // 1 minute
333
+ MEMORY_CHECK_INTERVAL_MS: 30000 // 30 seconds
334
+ } as const;
335
+
336
+ // Default config values
337
+ export const DEFAULT_CONFIG: ChainCSSConfig = {
338
+ inputs: ['src/**/*.chain.{js,ts}', 'src/**/*.tsx'],
339
+ tokens: {
340
+ enabled: true,
341
+ prefix: 'chain'
342
+ },
343
+ atomic: {
344
+ enabled: true,
345
+ threshold: 2,
346
+ naming: (process.env.NODE_ENV === 'production' ? 'hash' : 'readable') as NamingScheme,
347
+ cache: true,
348
+ cachePath: DEFAULT_CACHE_PATH,
349
+ minify: true,
350
+ mode: 'hybrid' as AtomicMode,
351
+ outputStrategy: 'component-first' as OutputStrategy,
352
+ alwaysAtomic: ALWAYS_ATOMIC_PROPERTIES,
353
+ neverAtomic: NEVER_ATOMIC_PROPERTIES,
354
+ verbose: false
355
+ },
356
+ prefixer: {
357
+ enabled: true,
358
+ mode: 'auto' as PrefixerMode,
359
+ browsers: DEFAULT_BROWSERS,
360
+ sourceMap: true,
361
+ sourceMapInline: false
362
+ },
363
+ output: {
364
+ cssFile: DEFAULT_CSS_FILENAME,
365
+ classMapFile: DEFAULT_CLASS_MAP_FILENAME,
366
+ typesFile: DEFAULT_TYPES_FILENAME,
367
+ minify: true,
368
+ generateGlobalCSS: true
369
+ },
370
+ cachePath: DEFAULT_CACHE_PATH,
371
+ cacheEnabled: true,
372
+ persistentCachePath: './.chaincss/persistent-cache',
373
+ cacheMaxAgeDays: 30,
374
+ cacheMaxSizeMB: 500,
375
+ debug: false,
376
+ sourceComments: true,
377
+ timeline: false,
378
+ framework: 'auto',
379
+ namespace: 'chain',
380
+ verbose: false
381
+ };
382
+
383
+ // Runtime constants
384
+ export const RUNTIME = {
385
+ STYLE_ID_PREFIX: 'chaincss-runtime',
386
+ CLASS_NAME_PREFIX: 'c',
387
+ HASH_LENGTH: 6,
388
+ MAX_CACHE_SIZE: 100,
389
+ INJECTION_DELAY: 16 // ~1 frame at 60fps
390
+ };
391
+
392
+ // Development-only constants
393
+ export const DEV = {
394
+ HOT_RELOAD_PORT: 3000,
395
+ DEBOUNCE_DELAY: 100,
396
+ LOG_PREFIX: '[ChainCSS]'
397
+ };
398
+
399
+ // Production constants
400
+ export const PROD = {
401
+ COMPRESSION_LEVEL: 6,
402
+ SOURCE_MAP_COMMENT: '/*# sourceMappingURL=styles.css.map */'
403
+ };
404
+
405
+ // Type guard functions
406
+ export function isNamingScheme(value: unknown): value is NamingScheme {
407
+ return typeof value === 'string' && NAMING_SCHEMES.includes(value as any);
408
+ }
409
+
410
+ export function isAtomicMode(value: unknown): value is AtomicMode {
411
+ return typeof value === 'string' && ATOMIC_MODES.includes(value as any);
412
+ }
413
+
414
+ export function isOutputStrategy(value: unknown): value is OutputStrategy {
415
+ return typeof value === 'string' && OUTPUT_STRATEGIES.includes(value as any);
416
+ }
417
+
418
+ export function isPrefixerMode(value: unknown): value is PrefixerMode {
419
+ return typeof value === 'string' && PREFIXER_MODES.includes(value as any);
420
+ }
421
+
422
+ export function isFramework(value: unknown): value is Framework {
423
+ return typeof value === 'string' && value in FRAMEWORK_CONFIGS;
424
+ }
@@ -0,0 +1,107 @@
1
+ // src/core/index.ts
2
+
3
+ // Core compiler
4
+ export { ChainCSSCompiler, compileChainCSS } from './compiler.js';
5
+
6
+ // Types
7
+ export type {
8
+ ChainCSSConfig,
9
+ CompileResult,
10
+ StyleDefinition,
11
+ AtomicClass,
12
+ AtRule,
13
+ NestedRule,
14
+ ThemeBlock,
15
+ ChainCSSPlugin
16
+ } from './types.js';
17
+
18
+ // Constants
19
+ export {
20
+ VERSION,
21
+ DEFAULT_CONFIG,
22
+ DEFAULT_BREAKPOINTS,
23
+ NEVER_ATOMIC_PROPERTIES,
24
+ ALWAYS_ATOMIC_PROPERTIES,
25
+ NAMING_SCHEMES,
26
+ ATOMIC_MODES,
27
+ OUTPUT_STRATEGIES,
28
+ PREFIXER_MODES,
29
+ EXIT_CODES,
30
+ LOG_LEVELS,
31
+ PERFORMANCE,
32
+ MEMORY,
33
+ VALIDATION
34
+ } from './constants.js';
35
+
36
+ // Utilities (all of them)
37
+ export {
38
+ // Hashing & naming
39
+ hashString,
40
+ generateClassName,
41
+ generateAtomicClassName,
42
+ generateComponentClassName,
43
+
44
+ // String conversion
45
+ kebabCase,
46
+ camelCase,
47
+ pascalCase,
48
+ snakeCase,
49
+
50
+ // Formatting
51
+ formatCSS,
52
+ formatJS,
53
+ truncate,
54
+ indent,
55
+ stripIndent,
56
+
57
+ // Object manipulation
58
+ deepMerge,
59
+ deepClone,
60
+ deepEqual,
61
+ pick,
62
+ omit,
63
+
64
+ // Arrays
65
+ unique,
66
+ chunk,
67
+ groupBy,
68
+
69
+ // Performance
70
+ debounce,
71
+ throttle,
72
+
73
+ // Error handling
74
+ ChainCSSError,
75
+ tryOrWarn,
76
+ tryOrThrow,
77
+
78
+ // Logging
79
+ setLogLevel,
80
+ logDebug,
81
+ logInfo,
82
+ logWarn,
83
+ logError,
84
+
85
+ // Memory
86
+ getMemoryUsage,
87
+ formatBytes,
88
+
89
+ // Validation
90
+ isValidSelector,
91
+ isValidClassName,
92
+ isValidCSSProperty
93
+ } from './utils.js';
94
+
95
+ // Common utilities (shared with runtime)
96
+ export {
97
+ processStyleObject,
98
+ extractCSS,
99
+ extractHoverCSS,
100
+ mergeStyles,
101
+ isValidCSSLength,
102
+ isValidCSSColor,
103
+ escapeSelector,
104
+ cleanClassName,
105
+ sortClassNames
106
+ } from './common-utils.js';
107
+
@@ -0,0 +1,163 @@
1
+ // src/core/smart-chain.ts
2
+
3
+ import { chain as buildChainFunction } from '../compiler/Chain.js';
4
+ import { RuntimeChain } from '../runtime/Chain.js';
5
+ import { autoDetector, type AnalysisResult } from './auto-detector.js';
6
+
7
+ interface SmartCall {
8
+ prop: string;
9
+ value: any;
10
+ args: any[];
11
+ index: number;
12
+ }
13
+
14
+ class SmartChainProxy {
15
+ private calls: SmartCall[] = [];
16
+ private callIndex = 0;
17
+ private useTokens: boolean;
18
+ private readonly MAX_CALLS = 500; // Safety cap
19
+
20
+ constructor(useTokens: boolean = true) {
21
+ this.useTokens = useTokens;
22
+ }
23
+
24
+ private recordCall(prop: string, ...args: any[]): this {
25
+ // Safety: prevent unbounded growth
26
+ if (this.calls.length >= this.MAX_CALLS) {
27
+ console.warn('⚠️ ChainCSS: Smart chain call limit reached. Consider using build chain for static styles.');
28
+ return this;
29
+ }
30
+
31
+ this.calls.push({
32
+ prop,
33
+ value: args[0],
34
+ args,
35
+ index: this.callIndex++
36
+ });
37
+ return this;
38
+ }
39
+
40
+ private processHybrid(analysis: AnalysisResult, selectors: string[]): any {
41
+ const buildInstance = buildChainFunction(this.useTokens);
42
+ const runtimeInstance = new RuntimeChain(this.useTokens).proxy;
43
+
44
+ // Apply static parts to build mode
45
+ for (const part of analysis.staticParts) {
46
+ const call = this.calls[part.index];
47
+ if (call && (buildInstance as any)[call.prop]) {
48
+ (buildInstance as any)[call.prop](...call.args);
49
+ }
50
+ }
51
+
52
+ // Apply dynamic and runtime-only parts to runtime mode
53
+ const allDynamic = [...analysis.dynamicParts, ...analysis.runtimeOnlyParts];
54
+ for (const part of allDynamic) {
55
+ const call = this.calls[part.index];
56
+ if (call && (runtimeInstance as any)[call.prop]) {
57
+ (runtimeInstance as any)[call.prop](...call.args);
58
+ }
59
+ }
60
+
61
+ const buildResult = buildInstance.$el(...selectors);
62
+ const runtimeResult = runtimeInstance.$el(...selectors);
63
+
64
+ return {
65
+ ...(typeof buildResult === 'object' ? buildResult : {}),
66
+ ...(typeof runtimeResult === 'object' ? runtimeResult : {}),
67
+ __buildClasses: buildResult,
68
+ __runtimeClasses: runtimeResult,
69
+ __isHybrid: true
70
+ };
71
+ }
72
+
73
+ private processPureBuild(selectors: string[]): any {
74
+ const buildInstance = buildChainFunction(this.useTokens);
75
+
76
+ for (const call of this.calls) {
77
+ if ((buildInstance as any)[call.prop]) {
78
+ (buildInstance as any)[call.prop](...call.args);
79
+ }
80
+ }
81
+
82
+ return buildInstance.$el(...selectors);
83
+ }
84
+
85
+ private processPureRuntime(selectors: string[]): any {
86
+ const runtimeInstance = new RuntimeChain(this.useTokens).proxy;
87
+
88
+ for (const call of this.calls) {
89
+ if ((runtimeInstance as any)[call.prop]) {
90
+ (runtimeInstance as any)[call.prop](...call.args);
91
+ }
92
+ }
93
+
94
+ return runtimeInstance.$el(...selectors);
95
+ }
96
+
97
+ $el(...selectors: string[]): any {
98
+ if (this.calls.length === 0) {
99
+ return {};
100
+ }
101
+
102
+ const callsWithIndex = this.calls.map((call, idx) => ({
103
+ prop: call.prop,
104
+ value: call.value,
105
+ index: idx
106
+ }));
107
+
108
+ const analysis = autoDetector.analyzeChain(callsWithIndex);
109
+
110
+ // Safety check: prevent recursion if a smart chain is passed to another smart chain
111
+ if (this.calls[0]?.prop === '__isSmartChain') {
112
+ return this.processPureRuntime(selectors);
113
+ }
114
+
115
+ let result: any;
116
+ switch (analysis.mode) {
117
+ case 'hybrid':
118
+ result = this.processHybrid(analysis, selectors);
119
+ break;
120
+ case 'runtime':
121
+ result = this.processPureRuntime(selectors);
122
+ break;
123
+ case 'build':
124
+ default:
125
+ result = this.processPureBuild(selectors);
126
+ break;
127
+ }
128
+
129
+ // Clear calls after finalizing to free memory
130
+ this.calls = [];
131
+ this.callIndex = 0;
132
+
133
+ return result;
134
+ }
135
+
136
+ getProxy(): any {
137
+ const proxy = new Proxy(this, {
138
+ get(target, prop: string) {
139
+ // Special markers for detection
140
+ if (prop === '__isSmartChain') return true;
141
+ if (prop === '$el') return target.$el.bind(target);
142
+ if (prop === 'then') return undefined; // Prevent Promise resolution issues
143
+
144
+ // For any other property, record the call and return the proxy
145
+ return (...args: any[]) => {
146
+ target.recordCall(prop, ...args);
147
+ return proxy;
148
+ };
149
+ }
150
+ });
151
+
152
+ return proxy;
153
+ }
154
+ }
155
+
156
+ export function smartChain(useTokens: boolean = true): any {
157
+ const proxy = new SmartChainProxy(useTokens);
158
+ return proxy.getProxy();
159
+ }
160
+
161
+ // Legacy support functions
162
+ export const buildChain = (useTokens?: boolean) => buildChainFunction(useTokens);
163
+ export const runtimeChain = (useTokens?: boolean) => new RuntimeChain(useTokens || true).proxy;