tailwind-styled-v4 5.0.11 → 5.0.13

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 (110) hide show
  1. package/README.md +100 -4
  2. package/dist/{analyzeWorkspace-DDOQdzzI.d.ts → analyzeWorkspace-CopJNGmi.d.ts} +2 -0
  3. package/dist/{analyzeWorkspace-BS5O4rhC.d.mts → analyzeWorkspace-DpVPccjz.d.mts} +2 -0
  4. package/dist/analyzer.d.mts +4 -4
  5. package/dist/analyzer.d.ts +4 -4
  6. package/dist/analyzer.js +34 -69
  7. package/dist/analyzer.js.map +1 -1
  8. package/dist/analyzer.mjs +33 -68
  9. package/dist/analyzer.mjs.map +1 -1
  10. package/dist/animate.d.mts +4 -0
  11. package/dist/animate.d.ts +4 -0
  12. package/dist/animate.js +33 -11
  13. package/dist/animate.js.map +1 -1
  14. package/dist/animate.mjs +33 -11
  15. package/dist/animate.mjs.map +1 -1
  16. package/dist/atomic.js +57 -6
  17. package/dist/atomic.js.map +1 -1
  18. package/dist/atomic.mjs +57 -6
  19. package/dist/atomic.mjs.map +1 -1
  20. package/dist/cli.js +404 -190
  21. package/dist/cli.js.map +1 -1
  22. package/dist/cli.mjs +401 -187
  23. package/dist/cli.mjs.map +1 -1
  24. package/dist/compiler.d.mts +2700 -212
  25. package/dist/compiler.d.ts +2700 -212
  26. package/dist/compiler.js +1996 -503
  27. package/dist/compiler.js.map +1 -1
  28. package/dist/compiler.mjs +1847 -448
  29. package/dist/compiler.mjs.map +1 -1
  30. package/dist/devtools.js +17 -4
  31. package/dist/devtools.js.map +1 -1
  32. package/dist/devtools.mjs +17 -4
  33. package/dist/devtools.mjs.map +1 -1
  34. package/dist/engine.d.mts +11 -470
  35. package/dist/engine.d.ts +11 -470
  36. package/dist/engine.js +2777 -455
  37. package/dist/engine.js.map +1 -1
  38. package/dist/engine.mjs +2776 -454
  39. package/dist/engine.mjs.map +1 -1
  40. package/dist/index-BDQw13kn.d.ts +464 -0
  41. package/dist/index-DJv28Uzq.d.mts +464 -0
  42. package/dist/index.browser.mjs +143 -255
  43. package/dist/index.browser.mjs.map +1 -1
  44. package/dist/index.d.mts +23 -39
  45. package/dist/index.d.ts +23 -39
  46. package/dist/index.js +7234 -1400
  47. package/dist/index.js.map +1 -1
  48. package/dist/index.mjs +7234 -1400
  49. package/dist/index.mjs.map +1 -1
  50. package/dist/next.d.mts +44 -1
  51. package/dist/next.d.ts +44 -1
  52. package/dist/next.js +3224 -1065
  53. package/dist/next.js.map +1 -1
  54. package/dist/next.mjs +3223 -1066
  55. package/dist/next.mjs.map +1 -1
  56. package/dist/rspack.d.mts +9 -0
  57. package/dist/rspack.d.ts +9 -0
  58. package/dist/rspack.js +99 -61
  59. package/dist/rspack.js.map +1 -1
  60. package/dist/rspack.mjs +99 -61
  61. package/dist/rspack.mjs.map +1 -1
  62. package/dist/runtime-css.d.mts +8 -0
  63. package/dist/runtime-css.d.ts +8 -0
  64. package/dist/runtime-css.js +23 -7
  65. package/dist/runtime-css.js.map +1 -1
  66. package/dist/runtime-css.mjs +23 -7
  67. package/dist/runtime-css.mjs.map +1 -1
  68. package/dist/scanner.js +16 -37
  69. package/dist/scanner.js.map +1 -1
  70. package/dist/scanner.mjs +15 -36
  71. package/dist/scanner.mjs.map +1 -1
  72. package/dist/shared.d.mts +107 -1
  73. package/dist/shared.d.ts +107 -1
  74. package/dist/shared.js +3014 -466
  75. package/dist/shared.js.map +1 -1
  76. package/dist/shared.mjs +3008 -445
  77. package/dist/shared.mjs.map +1 -1
  78. package/dist/svelte.js +39 -35
  79. package/dist/svelte.js.map +1 -1
  80. package/dist/svelte.mjs +38 -34
  81. package/dist/svelte.mjs.map +1 -1
  82. package/dist/theme.js +85 -76
  83. package/dist/theme.js.map +1 -1
  84. package/dist/theme.mjs +83 -74
  85. package/dist/theme.mjs.map +1 -1
  86. package/dist/turbopackLoader.js +2351 -187
  87. package/dist/turbopackLoader.js.map +1 -1
  88. package/dist/turbopackLoader.mjs +2351 -187
  89. package/dist/turbopackLoader.mjs.map +1 -1
  90. package/dist/tw.js +404 -190
  91. package/dist/tw.js.map +1 -1
  92. package/dist/tw.mjs +401 -187
  93. package/dist/tw.mjs.map +1 -1
  94. package/dist/vite.js +2657 -320
  95. package/dist/vite.js.map +1 -1
  96. package/dist/vite.mjs +2657 -320
  97. package/dist/vite.mjs.map +1 -1
  98. package/dist/vue.js +39 -35
  99. package/dist/vue.js.map +1 -1
  100. package/dist/vue.mjs +38 -34
  101. package/dist/vue.mjs.map +1 -1
  102. package/dist/webpackLoader.js +190 -33
  103. package/dist/webpackLoader.js.map +1 -1
  104. package/dist/webpackLoader.mjs +190 -33
  105. package/dist/webpackLoader.mjs.map +1 -1
  106. package/native/index.node +0 -0
  107. package/native/tailwind-styled-native.node +0 -0
  108. package/native/tailwind-styled-native.win32-x64-msvc.node +0 -0
  109. package/package.json +9 -4
  110. package/CHANGELOG.md +0 -285
package/README.md CHANGED
@@ -372,12 +372,17 @@ Diukur di Node.js 22, Rust 1.75.
372
372
  tailwind-styled-v4/
373
373
  ├── native/ # Rust engine (NAPI-RS)
374
374
  │ ├── src/application/
375
- │ │ └── ast_extract.rs # Extract Tailwind classes dari source files
375
+ │ │ ├── ast_extract.rs # Extract Tailwind classes dari source files
376
+ │ │ ├── variant_resolver.rs # Variant resolution with precedence
377
+ │ │ ├── variant_system.rs # Variant composition system
378
+ │ │ └── theme_resolver_pool.rs # Multi-tier caching
376
379
  │ ├── src/domain/
377
380
  │ │ ├── variants.rs # Variant resolution (props override defaults)
381
+ │ │ ├── variant_precedence.rs # Precedence calculation
378
382
  │ │ └── transform.rs # Transform object config → JS component
379
383
  │ └── src/infrastructure/
380
- └── cache_store.rs # Persistent cache dengan bracket-aware parser
384
+ ├── napi_bridge_*.rs # Modularized NAPI bridges
385
+ │ └── cache_*.rs # Multi-tier cache backends
381
386
 
382
387
  ├── packages/
383
388
  │ ├── domain/
@@ -385,11 +390,30 @@ tailwind-styled-v4/
385
390
  │ │ ├── compiler/ # Tailwind JS + LightningCSS pipeline
386
391
  │ │ └── scanner/ # File scanner (Rust-backed)
387
392
  │ ├── presentation/
388
- │ │ └── next/ # Next.js plugin (withTailwindStyled)
393
+ │ │ ├── next/ # Next.js plugin (withTailwindStyled)
394
+ │ │ ├── vite/ # Vite plugin
395
+ │ │ └── rspack/ # Rspack plugin
389
396
  │ └── infrastructure/
390
397
  │ └── cli/ # CLI (tw setup, tw audit, dll)
398
+
399
+ ├── config/ # Configuration files (centralized)
400
+ │ ├── biome.json
401
+ │ ├── tsconfig.base.json
402
+ │ ├── turbo.json
403
+ │ └── ...
404
+
405
+ ├── docs/
406
+ │ ├── archive/ # Phase docs, session summaries, reference
407
+ │ ├── phase-4/, phase-5/, phase-6/ # Phase-specific documentation
408
+ │ └── api/ # API reference
391
409
  ```
392
410
 
411
+ **New Structure (Phase 7):**
412
+ - Configuration files centralized in `config/` directory
413
+ - Documentation archived in `docs/archive/` for cleaner root
414
+ - Modularized NAPI bridges (`napi_bridge_*.rs`) for better maintainability
415
+ - Phase-specific docs in dedicated directories
416
+
393
417
  ---
394
418
 
395
419
  ## TypeScript
@@ -434,7 +458,79 @@ Card.xyz // ❌ TypeScript error
434
458
 
435
459
  ---
436
460
 
437
- ## Development
461
+ ## Architecture Updates (Phase 7)
462
+
463
+ ### R1-R6: Parser Consolidation through Resolver Caching ✅ Completed 2026-06-12
464
+
465
+ Recent Phase 7 updates span multiple refactoring rounds:
466
+
467
+ **R1: Parser Consolidation** ✅
468
+ - Single unified production parser (v2-based)
469
+ - ~5% binary size reduction
470
+ - 100% backward compatible, all 545+ tests passing
471
+
472
+ **R2-R3: Infrastructure Modularization** ✅
473
+ - NAPI bridge modularized into specialized modules
474
+ - Comprehensive integration tests covering all layers
475
+ - Cache backend infrastructure refactored
476
+
477
+ **R4: Property Testing Framework** ✅
478
+ - 6 core properties verified across 53 test cases
479
+ - Parser determinism property testing
480
+ - Round-trip parsing validation
481
+ - Cache consistency & eviction properties
482
+
483
+ **R5: Variant Precedence System** ✅
484
+ - Native variant resolution with precedence handling
485
+ - Compound variant support
486
+ - Theme-aware variant composition
487
+
488
+ **R6: Resolver Caching** ✅
489
+ - Multi-tier caching for theme resolver
490
+ - Performance optimization verified
491
+
492
+ For architecture details and improvements roadmap, see:
493
+ - [Phase 7 Architecture Design](.kiro/specs/phase-7-architecture/design.md)
494
+ - [R4 Property Tests Design](.kiro/specs/phase-7-architecture/R4_PROPERTY_TESTS_DESIGN.md)
495
+ - [R5 Variant Precedence Design](.kiro/specs/phase-7-architecture/R5_VARIANT_PRECEDENCE_DESIGN.md)
496
+ - [Full spec directory](.kiro/specs/phase-7-architecture/)
497
+
498
+ ---
499
+
500
+ ## Recent Changes (82 commits, not yet pushed)
501
+
502
+ ### Infrastructure & Organization 🏗️
503
+ - **Config centralization** — moved 6 root config files to `config/` directory
504
+ - **Docs reorganization** — 42 summary/reference files moved to `docs/archive/`
505
+ - **Benchmarking suite** — added comprehensive performance benchmarking (`native/benches/`)
506
+
507
+ ### Rust Engine Enhancements 🦀
508
+ - **Modularized NAPI bridges** — split monolithic bridge into specialized modules:
509
+ - `napi_bridge_cache.rs` — caching layer
510
+ - `napi_bridge_redis.rs` — distributed cache
511
+ - `napi_bridge_theme.rs` — theme resolution
512
+ - `napi_bridge_variants.rs` — variant composition
513
+ - And 5 more specialized modules
514
+ - **Theme resolver pool** — multi-tier caching with adaptive strategies
515
+ - **Variant system improvements** — precedence calculation, compound variant support
516
+
517
+ ### Testing & Validation ✅
518
+ - **Property testing** — 6 core properties across 53 test cases
519
+ - **Integration tests** — comprehensive NAPI module tests (1000+ tests added)
520
+ - **Variant precedence tests** — 493+ test cases for variant resolution
521
+ - **Performance benchmarks** — week8, week9 scale testing suites
522
+
523
+ ### TypeScript/JS Improvements
524
+ - **Native bridge refactor** — simplified async/sync patterns, improved error handling
525
+ - **Cache integration** — unified cache interface across Redis, LRU, and file-based backends
526
+ - **Stream support** — added streaming CSS compilation
527
+
528
+ ### Documentation 📚
529
+ - **Phase 7 specs** — comprehensive design docs in `.kiro/specs/phase-7-architecture/`
530
+ - **NAPI module guide** — `MIGRATION_GUIDE_PHASE_7_3.md`
531
+ - **Architecture docs** — modular bridge patterns and integration guide
532
+
533
+ ---
438
534
 
439
535
  ```bash
440
536
  git clone https://github.com/Dictionar32/tailwind-styled-v4.git
@@ -93,6 +93,8 @@ interface NativeAnalyzerBinding {
93
93
  utilityPrefix: string;
94
94
  isArbitrary: boolean;
95
95
  }>;
96
+ /** Map Tailwind class base → conflict group name. Return "" if no group. */
97
+ resolveConflictGroup?(base: string): string;
96
98
  /** Aggregate class counts from scan files JSON. */
97
99
  collectClassCounts?(filesJson: string): Array<{
98
100
  name: string;
@@ -93,6 +93,8 @@ interface NativeAnalyzerBinding {
93
93
  utilityPrefix: string;
94
94
  isArbitrary: boolean;
95
95
  }>;
96
+ /** Map Tailwind class base → conflict group name. Return "" if no group. */
97
+ resolveConflictGroup?(base: string): string;
96
98
  /** Aggregate class counts from scan files JSON. */
97
99
  collectClassCounts?(filesJson: string): Array<{
98
100
  name: string;
@@ -1,5 +1,5 @@
1
- import { C as ClassToCssOptions, a as ClassToCssResult, c as collectClassCounts, b as buildDistribution } from './analyzeWorkspace-BS5O4rhC.mjs';
2
- export { A as AnalyzerOptions, d as AnalyzerReport, e as AnalyzerSemanticReport, f as ClassConflict, g as ClassUsage, h as analyzeWorkspace } from './analyzeWorkspace-BS5O4rhC.mjs';
1
+ import { C as ClassToCssOptions, a as ClassToCssResult, c as collectClassCounts, b as buildDistribution } from './analyzeWorkspace-DpVPccjz.mjs';
2
+ export { A as AnalyzerOptions, d as AnalyzerReport, e as AnalyzerSemanticReport, f as ClassConflict, g as ClassUsage, h as analyzeWorkspace } from './analyzeWorkspace-DpVPccjz.mjs';
3
3
  import './schemas-DR-SLxZZ.mjs';
4
4
  import 'zod';
5
5
 
@@ -17,14 +17,14 @@ declare const classToCss: (input: string | string[], options?: ClassToCssOptions
17
17
  */
18
18
 
19
19
  declare const __internal: {
20
- normalizeClassInput: (input: string | string[], _binding?: {
20
+ normalizeClassInput: (input: string | string[], binding: {
21
21
  normalizeClassInput?: (s: string) => string[];
22
22
  }) => string[];
23
23
  splitVariantAndBase: (className: string) => {
24
24
  variantKey: string;
25
25
  base: string;
26
26
  };
27
- resolveConflictGroup: (base: string) => string | null;
27
+ resolveConflictGroup: (base: string) => Promise<string | null>;
28
28
  collectClassCounts: typeof collectClassCounts;
29
29
  buildDistribution: typeof buildDistribution;
30
30
  utilityPrefix: (baseClass: string) => string;
@@ -1,5 +1,5 @@
1
- import { C as ClassToCssOptions, a as ClassToCssResult, c as collectClassCounts, b as buildDistribution } from './analyzeWorkspace-DDOQdzzI.js';
2
- export { A as AnalyzerOptions, d as AnalyzerReport, e as AnalyzerSemanticReport, f as ClassConflict, g as ClassUsage, h as analyzeWorkspace } from './analyzeWorkspace-DDOQdzzI.js';
1
+ import { C as ClassToCssOptions, a as ClassToCssResult, c as collectClassCounts, b as buildDistribution } from './analyzeWorkspace-CopJNGmi.js';
2
+ export { A as AnalyzerOptions, d as AnalyzerReport, e as AnalyzerSemanticReport, f as ClassConflict, g as ClassUsage, h as analyzeWorkspace } from './analyzeWorkspace-CopJNGmi.js';
3
3
  import './schemas-DR-SLxZZ.js';
4
4
  import 'zod';
5
5
 
@@ -17,14 +17,14 @@ declare const classToCss: (input: string | string[], options?: ClassToCssOptions
17
17
  */
18
18
 
19
19
  declare const __internal: {
20
- normalizeClassInput: (input: string | string[], _binding?: {
20
+ normalizeClassInput: (input: string | string[], binding: {
21
21
  normalizeClassInput?: (s: string) => string[];
22
22
  }) => string[];
23
23
  splitVariantAndBase: (className: string) => {
24
24
  variantKey: string;
25
25
  base: string;
26
26
  };
27
- resolveConflictGroup: (base: string) => string | null;
27
+ resolveConflictGroup: (base: string) => Promise<string | null>;
28
28
  collectClassCounts: typeof collectClassCounts;
29
29
  buildDistribution: typeof buildDistribution;
30
30
  utilityPrefix: (baseClass: string) => string;
package/dist/analyzer.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  require('crypto');
4
- var fs4 = require('fs');
4
+ var fs3 = require('fs');
5
5
  var path5 = require('path');
6
6
  var url = require('url');
7
7
  var module$1 = require('module');
@@ -12,7 +12,7 @@ var zod = require('zod');
12
12
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
13
13
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
14
 
15
- var fs4__default = /*#__PURE__*/_interopDefault(fs4);
15
+ var fs3__default = /*#__PURE__*/_interopDefault(fs3);
16
16
  var path5__default = /*#__PURE__*/_interopDefault(path5);
17
17
 
18
18
  /* tailwind-styled-v4 v5.0.4 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
@@ -77,7 +77,7 @@ function loadNativeBinding(options) {
77
77
  for (const candidate of candidates) {
78
78
  const candidatePath = path5__default.default.resolve(runtimeDir, candidate);
79
79
  try {
80
- if (!fs4__default.default.existsSync(candidatePath) && !fs4__default.default.existsSync(candidatePath + ".node")) {
80
+ if (!fs3__default.default.existsSync(candidatePath) && !fs3__default.default.existsSync(candidatePath + ".node")) {
81
81
  continue;
82
82
  }
83
83
  const mod = requireNativeModule(candidatePath);
@@ -109,9 +109,9 @@ function resolveNativeBindingCandidates(options) {
109
109
  }
110
110
  }
111
111
  if (!includeDefaultCandidates) return candidates;
112
- if (fs4__default.default.existsSync(runtimeDir)) {
112
+ if (fs3__default.default.existsSync(runtimeDir)) {
113
113
  try {
114
- for (const entry of fs4__default.default.readdirSync(runtimeDir)) {
114
+ for (const entry of fs3__default.default.readdirSync(runtimeDir)) {
115
115
  if (entry.endsWith(".node")) candidates.push(entry);
116
116
  }
117
117
  } catch {
@@ -527,7 +527,7 @@ function defaultCachePath(rootDir, cacheDir) {
527
527
  }
528
528
  function readCache(rootDir, cacheDir) {
529
529
  const cachePath = defaultCachePath(rootDir, cacheDir);
530
- fs4__default.default.mkdirSync(path5__default.default.dirname(cachePath), { recursive: true });
530
+ fs3__default.default.mkdirSync(path5__default.default.dirname(cachePath), { recursive: true });
531
531
  const result = cacheReadNative(cachePath);
532
532
  if (!result) return [];
533
533
  return result.entries.map((e) => ({
@@ -542,7 +542,7 @@ function readCache(rootDir, cacheDir) {
542
542
  }
543
543
  function writeCache(rootDir, entries, cacheDir) {
544
544
  const cachePath = defaultCachePath(rootDir, cacheDir);
545
- fs4__default.default.mkdirSync(path5__default.default.dirname(cachePath), { recursive: true });
545
+ fs3__default.default.mkdirSync(path5__default.default.dirname(cachePath), { recursive: true });
546
546
  const success = cacheWriteNative(cachePath, entries);
547
547
  if (!success) {
548
548
  throw new Error(
@@ -569,27 +569,7 @@ var init_cache_native = __esm({
569
569
  function collectFiles(rootDir, extensions, ignoreDirs) {
570
570
  const native = collectFilesNative(rootDir, extensions, ignoreDirs);
571
571
  if (native !== null) return native;
572
- const files = [];
573
- function walk(dir) {
574
- let entries;
575
- try {
576
- entries = fs4__default.default.readdirSync(dir, { withFileTypes: true });
577
- } catch {
578
- return;
579
- }
580
- for (const entry of entries) {
581
- const fullPath = path5__default.default.join(dir, entry.name);
582
- const rel = path5__default.default.relative(rootDir, fullPath);
583
- if (entry.isDirectory()) {
584
- const ignored = ignoreDirs.some((d) => entry.name === d || rel.startsWith(d + path5__default.default.sep));
585
- if (!ignored) walk(fullPath);
586
- } else if (isScannableFile(entry.name, extensions)) {
587
- files.push(fullPath);
588
- }
589
- }
590
- }
591
- walk(rootDir);
592
- return files;
572
+ throw new Error("FATAL: Native binding 'collectFiles' is required but not available.");
593
573
  }
594
574
  function mergeResults(batchResults) {
595
575
  const files = batchResults.map((r) => ({
@@ -599,8 +579,7 @@ function mergeResults(batchResults) {
599
579
  }));
600
580
  const native = rebuildWorkspaceResultNative(files);
601
581
  if (native) return native;
602
- const unique = new Set(files.flatMap((f) => f.classes));
603
- return { files, totalFiles: files.length, uniqueClasses: Array.from(unique).sort() };
582
+ throw new Error("FATAL: Native binding 'rebuildWorkspaceResult' is required but not available.");
604
583
  }
605
584
  function runChunkInWorker(filePaths) {
606
585
  return new Promise((resolve, reject) => {
@@ -739,7 +718,7 @@ __export(src_exports, {
739
718
  DEFAULT_IGNORES: () => DEFAULT_IGNORES,
740
719
  batchExtractClassesNative: () => batchExtractClassesNative,
741
720
  extractClassesNative: () => extractClassesNative,
742
- isScannableFile: () => isScannableFile,
721
+ isScannableFile: () => isScannableFile2,
743
722
  parseScanWorkspaceOptions: () => parseScanWorkspaceOptions,
744
723
  parseScanWorkspaceResult: () => parseScanWorkspaceResult,
745
724
  parseScannerWorkerMessage: () => parseScannerWorkerMessage,
@@ -773,7 +752,7 @@ function resolveScannerWorkerModulePath() {
773
752
  path5__default.default.resolve(runtimeDir, "worker.ts")
774
753
  ];
775
754
  for (const candidate of candidates) {
776
- if (fs4__default.default.existsSync(candidate)) return candidate;
755
+ if (fs3__default.default.existsSync(candidate)) return candidate;
777
756
  }
778
757
  return null;
779
758
  }
@@ -830,7 +809,7 @@ function collectCandidates(rootDir, ignoreDirectories, extensionSet) {
830
809
  if (!currentDir) continue;
831
810
  const entries = (() => {
832
811
  try {
833
- return fs4__default.default.readdirSync(currentDir, { withFileTypes: true });
812
+ return fs3__default.default.readdirSync(currentDir, { withFileTypes: true });
834
813
  } catch {
835
814
  return [];
836
815
  }
@@ -868,7 +847,7 @@ function scanSource(source) {
868
847
  "FATAL: Native parser binding is required but not available.\nThis package requires native Rust bindings.\n\nResolution steps:\n1. Build the native Rust module: npm run build:rust"
869
848
  );
870
849
  }
871
- function isScannableFile(filePath, includeExtensions = DEFAULT_EXTENSIONS) {
850
+ function isScannableFile2(filePath, includeExtensions = DEFAULT_EXTENSIONS) {
872
851
  return includeExtensions.includes(path5__default.default.extname(filePath));
873
852
  }
874
853
  function scanFile(filePath) {
@@ -929,7 +908,7 @@ function scanWorkspace(rootDir, options = {}) {
929
908
  for (const filePath of candidates) {
930
909
  const stat = (() => {
931
910
  try {
932
- return fs4__default.default.statSync(filePath);
911
+ return fs3__default.default.statSync(filePath);
933
912
  } catch {
934
913
  return null;
935
914
  }
@@ -955,7 +934,7 @@ function scanWorkspace(rootDir, options = {}) {
955
934
  for (const { filePath, stat, size, cached } of ranked) {
956
935
  const content = (() => {
957
936
  try {
958
- return fs4__default.default.readFileSync(filePath, "utf8");
937
+ return fs3__default.default.readFileSync(filePath, "utf8");
959
938
  } catch {
960
939
  return null;
961
940
  }
@@ -1099,7 +1078,7 @@ var init_src2 = __esm({
1099
1078
  )
1100
1079
  ];
1101
1080
  for (const fullPath of candidates) {
1102
- if (!fs4__default.default.existsSync(fullPath)) continue;
1081
+ if (!fs3__default.default.existsSync(fullPath)) continue;
1103
1082
  try {
1104
1083
  const required = req(fullPath);
1105
1084
  if (required && (typeof required.extractClassesFromSource === "function" || typeof required.parseClasses === "function" || typeof required.parse_classes === "function")) {
@@ -1153,7 +1132,7 @@ function isRecord(value) {
1153
1132
  }
1154
1133
  async function pathExists(filePath) {
1155
1134
  try {
1156
- await fs4__default.default.promises.access(filePath, fs4__default.default.constants.F_OK);
1135
+ await fs3__default.default.promises.access(filePath, fs3__default.default.constants.F_OK);
1157
1136
  return true;
1158
1137
  } catch {
1159
1138
  return false;
@@ -1369,27 +1348,13 @@ var splitVariantAndBase = (className) => {
1369
1348
  const base = parts.pop() ?? className;
1370
1349
  return { variantKey: parts.join(":"), base };
1371
1350
  };
1372
- var isArbitraryUtility = (baseClass) => {
1373
- return baseClass.includes("[") && baseClass.includes("]");
1374
- };
1375
- var resolveConflictGroup = (base) => {
1376
- if (isArbitraryUtility(base)) return null;
1377
- if (["block", "inline", "inline-block", "inline-flex", "flex", "grid", "hidden"].includes(base))
1378
- return "display";
1379
- if (base.startsWith("bg-")) return "bg";
1380
- if (base.startsWith("text-")) return "text";
1381
- if (base.startsWith("font-")) return "font";
1382
- if (base.startsWith("rounded")) return "rounded";
1383
- if (base.startsWith("shadow")) return "shadow";
1384
- if (base.startsWith("border-")) return "border";
1385
- if (base.startsWith("opacity-")) return "opacity";
1386
- if (base.startsWith("w-") || base.startsWith("min-w-") || base.startsWith("max-w-"))
1387
- return "width";
1388
- if (base.startsWith("h-") || base.startsWith("min-h-") || base.startsWith("max-h-"))
1389
- return "height";
1390
- if (base.startsWith("p-") || base.startsWith("px-") || base.startsWith("py-")) return "padding";
1391
- if (base.startsWith("m-") || base.startsWith("mx-") || base.startsWith("my-")) return "margin";
1392
- return null;
1351
+ var resolveConflictGroup = async (base) => {
1352
+ const native = await getNativeBinding();
1353
+ if (!native?.resolveConflictGroup) {
1354
+ throw new Error("Native binding 'resolveConflictGroup' is required but not available.");
1355
+ }
1356
+ const result = native.resolveConflictGroup(base);
1357
+ return result.length > 0 ? result : null;
1393
1358
  };
1394
1359
  var detectConflicts = async (usages) => {
1395
1360
  const native = await getNativeBinding();
@@ -1477,7 +1442,7 @@ var collectCustomUtilities = (config) => {
1477
1442
  return out;
1478
1443
  };
1479
1444
  var collectSafelistFromSource = async (configPath) => {
1480
- const source = await fs4__default.default.promises.readFile(configPath, "utf8");
1445
+ const source = await fs3__default.default.promises.readFile(configPath, "utf8");
1481
1446
  const { extractClassesNative: extractClassesNative2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
1482
1447
  const allTokens = extractClassesNative2(source);
1483
1448
  const hasSafelist = source.includes("safelist");
@@ -1504,7 +1469,7 @@ var loadTailwindConfig = async (root, semanticOption) => {
1504
1469
  customUtilities: /* @__PURE__ */ new Set()
1505
1470
  };
1506
1471
  }
1507
- const configStat = await fs4__default.default.promises.stat(configPath).catch(() => null);
1472
+ const configStat = await fs3__default.default.promises.stat(configPath).catch(() => null);
1508
1473
  if (configStat) {
1509
1474
  const cached = tailwindConfigCache.get(configPath);
1510
1475
  if (cached && cached.mtimeMs === configStat.mtimeMs && cached.size === configStat.size) {
@@ -1785,12 +1750,12 @@ async function analyzeWorkspace(root, options = {}) {
1785
1750
  }
1786
1751
 
1787
1752
  // packages/domain/analyzer/src/classToCss.ts
1788
- var normalizeClassInput = (input, _binding) => {
1753
+ var normalizeClassInput = (input, binding) => {
1789
1754
  if (typeof input === "string") {
1790
- if (_binding?.normalizeClassInput) {
1791
- return _binding.normalizeClassInput(input);
1755
+ if (!binding.normalizeClassInput) {
1756
+ throw new Error("FATAL: Native binding 'normalizeClassInput' is required but not available.");
1792
1757
  }
1793
- return input.split(/\s+/).map((item) => item.trim()).filter((item) => item.length > 0);
1758
+ return binding.normalizeClassInput(input);
1794
1759
  }
1795
1760
  if (!Array.isArray(input)) {
1796
1761
  throw new TypeError("classToCss input must be a string or an array of strings.");
@@ -1822,11 +1787,11 @@ var mergeDeclarationMap = (target, css, binding) => {
1822
1787
  }
1823
1788
  };
1824
1789
  var declarationMapToString = (declarationMap, binding) => {
1825
- const entries = Array.from(declarationMap.entries()).map(([property, value]) => ({ property, value }));
1826
- if (binding?.declarationMapToString) {
1827
- return binding.declarationMapToString(entries);
1790
+ if (!binding.declarationMapToString) {
1791
+ throw new Error("FATAL: Native binding 'declarationMapToString' is required but not available.");
1828
1792
  }
1829
- return entries.map(({ property, value }) => `${property}: ${value}`).join("; ");
1793
+ const entries = Array.from(declarationMap.entries()).map(([property, value]) => ({ property, value }));
1794
+ return binding.declarationMapToString(entries);
1830
1795
  };
1831
1796
  var classToCss = async (input, options = {}) => {
1832
1797
  const binding = await requireNativeCssCompiler();