tailwind-styled-v4 5.0.9 → 5.0.10

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 (137) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/dist/{analyzeWorkspace-DuJKh7Ty.d.mts → analyzeWorkspace-BS5O4rhC.d.mts} +47 -2
  3. package/dist/{analyzeWorkspace-Ct_NTAWt.d.ts → analyzeWorkspace-DDOQdzzI.d.ts} +47 -2
  4. package/dist/analyzer.d.mts +5 -3
  5. package/dist/analyzer.d.ts +5 -3
  6. package/dist/analyzer.js +563 -468
  7. package/dist/analyzer.js.map +1 -1
  8. package/dist/analyzer.mjs +562 -467
  9. package/dist/analyzer.mjs.map +1 -1
  10. package/dist/animate.d.mts +4 -7
  11. package/dist/animate.d.ts +4 -7
  12. package/dist/animate.js +171 -265
  13. package/dist/animate.js.map +1 -1
  14. package/dist/animate.mjs +165 -264
  15. package/dist/animate.mjs.map +1 -1
  16. package/dist/atomic.d.mts +22 -1
  17. package/dist/atomic.d.ts +22 -1
  18. package/dist/atomic.js +221 -165
  19. package/dist/atomic.js.map +1 -1
  20. package/dist/atomic.mjs +200 -165
  21. package/dist/atomic.mjs.map +1 -1
  22. package/dist/cli.d.mts +60 -1
  23. package/dist/cli.d.ts +60 -1
  24. package/dist/cli.js +1261 -1517
  25. package/dist/cli.js.map +1 -1
  26. package/dist/cli.mjs +1238 -1513
  27. package/dist/cli.mjs.map +1 -1
  28. package/dist/compiler.d.mts +38 -7
  29. package/dist/compiler.d.ts +38 -7
  30. package/dist/compiler.js +174 -197
  31. package/dist/compiler.js.map +1 -1
  32. package/dist/compiler.mjs +151 -194
  33. package/dist/compiler.mjs.map +1 -1
  34. package/dist/devtools.js +7 -31
  35. package/dist/devtools.js.map +1 -1
  36. package/dist/devtools.mjs +7 -31
  37. package/dist/devtools.mjs.map +1 -1
  38. package/dist/engine.d.mts +134 -63
  39. package/dist/engine.d.ts +134 -63
  40. package/dist/engine.js +2863 -2482
  41. package/dist/engine.js.map +1 -1
  42. package/dist/engine.mjs +2852 -2485
  43. package/dist/engine.mjs.map +1 -1
  44. package/dist/{index-eWAocnD2.d.mts → index-NDINUhLN.d.mts} +3 -1
  45. package/dist/{index-eWAocnD2.d.ts → index-NDINUhLN.d.ts} +3 -1
  46. package/dist/index.d.mts +45 -32
  47. package/dist/index.d.ts +45 -32
  48. package/dist/index.js +271 -158
  49. package/dist/index.js.map +1 -1
  50. package/dist/index.mjs +251 -158
  51. package/dist/index.mjs.map +1 -1
  52. package/dist/{liveTokenEngine-DSUk88P6.d.ts → liveTokenEngine-CN9ian1R.d.ts} +1 -1
  53. package/dist/{liveTokenEngine-CX5_0c4q.d.mts → liveTokenEngine-DKoWRtqH.d.mts} +1 -1
  54. package/dist/next.js +20 -39
  55. package/dist/next.js.map +1 -1
  56. package/dist/next.mjs +18 -37
  57. package/dist/next.mjs.map +1 -1
  58. package/dist/plugin-api.d.mts +8 -2
  59. package/dist/plugin-api.d.ts +8 -2
  60. package/dist/plugin-api.js +14 -2
  61. package/dist/plugin-api.js.map +1 -1
  62. package/dist/plugin-api.mjs +14 -3
  63. package/dist/plugin-api.mjs.map +1 -1
  64. package/dist/plugin-registry.js +51 -11
  65. package/dist/plugin-registry.js.map +1 -1
  66. package/dist/plugin-registry.mjs +51 -11
  67. package/dist/plugin-registry.mjs.map +1 -1
  68. package/dist/plugin.d.mts +5 -7
  69. package/dist/plugin.d.ts +5 -7
  70. package/dist/plugin.js +16 -15
  71. package/dist/plugin.js.map +1 -1
  72. package/dist/plugin.mjs +16 -16
  73. package/dist/plugin.mjs.map +1 -1
  74. package/dist/rspack.js +17 -38
  75. package/dist/rspack.js.map +1 -1
  76. package/dist/rspack.mjs +15 -36
  77. package/dist/rspack.mjs.map +1 -1
  78. package/dist/runtime.d.mts +2 -2
  79. package/dist/runtime.d.ts +2 -2
  80. package/dist/scanner.d.mts +10 -1
  81. package/dist/scanner.d.ts +10 -1
  82. package/dist/scanner.js +298 -124
  83. package/dist/scanner.js.map +1 -1
  84. package/dist/scanner.mjs +296 -124
  85. package/dist/scanner.mjs.map +1 -1
  86. package/dist/shared.d.mts +1 -1
  87. package/dist/shared.d.ts +1 -1
  88. package/dist/shared.js +104 -176
  89. package/dist/shared.js.map +1 -1
  90. package/dist/shared.mjs +85 -176
  91. package/dist/shared.mjs.map +1 -1
  92. package/dist/storybook-addon.d.mts +1 -1
  93. package/dist/storybook-addon.d.ts +1 -1
  94. package/dist/svelte.d.mts +1 -1
  95. package/dist/svelte.d.ts +1 -1
  96. package/dist/svelte.js +166 -3
  97. package/dist/svelte.js.map +1 -1
  98. package/dist/svelte.mjs +143 -1
  99. package/dist/svelte.mjs.map +1 -1
  100. package/dist/syntax.js +21 -21
  101. package/dist/syntax.js.map +1 -1
  102. package/dist/syntax.mjs +21 -21
  103. package/dist/syntax.mjs.map +1 -1
  104. package/dist/testing.js +9 -1
  105. package/dist/testing.js.map +1 -1
  106. package/dist/testing.mjs +9 -1
  107. package/dist/testing.mjs.map +1 -1
  108. package/dist/theme.d.mts +2 -2
  109. package/dist/theme.d.ts +2 -2
  110. package/dist/theme.js +40 -112
  111. package/dist/theme.js.map +1 -1
  112. package/dist/theme.mjs +37 -110
  113. package/dist/theme.mjs.map +1 -1
  114. package/dist/turbopackLoader.js +79 -124
  115. package/dist/turbopackLoader.js.map +1 -1
  116. package/dist/turbopackLoader.mjs +63 -122
  117. package/dist/turbopackLoader.mjs.map +1 -1
  118. package/dist/tw.js +1256 -1517
  119. package/dist/tw.js.map +1 -1
  120. package/dist/tw.mjs +1236 -1513
  121. package/dist/tw.mjs.map +1 -1
  122. package/dist/vite.js +1783 -823
  123. package/dist/vite.js.map +1 -1
  124. package/dist/vite.mjs +1767 -821
  125. package/dist/vite.mjs.map +1 -1
  126. package/dist/vue.d.mts +1 -1
  127. package/dist/vue.d.ts +1 -1
  128. package/dist/vue.js +165 -4
  129. package/dist/vue.js.map +1 -1
  130. package/dist/vue.mjs +141 -1
  131. package/dist/vue.mjs.map +1 -1
  132. package/dist/webpackLoader.js +65 -108
  133. package/dist/webpackLoader.js.map +1 -1
  134. package/dist/webpackLoader.mjs +45 -104
  135. package/dist/webpackLoader.mjs.map +1 -1
  136. package/native/tailwind-styled-native.node +0 -0
  137. package/package.json +22 -24
package/dist/analyzer.mjs CHANGED
@@ -1,8 +1,10 @@
1
- import path3 from 'path';
1
+ import 'crypto';
2
+ import fs3 from 'fs';
3
+ import path5 from 'path';
2
4
  import { fileURLToPath, pathToFileURL } from 'url';
3
- import fs from 'fs';
4
5
  import { createRequire } from 'module';
5
- import { Worker } from 'worker_threads';
6
+ import { Worker, isMainThread, parentPort, workerData } from 'worker_threads';
7
+ import { availableParallelism } from 'os';
6
8
  import { z } from 'zod';
7
9
 
8
10
  /* tailwind-styled-v4 v5.0.4 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
@@ -10,12 +12,6 @@ var __defProp = Object.defineProperty;
10
12
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11
13
  var __getOwnPropNames = Object.getOwnPropertyNames;
12
14
  var __hasOwnProp = Object.prototype.hasOwnProperty;
13
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
14
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
15
- }) : x)(function(x) {
16
- if (typeof require !== "undefined") return require.apply(this, arguments);
17
- throw Error('Dynamic require of "' + x + '" is not supported');
18
- });
19
15
  var __esm = (fn, res) => function __init() {
20
16
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
21
17
  };
@@ -32,41 +28,6 @@ var __copyProps = (to, from, except, desc) => {
32
28
  return to;
33
29
  };
34
30
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
35
-
36
- // packages/domain/shared/src/index.ts
37
- function getNodeModuleRef() {
38
- if (isBrowser) return null;
39
- if (nodeModuleRef !== null) return nodeModuleRef;
40
- try {
41
- const test = typeof __require === "function" ? __require("module") : null;
42
- nodeModuleRef = test;
43
- return test;
44
- } catch {
45
- nodeModuleRef = null;
46
- return null;
47
- }
48
- }
49
- function getNodeFs() {
50
- if (isBrowser) throw new Error("node:fs not available in browser");
51
- const nodeRequire = getNodeModuleRef();
52
- if (!nodeRequire) throw new Error("require not available");
53
- if (!_nodeFs) _nodeFs = nodeRequire.createRequire(import.meta.url)("node:fs");
54
- return _nodeFs;
55
- }
56
- function getNodePath() {
57
- if (isBrowser) throw new Error("node:path not available in browser");
58
- const nodeRequire = getNodeModuleRef();
59
- if (!nodeRequire) throw new Error("require not available");
60
- if (!_nodePath) _nodePath = nodeRequire.createRequire(import.meta.url)("node:path");
61
- return _nodePath;
62
- }
63
- function getNodeUrl() {
64
- if (isBrowser) throw new Error("node:url not available in browser");
65
- const nodeRequire = getNodeModuleRef();
66
- if (!nodeRequire) throw new Error("require not available");
67
- if (!_nodeUrl) _nodeUrl = nodeRequire.createRequire(import.meta.url)("node:url");
68
- return _nodeUrl;
69
- }
70
31
  function createLogger(namespace) {
71
32
  const prefix = `[${namespace}]`;
72
33
  return {
@@ -96,24 +57,19 @@ function createDebugLogger(namespace, label) {
96
57
  }
97
58
  };
98
59
  }
99
- function formatIssuePath(path6) {
100
- if (!path6 || path6.length === 0) return "(root)";
101
- return path6.map(
60
+ function formatIssuePath(path8) {
61
+ if (!path8 || path8.length === 0) return "(root)";
62
+ return path8.map(
102
63
  (segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
103
64
  ).join(".");
104
65
  }
105
66
  function loadNativeBinding(options) {
106
- if (isBrowser) {
107
- return { binding: null, loadErrors: [{ path: "", message: "Native bindings not available in browser" }] };
108
- }
109
67
  const { runtimeDir, candidates, isValid } = options;
110
68
  const loadErrors = [];
111
- const path6 = getNodePath();
112
- const fs4 = getNodeFs();
113
69
  for (const candidate of candidates) {
114
- const candidatePath = path6.resolve(runtimeDir, candidate);
70
+ const candidatePath = path5.resolve(runtimeDir, candidate);
115
71
  try {
116
- if (!fs4.existsSync(candidatePath) && !fs4.existsSync(candidatePath + ".node")) {
72
+ if (!fs3.existsSync(candidatePath) && !fs3.existsSync(candidatePath + ".node")) {
117
73
  continue;
118
74
  }
119
75
  const mod = requireNativeModule(candidatePath);
@@ -127,72 +83,56 @@ function loadNativeBinding(options) {
127
83
  }
128
84
  return { binding: null, loadErrors };
129
85
  }
130
- function getRequire() {
131
- if (isBrowser) return (() => {
132
- throw new Error("require not available in browser");
133
- });
134
- const nodeRequire = getNodeModuleRef();
135
- if (!nodeRequire) return (() => {
136
- throw new Error("require not available");
137
- });
138
- return nodeRequire.createRequire(import.meta.url);
139
- }
140
- function requireNativeModule(path6) {
141
- return _require(path6);
86
+ function requireNativeModule(p) {
87
+ return _require(p);
142
88
  }
143
89
  function resolveNativeBindingCandidates(options) {
144
- if (isBrowser) return [];
145
- const { runtimeDir, envVarNames = [], includeDefaultCandidates = true, enforceNodeExtensionForEnvPath = false } = options;
90
+ const {
91
+ envVarNames = ["TW_NATIVE_PATH", "TWS_NATIVE_PATH"],
92
+ includeDefaultCandidates = true,
93
+ enforceNodeExtensionForEnvPath = false
94
+ } = options;
95
+ const runtimeDir = options.runtimeDir || process.cwd();
146
96
  const candidates = [];
147
- const path6 = getNodePath();
148
- const fs4 = getNodeFs();
149
97
  for (const envVar of envVarNames) {
150
98
  const envPath = process.env[envVar];
151
99
  if (envPath) {
152
- if (enforceNodeExtensionForEnvPath && !envPath.endsWith(".node")) {
153
- candidates.push(envPath + ".node");
154
- } else {
155
- candidates.push(envPath);
156
- }
100
+ candidates.push(enforceNodeExtensionForEnvPath && !envPath.endsWith(".node") ? envPath + ".node" : envPath);
157
101
  }
158
102
  }
159
103
  if (!includeDefaultCandidates) return candidates;
160
- if (fs4.existsSync(runtimeDir)) {
104
+ if (fs3.existsSync(runtimeDir)) {
161
105
  try {
162
- const entries = fs4.readdirSync(runtimeDir);
163
- for (const entry of entries) {
164
- if (entry.endsWith(".node")) {
165
- candidates.push(entry);
166
- }
106
+ for (const entry of fs3.readdirSync(runtimeDir)) {
107
+ if (entry.endsWith(".node")) candidates.push(entry);
167
108
  }
168
109
  } catch {
169
110
  }
170
111
  }
171
- const platform = typeof process !== "undefined" ? process.platform : "";
172
- const ext = platform === "win32" ? ".dll" : platform === "darwin" ? ".dylib" : ".so";
173
- const defaultBindingName = `tailwind_styled_parser${ext}`;
174
- candidates.push(path6.resolve(runtimeDir, "..", "..", "..", "native", defaultBindingName));
175
- candidates.push(path6.resolve(runtimeDir, "..", "..", "..", "..", "native", defaultBindingName));
176
- candidates.push(path6.resolve(process.cwd(), "native", defaultBindingName));
112
+ const BINARY_NAMES = ["tailwind-styled-native", "tailwind_styled_parser"];
113
+ const napiPlatform = process.platform === "linux" && process.arch === "x64" ? "linux-x64-gnu" : process.platform === "linux" && process.arch === "arm64" ? "linux-arm64-gnu" : `${process.platform}-${process.arch}`;
114
+ for (const bin of BINARY_NAMES) {
115
+ candidates.push(path5.resolve(runtimeDir, `${bin}.node`));
116
+ candidates.push(path5.resolve(runtimeDir, `${bin}.${napiPlatform}.node`));
117
+ candidates.push(path5.resolve(runtimeDir, "..", "..", "..", "..", "native", `${bin}.node`));
118
+ candidates.push(path5.resolve(runtimeDir, "..", "..", "..", "..", "native", `${bin}.${napiPlatform}.node`));
119
+ candidates.push(path5.resolve(runtimeDir, "..", "..", "..", "native", `${bin}.node`));
120
+ candidates.push(path5.resolve(process.cwd(), "native", `${bin}.node`));
121
+ candidates.push(path5.resolve(process.cwd(), "native", `${bin}.${napiPlatform}.node`));
122
+ }
177
123
  return Array.from(new Set(candidates));
178
124
  }
179
125
  function resolveRuntimeDir(dir, importMetaUrl) {
180
- if (isBrowser) return "";
181
- if (dir) return getNodePath().resolve(dir);
126
+ if (dir) return path5.resolve(dir);
182
127
  try {
183
- return getNodeUrl().fileURLToPath(importMetaUrl);
128
+ return path5.dirname(fileURLToPath(importMetaUrl));
184
129
  } catch {
185
130
  return process.cwd();
186
131
  }
187
132
  }
188
- var isBrowser, nodeModuleRef, _nodeFs, _nodePath, _nodeUrl, TwError, _require;
133
+ var TwError, _require;
189
134
  var init_src = __esm({
190
135
  "packages/domain/shared/src/index.ts"() {
191
- isBrowser = typeof window !== "undefined" || typeof document !== "undefined";
192
- nodeModuleRef = null;
193
- _nodeFs = null;
194
- _nodePath = null;
195
- _nodeUrl = null;
196
136
  TwError = class _TwError extends Error {
197
137
  /** @deprecated Gunakan source */
198
138
  domain;
@@ -226,8 +166,8 @@ var init_src = __esm({
226
166
  /** Buat TwError dari ZodError — dukung shape Zod v3 (`errors`) dan v4 (`issues`). */
227
167
  static fromZod(err) {
228
168
  const first = err.issues?.[0] ?? err.errors?.[0];
229
- const path6 = formatIssuePath(first?.path);
230
- const message = first ? `${path6}: ${first.message}` : "Schema validation failed";
169
+ const path8 = formatIssuePath(first?.path);
170
+ const message = first ? `${path8}: ${first.message}` : "Schema validation failed";
231
171
  return new _TwError("validation", "SCHEMA_VALIDATION_FAILED", message, err);
232
172
  }
233
173
  static wrap(source, code, err) {
@@ -245,21 +185,33 @@ var init_src = __esm({
245
185
  return `[${this.source.toUpperCase()}:${this.code}] ${this.message}`;
246
186
  }
247
187
  };
248
- _require = getRequire();
188
+ _require = createRequire(import.meta.url);
249
189
  }
250
190
  });
251
191
 
252
192
  // packages/domain/scanner/src/native-bridge.ts
253
193
  var native_bridge_exports = {};
254
194
  __export(native_bridge_exports, {
195
+ batchExtractClassesNative: () => batchExtractClassesNative,
255
196
  cachePriorityNative: () => cachePriorityNative,
256
197
  cacheReadNative: () => cacheReadNative,
257
198
  cacheWriteNative: () => cacheWriteNative,
199
+ collectFilesNative: () => collectFilesNative,
200
+ computeCacheStatsNative: () => computeCacheStatsNative,
258
201
  extractClassesNative: () => extractClassesNative,
202
+ generateSubComponentTypesNative: () => generateSubComponentTypesNative,
259
203
  hasNativeScannerBinding: () => hasNativeScannerBinding,
260
204
  hashContentNative: () => hashContentNative,
261
205
  isRustCacheAvailable: () => isRustCacheAvailable,
206
+ pruneStaleEntriesNative: () => pruneStaleEntriesNative,
207
+ rebuildWorkspaceResultNative: () => rebuildWorkspaceResultNative,
262
208
  resetScannerBridgeCache: () => resetScannerBridgeCache,
209
+ scanCacheGet: () => scanCacheGet,
210
+ scanCacheInvalidate: () => scanCacheInvalidate,
211
+ scanCachePut: () => scanCachePut,
212
+ scanCacheStats: () => scanCacheStats,
213
+ scanFileNative: () => scanFileNative,
214
+ scanFilesBatchNative: () => scanFilesBatchNative,
263
215
  scanWorkspaceNative: () => scanWorkspaceNative
264
216
  });
265
217
  function getDirname() {
@@ -267,7 +219,7 @@ function getDirname() {
267
219
  return __dirname;
268
220
  }
269
221
  if (typeof import.meta !== "undefined" && import.meta.url) {
270
- return path3.dirname(fileURLToPath(import.meta.url));
222
+ return path5.dirname(fileURLToPath(import.meta.url));
271
223
  }
272
224
  return process.cwd();
273
225
  }
@@ -348,6 +300,95 @@ function cachePriorityNative(mtimeMs, size, cachedMtimeMs, cachedSize, cachedHit
348
300
  }
349
301
  return result;
350
302
  }
303
+ function batchExtractClassesNative(filePaths) {
304
+ const binding = scannerGetBinding();
305
+ if (!binding.batchExtractClasses) {
306
+ throw new Error("FATAL: Native binding 'batchExtractClasses' is required but not available.");
307
+ }
308
+ return binding.batchExtractClasses(filePaths) ?? [];
309
+ }
310
+ function scanCacheGet(filePath, contentHash) {
311
+ const binding = scannerGetBinding();
312
+ if (!binding.scanCacheGet) {
313
+ throw new Error("FATAL: Native binding 'scanCacheGet' is required but not available.");
314
+ }
315
+ return binding.scanCacheGet(filePath, contentHash) ?? null;
316
+ }
317
+ function scanCachePut(filePath, contentHash, classes, mtimeMs, size) {
318
+ const binding = scannerGetBinding();
319
+ if (!binding.scanCachePut) {
320
+ throw new Error("FATAL: Native binding 'scanCachePut' is required but not available.");
321
+ }
322
+ binding.scanCachePut(filePath, contentHash, classes, mtimeMs, size);
323
+ }
324
+ function scanCacheInvalidate(filePath) {
325
+ const binding = scannerGetBinding();
326
+ if (!binding.scanCacheInvalidate) {
327
+ throw new Error("FATAL: Native binding 'scanCacheInvalidate' is required but not available.");
328
+ }
329
+ binding.scanCacheInvalidate(filePath);
330
+ }
331
+ function scanCacheStats() {
332
+ const binding = scannerGetBinding();
333
+ if (!binding.scanCacheStats) {
334
+ throw new Error("FATAL: Native binding 'scanCacheStats' is required but not available.");
335
+ }
336
+ return binding.scanCacheStats();
337
+ }
338
+ function scanFileNative(filePath) {
339
+ const binding = scannerGetBinding();
340
+ if (!binding.scanFile) {
341
+ throw new Error("FATAL: Native binding 'scanFile' is required but not available.");
342
+ }
343
+ return binding.scanFile(filePath);
344
+ }
345
+ function collectFilesNative(root, extensions, ignoreDirs) {
346
+ const binding = scannerGetBinding();
347
+ if (!binding.collectFiles) return null;
348
+ return binding.collectFiles(root, extensions, ignoreDirs);
349
+ }
350
+ function scanFilesBatchNative(filePaths) {
351
+ const binding = scannerGetBinding();
352
+ if (!binding.scanFilesBatch) {
353
+ return filePaths.map((fp) => {
354
+ try {
355
+ const r = binding.scanFile?.(fp);
356
+ return r ? { file: r.file, classes: r.classes, hash: r.hash ?? "" } : { file: fp, classes: [], hash: "" };
357
+ } catch {
358
+ return { file: fp, classes: [], hash: "" };
359
+ }
360
+ });
361
+ }
362
+ return binding.scanFilesBatch(filePaths);
363
+ }
364
+ function generateSubComponentTypesNative(root, outputPath) {
365
+ const binding = scannerGetBinding();
366
+ if (!binding.generateSubComponentTypes) return null;
367
+ return binding.generateSubComponentTypes(root, outputPath ?? null);
368
+ }
369
+ function pruneStaleEntriesNative(entries, maxAgeMs, checkExists) {
370
+ const binding = scannerGetBinding();
371
+ if (!binding.pruneStaleEntries) return null;
372
+ return binding.pruneStaleEntries(
373
+ entries.map((e) => ({ file: e.file, lastSeenMs: e.lastSeenMs ?? 0 })),
374
+ maxAgeMs ?? null,
375
+ checkExists ?? null
376
+ );
377
+ }
378
+ function rebuildWorkspaceResultNative(files) {
379
+ const binding = scannerBridgeLoader.get();
380
+ if (!binding?.rebuildWorkspaceResult) return null;
381
+ try {
382
+ return binding.rebuildWorkspaceResult(files);
383
+ } catch {
384
+ return null;
385
+ }
386
+ }
387
+ function computeCacheStatsNative(filesClasses, sizes, top) {
388
+ const binding = scannerGetBinding();
389
+ if (!binding.computeCacheStats) return null;
390
+ return binding.computeCacheStats(filesClasses, sizes, top ?? null);
391
+ }
351
392
  var log, isValidScannerBinding, createScannerBridgeLoader, scannerBridgeLoader, scannerGetBinding, resetScannerBridgeCache;
352
393
  var init_native_bridge = __esm({
353
394
  "packages/domain/scanner/src/native-bridge.ts"() {
@@ -431,15 +472,9 @@ var init_native_bridge = __esm({
431
472
  resetScannerBridgeCache = scannerBridgeLoader.reset;
432
473
  }
433
474
  });
434
-
435
- // packages/domain/scanner/src/index.ts
436
- init_src();
437
-
438
- // packages/domain/scanner/src/cache-native.ts
439
- init_native_bridge();
440
475
  function defaultCachePath(rootDir, cacheDir) {
441
- const dir = cacheDir ? path3.resolve(rootDir, cacheDir) : path3.join(process.cwd(), ".cache", "tailwind-styled");
442
- return path3.join(dir, "scanner-cache.json");
476
+ const dir = cacheDir ? path5.resolve(rootDir, cacheDir) : path5.join(process.cwd(), ".cache", "tailwind-styled");
477
+ return path5.join(dir, "scanner-cache.json");
443
478
  }
444
479
  function readCache(rootDir, cacheDir) {
445
480
  const cachePath = defaultCachePath(rootDir, cacheDir);
@@ -475,158 +510,219 @@ function filePriority(mtimeMs, size, cached, nowMs = Date.now()) {
475
510
  nowMs
476
511
  );
477
512
  }
478
-
479
- // packages/domain/scanner/src/index.ts
480
- init_native_bridge();
481
-
482
- // packages/domain/scanner/src/schemas.ts
483
- init_src();
484
- var formatIssuePath2 = (path6) => path6.length > 0 ? path6.map(
485
- (segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
486
- ).join(".") : "<root>";
487
- var formatIssues = (error) => error.issues.map((issue) => {
488
- const path6 = formatIssuePath2(issue.path);
489
- return `${path6}: ${issue.message}`;
490
- }).join("; ");
491
- var parseWithSchema = (schema, data, label) => {
492
- const parsed = schema.safeParse(data);
493
- if (parsed.success) return parsed.data;
494
- const details = formatIssues(parsed.error);
495
- throw new TwError(
496
- "validation",
497
- "SCHEMA_VALIDATION_FAILED",
498
- details ? `${label}: ${details}` : label,
499
- parsed.error
500
- );
501
- };
502
- var NonNegativeIntegerSchema = z.number().int().min(0);
503
- var ScanWorkspaceOptionsSchema = z.object({
504
- includeExtensions: z.array(z.string()).optional(),
505
- ignoreDirectories: z.array(z.string()).optional(),
506
- useCache: z.boolean().optional(),
507
- cacheDir: z.string().min(1).optional(),
508
- smartInvalidation: z.boolean().optional()
509
- });
510
- var ScanFileResultSchema = z.object({
511
- file: z.string(),
512
- classes: z.array(z.string()),
513
- hash: z.string().optional()
514
- });
515
- var ScanWorkspaceResultSchema = z.object({
516
- files: z.array(ScanFileResultSchema),
517
- totalFiles: NonNegativeIntegerSchema,
518
- uniqueClasses: z.array(z.string())
519
- }).refine((value) => value.totalFiles === value.files.length, {
520
- message: "scan result totalFiles must match files.length",
521
- path: ["totalFiles"]
522
- });
523
- z.object({
524
- rootDir: z.string().min(1),
525
- options: ScanWorkspaceOptionsSchema.optional()
513
+ var init_cache_native = __esm({
514
+ "packages/domain/scanner/src/cache-native.ts"() {
515
+ init_native_bridge();
516
+ }
526
517
  });
527
- var ScannerWorkerSuccessMessageSchema = z.object({
528
- ok: z.literal(true),
529
- result: ScanWorkspaceResultSchema
518
+ function collectFiles(rootDir, extensions, ignoreDirs) {
519
+ const native = collectFilesNative(rootDir, extensions, ignoreDirs);
520
+ if (native !== null) return native;
521
+ const files = [];
522
+ function walk(dir) {
523
+ let entries;
524
+ try {
525
+ entries = fs3.readdirSync(dir, { withFileTypes: true });
526
+ } catch {
527
+ return;
528
+ }
529
+ for (const entry of entries) {
530
+ const fullPath = path5.join(dir, entry.name);
531
+ const rel = path5.relative(rootDir, fullPath);
532
+ if (entry.isDirectory()) {
533
+ const ignored = ignoreDirs.some((d) => entry.name === d || rel.startsWith(d + path5.sep));
534
+ if (!ignored) walk(fullPath);
535
+ } else if (isScannableFile(entry.name, extensions)) {
536
+ files.push(fullPath);
537
+ }
538
+ }
539
+ }
540
+ walk(rootDir);
541
+ return files;
542
+ }
543
+ function mergeResults(batchResults) {
544
+ const files = batchResults.map((r) => ({
545
+ file: r.file,
546
+ classes: r.classes,
547
+ hash: r.content_hash
548
+ }));
549
+ const native = rebuildWorkspaceResultNative(files);
550
+ if (native) return native;
551
+ const unique = new Set(files.flatMap((f) => f.classes));
552
+ return { files, totalFiles: files.length, uniqueClasses: Array.from(unique).sort() };
553
+ }
554
+ function runChunkInWorker(filePaths) {
555
+ return new Promise((resolve, reject) => {
556
+ const worker = new Worker(_workerFilename, {
557
+ workerData: { filePaths }
558
+ });
559
+ worker.once("message", (payload) => {
560
+ if (payload.ok) {
561
+ resolve(payload.results);
562
+ } else {
563
+ reject(new Error(payload.error ?? "parallel-scanner worker failed"));
564
+ }
565
+ });
566
+ worker.once("error", reject);
567
+ worker.once("exit", (code) => {
568
+ if (code !== 0) reject(new Error(`parallel-scanner worker exited with code ${code}`));
569
+ });
570
+ });
571
+ }
572
+ async function scanWorkspaceParallel(rootDir, options = {}) {
573
+ const {
574
+ extensions = DEFAULT_EXTENSIONS,
575
+ ignoreDirs = DEFAULT_IGNORES,
576
+ maxWorkers = Math.max(1, availableParallelism() - 1),
577
+ chunkSize = DEFAULT_CHUNK_SIZE
578
+ } = options;
579
+ const files = collectFiles(path5.resolve(rootDir), extensions, ignoreDirs);
580
+ if (files.length < PARALLEL_THRESHOLD) {
581
+ return mergeResults(batchExtractClassesNative(files));
582
+ }
583
+ const chunks = [];
584
+ for (let i = 0; i < files.length; i += chunkSize) {
585
+ chunks.push(files.slice(i, i + chunkSize));
586
+ }
587
+ const allResults = [];
588
+ for (let i = 0; i < chunks.length; i += maxWorkers) {
589
+ const batch = chunks.slice(i, i + maxWorkers);
590
+ const batchResults = await Promise.all(batch.map(runChunkInWorker));
591
+ allResults.push(...batchResults.flat());
592
+ }
593
+ return mergeResults(allResults);
594
+ }
595
+ var PARALLEL_THRESHOLD, DEFAULT_CHUNK_SIZE, _workerFilename;
596
+ var init_parallel_scanner = __esm({
597
+ "packages/domain/scanner/src/parallel-scanner.ts"() {
598
+ init_src2();
599
+ init_native_bridge();
600
+ PARALLEL_THRESHOLD = 50;
601
+ DEFAULT_CHUNK_SIZE = 150;
602
+ if (!isMainThread && parentPort) {
603
+ const { filePaths } = workerData;
604
+ try {
605
+ const results = batchExtractClassesNative(filePaths);
606
+ const msg = { ok: true, results };
607
+ parentPort.postMessage(msg);
608
+ } catch (error) {
609
+ const msg = {
610
+ ok: false,
611
+ error: error instanceof Error ? error.message : String(error)
612
+ };
613
+ parentPort.postMessage(msg);
614
+ }
615
+ }
616
+ _workerFilename = typeof __filename !== "undefined" ? __filename : fileURLToPath(import.meta.url);
617
+ }
530
618
  });
531
- var ScannerWorkerErrorMessageSchema = z.object({
532
- ok: z.literal(false),
533
- error: z.string().optional()
619
+ var formatIssuePath2, formatIssues, parseWithSchema, NonNegativeIntegerSchema, ScanWorkspaceOptionsSchema, ScanFileResultSchema, ScanWorkspaceResultSchema, ScannerWorkerSuccessMessageSchema, ScannerWorkerErrorMessageSchema, ScannerWorkerMessageSchema, parseScanWorkspaceOptions, parseScanWorkspaceResult, parseScannerWorkerMessage;
620
+ var init_schemas = __esm({
621
+ "packages/domain/scanner/src/schemas.ts"() {
622
+ init_src();
623
+ formatIssuePath2 = (path8) => path8.length > 0 ? path8.map(
624
+ (segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
625
+ ).join(".") : "<root>";
626
+ formatIssues = (error) => error.issues.map((issue) => {
627
+ const path8 = formatIssuePath2(issue.path);
628
+ return `${path8}: ${issue.message}`;
629
+ }).join("; ");
630
+ parseWithSchema = (schema, data, label) => {
631
+ const parsed = schema.safeParse(data);
632
+ if (parsed.success) return parsed.data;
633
+ const details = formatIssues(parsed.error);
634
+ throw new TwError(
635
+ "validation",
636
+ "SCHEMA_VALIDATION_FAILED",
637
+ details ? `${label}: ${details}` : label,
638
+ parsed.error
639
+ );
640
+ };
641
+ NonNegativeIntegerSchema = z.number().int().min(0);
642
+ ScanWorkspaceOptionsSchema = z.object({
643
+ includeExtensions: z.array(z.string()).optional(),
644
+ ignoreDirectories: z.array(z.string()).optional(),
645
+ useCache: z.boolean().optional(),
646
+ cacheDir: z.string().min(1).optional(),
647
+ smartInvalidation: z.boolean().optional()
648
+ });
649
+ ScanFileResultSchema = z.object({
650
+ file: z.string(),
651
+ classes: z.array(z.string()),
652
+ hash: z.string().optional()
653
+ });
654
+ ScanWorkspaceResultSchema = z.object({
655
+ files: z.array(ScanFileResultSchema),
656
+ totalFiles: NonNegativeIntegerSchema,
657
+ uniqueClasses: z.array(z.string())
658
+ }).refine((value) => value.totalFiles === value.files.length, {
659
+ message: "scan result totalFiles must match files.length",
660
+ path: ["totalFiles"]
661
+ });
662
+ z.object({
663
+ rootDir: z.string().min(1),
664
+ options: ScanWorkspaceOptionsSchema.optional()
665
+ });
666
+ ScannerWorkerSuccessMessageSchema = z.object({
667
+ ok: z.literal(true),
668
+ result: ScanWorkspaceResultSchema
669
+ });
670
+ ScannerWorkerErrorMessageSchema = z.object({
671
+ ok: z.literal(false),
672
+ error: z.string().optional()
673
+ });
674
+ ScannerWorkerMessageSchema = z.union([
675
+ ScannerWorkerSuccessMessageSchema,
676
+ ScannerWorkerErrorMessageSchema
677
+ ]);
678
+ parseScanWorkspaceOptions = (options) => parseWithSchema(ScanWorkspaceOptionsSchema, options ?? {}, "scanner options are invalid");
679
+ parseScanWorkspaceResult = (result) => parseWithSchema(ScanWorkspaceResultSchema, result, "scanner workspace result is invalid");
680
+ parseScannerWorkerMessage = (message) => parseWithSchema(ScannerWorkerMessageSchema, message, "scanner worker message is invalid");
681
+ }
534
682
  });
535
- var ScannerWorkerMessageSchema = z.union([
536
- ScannerWorkerSuccessMessageSchema,
537
- ScannerWorkerErrorMessageSchema
538
- ]);
539
- var parseScanWorkspaceOptions = (options) => parseWithSchema(ScanWorkspaceOptionsSchema, options ?? {}, "scanner options are invalid");
540
- var parseScanWorkspaceResult = (result) => parseWithSchema(ScanWorkspaceResultSchema, result, "scanner workspace result is invalid");
541
- var parseScannerWorkerMessage = (message) => parseWithSchema(ScannerWorkerMessageSchema, message, "scanner worker message is invalid");
542
683
 
543
684
  // packages/domain/scanner/src/index.ts
544
- var log2 = createLogger("scanner");
545
- var SCAN_WORKER_TIMEOUT_MS = 12e4;
685
+ var src_exports = {};
686
+ __export(src_exports, {
687
+ DEFAULT_EXTENSIONS: () => DEFAULT_EXTENSIONS,
688
+ DEFAULT_IGNORES: () => DEFAULT_IGNORES,
689
+ batchExtractClassesNative: () => batchExtractClassesNative,
690
+ extractClassesNative: () => extractClassesNative,
691
+ isScannableFile: () => isScannableFile,
692
+ parseScanWorkspaceOptions: () => parseScanWorkspaceOptions,
693
+ parseScanWorkspaceResult: () => parseScanWorkspaceResult,
694
+ parseScannerWorkerMessage: () => parseScannerWorkerMessage,
695
+ scanFile: () => scanFile,
696
+ scanSource: () => scanSource,
697
+ scanWorkspace: () => scanWorkspace,
698
+ scanWorkspaceAsync: () => scanWorkspaceAsync
699
+ });
546
700
  function getRuntimeDir() {
547
701
  if (typeof __dirname !== "undefined" && __dirname.length > 0) {
548
702
  return __dirname;
549
703
  }
550
704
  if (typeof import.meta !== "undefined" && import.meta.url) {
551
- return path3.dirname(fileURLToPath(import.meta.url));
705
+ return path5.dirname(fileURLToPath(import.meta.url));
552
706
  }
553
707
  return process.cwd();
554
708
  }
555
- var createNativeParserLoader = () => {
556
- const _state = {
557
- binding: void 0,
558
- initError: null
559
- };
560
- const debugNative = (message) => {
561
- log2.debug(`[native] ${message}`);
562
- };
563
- const loadNativeParserBinding = () => {
564
- if (_state.binding !== void 0) return _state.binding;
565
- const runtimeDir = getRuntimeDir();
566
- const req = createRequire(path3.join(runtimeDir, "noop.cjs"));
567
- const candidates = [
568
- path3.resolve(process.cwd(), "native/tailwind_styled_parser.node"),
569
- path3.resolve(process.cwd(), "native/build/Release/tailwind_styled_parser.node"),
570
- path3.resolve(runtimeDir, "..", "..", "..", "native", "tailwind_styled_parser.node"),
571
- path3.resolve(
572
- runtimeDir,
573
- "..",
574
- "..",
575
- "..",
576
- "native",
577
- "build",
578
- "Release",
579
- "tailwind_styled_parser.node"
580
- )
581
- ];
582
- for (const fullPath of candidates) {
583
- if (!fs.existsSync(fullPath)) continue;
584
- try {
585
- const required = req(fullPath);
586
- if (required && (typeof required.extractClassesFromSource === "function" || typeof required.parseClasses === "function" || typeof required.parse_classes === "function")) {
587
- _state.binding = required;
588
- debugNative(`using native parser from ${fullPath}`);
589
- return _state.binding;
590
- }
591
- } catch (error) {
592
- _state.initError = error instanceof Error ? error.message : String(error);
593
- }
594
- }
595
- _state.binding = null;
596
- if (!_state.initError) {
597
- _state.initError = "native .node binding not found";
598
- }
599
- debugNative(`native binding not available: ${_state.initError}`);
600
- return _state.binding;
601
- };
602
- return {
603
- get: loadNativeParserBinding,
604
- reset: () => {
605
- _state.binding = void 0;
606
- _state.initError = null;
607
- }
608
- };
609
- };
610
- var nativeParserLoader = createNativeParserLoader();
611
- var DEFAULT_EXTENSIONS = [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs"];
612
- var DEFAULT_IGNORES = ["node_modules", ".git", ".next", "dist", "out", ".turbo", ".cache"];
613
709
  function resolveScannerWorkerModulePath() {
614
710
  const runtimeDir = (() => {
615
711
  if (typeof __dirname !== "undefined" && __dirname.length > 0) {
616
712
  return __dirname;
617
713
  }
618
714
  if (typeof import.meta !== "undefined" && import.meta.url) {
619
- return path3.dirname(fileURLToPath(import.meta.url));
715
+ return path5.dirname(fileURLToPath(import.meta.url));
620
716
  }
621
717
  return process.cwd();
622
718
  })();
623
719
  const candidates = [
624
- path3.resolve(runtimeDir, "worker.cjs"),
625
- path3.resolve(runtimeDir, "worker.js"),
626
- path3.resolve(runtimeDir, "worker.ts")
720
+ path5.resolve(runtimeDir, "worker.cjs"),
721
+ path5.resolve(runtimeDir, "worker.js"),
722
+ path5.resolve(runtimeDir, "worker.ts")
627
723
  ];
628
724
  for (const candidate of candidates) {
629
- if (fs.existsSync(candidate)) return candidate;
725
+ if (fs3.existsSync(candidate)) return candidate;
630
726
  }
631
727
  return null;
632
728
  }
@@ -683,19 +779,19 @@ function collectCandidates(rootDir, ignoreDirectories, extensionSet) {
683
779
  if (!currentDir) continue;
684
780
  const entries = (() => {
685
781
  try {
686
- return fs.readdirSync(currentDir, { withFileTypes: true });
782
+ return fs3.readdirSync(currentDir, { withFileTypes: true });
687
783
  } catch {
688
784
  return [];
689
785
  }
690
786
  })();
691
787
  for (const entry of entries) {
692
- const fullPath = path3.join(currentDir, entry.name);
788
+ const fullPath = path5.join(currentDir, entry.name);
693
789
  if (entry.isDirectory()) {
694
790
  if (!ignoreDirectories.has(entry.name)) directories.push(fullPath);
695
791
  continue;
696
792
  }
697
793
  if (!entry.isFile()) continue;
698
- if (!extensionSet.has(path3.extname(entry.name))) continue;
794
+ if (!extensionSet.has(path5.extname(entry.name))) continue;
699
795
  candidates.push(fullPath);
700
796
  }
701
797
  }
@@ -709,22 +805,31 @@ function toCacheSize(size) {
709
805
  function scanSource(source) {
710
806
  const nativeBinding = nativeParserLoader.get();
711
807
  if (nativeBinding?.extractClassesFromSource) {
712
- const classes = nativeBinding.extractClassesFromSource(source);
713
- if (Array.isArray(classes)) {
714
- return Array.from(new Set(classes.filter(Boolean)));
808
+ const result = nativeBinding.extractClassesFromSource(source);
809
+ if (Array.isArray(result)) {
810
+ return Array.from(new Set(result.filter(Boolean)));
811
+ }
812
+ if (result !== null && result !== void 0 && Array.isArray(result.classes)) {
813
+ return Array.from(new Set(result.classes.filter(Boolean)));
715
814
  }
716
815
  }
717
816
  throw new Error(
718
817
  "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"
719
818
  );
720
819
  }
820
+ function isScannableFile(filePath, includeExtensions = DEFAULT_EXTENSIONS) {
821
+ return includeExtensions.includes(path5.extname(filePath));
822
+ }
721
823
  function scanFile(filePath) {
722
- const source = fs.readFileSync(filePath, "utf8");
723
- const hash = hashContentNative(source) ?? void 0;
824
+ const { scanFileNative: scanFileNative2 } = (init_native_bridge(), __toCommonJS(native_bridge_exports));
825
+ const result = scanFileNative2(filePath);
826
+ if (!result.ok) {
827
+ throw new Error(`scanFile failed for ${filePath}: ${result.error ?? "unknown error"}`);
828
+ }
724
829
  return {
725
- file: filePath,
726
- classes: scanSource(source),
727
- ...hash ? { hash } : {}
830
+ file: result.file,
831
+ classes: result.classes,
832
+ ...result.hash ? { hash: result.hash } : {}
728
833
  };
729
834
  }
730
835
  function scanWorkspace(rootDir, options = {}) {
@@ -773,7 +878,7 @@ function scanWorkspace(rootDir, options = {}) {
773
878
  for (const filePath of candidates) {
774
879
  const stat = (() => {
775
880
  try {
776
- return fs.statSync(filePath);
881
+ return fs3.statSync(filePath);
777
882
  } catch {
778
883
  return null;
779
884
  }
@@ -799,7 +904,7 @@ function scanWorkspace(rootDir, options = {}) {
799
904
  for (const { filePath, stat, size, cached } of ranked) {
800
905
  const content = (() => {
801
906
  try {
802
- return fs.readFileSync(filePath, "utf8");
907
+ return fs3.readFileSync(filePath, "utf8");
803
908
  } catch {
804
909
  return null;
805
910
  }
@@ -861,18 +966,113 @@ function scanWorkspace(rootDir, options = {}) {
861
966
  }
862
967
  async function scanWorkspaceAsync(rootDir, options = {}) {
863
968
  const normalizedOptions = parseScanWorkspaceOptions(options);
864
- if (process.env.TWS_DISABLE_SCANNER_WORKER === "1") {
865
- return scanWorkspace(rootDir, normalizedOptions);
969
+ try {
970
+ return await scanWorkspaceParallel(rootDir, {
971
+ extensions: normalizedOptions.includeExtensions,
972
+ ignoreDirs: normalizedOptions.ignoreDirectories
973
+ });
974
+ } catch (parallelError) {
975
+ log2.debug(
976
+ `parallel scan failed, retrying with single worker: ${parallelError instanceof Error ? parallelError.message : String(parallelError)}`
977
+ );
866
978
  }
867
979
  try {
868
980
  return await scanWorkspaceInWorker(rootDir, normalizedOptions);
869
981
  } catch (error) {
870
982
  log2.debug(
871
- `worker scan failed, falling back to sync scanner: ${error instanceof Error ? error.message : String(error)}`
983
+ `worker scan failed, retrying with sync native scanner: ${error instanceof Error ? error.message : String(error)}`
872
984
  );
873
985
  return scanWorkspace(rootDir, normalizedOptions);
874
986
  }
875
987
  }
988
+ var log2, SCAN_WORKER_TIMEOUT_MS, createNativeParserLoader, nativeParserLoader, DEFAULT_EXTENSIONS, DEFAULT_IGNORES;
989
+ var init_src2 = __esm({
990
+ "packages/domain/scanner/src/index.ts"() {
991
+ init_src();
992
+ init_cache_native();
993
+ init_native_bridge();
994
+ init_parallel_scanner();
995
+ init_schemas();
996
+ init_schemas();
997
+ init_native_bridge();
998
+ log2 = createLogger("scanner");
999
+ SCAN_WORKER_TIMEOUT_MS = 12e4;
1000
+ createNativeParserLoader = () => {
1001
+ const _state = {
1002
+ binding: void 0,
1003
+ initError: null
1004
+ };
1005
+ const debugNative = (message) => {
1006
+ log2.debug(`[native] ${message}`);
1007
+ };
1008
+ const loadNativeParserBinding = () => {
1009
+ if (_state.binding !== void 0) return _state.binding;
1010
+ const runtimeDir = getRuntimeDir();
1011
+ const req = createRequire(path5.join(runtimeDir, "noop.cjs"));
1012
+ const candidates = [
1013
+ // ── binaryName baru: tailwind-styled-native (napi-rs naming) ──
1014
+ // cwd = repo root saat run dari root, atau package dir saat workspaces
1015
+ path5.resolve(process.cwd(), "native", "tailwind-styled-native.node"),
1016
+ path5.resolve(process.cwd(), "native", `tailwind-styled-native.${process.platform}-${process.arch}.node`),
1017
+ path5.resolve(process.cwd(), "native", `tailwind-styled-native.${process.platform}-${process.arch}-gnu.node`),
1018
+ // runtimeDir = dist/ → naik 4 level ke repo root
1019
+ path5.resolve(runtimeDir, "..", "..", "..", "..", "native", "tailwind-styled-native.node"),
1020
+ path5.resolve(runtimeDir, "..", "..", "..", "..", "native", `tailwind-styled-native.${process.platform}-${process.arch}-gnu.node`),
1021
+ // 3 level fallback (jika package di-nest lebih dangkal)
1022
+ path5.resolve(runtimeDir, "..", "..", "..", "native", "tailwind-styled-native.node"),
1023
+ path5.resolve(runtimeDir, "..", "..", "..", "native", `tailwind-styled-native.${process.platform}-${process.arch}-gnu.node`),
1024
+ // ── binaryName lama: tailwind_styled_parser (backward compat) ──
1025
+ path5.resolve(process.cwd(), "native/tailwind_styled_parser.node"),
1026
+ path5.resolve(process.cwd(), "native/build/Release/tailwind_styled_parser.node"),
1027
+ path5.resolve(runtimeDir, "..", "..", "..", "..", "native", "tailwind_styled_parser.node"),
1028
+ path5.resolve(runtimeDir, "..", "..", "..", "native", "tailwind_styled_parser.node"),
1029
+ path5.resolve(
1030
+ runtimeDir,
1031
+ "..",
1032
+ "..",
1033
+ "..",
1034
+ "native",
1035
+ "build",
1036
+ "Release",
1037
+ "tailwind_styled_parser.node"
1038
+ )
1039
+ ];
1040
+ for (const fullPath of candidates) {
1041
+ if (!fs3.existsSync(fullPath)) continue;
1042
+ try {
1043
+ const required = req(fullPath);
1044
+ if (required && (typeof required.extractClassesFromSource === "function" || typeof required.parseClasses === "function" || typeof required.parse_classes === "function")) {
1045
+ _state.binding = required;
1046
+ debugNative(`using native parser from ${fullPath}`);
1047
+ return _state.binding;
1048
+ }
1049
+ } catch (error) {
1050
+ _state.initError = error instanceof Error ? error.message : String(error);
1051
+ }
1052
+ }
1053
+ _state.binding = null;
1054
+ if (!_state.initError) {
1055
+ _state.initError = "native .node binding not found";
1056
+ }
1057
+ debugNative(`native binding not available: ${_state.initError}`);
1058
+ return _state.binding;
1059
+ };
1060
+ return {
1061
+ get: loadNativeParserBinding,
1062
+ reset: () => {
1063
+ _state.binding = void 0;
1064
+ _state.initError = null;
1065
+ }
1066
+ };
1067
+ };
1068
+ nativeParserLoader = createNativeParserLoader();
1069
+ DEFAULT_EXTENSIONS = [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs"];
1070
+ DEFAULT_IGNORES = ["node_modules", ".git", ".next", "dist", "out", ".turbo", ".cache"];
1071
+ }
1072
+ });
1073
+
1074
+ // packages/domain/analyzer/src/analyzeWorkspace.ts
1075
+ init_src2();
876
1076
 
877
1077
  // packages/domain/analyzer/src/binding.ts
878
1078
  init_src();
@@ -892,7 +1092,7 @@ function isRecord(value) {
892
1092
  }
893
1093
  async function pathExists(filePath) {
894
1094
  try {
895
- await fs.promises.access(filePath, fs.constants.F_OK);
1095
+ await fs3.promises.access(filePath, fs3.constants.F_OK);
896
1096
  return true;
897
1097
  } catch {
898
1098
  return false;
@@ -955,6 +1155,9 @@ var createAnalyzerBindingLoader = () => {
955
1155
  };
956
1156
  };
957
1157
  var analyzerBindingLoader = createAnalyzerBindingLoader();
1158
+ async function getNativeBinding() {
1159
+ return analyzerBindingLoader.get();
1160
+ }
958
1161
  async function requireNativeBinding() {
959
1162
  const binding = await analyzerBindingLoader.get();
960
1163
  if (binding?.analyzeClasses) return binding;
@@ -993,7 +1196,7 @@ async function requireNativeCssCompiler() {
993
1196
 
994
1197
  // packages/domain/analyzer/src/schemas.ts
995
1198
  init_src();
996
- var formatIssuePath3 = (path6) => path6.length > 0 ? path6.map(
1199
+ var formatIssuePath3 = (path8) => path8.length > 0 ? path8.map(
997
1200
  (segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
998
1201
  ).join(".") : "<root>";
999
1202
  var isPlainObject = (value) => {
@@ -1002,8 +1205,8 @@ var isPlainObject = (value) => {
1002
1205
  return proto === Object.prototype || proto === null;
1003
1206
  };
1004
1207
  var formatIssues2 = (error) => error.issues.map((issue) => {
1005
- const path6 = formatIssuePath3(issue.path);
1006
- return `${path6}: ${issue.message}`;
1208
+ const path8 = formatIssuePath3(issue.path);
1209
+ return `${path8}: ${issue.message}`;
1007
1210
  }).join("; ");
1008
1211
  var parseWithSchema2 = (schema, data, label) => {
1009
1212
  const parsed = schema.safeParse(data);
@@ -1098,112 +1301,6 @@ var parseNativeCssCompileResult = (result, className) => parseWithSchema2(
1098
1301
  );
1099
1302
  var parseClassToCssOptions = (options) => parseWithSchema2(ClassToCssOptionsSchema, options ?? {}, "classToCss options are invalid");
1100
1303
  var SUPPORTED_TAILWIND_CONFIG_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".js", ".cjs", ".mjs"]);
1101
- var KNOWN_UTILITY_PREFIXES = /* @__PURE__ */ new Set([
1102
- "absolute",
1103
- "align",
1104
- "animate",
1105
- "arbitrary",
1106
- "aspect",
1107
- "backdrop",
1108
- "basis",
1109
- "bg",
1110
- "block",
1111
- "border",
1112
- "bottom",
1113
- "col",
1114
- "container",
1115
- "contents",
1116
- "cursor",
1117
- "dark",
1118
- "display",
1119
- "divide",
1120
- "fill",
1121
- "fixed",
1122
- "flex",
1123
- "float",
1124
- "font",
1125
- "from",
1126
- "gap",
1127
- "grid",
1128
- "grow",
1129
- "h",
1130
- "hidden",
1131
- "inset",
1132
- "inline",
1133
- "isolate",
1134
- "items",
1135
- "justify",
1136
- "left",
1137
- "leading",
1138
- "line",
1139
- "list",
1140
- "m",
1141
- "max-h",
1142
- "max-w",
1143
- "mb",
1144
- "min-h",
1145
- "min-w",
1146
- "ml",
1147
- "mr",
1148
- "mt",
1149
- "mx",
1150
- "my",
1151
- "object",
1152
- "opacity",
1153
- "order",
1154
- "origin",
1155
- "outline",
1156
- "overflow",
1157
- "overscroll",
1158
- "p",
1159
- "pb",
1160
- "pe",
1161
- "perspective",
1162
- "place",
1163
- "pl",
1164
- "pointer",
1165
- "position",
1166
- "pr",
1167
- "ps",
1168
- "pt",
1169
- "px",
1170
- "py",
1171
- "relative",
1172
- "right",
1173
- "ring",
1174
- "rotate",
1175
- "rounded",
1176
- "row",
1177
- "scale",
1178
- "shadow",
1179
- "shrink",
1180
- "size",
1181
- "skew",
1182
- "snap",
1183
- "space-x",
1184
- "space-y",
1185
- "sr",
1186
- "start",
1187
- "static",
1188
- "sticky",
1189
- "stroke",
1190
- "table",
1191
- "text",
1192
- "to",
1193
- "top",
1194
- "touch",
1195
- "tracking",
1196
- "transform",
1197
- "transition",
1198
- "translate",
1199
- "truncate",
1200
- "underline",
1201
- "via",
1202
- "visible",
1203
- "w",
1204
- "whitespace",
1205
- "z"
1206
- ]);
1207
1304
  var tailwindConfigCache = /* @__PURE__ */ new Map();
1208
1305
  var splitVariantAndBase = (className) => {
1209
1306
  const parts = className.split(":");
@@ -1233,48 +1330,28 @@ var resolveConflictGroup = (base) => {
1233
1330
  if (base.startsWith("m-") || base.startsWith("mx-") || base.startsWith("my-")) return "margin";
1234
1331
  return null;
1235
1332
  };
1236
- var detectConflicts = (usages) => {
1237
- const buckets = /* @__PURE__ */ new Map();
1238
- for (const usage of usages) {
1239
- const { variantKey, base } = splitVariantAndBase(usage.name);
1240
- const group = resolveConflictGroup(base);
1241
- if (!group) continue;
1242
- const key = `${variantKey}::${group}`;
1243
- const bucket = buckets.get(key) ?? {
1244
- variantKey,
1245
- group,
1246
- classes: /* @__PURE__ */ new Set()
1247
- };
1248
- bucket.classes.add(usage.name);
1249
- buckets.set(key, bucket);
1250
- }
1251
- const conflicts = [];
1252
- const conflictedClassNames = /* @__PURE__ */ new Set();
1253
- for (const bucket of buckets.values()) {
1254
- if (bucket.classes.size <= 1) continue;
1255
- const classes = Array.from(bucket.classes).sort();
1256
- for (const className of classes) conflictedClassNames.add(className);
1257
- const variantLabel = bucket.variantKey.length > 0 ? bucket.variantKey : "base";
1258
- conflicts.push({
1259
- className: bucket.group,
1260
- variants: bucket.variantKey.length > 0 ? bucket.variantKey.split(":") : [],
1261
- classes,
1262
- message: `Multiple ${bucket.group} utilities detected for "${variantLabel}".`
1263
- });
1333
+ var detectConflicts = async (usages) => {
1334
+ const native = await getNativeBinding();
1335
+ if (!native?.detectClassConflicts) {
1336
+ throw new Error("FATAL: Native binding 'detectClassConflicts' is required but not available.");
1264
1337
  }
1265
- conflicts.sort((left, right) => {
1266
- if (right.classes.length !== left.classes.length)
1267
- return right.classes.length - left.classes.length;
1268
- return left.className.localeCompare(right.className);
1269
- });
1270
- return { conflicts, conflictedClassNames };
1338
+ const result = native.detectClassConflicts(JSON.stringify(usages.map((u) => ({ name: u.name, count: u.count }))));
1339
+ return {
1340
+ conflicts: result.conflicts.map((c) => ({
1341
+ className: c.group,
1342
+ variants: c.variantKey.length > 0 ? c.variantKey.split(":") : [],
1343
+ classes: c.classes,
1344
+ message: c.message
1345
+ })),
1346
+ conflictedClassNames: new Set(result.conflictedClassNames)
1347
+ };
1271
1348
  };
1272
1349
  var isSupportedTailwindConfigPath = (configPath) => {
1273
- return SUPPORTED_TAILWIND_CONFIG_EXTENSIONS.has(path3.extname(configPath).toLowerCase());
1350
+ return SUPPORTED_TAILWIND_CONFIG_EXTENSIONS.has(path5.extname(configPath).toLowerCase());
1274
1351
  };
1275
1352
  var resolveTailwindConfigPath = async (root, explicitPath) => {
1276
1353
  if (explicitPath) {
1277
- const resolved = path3.resolve(root, explicitPath);
1354
+ const resolved = path5.resolve(root, explicitPath);
1278
1355
  if (!await pathExists(resolved)) return null;
1279
1356
  return resolved;
1280
1357
  }
@@ -1285,7 +1362,7 @@ var resolveTailwindConfigPath = async (root, explicitPath) => {
1285
1362
  "tailwind.config.mjs"
1286
1363
  ];
1287
1364
  for (const candidate of candidates) {
1288
- const fullPath = path3.resolve(root, candidate);
1365
+ const fullPath = path5.resolve(root, candidate);
1289
1366
  if (await pathExists(fullPath)) return fullPath;
1290
1367
  }
1291
1368
  return null;
@@ -1339,15 +1416,19 @@ var collectCustomUtilities = (config) => {
1339
1416
  return out;
1340
1417
  };
1341
1418
  var collectSafelistFromSource = async (configPath) => {
1342
- const source = await fs.promises.readFile(configPath, "utf8");
1343
- const safelistBlock = source.match(/safelist\s*:\s*\[([\s\S]*?)\]/m)?.[1];
1344
- if (!safelistBlock) return [];
1345
- const out = /* @__PURE__ */ new Set();
1346
- for (const token of safelistBlock.matchAll(/["'`]([^"'`]+)["'`]/g)) {
1419
+ const source = await fs3.promises.readFile(configPath, "utf8");
1420
+ const { extractClassesNative: extractClassesNative2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
1421
+ const allTokens = extractClassesNative2(source);
1422
+ const hasSafelist = source.includes("safelist");
1423
+ if (!hasSafelist) return [];
1424
+ const safelistMatch = source.match(/safelist\s*:\s*\[([\s\S]*?)\]/m)?.[1];
1425
+ if (!safelistMatch) return [];
1426
+ const safelistSet = /* @__PURE__ */ new Set();
1427
+ for (const token of safelistMatch.matchAll(/["'`]([^"'`]+)["'`]/g)) {
1347
1428
  const value = token[1].trim();
1348
- if (value.length > 0) out.add(value);
1429
+ if (value.length > 0) safelistSet.add(value);
1349
1430
  }
1350
- return Array.from(out);
1431
+ return allTokens.filter((t) => safelistSet.has(t));
1351
1432
  };
1352
1433
  var loadTailwindConfig = async (root, semanticOption) => {
1353
1434
  const startMs = Date.now();
@@ -1362,7 +1443,7 @@ var loadTailwindConfig = async (root, semanticOption) => {
1362
1443
  customUtilities: /* @__PURE__ */ new Set()
1363
1444
  };
1364
1445
  }
1365
- const configStat = await fs.promises.stat(configPath).catch(() => null);
1446
+ const configStat = await fs3.promises.stat(configPath).catch(() => null);
1366
1447
  if (configStat) {
1367
1448
  const cached = tailwindConfigCache.get(configPath);
1368
1449
  if (cached && cached.mtimeMs === configStat.mtimeMs && cached.size === configStat.size) {
@@ -1448,21 +1529,27 @@ var utilityPrefix = (baseClass) => {
1448
1529
  if (hyphen < 0) return normalized;
1449
1530
  return normalized.slice(0, hyphen);
1450
1531
  };
1451
- var isKnownTailwindClass = (className, safelist, customUtilities) => {
1452
- if (safelist.has(className) || customUtilities.has(className)) return true;
1453
- const { base } = splitVariantAndBase(className);
1454
- if (customUtilities.has(base)) return true;
1455
- const prefix = utilityPrefix(base);
1456
- return KNOWN_UTILITY_PREFIXES.has(prefix);
1457
- };
1458
1532
  var buildSemanticReport = async (usages, root, semanticOption) => {
1459
1533
  const loadedConfig = await loadTailwindConfig(root, semanticOption);
1460
1534
  const safelist = loadedConfig?.safelist ?? /* @__PURE__ */ new Set();
1461
1535
  const customUtilities = loadedConfig?.customUtilities ?? /* @__PURE__ */ new Set();
1462
1536
  const usageNames = new Set(usages.map((usage) => usage.name));
1463
1537
  const unusedClasses = Array.from(safelist).filter((className) => !usageNames.has(className)).sort().map((className) => ({ name: className, count: 0, isUnused: true }));
1464
- const unknownClasses = usages.filter((usage) => !isKnownTailwindClass(usage.name, safelist, customUtilities)).map((usage) => ({ ...usage, isUnused: true }));
1465
- const { conflicts } = detectConflicts(usages);
1538
+ const native = await getNativeBinding();
1539
+ if (!native?.classifyKnownClasses) {
1540
+ throw new Error("FATAL: Native binding 'classifyKnownClasses' is required but not available.");
1541
+ }
1542
+ const classNames = usages.map((u) => u.name);
1543
+ const results = native.classifyKnownClasses(
1544
+ classNames,
1545
+ Array.from(safelist),
1546
+ Array.from(customUtilities)
1547
+ );
1548
+ const unknownSet = new Set(
1549
+ results.filter((r) => !r.isKnown).map((r) => r.className)
1550
+ );
1551
+ const unknownClasses = usages.filter((usage) => unknownSet.has(usage.name)).map((usage) => ({ ...usage, isUnused: true }));
1552
+ const { conflicts } = await detectConflicts(usages);
1466
1553
  return {
1467
1554
  unusedClasses,
1468
1555
  unknownClasses,
@@ -1498,13 +1585,17 @@ function normalizeScan(scan, includeClass) {
1498
1585
  uniqueClasses: Array.from(unique).sort()
1499
1586
  };
1500
1587
  }
1501
- function collectClassCounts(scan) {
1502
- const counts = /* @__PURE__ */ new Map();
1503
- for (const file of scan.files) {
1504
- for (const className of file.classes) {
1505
- counts.set(className, (counts.get(className) ?? 0) + 1);
1506
- }
1588
+ async function collectClassCounts(scan) {
1589
+ const native = await requireNativeBinding();
1590
+ if (!native?.collectClassCounts) {
1591
+ throw new Error("FATAL: Native binding 'collectClassCounts' is required but not available.");
1507
1592
  }
1593
+ const filesJson = JSON.stringify(
1594
+ scan.files.map((f) => ({ file: f.file ?? "", classes: f.classes }))
1595
+ );
1596
+ const result = native.collectClassCounts(filesJson);
1597
+ const counts = /* @__PURE__ */ new Map();
1598
+ for (const entry of result) counts.set(entry.name, entry.count);
1508
1599
  return counts;
1509
1600
  }
1510
1601
  function buildClassUsage(counts) {
@@ -1513,29 +1604,24 @@ function buildClassUsage(counts) {
1513
1604
  return left.name.localeCompare(right.name);
1514
1605
  });
1515
1606
  }
1516
- function buildDistribution(usages) {
1517
- const distribution = {
1518
- "1": 0,
1519
- "2-3": 0,
1520
- "4-7": 0,
1521
- "8+": 0
1522
- };
1523
- for (const usage of usages) {
1524
- if (usage.count === 1) {
1525
- distribution["1"] += 1;
1526
- } else if (usage.count <= 3) {
1527
- distribution["2-3"] += 1;
1528
- } else if (usage.count <= 7) {
1529
- distribution["4-7"] += 1;
1530
- } else {
1531
- distribution["8+"] += 1;
1532
- }
1607
+ async function buildDistribution(usages, native) {
1608
+ const binding = native ?? await requireNativeBinding();
1609
+ if (!binding?.buildDistribution) {
1610
+ throw new Error("FATAL: Native binding 'buildDistribution' is required but not available.");
1533
1611
  }
1534
- return distribution;
1612
+ const result = binding.buildDistribution(
1613
+ JSON.stringify(usages.map((u) => ({ name: u.name, count: u.count })))
1614
+ );
1615
+ return {
1616
+ "1": result.once,
1617
+ "2-3": result.few,
1618
+ "4-7": result.moderate,
1619
+ "8+": result.frequent
1620
+ };
1535
1621
  }
1536
1622
  async function analyzeWorkspace(root, options = {}) {
1537
1623
  const startedAtMs = Date.now();
1538
- const resolvedRoot = path3.resolve(root);
1624
+ const resolvedRoot = path5.resolve(root);
1539
1625
  const normalizedOptions = parseAnalyzerOptions(options);
1540
1626
  const scan = await (async () => {
1541
1627
  const scanStartedAtMs = Date.now();
@@ -1579,7 +1665,7 @@ async function analyzeWorkspace(root, options = {}) {
1579
1665
  );
1580
1666
  }
1581
1667
  })();
1582
- const counts = collectClassCounts(normalizedScan);
1668
+ const counts = await collectClassCounts(normalizedScan);
1583
1669
  const baseAll = buildClassUsage(counts);
1584
1670
  const { all, semanticReport } = await (async () => {
1585
1671
  if (!normalizedOptions.semantic) {
@@ -1605,13 +1691,19 @@ async function analyzeWorkspace(root, options = {}) {
1605
1691
  );
1606
1692
  }
1607
1693
  })();
1608
- const top = all.slice(0, topLimit);
1609
- const frequent = all.filter((usage) => usage.count >= frequentThreshold).slice(0, topLimit);
1610
- const unique = all.filter((usage) => usage.count === 1);
1611
- const totalClassOccurrences = all.reduce((sum, usage) => sum + usage.count, 0);
1694
+ const classStatsNative = binding?.computeClassStats?.(
1695
+ JSON.stringify(all),
1696
+ topLimit,
1697
+ frequentThreshold
1698
+ );
1699
+ const top = classStatsNative ? JSON.parse(classStatsNative.topJson) : all.slice(0, topLimit);
1700
+ const frequent = classStatsNative ? JSON.parse(classStatsNative.frequentJson) : all.filter((usage) => usage.count >= frequentThreshold).slice(0, topLimit);
1701
+ const unique = classStatsNative ? JSON.parse(classStatsNative.uniqueJson) : all.filter((usage) => usage.count === 1);
1702
+ const totalClassOccurrences = classStatsNative ? classStatsNative.totalClassOccurrences : all.reduce((sum, usage) => sum + usage.count, 0);
1612
1703
  debugLog(
1613
1704
  `analyzeWorkspace completed in ${Date.now() - startedAtMs}ms (files=${normalizedScan.totalFiles}, uniqueClasses=${all.length})`
1614
1705
  );
1706
+ const distribution = await buildDistribution(all, binding);
1615
1707
  return {
1616
1708
  root: nativeReport.root || resolvedRoot,
1617
1709
  totalFiles: nativeReport.totalFiles,
@@ -1622,16 +1714,21 @@ async function analyzeWorkspace(root, options = {}) {
1622
1714
  top,
1623
1715
  frequent,
1624
1716
  unique,
1625
- distribution: buildDistribution(all)
1717
+ distribution
1626
1718
  },
1719
+ // topClasses — alias for classStats.top (test contract & backward compat)
1720
+ topClasses: top,
1627
1721
  safelist: all.map((usage) => usage.name),
1628
1722
  ...semanticReport ? { semantic: semanticReport } : {}
1629
1723
  };
1630
1724
  }
1631
1725
 
1632
1726
  // packages/domain/analyzer/src/classToCss.ts
1633
- var normalizeClassInput = (input) => {
1727
+ var normalizeClassInput = (input, _binding) => {
1634
1728
  if (typeof input === "string") {
1729
+ if (_binding?.normalizeClassInput) {
1730
+ return _binding.normalizeClassInput(input);
1731
+ }
1635
1732
  return input.split(/\s+/).map((item) => item.trim()).filter((item) => item.length > 0);
1636
1733
  }
1637
1734
  if (!Array.isArray(input)) {
@@ -1653,27 +1750,26 @@ var normalizeClassToCssOptions = (options) => {
1653
1750
  const prefix = parsed.prefix ?? null;
1654
1751
  return { prefix, strict };
1655
1752
  };
1656
- var mergeDeclarationMap = (target, css) => {
1657
- for (const ruleMatch of css.matchAll(/\{([^}]*)\}/g)) {
1658
- const body = ruleMatch[1];
1659
- for (const raw of body.split(";")) {
1660
- const declaration = raw.trim();
1661
- if (declaration.length === 0) continue;
1662
- const colonIndex = declaration.indexOf(":");
1663
- if (colonIndex <= 0) continue;
1664
- const property = declaration.slice(0, colonIndex).trim();
1665
- const value = declaration.slice(colonIndex + 1).trim();
1666
- if (property.length === 0 || value.length === 0) continue;
1667
- if (target.has(property)) target.delete(property);
1668
- target.set(property, value);
1669
- }
1753
+ var mergeDeclarationMap = (target, css, binding) => {
1754
+ if (!binding.parseCssRules) {
1755
+ throw new Error("FATAL: Native binding 'parseCssRules' is required but not available.");
1756
+ }
1757
+ const rules = binding.parseCssRules(css);
1758
+ for (const rule of rules) {
1759
+ if (target.has(rule.property)) target.delete(rule.property);
1760
+ target.set(rule.property, rule.isImportant ? `${rule.value} !important` : rule.value);
1670
1761
  }
1671
1762
  };
1672
- var declarationMapToString = (declarationMap) => {
1673
- return Array.from(declarationMap.entries()).map(([property, value]) => `${property}: ${value}`).join("; ");
1763
+ var declarationMapToString = (declarationMap, binding) => {
1764
+ const entries = Array.from(declarationMap.entries()).map(([property, value]) => ({ property, value }));
1765
+ if (binding?.declarationMapToString) {
1766
+ return binding.declarationMapToString(entries);
1767
+ }
1768
+ return entries.map(({ property, value }) => `${property}: ${value}`).join("; ");
1674
1769
  };
1675
1770
  var classToCss = async (input, options = {}) => {
1676
- const inputClasses = normalizeClassInput(input);
1771
+ const binding = await requireNativeCssCompiler();
1772
+ const inputClasses = normalizeClassInput(input, binding);
1677
1773
  const normalizedOptions = normalizeClassToCssOptions(options);
1678
1774
  if (inputClasses.length === 0) {
1679
1775
  return {
@@ -1685,7 +1781,6 @@ var classToCss = async (input, options = {}) => {
1685
1781
  sizeBytes: 0
1686
1782
  };
1687
1783
  }
1688
- const binding = await requireNativeCssCompiler();
1689
1784
  const prefix = normalizedOptions.prefix;
1690
1785
  const results = await Promise.all(
1691
1786
  inputClasses.map(async (className) => {
@@ -1718,7 +1813,7 @@ var classToCss = async (input, options = {}) => {
1718
1813
  const sizeBytes = results.reduce((sum, r) => sum + r.sizeBytes, 0);
1719
1814
  const declarationMap = /* @__PURE__ */ new Map();
1720
1815
  for (const result of results) {
1721
- mergeDeclarationMap(declarationMap, result.css);
1816
+ mergeDeclarationMap(declarationMap, result.css, binding);
1722
1817
  }
1723
1818
  const uniqueUnknown = Array.from(new Set(unknownClasses));
1724
1819
  if (normalizedOptions.strict && uniqueUnknown.length > 0) {
@@ -1727,7 +1822,7 @@ var classToCss = async (input, options = {}) => {
1727
1822
  return {
1728
1823
  inputClasses,
1729
1824
  css: cssChunks.filter((chunk) => chunk.length > 0).join("\n"),
1730
- declarations: declarationMapToString(declarationMap),
1825
+ declarations: declarationMapToString(declarationMap, binding),
1731
1826
  resolvedClasses: Array.from(new Set(resolvedClasses)),
1732
1827
  unknownClasses: uniqueUnknown,
1733
1828
  sizeBytes