tailwind-styled-v4 5.0.8 → 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.
- package/CHANGELOG.md +204 -416
- package/README.md +45 -15
- package/dist/{analyzeWorkspace-DuJKh7Ty.d.mts → analyzeWorkspace-BS5O4rhC.d.mts} +47 -2
- package/dist/{analyzeWorkspace-Ct_NTAWt.d.ts → analyzeWorkspace-DDOQdzzI.d.ts} +47 -2
- package/dist/analyzer.d.mts +5 -3
- package/dist/analyzer.d.ts +5 -3
- package/dist/analyzer.js +563 -468
- package/dist/analyzer.js.map +1 -1
- package/dist/analyzer.mjs +562 -467
- package/dist/analyzer.mjs.map +1 -1
- package/dist/animate.d.mts +4 -7
- package/dist/animate.d.ts +4 -7
- package/dist/animate.js +171 -265
- package/dist/animate.js.map +1 -1
- package/dist/animate.mjs +165 -264
- package/dist/animate.mjs.map +1 -1
- package/dist/atomic.d.mts +22 -1
- package/dist/atomic.d.ts +22 -1
- package/dist/atomic.js +221 -165
- package/dist/atomic.js.map +1 -1
- package/dist/atomic.mjs +200 -165
- package/dist/atomic.mjs.map +1 -1
- package/dist/cli.d.mts +60 -1
- package/dist/cli.d.ts +60 -1
- package/dist/cli.js +1261 -1517
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +1238 -1513
- package/dist/cli.mjs.map +1 -1
- package/dist/compiler.d.mts +38 -7
- package/dist/compiler.d.ts +38 -7
- package/dist/compiler.js +174 -197
- package/dist/compiler.js.map +1 -1
- package/dist/compiler.mjs +151 -194
- package/dist/compiler.mjs.map +1 -1
- package/dist/devtools.js +7 -31
- package/dist/devtools.js.map +1 -1
- package/dist/devtools.mjs +7 -31
- package/dist/devtools.mjs.map +1 -1
- package/dist/engine.d.mts +134 -63
- package/dist/engine.d.ts +134 -63
- package/dist/engine.js +2863 -2482
- package/dist/engine.js.map +1 -1
- package/dist/engine.mjs +2852 -2485
- package/dist/engine.mjs.map +1 -1
- package/dist/{index-eWAocnD2.d.mts → index-NDINUhLN.d.mts} +3 -1
- package/dist/{index-eWAocnD2.d.ts → index-NDINUhLN.d.ts} +3 -1
- package/dist/index.d.mts +63 -32
- package/dist/index.d.ts +63 -32
- package/dist/index.js +335 -169
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +315 -169
- package/dist/index.mjs.map +1 -1
- package/dist/{liveTokenEngine-DSUk88P6.d.ts → liveTokenEngine-CN9ian1R.d.ts} +1 -1
- package/dist/{liveTokenEngine-CX5_0c4q.d.mts → liveTokenEngine-DKoWRtqH.d.mts} +1 -1
- package/dist/next.d.mts +10 -4
- package/dist/next.d.ts +10 -4
- package/dist/next.js +32 -45
- package/dist/next.js.map +1 -1
- package/dist/next.mjs +30 -43
- package/dist/next.mjs.map +1 -1
- package/dist/plugin-api.d.mts +8 -2
- package/dist/plugin-api.d.ts +8 -2
- package/dist/plugin-api.js +14 -2
- package/dist/plugin-api.js.map +1 -1
- package/dist/plugin-api.mjs +14 -3
- package/dist/plugin-api.mjs.map +1 -1
- package/dist/plugin-registry.js +51 -11
- package/dist/plugin-registry.js.map +1 -1
- package/dist/plugin-registry.mjs +51 -11
- package/dist/plugin-registry.mjs.map +1 -1
- package/dist/plugin.d.mts +5 -7
- package/dist/plugin.d.ts +5 -7
- package/dist/plugin.js +16 -15
- package/dist/plugin.js.map +1 -1
- package/dist/plugin.mjs +16 -16
- package/dist/plugin.mjs.map +1 -1
- package/dist/rspack.js +17 -38
- package/dist/rspack.js.map +1 -1
- package/dist/rspack.mjs +15 -36
- package/dist/rspack.mjs.map +1 -1
- package/dist/runtime.d.mts +2 -2
- package/dist/runtime.d.ts +2 -2
- package/dist/scanner.d.mts +10 -1
- package/dist/scanner.d.ts +10 -1
- package/dist/scanner.js +298 -124
- package/dist/scanner.js.map +1 -1
- package/dist/scanner.mjs +296 -124
- package/dist/scanner.mjs.map +1 -1
- package/dist/shared.d.mts +1 -1
- package/dist/shared.d.ts +1 -1
- package/dist/shared.js +104 -176
- package/dist/shared.js.map +1 -1
- package/dist/shared.mjs +85 -176
- package/dist/shared.mjs.map +1 -1
- package/dist/storybook-addon.d.mts +1 -1
- package/dist/storybook-addon.d.ts +1 -1
- package/dist/svelte.d.mts +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/svelte.js +166 -3
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +143 -1
- package/dist/svelte.mjs.map +1 -1
- package/dist/syntax.js +21 -21
- package/dist/syntax.js.map +1 -1
- package/dist/syntax.mjs +21 -21
- package/dist/syntax.mjs.map +1 -1
- package/dist/testing.js +9 -1
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +9 -1
- package/dist/testing.mjs.map +1 -1
- package/dist/theme.d.mts +2 -2
- package/dist/theme.d.ts +2 -2
- package/dist/theme.js +40 -112
- package/dist/theme.js.map +1 -1
- package/dist/theme.mjs +37 -110
- package/dist/theme.mjs.map +1 -1
- package/dist/turbopackLoader.js +84 -126
- package/dist/turbopackLoader.js.map +1 -1
- package/dist/turbopackLoader.mjs +68 -124
- package/dist/turbopackLoader.mjs.map +1 -1
- package/dist/tw.js +1256 -1517
- package/dist/tw.js.map +1 -1
- package/dist/tw.mjs +1236 -1513
- package/dist/tw.mjs.map +1 -1
- package/dist/vite.js +1783 -823
- package/dist/vite.js.map +1 -1
- package/dist/vite.mjs +1767 -821
- package/dist/vite.mjs.map +1 -1
- package/dist/vue.d.mts +1 -1
- package/dist/vue.d.ts +1 -1
- package/dist/vue.js +165 -4
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +141 -1
- package/dist/vue.mjs.map +1 -1
- package/dist/webpackLoader.js +69 -108
- package/dist/webpackLoader.js.map +1 -1
- package/dist/webpackLoader.mjs +49 -104
- package/dist/webpackLoader.mjs.map +1 -1
- package/native/tailwind-styled-native.node +0 -0
- package/package.json +22 -24
package/dist/vite.mjs
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
1
2
|
import { createRequire } from 'module';
|
|
2
|
-
import
|
|
3
|
+
import * as fs4 from 'fs';
|
|
4
|
+
import fs4__default from 'fs';
|
|
5
|
+
import * as path6 from 'path';
|
|
6
|
+
import path6__default from 'path';
|
|
7
|
+
import { createHash } from 'crypto';
|
|
3
8
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import { z } from 'zod';
|
|
9
|
+
import { Worker, isMainThread, parentPort, workerData } from 'worker_threads';
|
|
10
|
+
import { availableParallelism } from 'os';
|
|
7
11
|
import 'perf_hooks';
|
|
8
12
|
|
|
9
13
|
/* tailwind-styled-v4 v5.0.4 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
|
|
@@ -34,6 +38,260 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
34
38
|
};
|
|
35
39
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
36
40
|
|
|
41
|
+
// packages/domain/shared/src/trace.ts
|
|
42
|
+
function getHealthColor(status) {
|
|
43
|
+
switch (status) {
|
|
44
|
+
case "healthy":
|
|
45
|
+
return "#34d399";
|
|
46
|
+
case "degraded":
|
|
47
|
+
return "#fbbf24";
|
|
48
|
+
case "unhealthy":
|
|
49
|
+
return "#f87171";
|
|
50
|
+
default:
|
|
51
|
+
return "#52525b";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function getModeColor(mode) {
|
|
55
|
+
switch (mode) {
|
|
56
|
+
case "build":
|
|
57
|
+
return "#fbbf24";
|
|
58
|
+
case "watch":
|
|
59
|
+
return "#34d399";
|
|
60
|
+
case "jit":
|
|
61
|
+
return "#60a5fa";
|
|
62
|
+
case "error":
|
|
63
|
+
return "#f87171";
|
|
64
|
+
case "idle":
|
|
65
|
+
return "#71717a";
|
|
66
|
+
default:
|
|
67
|
+
return "#52525b";
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function formatMemory(bytes) {
|
|
71
|
+
if (bytes < 1024) return `${Math.round(bytes)}B`;
|
|
72
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
73
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
74
|
+
}
|
|
75
|
+
function formatDuration(ms) {
|
|
76
|
+
if (ms === null) return "\u2014";
|
|
77
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
78
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
79
|
+
}
|
|
80
|
+
function calculateHealth(metrics, summary) {
|
|
81
|
+
if (summary?.health?.status) return summary.health.status;
|
|
82
|
+
if (metrics.mode === "error") return "unhealthy";
|
|
83
|
+
if ((metrics.buildMs ?? 0) > 5e3) return "degraded";
|
|
84
|
+
if (metrics.memoryMb && metrics.memoryMb.heapUsed > 500) return "degraded";
|
|
85
|
+
return "healthy";
|
|
86
|
+
}
|
|
87
|
+
function getBuildTimeColor(ms) {
|
|
88
|
+
if (ms === null) return "#52525b";
|
|
89
|
+
if (ms > 1e3) return "#f87171";
|
|
90
|
+
if (ms > 500) return "#fbbf24";
|
|
91
|
+
return "#34d399";
|
|
92
|
+
}
|
|
93
|
+
function getMemoryColor(mb) {
|
|
94
|
+
if (mb > 500) return "#f87171";
|
|
95
|
+
if (mb > 250) return "#fbbf24";
|
|
96
|
+
return "#34d399";
|
|
97
|
+
}
|
|
98
|
+
function createTraceSnapshot(data) {
|
|
99
|
+
return {
|
|
100
|
+
generatedAt: data.generatedAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
101
|
+
buildMs: data.buildMs ?? null,
|
|
102
|
+
scanMs: data.scanMs ?? null,
|
|
103
|
+
analyzeMs: data.analyzeMs ?? null,
|
|
104
|
+
compileMs: data.compileMs ?? null,
|
|
105
|
+
memoryMb: data.memoryMb ?? null,
|
|
106
|
+
classCount: data.classCount ?? null,
|
|
107
|
+
fileCount: data.fileCount ?? null,
|
|
108
|
+
cssBytes: data.cssBytes ?? null,
|
|
109
|
+
mode: data.mode ?? null,
|
|
110
|
+
eventsReceived: data.eventsReceived ?? void 0,
|
|
111
|
+
eventsProcessed: data.eventsProcessed ?? void 0,
|
|
112
|
+
batchesProcessed: data.batchesProcessed ?? void 0,
|
|
113
|
+
incrementalUpdates: data.incrementalUpdates ?? void 0,
|
|
114
|
+
fullRescans: data.fullRescans ?? void 0
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function getPipelinePercentages(metrics) {
|
|
118
|
+
const scan = metrics.scanMs ?? 0;
|
|
119
|
+
const analyze = metrics.analyzeMs ?? 0;
|
|
120
|
+
const compile = metrics.compileMs ?? 0;
|
|
121
|
+
const total = scan + analyze + compile;
|
|
122
|
+
if (total === 0) {
|
|
123
|
+
return { scanPct: 0, analyzePct: 0, compilePct: 0 };
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
scanPct: scan / total * 100,
|
|
127
|
+
analyzePct: analyze / total * 100,
|
|
128
|
+
compilePct: compile / total * 100
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
var init_trace = __esm({
|
|
132
|
+
"packages/domain/shared/src/trace.ts"() {
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// packages/domain/shared/src/error-codes.ts
|
|
137
|
+
function getSuggestion(code) {
|
|
138
|
+
return ERROR_SUGGESTIONS[code];
|
|
139
|
+
}
|
|
140
|
+
function formatErrorCode(code) {
|
|
141
|
+
const prefix = code.startsWith("E") ? "Error" : code.startsWith("W") ? "Warning" : "Code";
|
|
142
|
+
return `[${prefix} ${code}]`;
|
|
143
|
+
}
|
|
144
|
+
var ERROR_CODES, ERROR_SUGGESTIONS;
|
|
145
|
+
var init_error_codes = __esm({
|
|
146
|
+
"packages/domain/shared/src/error-codes.ts"() {
|
|
147
|
+
ERROR_CODES = {
|
|
148
|
+
// E0xx — Native binding
|
|
149
|
+
NATIVE_NOT_FOUND: "E001",
|
|
150
|
+
NATIVE_LOAD_FAILED: "E002",
|
|
151
|
+
NATIVE_VERSION_MISMATCH: "E003",
|
|
152
|
+
SCANNER_NATIVE_NOT_FOUND: "E004",
|
|
153
|
+
SCANNER_HASH_FAILED: "E005",
|
|
154
|
+
NATIVE_TRANSFORM_UNAVAILABLE: "E006",
|
|
155
|
+
// E2xx — Compilation
|
|
156
|
+
MISSING_REACT_IMPORT: "E201",
|
|
157
|
+
UNSUPPORTED_PATTERN: "E202",
|
|
158
|
+
TEMPLATE_PARSE_ERROR: "E203",
|
|
159
|
+
COMPILE_TIMEOUT: "E204",
|
|
160
|
+
// E3xx — Compatibility
|
|
161
|
+
TAILWIND_VERSION_UNSUPPORTED: "E301",
|
|
162
|
+
NODE_VERSION_UNSUPPORTED: "E302",
|
|
163
|
+
// E4xx — Cache
|
|
164
|
+
CACHE_READ_FAILED: "E401",
|
|
165
|
+
CACHE_WRITE_FAILED: "E402",
|
|
166
|
+
CACHE_CORRUPTED: "E403",
|
|
167
|
+
// E5xx — RSC
|
|
168
|
+
RSC_BOUNDARY_CONFLICT: "E501",
|
|
169
|
+
// W1xx — Warnings
|
|
170
|
+
DYNAMIC_CONTENT: "W101",
|
|
171
|
+
INVALID_VARIANT_VALUE: "W201",
|
|
172
|
+
DEPRECATED_MODE: "W301"
|
|
173
|
+
};
|
|
174
|
+
ERROR_SUGGESTIONS = {
|
|
175
|
+
E001: "Run: npm install @tailwind-styled/native-{platform} or build from source",
|
|
176
|
+
E002: "Try: npm rebuild or reinstall the package",
|
|
177
|
+
E003: "Run: npm install tailwind-styled-v4@latest to sync versions",
|
|
178
|
+
E004: "Run: npm install @tailwind-styled/scanner",
|
|
179
|
+
E006: "Run: npm install @tailwind-styled/compiler",
|
|
180
|
+
E301: "Upgrade: npm install tailwindcss@^4"
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// packages/domain/shared/src/compatibility.ts
|
|
186
|
+
function detectTailwind() {
|
|
187
|
+
try {
|
|
188
|
+
const pkgPath = __require.resolve("tailwindcss/package.json");
|
|
189
|
+
const { version } = __require(pkgPath);
|
|
190
|
+
const major = Number.parseInt(version.split(".")[0], 10);
|
|
191
|
+
return { version, major, supported: major >= 4, path: pkgPath };
|
|
192
|
+
} catch {
|
|
193
|
+
return { version: "not-installed", major: 0, supported: false, path: null };
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function assertTailwindV4() {
|
|
197
|
+
const info = detectTailwind();
|
|
198
|
+
if (!info.supported) {
|
|
199
|
+
const message = info.major === 0 ? "tailwindcss is not installed. Run: npm install tailwindcss@^4" : `tailwind-styled-v4 requires Tailwind CSS v4.x. Found: v${info.version}. Upgrade: npm install tailwindcss@^4`;
|
|
200
|
+
if (process.env.NODE_ENV !== "production") {
|
|
201
|
+
console.warn(`[tailwind-styled] ${message}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function getTailwindVersion() {
|
|
206
|
+
return detectTailwind().version;
|
|
207
|
+
}
|
|
208
|
+
function isTailwindV4() {
|
|
209
|
+
return detectTailwind().supported;
|
|
210
|
+
}
|
|
211
|
+
var init_compatibility = __esm({
|
|
212
|
+
"packages/domain/shared/src/compatibility.ts"() {
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
function safeParseNative(schema, data, fallback) {
|
|
216
|
+
const result = schema.safeParse(data);
|
|
217
|
+
return result.success ? result.data : fallback;
|
|
218
|
+
}
|
|
219
|
+
function parseNative(schema, data, context) {
|
|
220
|
+
const result = schema.safeParse(data);
|
|
221
|
+
if (!result.success) {
|
|
222
|
+
const first = result.error.issues[0];
|
|
223
|
+
const path13 = first?.path?.join(".") ?? "(root)";
|
|
224
|
+
throw new Error(
|
|
225
|
+
`[${context}] Native binding returned unexpected data: ${path13}: ${first?.message ?? "validation failed"}`
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
return result.data;
|
|
229
|
+
}
|
|
230
|
+
var NativeScanFileSchema, NativeScanResultSchema, NativeClassUsageSchema, NativeAnalyzerReportSchema, NativeTransformResultSchema, NativeCssCompileResultSchema, NativeWatchResultSchema, NativeCacheEntrySchema, NativeCacheReadResultSchema;
|
|
231
|
+
var init_native_schemas = __esm({
|
|
232
|
+
"packages/domain/shared/src/native-schemas.ts"() {
|
|
233
|
+
NativeScanFileSchema = z.object({
|
|
234
|
+
file: z.string().min(1, "file path cannot be empty"),
|
|
235
|
+
classes: z.array(z.string()),
|
|
236
|
+
hash: z.string().optional()
|
|
237
|
+
});
|
|
238
|
+
NativeScanResultSchema = z.object({
|
|
239
|
+
files: z.array(NativeScanFileSchema),
|
|
240
|
+
totalFiles: z.number().int().nonnegative(),
|
|
241
|
+
uniqueClasses: z.array(z.string())
|
|
242
|
+
});
|
|
243
|
+
NativeClassUsageSchema = z.object({
|
|
244
|
+
name: z.string(),
|
|
245
|
+
count: z.number().int().nonnegative(),
|
|
246
|
+
files: z.array(z.string()).optional()
|
|
247
|
+
});
|
|
248
|
+
NativeAnalyzerReportSchema = z.object({
|
|
249
|
+
root: z.string(),
|
|
250
|
+
topClasses: z.array(NativeClassUsageSchema).optional(),
|
|
251
|
+
safelist: z.array(z.string()).optional(),
|
|
252
|
+
css: z.string().optional(),
|
|
253
|
+
conflicts: z.array(z.unknown()).optional(),
|
|
254
|
+
unusedClasses: z.array(z.string()).optional(),
|
|
255
|
+
durationMs: z.number().nonnegative().optional()
|
|
256
|
+
});
|
|
257
|
+
NativeTransformResultSchema = z.object({
|
|
258
|
+
code: z.string(),
|
|
259
|
+
classes: z.array(z.string()),
|
|
260
|
+
changed: z.boolean(),
|
|
261
|
+
rsc: z.object({
|
|
262
|
+
isServer: z.boolean(),
|
|
263
|
+
needsClientDirective: z.boolean(),
|
|
264
|
+
clientReasons: z.array(z.string())
|
|
265
|
+
}).optional()
|
|
266
|
+
});
|
|
267
|
+
NativeCssCompileResultSchema = z.object({
|
|
268
|
+
css: z.string(),
|
|
269
|
+
resolvedClasses: z.array(z.string()),
|
|
270
|
+
unresolvedClasses: z.array(z.string()).optional()
|
|
271
|
+
});
|
|
272
|
+
z.object({
|
|
273
|
+
type: z.enum(["change", "unlink", "create"]),
|
|
274
|
+
path: z.string()
|
|
275
|
+
});
|
|
276
|
+
NativeWatchResultSchema = z.object({
|
|
277
|
+
status: z.enum(["ok", "error"]),
|
|
278
|
+
handleId: z.string().optional(),
|
|
279
|
+
error: z.string().optional()
|
|
280
|
+
});
|
|
281
|
+
NativeCacheEntrySchema = z.object({
|
|
282
|
+
file: z.string(),
|
|
283
|
+
hash: z.string(),
|
|
284
|
+
classes: z.array(z.string()),
|
|
285
|
+
timestamp: z.number(),
|
|
286
|
+
size: z.number().optional()
|
|
287
|
+
});
|
|
288
|
+
NativeCacheReadResultSchema = z.object({
|
|
289
|
+
entries: z.array(NativeCacheEntrySchema),
|
|
290
|
+
version: z.string().optional()
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
|
|
37
295
|
// packages/domain/shared/src/esmHelpers.ts
|
|
38
296
|
function getNodeModuleRef() {
|
|
39
297
|
if (isBrowser) return null;
|
|
@@ -61,88 +319,551 @@ function getNodeUrl() {
|
|
|
61
319
|
if (!_nodeUrl) _nodeUrl = nodeRequire.createRequire(import.meta.url)("node:url");
|
|
62
320
|
return _nodeUrl;
|
|
63
321
|
}
|
|
322
|
+
function getNodeFs() {
|
|
323
|
+
if (isBrowser) throw new Error("node:fs not available in browser");
|
|
324
|
+
const nodeRequire = getNodeModuleRef();
|
|
325
|
+
if (!nodeRequire) throw new Error("require not available");
|
|
326
|
+
if (!_nodeFs) _nodeFs = nodeRequire.createRequire(import.meta.url)("node:fs");
|
|
327
|
+
return _nodeFs;
|
|
328
|
+
}
|
|
329
|
+
function createEsmRequire(importMetaUrl) {
|
|
330
|
+
if (isBrowser) throw new Error("require not available in browser");
|
|
331
|
+
const nodeRequire = getNodeModuleRef();
|
|
332
|
+
if (!nodeRequire) throw new Error("require not available");
|
|
333
|
+
return nodeRequire.createRequire(importMetaUrl);
|
|
334
|
+
}
|
|
64
335
|
function getDirname(importMetaUrl) {
|
|
65
336
|
if (isBrowser) return "";
|
|
66
337
|
const nodePath = getNodePath();
|
|
67
338
|
const nodeUrl = getNodeUrl();
|
|
68
339
|
return nodePath.dirname(nodeUrl.fileURLToPath(importMetaUrl));
|
|
69
340
|
}
|
|
70
|
-
|
|
341
|
+
function getFilename(importMetaUrl) {
|
|
342
|
+
if (isBrowser) return "";
|
|
343
|
+
return getNodeUrl().fileURLToPath(importMetaUrl);
|
|
344
|
+
}
|
|
345
|
+
function resolveFromRoot(...segments) {
|
|
346
|
+
if (isBrowser) return segments.join("/");
|
|
347
|
+
const nodePath = getNodePath();
|
|
348
|
+
const nodeFs = getNodeFs();
|
|
349
|
+
let dir = getDirname(import.meta.url);
|
|
350
|
+
for (let i = 0; i < 10; i++) {
|
|
351
|
+
const pkgPath = nodePath.join(dir, "package.json");
|
|
352
|
+
try {
|
|
353
|
+
const pkg = JSON.parse(nodeFs.readFileSync(pkgPath, "utf-8"));
|
|
354
|
+
if (pkg.workspaces) {
|
|
355
|
+
return nodePath.resolve(dir, ...segments);
|
|
356
|
+
}
|
|
357
|
+
} catch {
|
|
358
|
+
}
|
|
359
|
+
dir = nodePath.dirname(dir);
|
|
360
|
+
}
|
|
361
|
+
return nodePath.resolve(process.cwd(), ...segments);
|
|
362
|
+
}
|
|
363
|
+
function tryRequire(moduleName, importMetaUrl) {
|
|
364
|
+
if (isBrowser) return null;
|
|
365
|
+
try {
|
|
366
|
+
return createEsmRequire(importMetaUrl)(moduleName);
|
|
367
|
+
} catch {
|
|
368
|
+
}
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
function resolveNativeNodePath(importMetaUrl, ...relativeSegments) {
|
|
372
|
+
if (isBrowser) return relativeSegments.join("/");
|
|
373
|
+
return getNodePath().resolve(getDirname(importMetaUrl), ...relativeSegments);
|
|
374
|
+
}
|
|
375
|
+
var isBrowser, nodeModuleRef, _nodePath, _nodeUrl, _nodeFs;
|
|
71
376
|
var init_esmHelpers = __esm({
|
|
72
377
|
"packages/domain/shared/src/esmHelpers.ts"() {
|
|
73
378
|
isBrowser = typeof window !== "undefined" || typeof document !== "undefined";
|
|
74
379
|
nodeModuleRef = null;
|
|
75
380
|
_nodePath = null;
|
|
76
381
|
_nodeUrl = null;
|
|
382
|
+
_nodeFs = null;
|
|
77
383
|
}
|
|
78
384
|
});
|
|
79
385
|
|
|
80
|
-
// packages/domain/shared/src/
|
|
81
|
-
function
|
|
82
|
-
if (
|
|
83
|
-
|
|
386
|
+
// packages/domain/shared/src/telemetry.ts
|
|
387
|
+
function getGlobalTelemetry() {
|
|
388
|
+
if (!_globalCollector) {
|
|
389
|
+
_globalCollector = new TelemetryCollector();
|
|
390
|
+
}
|
|
391
|
+
return _globalCollector;
|
|
392
|
+
}
|
|
393
|
+
function resetGlobalTelemetry() {
|
|
394
|
+
_globalCollector = null;
|
|
395
|
+
}
|
|
396
|
+
function createBuildTimer() {
|
|
397
|
+
const start = Date.now();
|
|
398
|
+
const phases = {};
|
|
399
|
+
let phaseStart = start;
|
|
400
|
+
return {
|
|
401
|
+
phase(name) {
|
|
402
|
+
const now = Date.now();
|
|
403
|
+
phases[name] = now - phaseStart;
|
|
404
|
+
phaseStart = now;
|
|
405
|
+
},
|
|
406
|
+
finish(opts) {
|
|
407
|
+
const now = Date.now();
|
|
408
|
+
const record = {
|
|
409
|
+
timestamp: start,
|
|
410
|
+
durationMs: now - start,
|
|
411
|
+
phases: {
|
|
412
|
+
scan: phases.scan ?? 0,
|
|
413
|
+
compile: phases.compile ?? 0,
|
|
414
|
+
engine: phases.engine ?? 0,
|
|
415
|
+
output: phases.output ?? now - start
|
|
416
|
+
},
|
|
417
|
+
cacheHitRate: opts.cacheHitRate ?? 0,
|
|
418
|
+
...opts
|
|
419
|
+
};
|
|
420
|
+
getGlobalTelemetry().record(record);
|
|
421
|
+
return record;
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
var RING_BUFFER_SIZE, TelemetryCollector, _globalCollector;
|
|
426
|
+
var init_telemetry = __esm({
|
|
427
|
+
"packages/domain/shared/src/telemetry.ts"() {
|
|
428
|
+
RING_BUFFER_SIZE = 100;
|
|
429
|
+
TelemetryCollector = class {
|
|
430
|
+
data = [];
|
|
431
|
+
enabled;
|
|
432
|
+
constructor(enabled) {
|
|
433
|
+
this.enabled = enabled ?? (process.env.TWS_TELEMETRY === "1" || process.env.TWS_TELEMETRY === "true");
|
|
434
|
+
}
|
|
435
|
+
record(build) {
|
|
436
|
+
if (!this.enabled) return;
|
|
437
|
+
if (this.data.length >= RING_BUFFER_SIZE) {
|
|
438
|
+
this.data.shift();
|
|
439
|
+
}
|
|
440
|
+
this.data.push(build);
|
|
441
|
+
}
|
|
442
|
+
snapshot() {
|
|
443
|
+
return [...this.data];
|
|
444
|
+
}
|
|
445
|
+
summary() {
|
|
446
|
+
if (this.data.length === 0) return null;
|
|
447
|
+
const durations = this.data.map((d) => d.durationMs).sort((a, b) => a - b);
|
|
448
|
+
const p95Idx = Math.floor(durations.length * 0.95);
|
|
449
|
+
const avg = (arr) => arr.reduce((a, b) => a + b, 0) / arr.length;
|
|
450
|
+
return {
|
|
451
|
+
totalBuilds: this.data.length,
|
|
452
|
+
avgDurationMs: avg(durations),
|
|
453
|
+
p95DurationMs: durations[p95Idx] ?? durations[durations.length - 1] ?? 0,
|
|
454
|
+
avgCacheHitRate: avg(this.data.map((d) => d.cacheHitRate)),
|
|
455
|
+
avgFilesScanned: avg(this.data.map((d) => d.filesScanned)),
|
|
456
|
+
avgClassesExtracted: avg(this.data.map((d) => d.classesExtracted)),
|
|
457
|
+
phaseAvgs: {
|
|
458
|
+
scan: avg(this.data.map((d) => d.phases.scan)),
|
|
459
|
+
compile: avg(this.data.map((d) => d.phases.compile)),
|
|
460
|
+
engine: avg(this.data.map((d) => d.phases.engine)),
|
|
461
|
+
output: avg(this.data.map((d) => d.phases.output))
|
|
462
|
+
},
|
|
463
|
+
slowestBuildMs: durations[durations.length - 1] ?? 0,
|
|
464
|
+
fastestBuildMs: durations[0] ?? 0
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
reset() {
|
|
468
|
+
this.data = [];
|
|
469
|
+
}
|
|
470
|
+
/** Format ringkas untuk CLI output */
|
|
471
|
+
formatCli() {
|
|
472
|
+
const s = this.summary();
|
|
473
|
+
if (!s) return "[telemetry] no data";
|
|
474
|
+
return [
|
|
475
|
+
`[telemetry] ${s.totalBuilds} builds`,
|
|
476
|
+
`avg ${s.avgDurationMs.toFixed(0)}ms`,
|
|
477
|
+
`p95 ${s.p95DurationMs.toFixed(0)}ms`,
|
|
478
|
+
`cache hit ${(s.avgCacheHitRate * 100).toFixed(0)}%`,
|
|
479
|
+
`${s.avgFilesScanned.toFixed(0)} files`
|
|
480
|
+
].join(" \xB7 ");
|
|
481
|
+
}
|
|
482
|
+
/** Export sebagai JSON untuk dashboard/prometheus */
|
|
483
|
+
toJSON() {
|
|
484
|
+
return {
|
|
485
|
+
summary: this.summary(),
|
|
486
|
+
history: this.data.slice(-20)
|
|
487
|
+
// last 20 builds
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
_globalCollector = null;
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
function parseJsonWithSchema(jsonString, schema, sourceName) {
|
|
495
|
+
let parsed;
|
|
84
496
|
try {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
497
|
+
parsed = JSON.parse(jsonString);
|
|
498
|
+
} catch (err) {
|
|
499
|
+
throw new Error(
|
|
500
|
+
`[${sourceName}] Invalid JSON: ${err instanceof Error ? err.message : String(err)}`
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
const result = schema.safeParse(parsed);
|
|
504
|
+
if (!result.success) {
|
|
505
|
+
const issues = result.error.issues.map((e) => ` ${e.path.join(".")}: ${e.message}`).join("\n");
|
|
506
|
+
throw new Error(`[${sourceName}] Schema validation failed:
|
|
507
|
+
${issues}`);
|
|
508
|
+
}
|
|
509
|
+
return result.data;
|
|
510
|
+
}
|
|
511
|
+
function parseJsonFileWithSchema(filePath, schema) {
|
|
512
|
+
const { readFileSync } = __require("fs");
|
|
513
|
+
const { basename } = __require("path");
|
|
514
|
+
let content;
|
|
515
|
+
try {
|
|
516
|
+
content = readFileSync(filePath, "utf-8");
|
|
517
|
+
} catch (err) {
|
|
518
|
+
throw new Error(
|
|
519
|
+
`[${basename(filePath)}] Could not read file: ${err instanceof Error ? err.message : String(err)}`
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
return parseJsonWithSchema(content, schema, basename(filePath));
|
|
523
|
+
}
|
|
524
|
+
var ScanCacheClassEntrySchema, ScanCacheSchema, TailwindContentItemSchema, TailwindConfigSchema, RegistryPluginEntrySchema, RegistryFileSchema, PackageJsonSchema;
|
|
525
|
+
var init_configSchemas = __esm({
|
|
526
|
+
"packages/domain/shared/src/configSchemas.ts"() {
|
|
527
|
+
ScanCacheClassEntrySchema = z.object({
|
|
528
|
+
name: z.string().min(1),
|
|
529
|
+
usedIn: z.array(z.string()),
|
|
530
|
+
risk: z.enum(["low", "medium", "high"]).default("low"),
|
|
531
|
+
bundleContribution: z.number().nonnegative().default(0),
|
|
532
|
+
variants: z.array(z.string()).default([])
|
|
533
|
+
});
|
|
534
|
+
ScanCacheSchema = z.object({
|
|
535
|
+
version: z.string().default("1"),
|
|
536
|
+
generatedAt: z.string(),
|
|
537
|
+
root: z.string(),
|
|
538
|
+
classNames: z.array(ScanCacheClassEntrySchema),
|
|
539
|
+
totalFiles: z.number().int().nonnegative(),
|
|
540
|
+
uniqueCount: z.number().int().nonnegative()
|
|
541
|
+
});
|
|
542
|
+
TailwindContentItemSchema = z.union([
|
|
543
|
+
z.string(),
|
|
544
|
+
z.object({
|
|
545
|
+
raw: z.string(),
|
|
546
|
+
extension: z.string().optional()
|
|
547
|
+
}),
|
|
548
|
+
z.object({
|
|
549
|
+
files: z.array(z.string()),
|
|
550
|
+
transform: z.record(z.string(), z.unknown()).optional()
|
|
551
|
+
})
|
|
552
|
+
]);
|
|
553
|
+
TailwindConfigSchema = z.object({
|
|
554
|
+
content: z.array(TailwindContentItemSchema).optional(),
|
|
555
|
+
theme: z.record(z.string(), z.unknown()).optional(),
|
|
556
|
+
plugins: z.array(z.unknown()).optional(),
|
|
557
|
+
darkMode: z.union([z.literal("class"), z.literal("media"), z.literal(false)]).optional(),
|
|
558
|
+
prefix: z.string().optional(),
|
|
559
|
+
safelist: z.array(z.union([z.string(), z.object({ pattern: z.instanceof(RegExp) })])).optional(),
|
|
560
|
+
blocklist: z.array(z.string()).optional()
|
|
561
|
+
}).passthrough();
|
|
562
|
+
RegistryPluginEntrySchema = z.object({
|
|
563
|
+
name: z.string().min(1),
|
|
564
|
+
description: z.string(),
|
|
565
|
+
version: z.string(),
|
|
566
|
+
tags: z.array(z.string()).default([]),
|
|
567
|
+
official: z.boolean().default(false),
|
|
568
|
+
docs: z.string().url().optional(),
|
|
569
|
+
install: z.string().optional(),
|
|
570
|
+
integrity: z.string().optional()
|
|
571
|
+
});
|
|
572
|
+
RegistryFileSchema = z.object({
|
|
573
|
+
version: z.string(),
|
|
574
|
+
official: z.array(RegistryPluginEntrySchema).default([]),
|
|
575
|
+
community: z.array(RegistryPluginEntrySchema).default([])
|
|
576
|
+
});
|
|
577
|
+
PackageJsonSchema = z.object({
|
|
578
|
+
name: z.string(),
|
|
579
|
+
version: z.string(),
|
|
580
|
+
scripts: z.record(z.string(), z.string()).optional(),
|
|
581
|
+
dependencies: z.record(z.string(), z.string()).optional(),
|
|
582
|
+
devDependencies: z.record(z.string(), z.string()).optional(),
|
|
583
|
+
peerDependencies: z.record(z.string(), z.string()).optional(),
|
|
584
|
+
main: z.string().optional(),
|
|
585
|
+
module: z.string().optional(),
|
|
586
|
+
exports: z.unknown().optional(),
|
|
587
|
+
type: z.enum(["module", "commonjs"]).optional()
|
|
588
|
+
}).passthrough();
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
// packages/domain/shared/src/workerResolver.ts
|
|
593
|
+
function getDirnameFromUrl(importMetaUrl) {
|
|
594
|
+
if (!importMetaUrl) return "";
|
|
595
|
+
if (isBrowser2) return "";
|
|
596
|
+
try {
|
|
597
|
+
const nodeUrl = __require(NODE_URL);
|
|
598
|
+
const nodePath = __require(NODE_PATH);
|
|
599
|
+
return nodePath.dirname(nodeUrl.fileURLToPath(importMetaUrl));
|
|
88
600
|
} catch {
|
|
89
|
-
|
|
90
|
-
|
|
601
|
+
if (importMetaUrl.startsWith("file://")) {
|
|
602
|
+
const filePath = importMetaUrl.slice(7);
|
|
603
|
+
const lastSlash = filePath.lastIndexOf("/");
|
|
604
|
+
return lastSlash >= 0 ? filePath.slice(0, lastSlash) : filePath;
|
|
605
|
+
}
|
|
606
|
+
return "";
|
|
91
607
|
}
|
|
92
608
|
}
|
|
93
|
-
function
|
|
94
|
-
if (isBrowser2) return
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
609
|
+
function resolvePath(...segments) {
|
|
610
|
+
if (isBrowser2) return segments.join("/").replace(/\/+/g, "/");
|
|
611
|
+
try {
|
|
612
|
+
const nodePath = __require(NODE_PATH);
|
|
613
|
+
return nodePath.resolve(...segments);
|
|
614
|
+
} catch {
|
|
615
|
+
return segments.join("/").replace(/\/+/g, "/");
|
|
616
|
+
}
|
|
99
617
|
}
|
|
100
|
-
function
|
|
101
|
-
if (isBrowser2) return
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
618
|
+
function existsSync(path13) {
|
|
619
|
+
if (isBrowser2) return false;
|
|
620
|
+
try {
|
|
621
|
+
const nodeFs = __require(NODE_FS);
|
|
622
|
+
return nodeFs.existsSync(path13);
|
|
623
|
+
} catch {
|
|
624
|
+
return false;
|
|
625
|
+
}
|
|
106
626
|
}
|
|
107
|
-
function
|
|
108
|
-
if (isBrowser2)
|
|
109
|
-
throw new Error("
|
|
110
|
-
}
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
627
|
+
function resolveWorkerPath(opts) {
|
|
628
|
+
if (isBrowser2) {
|
|
629
|
+
throw new Error("Worker resolution not available in browser");
|
|
630
|
+
}
|
|
631
|
+
const {
|
|
632
|
+
basename,
|
|
633
|
+
importMetaUrl,
|
|
634
|
+
extensions = [".cjs", ".js", ".mjs"],
|
|
635
|
+
subdirs = [".", "workers", "lib"],
|
|
636
|
+
required = true
|
|
637
|
+
} = opts;
|
|
638
|
+
const runtimeDir = getDirnameFromUrl(importMetaUrl);
|
|
639
|
+
for (const subdir of subdirs) {
|
|
640
|
+
for (const ext of extensions) {
|
|
641
|
+
const candidate = resolvePath(runtimeDir, subdir, `${basename}${ext}`);
|
|
642
|
+
if (existsSync(candidate)) {
|
|
643
|
+
return {
|
|
644
|
+
path: candidate,
|
|
645
|
+
extension: ext,
|
|
646
|
+
format: ext === ".cjs" ? "cjs" : "esm"
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
if (required) {
|
|
652
|
+
const tried = subdirs.flatMap(
|
|
653
|
+
(d) => extensions.map((e) => resolvePath(runtimeDir, d, `${basename}${e}`))
|
|
654
|
+
);
|
|
655
|
+
throw new Error(
|
|
656
|
+
`[worker-resolver] Could not find worker script "${basename}".
|
|
657
|
+
Tried:
|
|
658
|
+
${tried.map((p) => ` - ${p}`).join("\n")}
|
|
659
|
+
Ensure the package is built: npm run build`
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
return { path: "", extension: "", format: "cjs" };
|
|
663
|
+
}
|
|
664
|
+
function resolveLoaderPath(loaderBasename, importMetaUrl) {
|
|
665
|
+
return resolveWorkerPath({
|
|
666
|
+
basename: loaderBasename,
|
|
667
|
+
importMetaUrl,
|
|
668
|
+
extensions: [".cjs", ".js", ".mjs"],
|
|
669
|
+
subdirs: [".", "loaders", "lib"]
|
|
670
|
+
}).path;
|
|
671
|
+
}
|
|
672
|
+
var isBrowser2, NODE_URL, NODE_FS, NODE_PATH;
|
|
673
|
+
var init_workerResolver = __esm({
|
|
674
|
+
"packages/domain/shared/src/workerResolver.ts"() {
|
|
675
|
+
isBrowser2 = typeof window !== "undefined" || typeof document !== "undefined";
|
|
676
|
+
NODE_URL = typeof window === "undefined" || typeof document === "undefined" ? "node:url" : null;
|
|
677
|
+
NODE_FS = typeof window === "undefined" || typeof document === "undefined" ? "node:fs" : null;
|
|
678
|
+
NODE_PATH = typeof window === "undefined" || typeof document === "undefined" ? "node:path" : null;
|
|
679
|
+
}
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
// packages/domain/shared/src/codegen.ts
|
|
683
|
+
function generateComponentCode(opts) {
|
|
684
|
+
const {
|
|
685
|
+
name,
|
|
686
|
+
tag = "div",
|
|
687
|
+
base = "",
|
|
688
|
+
variants = {},
|
|
689
|
+
defaultVariants = {},
|
|
690
|
+
compoundVariants = [],
|
|
691
|
+
framework = "react",
|
|
692
|
+
withTypes = true
|
|
693
|
+
} = opts;
|
|
694
|
+
const variantKeys = Object.keys(variants);
|
|
695
|
+
const lines = [];
|
|
696
|
+
if (framework === "react") {
|
|
697
|
+
lines.push(`import { tw } from "tailwind-styled-v4"`);
|
|
698
|
+
if (withTypes && variantKeys.length > 0) {
|
|
699
|
+
lines.push(`import type { InferVariantProps } from "tailwind-styled-v4"`);
|
|
700
|
+
}
|
|
701
|
+
} else if (framework === "vue") {
|
|
702
|
+
lines.push(`import { tw } from "@tailwind-styled/vue"`);
|
|
703
|
+
} else if (framework === "svelte") {
|
|
704
|
+
lines.push(`import { tw } from "@tailwind-styled/svelte"`);
|
|
705
|
+
}
|
|
706
|
+
lines.push("");
|
|
707
|
+
const configLines = [`export const ${name} = tw.${tag}({`];
|
|
708
|
+
if (base) configLines.push(` base: "${base}",`);
|
|
709
|
+
if (variantKeys.length > 0) {
|
|
710
|
+
configLines.push(` variants: {`);
|
|
711
|
+
for (const [key, values] of Object.entries(variants)) {
|
|
712
|
+
configLines.push(` ${key}: {`);
|
|
713
|
+
for (const [val, cls] of Object.entries(values)) {
|
|
714
|
+
configLines.push(` ${val}: "${cls}",`);
|
|
715
|
+
}
|
|
716
|
+
configLines.push(` },`);
|
|
717
|
+
}
|
|
718
|
+
configLines.push(` },`);
|
|
719
|
+
}
|
|
720
|
+
if (compoundVariants.length > 0) {
|
|
721
|
+
configLines.push(` compoundVariants: [`);
|
|
722
|
+
for (const cv of compoundVariants) {
|
|
723
|
+
const { class: cls, ...conditions } = cv;
|
|
724
|
+
const condStr = Object.entries(conditions).map(([k, v]) => `${k}: "${v}"`).join(", ");
|
|
725
|
+
configLines.push(` { ${condStr}, class: "${cls}" },`);
|
|
726
|
+
}
|
|
727
|
+
configLines.push(` ],`);
|
|
728
|
+
}
|
|
729
|
+
if (Object.keys(defaultVariants).length > 0) {
|
|
730
|
+
configLines.push(` defaultVariants: {`);
|
|
731
|
+
for (const [k, v] of Object.entries(defaultVariants)) {
|
|
732
|
+
configLines.push(` ${k}: "${v}",`);
|
|
733
|
+
}
|
|
734
|
+
configLines.push(` },`);
|
|
735
|
+
}
|
|
736
|
+
configLines.push(`})`);
|
|
737
|
+
lines.push(...configLines);
|
|
738
|
+
if (withTypes && variantKeys.length > 0 && framework === "react") {
|
|
739
|
+
lines.push("");
|
|
740
|
+
lines.push(`export type ${name}Props = InferVariantProps<typeof ${name}> & {`);
|
|
741
|
+
lines.push(` children?: React.ReactNode`);
|
|
742
|
+
lines.push(` className?: string`);
|
|
743
|
+
lines.push(`}`);
|
|
744
|
+
}
|
|
745
|
+
return lines.join("\n");
|
|
746
|
+
}
|
|
747
|
+
function generateStorybookStory(opts) {
|
|
748
|
+
const { name, variants = {}, defaultVariants = {} } = opts;
|
|
749
|
+
const lines = [];
|
|
750
|
+
lines.push(`import type { Meta, StoryObj } from "@storybook/react"`);
|
|
751
|
+
lines.push(`import { ${name} } from "./${name}"`);
|
|
752
|
+
lines.push(`import { generateArgTypes, generateDefaultArgs } from "tailwind-styled-v4"`);
|
|
753
|
+
lines.push(``);
|
|
754
|
+
lines.push(`const config = {`);
|
|
755
|
+
if (Object.keys(variants).length > 0) {
|
|
756
|
+
lines.push(` variants: ${JSON.stringify(variants, null, 2).replace(/^/gm, " ")},`);
|
|
757
|
+
}
|
|
758
|
+
if (Object.keys(defaultVariants).length > 0) {
|
|
759
|
+
lines.push(` defaultVariants: ${JSON.stringify(defaultVariants)},`);
|
|
760
|
+
}
|
|
761
|
+
lines.push(`}`);
|
|
762
|
+
lines.push(``);
|
|
763
|
+
lines.push(`const meta: Meta<typeof ${name}> = {`);
|
|
764
|
+
lines.push(` title: "Components/${name}",`);
|
|
765
|
+
lines.push(` component: ${name},`);
|
|
766
|
+
lines.push(` argTypes: generateArgTypes(config),`);
|
|
767
|
+
lines.push(` args: generateDefaultArgs(config),`);
|
|
768
|
+
lines.push(`}`);
|
|
769
|
+
lines.push(``);
|
|
770
|
+
lines.push(`export default meta`);
|
|
771
|
+
lines.push(`type Story = StoryObj<typeof ${name}>`);
|
|
772
|
+
lines.push(``);
|
|
773
|
+
lines.push(`export const Default: Story = {}`);
|
|
774
|
+
const variantEntries = Object.entries(variants);
|
|
775
|
+
if (variantEntries.length > 0) {
|
|
776
|
+
const [firstKey, firstValues] = variantEntries[0];
|
|
777
|
+
const valueKeys = Object.keys(firstValues).slice(0, 4);
|
|
778
|
+
for (const val of valueKeys) {
|
|
779
|
+
const storyName = `${firstKey.charAt(0).toUpperCase()}${firstKey.slice(1)}${val.charAt(0).toUpperCase()}${val.slice(1)}`;
|
|
780
|
+
lines.push(``);
|
|
781
|
+
lines.push(`export const ${storyName}: Story = {`);
|
|
782
|
+
lines.push(` args: { ${firstKey}: "${val}" },`);
|
|
783
|
+
lines.push(`}`);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
return lines.join("\n");
|
|
787
|
+
}
|
|
788
|
+
function generateClassRenameCodemod(renames, opts = {}) {
|
|
789
|
+
const { format = "regex", filename = "rename-classes.mjs" } = opts;
|
|
790
|
+
const lines = [];
|
|
791
|
+
if (format === "regex") {
|
|
792
|
+
lines.push(`#!/usr/bin/env node`);
|
|
793
|
+
lines.push(`/**`);
|
|
794
|
+
lines.push(` * Auto-generated class rename codemod`);
|
|
795
|
+
lines.push(` * Usage: node ${filename} ./src`);
|
|
796
|
+
lines.push(` */`);
|
|
797
|
+
lines.push(`import fs from "node:fs"`);
|
|
798
|
+
lines.push(`import path from "node:path"`);
|
|
799
|
+
lines.push(`import { execSync } from "node:child_process"`);
|
|
800
|
+
lines.push(``);
|
|
801
|
+
lines.push(`const RENAMES = {`);
|
|
802
|
+
for (const [from, to] of Object.entries(renames)) {
|
|
803
|
+
lines.push(` "${from}": "${to}",`);
|
|
804
|
+
}
|
|
805
|
+
lines.push(`}`);
|
|
806
|
+
lines.push(``);
|
|
807
|
+
lines.push(`const dir = process.argv[2] ?? "."`);
|
|
808
|
+
lines.push(`const files = execSync(\`find \${dir} -name "*.tsx" -o -name "*.ts" -o -name "*.jsx"\`, { encoding: "utf-8" }).split("\\n").filter(Boolean)`);
|
|
809
|
+
lines.push(``);
|
|
810
|
+
lines.push(`let total = 0`);
|
|
811
|
+
lines.push(`for (const file of files) {`);
|
|
812
|
+
lines.push(` let content = fs.readFileSync(file, "utf-8")`);
|
|
813
|
+
lines.push(` let changed = false`);
|
|
814
|
+
lines.push(` for (const [from, to] of Object.entries(RENAMES)) {`);
|
|
815
|
+
lines.push(' const re = new RegExp(`\\\\b${from.replace(/[.*+?^${}()|[\\\\]\\\\]/g, "\\\\$&")}\\\\b`, "g")');
|
|
816
|
+
lines.push(` if (re.test(content)) { content = content.replace(re, to); changed = true; total++ }`);
|
|
817
|
+
lines.push(` }`);
|
|
818
|
+
lines.push(` if (changed) fs.writeFileSync(file, content)`);
|
|
819
|
+
lines.push(`}`);
|
|
820
|
+
lines.push(`console.log(\`Renamed \${total} occurrences in \${files.length} files\`)`);
|
|
821
|
+
}
|
|
822
|
+
return lines.join("\n");
|
|
823
|
+
}
|
|
824
|
+
function generateBarrelFile(exports$1, dir, opts = {}) {
|
|
825
|
+
const { includeTypes = true } = opts;
|
|
826
|
+
const lines = [];
|
|
827
|
+
lines.push(`// Auto-generated barrel file for ${dir}`);
|
|
828
|
+
lines.push(`// Run: npx tsx scripts/generate-barrel.ts to regenerate`);
|
|
829
|
+
lines.push(``);
|
|
830
|
+
for (const name of exports$1) {
|
|
831
|
+
lines.push(`export { default as ${name}, type ${name}Props } from "./${name}"`);
|
|
832
|
+
if (includeTypes) {
|
|
833
|
+
lines.push(`export type * from "./${name}"`);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
return lines.join("\n");
|
|
117
837
|
}
|
|
838
|
+
var init_codegen = __esm({
|
|
839
|
+
"packages/domain/shared/src/codegen.ts"() {
|
|
840
|
+
}
|
|
841
|
+
});
|
|
118
842
|
function platformKey() {
|
|
119
|
-
if (
|
|
843
|
+
if (isBrowser3) return "browser";
|
|
120
844
|
return `${process.platform}-${process.arch}`;
|
|
121
845
|
}
|
|
122
846
|
function resolveNativeBinary(runtimeDir) {
|
|
123
847
|
const platform = platformKey();
|
|
124
848
|
const tried = [];
|
|
125
|
-
if (
|
|
849
|
+
if (isBrowser3) {
|
|
126
850
|
return { path: null, source: "not-found", platform, tried: ["not available in browser"] };
|
|
127
851
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
852
|
+
if (process.env.TWS_DISABLE_NATIVE === "1") {
|
|
853
|
+
return { path: null, source: "not-found", platform, tried: [] };
|
|
854
|
+
}
|
|
131
855
|
const envPath = process.env.TW_NATIVE_PATH?.trim();
|
|
132
856
|
if (envPath) {
|
|
133
|
-
if (
|
|
857
|
+
if (fs4.existsSync(envPath)) {
|
|
134
858
|
return { path: envPath, source: "env", platform, tried };
|
|
135
859
|
}
|
|
136
860
|
tried.push(`env:${envPath} (not found)`);
|
|
137
861
|
}
|
|
138
|
-
if (process.env.TWS_NO_NATIVE === "1" || process.env.TWS_NO_RUST === "1" || process.env.TWS_DISABLE_NATIVE === "1") {
|
|
139
|
-
return { path: null, source: "not-found", platform, tried: ["disabled by env"] };
|
|
140
|
-
}
|
|
141
862
|
const prebuiltPkgs = PLATFORM_MAP[platform] ?? [];
|
|
142
863
|
for (const pkg of prebuiltPkgs) {
|
|
143
864
|
try {
|
|
144
|
-
const candidate =
|
|
145
|
-
if (
|
|
865
|
+
const candidate = _require.resolve(`${pkg}/tailwind_styled_parser.node`);
|
|
866
|
+
if (fs4.existsSync(candidate)) {
|
|
146
867
|
return { path: candidate, source: "prebuilt", platform, tried };
|
|
147
868
|
}
|
|
148
869
|
tried.push(`prebuilt:${pkg} (resolved but missing)`);
|
|
@@ -152,30 +873,57 @@ function resolveNativeBinary(runtimeDir) {
|
|
|
152
873
|
}
|
|
153
874
|
const cwd = process.cwd();
|
|
154
875
|
const base = runtimeDir ?? cwd;
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
876
|
+
const napiPlatform = platform === "linux-x64" ? "linux-x64-gnu" : platform === "linux-arm64" ? "linux-arm64-gnu" : platform;
|
|
877
|
+
const BINARY_NAMES = ["tailwind-styled-native", "tailwind_styled_parser"];
|
|
878
|
+
const localCandidates = [];
|
|
879
|
+
for (const bin of BINARY_NAMES) {
|
|
880
|
+
localCandidates.push(path6.resolve(base, `${bin}.node`));
|
|
881
|
+
localCandidates.push(path6.resolve(base, "..", `${bin}.node`));
|
|
882
|
+
localCandidates.push(path6.resolve(base, `${bin}.${platform}.node`));
|
|
883
|
+
localCandidates.push(path6.resolve(base, `${bin}.${napiPlatform}.node`));
|
|
884
|
+
}
|
|
885
|
+
for (const startDir of [cwd, base]) {
|
|
886
|
+
let dir = startDir;
|
|
887
|
+
for (let i = 0; i < 6; i++) {
|
|
888
|
+
const nativeDir = path6.resolve(dir, "native");
|
|
889
|
+
for (const bin of BINARY_NAMES) {
|
|
890
|
+
localCandidates.push(path6.resolve(nativeDir, `${bin}.node`));
|
|
891
|
+
localCandidates.push(path6.resolve(nativeDir, `${bin}.${platform}.node`));
|
|
892
|
+
localCandidates.push(path6.resolve(nativeDir, `${bin}.${napiPlatform}.node`));
|
|
893
|
+
localCandidates.push(path6.resolve(nativeDir, "target", "release", `${bin}.node`));
|
|
894
|
+
}
|
|
895
|
+
const parent = path6.resolve(dir, "..");
|
|
896
|
+
if (parent === dir) break;
|
|
897
|
+
dir = parent;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
163
900
|
for (const candidate of localCandidates) {
|
|
164
901
|
tried.push(`local:${candidate}`);
|
|
165
|
-
if (
|
|
902
|
+
if (fs4.existsSync(candidate)) {
|
|
166
903
|
return { path: candidate, source: "local", platform, tried };
|
|
167
904
|
}
|
|
168
905
|
}
|
|
169
906
|
return { path: null, source: "not-found", platform, tried };
|
|
170
907
|
}
|
|
171
|
-
|
|
908
|
+
function formatNativeNotFoundError(result) {
|
|
909
|
+
const lines = [
|
|
910
|
+
`[tailwind-styled] Native binding not found for ${result.platform}`,
|
|
911
|
+
``,
|
|
912
|
+
`Tried:`,
|
|
913
|
+
...result.tried.map((t) => ` - ${t}`),
|
|
914
|
+
``,
|
|
915
|
+
`Solutions:`,
|
|
916
|
+
` 1. Build locally: npm run build:rust`,
|
|
917
|
+
` 2. Install prebuilt: npm install @tailwind-styled/native-${result.platform}`,
|
|
918
|
+
` 3. Override path: TW_NATIVE_PATH=/path/to/parser.node`
|
|
919
|
+
];
|
|
920
|
+
return lines.join("\n");
|
|
921
|
+
}
|
|
922
|
+
var isBrowser3, _require, PLATFORM_MAP;
|
|
172
923
|
var init_native_resolution = __esm({
|
|
173
924
|
"packages/domain/shared/src/native-resolution.ts"() {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
_nodeFs = null;
|
|
177
|
-
_nodePath2 = null;
|
|
178
|
-
_require = null;
|
|
925
|
+
isBrowser3 = typeof window !== "undefined" || typeof document !== "undefined";
|
|
926
|
+
_require = typeof __require !== "undefined" ? __require : createRequire(import.meta.url);
|
|
179
927
|
PLATFORM_MAP = {
|
|
180
928
|
"linux-x64": ["@tailwind-styled/native-linux-x64"],
|
|
181
929
|
"linux-arm64": ["@tailwind-styled/native-linux-arm64"],
|
|
@@ -187,40 +935,111 @@ var init_native_resolution = __esm({
|
|
|
187
935
|
}
|
|
188
936
|
});
|
|
189
937
|
|
|
190
|
-
// packages/domain/shared/src/
|
|
191
|
-
function
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
938
|
+
// packages/domain/shared/src/observability.ts
|
|
939
|
+
function createObservabilityClient(opts = {}) {
|
|
940
|
+
const { baseUrl = "http://localhost:7421", timeoutMs = 3e3 } = opts;
|
|
941
|
+
async function fetchJson(path13) {
|
|
942
|
+
try {
|
|
943
|
+
const res = await fetch(`${baseUrl}${path13}`, {
|
|
944
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
945
|
+
});
|
|
946
|
+
if (!res.ok) return null;
|
|
947
|
+
return await res.json();
|
|
948
|
+
} catch {
|
|
949
|
+
return null;
|
|
950
|
+
}
|
|
201
951
|
}
|
|
952
|
+
return {
|
|
953
|
+
async inspectClass(className) {
|
|
954
|
+
const data = await fetchJson(`/inspect?class=${encodeURIComponent(className)}`);
|
|
955
|
+
if (!data) return null;
|
|
956
|
+
return { ...data, inspectedAt: Date.now() };
|
|
957
|
+
},
|
|
958
|
+
async getMetrics() {
|
|
959
|
+
return fetchJson("/metrics");
|
|
960
|
+
},
|
|
961
|
+
async getSummary() {
|
|
962
|
+
return fetchJson("/summary");
|
|
963
|
+
},
|
|
964
|
+
async getHistory() {
|
|
965
|
+
const data = await fetchJson("/history");
|
|
966
|
+
return Array.isArray(data) ? data : [];
|
|
967
|
+
}
|
|
968
|
+
};
|
|
202
969
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
970
|
+
var init_observability = __esm({
|
|
971
|
+
"packages/domain/shared/src/observability.ts"() {
|
|
972
|
+
}
|
|
973
|
+
});
|
|
974
|
+
|
|
975
|
+
// packages/domain/shared/src/index.ts
|
|
976
|
+
var src_exports = {};
|
|
977
|
+
__export(src_exports, {
|
|
978
|
+
ERROR_CODES: () => ERROR_CODES,
|
|
979
|
+
LRUCache: () => LRUCache,
|
|
980
|
+
NativeAnalyzerReportSchema: () => NativeAnalyzerReportSchema,
|
|
981
|
+
NativeCacheEntrySchema: () => NativeCacheEntrySchema,
|
|
982
|
+
NativeCacheReadResultSchema: () => NativeCacheReadResultSchema,
|
|
983
|
+
NativeCssCompileResultSchema: () => NativeCssCompileResultSchema,
|
|
984
|
+
NativeScanFileSchema: () => NativeScanFileSchema,
|
|
985
|
+
NativeScanResultSchema: () => NativeScanResultSchema,
|
|
986
|
+
NativeTransformResultSchema: () => NativeTransformResultSchema,
|
|
987
|
+
NativeWatchResultSchema: () => NativeWatchResultSchema,
|
|
988
|
+
PackageJsonSchema: () => PackageJsonSchema,
|
|
989
|
+
RegistryFileSchema: () => RegistryFileSchema,
|
|
990
|
+
RegistryPluginEntrySchema: () => RegistryPluginEntrySchema,
|
|
991
|
+
ScanCacheClassEntrySchema: () => ScanCacheClassEntrySchema,
|
|
992
|
+
ScanCacheSchema: () => ScanCacheSchema,
|
|
993
|
+
TailwindConfigSchema: () => TailwindConfigSchema,
|
|
994
|
+
TelemetryCollector: () => TelemetryCollector,
|
|
995
|
+
TwError: () => TwError,
|
|
996
|
+
assertTailwindV4: () => assertTailwindV4,
|
|
997
|
+
calculateHealth: () => calculateHealth,
|
|
998
|
+
createBuildTimer: () => createBuildTimer,
|
|
999
|
+
createDebugLogger: () => createDebugLogger,
|
|
1000
|
+
createEsmRequire: () => createEsmRequire,
|
|
1001
|
+
createLogger: () => createLogger,
|
|
1002
|
+
createObservabilityClient: () => createObservabilityClient,
|
|
1003
|
+
createTraceSnapshot: () => createTraceSnapshot,
|
|
1004
|
+
detectTailwind: () => detectTailwind,
|
|
1005
|
+
formatDuration: () => formatDuration,
|
|
1006
|
+
formatErrorCode: () => formatErrorCode,
|
|
1007
|
+
formatErrorMessage: () => formatErrorMessage,
|
|
1008
|
+
formatMemory: () => formatMemory,
|
|
1009
|
+
formatNativeNotFoundError: () => formatNativeNotFoundError,
|
|
1010
|
+
generateBarrelFile: () => generateBarrelFile,
|
|
1011
|
+
generateClassRenameCodemod: () => generateClassRenameCodemod,
|
|
1012
|
+
generateComponentCode: () => generateComponentCode,
|
|
1013
|
+
generateStorybookStory: () => generateStorybookStory,
|
|
1014
|
+
getBuildTimeColor: () => getBuildTimeColor,
|
|
1015
|
+
getDirname: () => getDirname,
|
|
1016
|
+
getFilename: () => getFilename,
|
|
1017
|
+
getGlobalTelemetry: () => getGlobalTelemetry,
|
|
1018
|
+
getHealthColor: () => getHealthColor,
|
|
1019
|
+
getMemoryColor: () => getMemoryColor,
|
|
1020
|
+
getModeColor: () => getModeColor,
|
|
1021
|
+
getPipelinePercentages: () => getPipelinePercentages,
|
|
1022
|
+
getSuggestion: () => getSuggestion,
|
|
1023
|
+
getTailwindVersion: () => getTailwindVersion,
|
|
1024
|
+
hashContent: () => hashContent,
|
|
1025
|
+
isTailwindV4: () => isTailwindV4,
|
|
1026
|
+
isTwError: () => isTwError,
|
|
1027
|
+
loadNativeBinding: () => loadNativeBinding,
|
|
1028
|
+
parseJsonFileWithSchema: () => parseJsonFileWithSchema,
|
|
1029
|
+
parseJsonWithSchema: () => parseJsonWithSchema,
|
|
1030
|
+
parseNative: () => parseNative,
|
|
1031
|
+
resetGlobalTelemetry: () => resetGlobalTelemetry,
|
|
1032
|
+
resolveFromRoot: () => resolveFromRoot,
|
|
1033
|
+
resolveLoaderPath: () => resolveLoaderPath,
|
|
1034
|
+
resolveNativeBinary: () => resolveNativeBinary,
|
|
1035
|
+
resolveNativeBindingCandidates: () => resolveNativeBindingCandidates,
|
|
1036
|
+
resolveNativeNodePath: () => resolveNativeNodePath,
|
|
1037
|
+
resolveRuntimeDir: () => resolveRuntimeDir,
|
|
1038
|
+
resolveWorkerPath: () => resolveWorkerPath,
|
|
1039
|
+
safeParseNative: () => safeParseNative,
|
|
1040
|
+
tryRequire: () => tryRequire,
|
|
1041
|
+
wrapUnknownError: () => wrapUnknownError
|
|
1042
|
+
});
|
|
224
1043
|
function createLogger(namespace) {
|
|
225
1044
|
const prefix = `[${namespace}]`;
|
|
226
1045
|
return {
|
|
@@ -250,27 +1069,25 @@ function createDebugLogger(namespace, label) {
|
|
|
250
1069
|
}
|
|
251
1070
|
};
|
|
252
1071
|
}
|
|
253
|
-
function formatIssuePath(
|
|
254
|
-
if (!
|
|
255
|
-
return
|
|
1072
|
+
function formatIssuePath(path13) {
|
|
1073
|
+
if (!path13 || path13.length === 0) return "(root)";
|
|
1074
|
+
return path13.map(
|
|
256
1075
|
(segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
|
|
257
1076
|
).join(".");
|
|
258
1077
|
}
|
|
259
1078
|
function wrapUnknownError(domain, code, error) {
|
|
260
1079
|
return TwError.wrap(domain, code, error);
|
|
261
1080
|
}
|
|
1081
|
+
function isTwError(err) {
|
|
1082
|
+
return err instanceof TwError;
|
|
1083
|
+
}
|
|
262
1084
|
function loadNativeBinding(options) {
|
|
263
|
-
if (isBrowser3) {
|
|
264
|
-
return { binding: null, loadErrors: [{ path: "", message: "Native bindings not available in browser" }] };
|
|
265
|
-
}
|
|
266
1085
|
const { runtimeDir, candidates, isValid } = options;
|
|
267
1086
|
const loadErrors = [];
|
|
268
|
-
const path11 = getNodePath3();
|
|
269
|
-
const fs9 = getNodeFs2();
|
|
270
1087
|
for (const candidate of candidates) {
|
|
271
|
-
const candidatePath =
|
|
1088
|
+
const candidatePath = path6__default.resolve(runtimeDir, candidate);
|
|
272
1089
|
try {
|
|
273
|
-
if (!
|
|
1090
|
+
if (!fs4__default.existsSync(candidatePath) && !fs4__default.existsSync(candidatePath + ".node")) {
|
|
274
1091
|
continue;
|
|
275
1092
|
}
|
|
276
1093
|
const mod = requireNativeModule(candidatePath);
|
|
@@ -284,74 +1101,76 @@ function loadNativeBinding(options) {
|
|
|
284
1101
|
}
|
|
285
1102
|
return { binding: null, loadErrors };
|
|
286
1103
|
}
|
|
287
|
-
function
|
|
288
|
-
|
|
289
|
-
throw new Error("require not available in browser");
|
|
290
|
-
});
|
|
291
|
-
const nodeRequire = getNodeModuleRef3();
|
|
292
|
-
if (!nodeRequire) return (() => {
|
|
293
|
-
throw new Error("require not available");
|
|
294
|
-
});
|
|
295
|
-
return nodeRequire.createRequire(import.meta.url);
|
|
296
|
-
}
|
|
297
|
-
function requireNativeModule(path11) {
|
|
298
|
-
return _require2(path11);
|
|
1104
|
+
function requireNativeModule(p) {
|
|
1105
|
+
return _require2(p);
|
|
299
1106
|
}
|
|
300
1107
|
function resolveNativeBindingCandidates(options) {
|
|
301
|
-
|
|
302
|
-
|
|
1108
|
+
const {
|
|
1109
|
+
envVarNames = ["TW_NATIVE_PATH", "TWS_NATIVE_PATH"],
|
|
1110
|
+
includeDefaultCandidates = true,
|
|
1111
|
+
enforceNodeExtensionForEnvPath = false
|
|
1112
|
+
} = options;
|
|
1113
|
+
const runtimeDir = options.runtimeDir || process.cwd();
|
|
303
1114
|
const candidates = [];
|
|
304
|
-
const path11 = getNodePath3();
|
|
305
|
-
const fs9 = getNodeFs2();
|
|
306
1115
|
for (const envVar of envVarNames) {
|
|
307
1116
|
const envPath = process.env[envVar];
|
|
308
1117
|
if (envPath) {
|
|
309
|
-
|
|
310
|
-
candidates.push(envPath + ".node");
|
|
311
|
-
} else {
|
|
312
|
-
candidates.push(envPath);
|
|
313
|
-
}
|
|
1118
|
+
candidates.push(enforceNodeExtensionForEnvPath && !envPath.endsWith(".node") ? envPath + ".node" : envPath);
|
|
314
1119
|
}
|
|
315
1120
|
}
|
|
316
1121
|
if (!includeDefaultCandidates) return candidates;
|
|
317
|
-
if (
|
|
1122
|
+
if (fs4__default.existsSync(runtimeDir)) {
|
|
318
1123
|
try {
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
if (entry.endsWith(".node")) {
|
|
322
|
-
candidates.push(entry);
|
|
323
|
-
}
|
|
1124
|
+
for (const entry of fs4__default.readdirSync(runtimeDir)) {
|
|
1125
|
+
if (entry.endsWith(".node")) candidates.push(entry);
|
|
324
1126
|
}
|
|
325
1127
|
} catch {
|
|
326
1128
|
}
|
|
327
1129
|
}
|
|
328
|
-
const
|
|
329
|
-
const
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
1130
|
+
const BINARY_NAMES = ["tailwind-styled-native", "tailwind_styled_parser"];
|
|
1131
|
+
const napiPlatform = process.platform === "linux" && process.arch === "x64" ? "linux-x64-gnu" : process.platform === "linux" && process.arch === "arm64" ? "linux-arm64-gnu" : `${process.platform}-${process.arch}`;
|
|
1132
|
+
for (const bin of BINARY_NAMES) {
|
|
1133
|
+
candidates.push(path6__default.resolve(runtimeDir, `${bin}.node`));
|
|
1134
|
+
candidates.push(path6__default.resolve(runtimeDir, `${bin}.${napiPlatform}.node`));
|
|
1135
|
+
candidates.push(path6__default.resolve(runtimeDir, "..", "..", "..", "..", "native", `${bin}.node`));
|
|
1136
|
+
candidates.push(path6__default.resolve(runtimeDir, "..", "..", "..", "..", "native", `${bin}.${napiPlatform}.node`));
|
|
1137
|
+
candidates.push(path6__default.resolve(runtimeDir, "..", "..", "..", "native", `${bin}.node`));
|
|
1138
|
+
candidates.push(path6__default.resolve(process.cwd(), "native", `${bin}.node`));
|
|
1139
|
+
candidates.push(path6__default.resolve(process.cwd(), "native", `${bin}.${napiPlatform}.node`));
|
|
1140
|
+
}
|
|
334
1141
|
return Array.from(new Set(candidates));
|
|
335
1142
|
}
|
|
336
1143
|
function resolveRuntimeDir(dir, importMetaUrl) {
|
|
337
|
-
if (
|
|
338
|
-
if (dir) return getNodePath3().resolve(dir);
|
|
1144
|
+
if (dir) return path6__default.resolve(dir);
|
|
339
1145
|
try {
|
|
340
|
-
return
|
|
1146
|
+
return path6__default.dirname(fileURLToPath(importMetaUrl));
|
|
341
1147
|
} catch {
|
|
342
1148
|
return process.cwd();
|
|
343
1149
|
}
|
|
344
1150
|
}
|
|
345
|
-
|
|
1151
|
+
function hashContent(content, algorithm = "md5", length) {
|
|
1152
|
+
const hash = createHash(algorithm).update(content).digest("hex");
|
|
1153
|
+
return length ? hash.slice(0, length) : hash;
|
|
1154
|
+
}
|
|
1155
|
+
function formatErrorMessage(error) {
|
|
1156
|
+
if (error instanceof TwError) return error.toString();
|
|
1157
|
+
if (error instanceof Error) return error.message;
|
|
1158
|
+
return String(error);
|
|
1159
|
+
}
|
|
1160
|
+
var TwError, _require2, LRUCache;
|
|
346
1161
|
var init_src = __esm({
|
|
347
1162
|
"packages/domain/shared/src/index.ts"() {
|
|
1163
|
+
init_trace();
|
|
1164
|
+
init_error_codes();
|
|
1165
|
+
init_compatibility();
|
|
1166
|
+
init_native_schemas();
|
|
348
1167
|
init_esmHelpers();
|
|
1168
|
+
init_telemetry();
|
|
1169
|
+
init_configSchemas();
|
|
1170
|
+
init_workerResolver();
|
|
1171
|
+
init_codegen();
|
|
349
1172
|
init_native_resolution();
|
|
350
|
-
|
|
351
|
-
nodeModuleRef3 = null;
|
|
352
|
-
_nodeFs2 = null;
|
|
353
|
-
_nodePath3 = null;
|
|
354
|
-
_nodeUrl2 = null;
|
|
1173
|
+
init_observability();
|
|
355
1174
|
TwError = class _TwError extends Error {
|
|
356
1175
|
/** @deprecated Gunakan source */
|
|
357
1176
|
domain;
|
|
@@ -385,8 +1204,8 @@ var init_src = __esm({
|
|
|
385
1204
|
/** Buat TwError dari ZodError — dukung shape Zod v3 (`errors`) dan v4 (`issues`). */
|
|
386
1205
|
static fromZod(err) {
|
|
387
1206
|
const first = err.issues?.[0] ?? err.errors?.[0];
|
|
388
|
-
const
|
|
389
|
-
const message = first ? `${
|
|
1207
|
+
const path13 = formatIssuePath(first?.path);
|
|
1208
|
+
const message = first ? `${path13}: ${first.message}` : "Schema validation failed";
|
|
390
1209
|
return new _TwError("validation", "SCHEMA_VALIDATION_FAILED", message, err);
|
|
391
1210
|
}
|
|
392
1211
|
static wrap(source, code, err) {
|
|
@@ -404,13 +1223,57 @@ var init_src = __esm({
|
|
|
404
1223
|
return `[${this.source.toUpperCase()}:${this.code}] ${this.message}`;
|
|
405
1224
|
}
|
|
406
1225
|
};
|
|
407
|
-
_require2 =
|
|
1226
|
+
_require2 = createRequire(import.meta.url);
|
|
1227
|
+
LRUCache = class {
|
|
1228
|
+
capacity;
|
|
1229
|
+
cache;
|
|
1230
|
+
constructor(capacity) {
|
|
1231
|
+
this.capacity = capacity;
|
|
1232
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
1233
|
+
}
|
|
1234
|
+
get(key) {
|
|
1235
|
+
if (!this.cache.has(key)) return void 0;
|
|
1236
|
+
const value = this.cache.get(key);
|
|
1237
|
+
this.cache.delete(key);
|
|
1238
|
+
this.cache.set(key, value);
|
|
1239
|
+
return value;
|
|
1240
|
+
}
|
|
1241
|
+
set(key, value) {
|
|
1242
|
+
if (this.cache.has(key)) {
|
|
1243
|
+
this.cache.delete(key);
|
|
1244
|
+
} else if (this.cache.size >= this.capacity) {
|
|
1245
|
+
const firstKey = this.cache.keys().next().value;
|
|
1246
|
+
if (firstKey !== void 0) {
|
|
1247
|
+
this.cache.delete(firstKey);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
this.cache.set(key, value);
|
|
1251
|
+
}
|
|
1252
|
+
delete(key) {
|
|
1253
|
+
return this.cache.delete(key);
|
|
1254
|
+
}
|
|
1255
|
+
has(key) {
|
|
1256
|
+
return this.cache.has(key);
|
|
1257
|
+
}
|
|
1258
|
+
clear() {
|
|
1259
|
+
this.cache.clear();
|
|
1260
|
+
}
|
|
1261
|
+
entries() {
|
|
1262
|
+
return this.cache.entries();
|
|
1263
|
+
}
|
|
1264
|
+
get size() {
|
|
1265
|
+
return this.cache.size;
|
|
1266
|
+
}
|
|
1267
|
+
};
|
|
408
1268
|
}
|
|
409
1269
|
});
|
|
410
|
-
|
|
1270
|
+
|
|
1271
|
+
// packages/domain/compiler/src/nativeBridge.ts
|
|
1272
|
+
var _loadNative, log, NATIVE_UNAVAILABLE_MESSAGE, nativeBridge, bridgeLoadAttempted, bridgeLoadError, isValidNativeBridge, getNativeBridge;
|
|
411
1273
|
var init_nativeBridge = __esm({
|
|
412
1274
|
"packages/domain/compiler/src/nativeBridge.ts"() {
|
|
413
1275
|
init_src();
|
|
1276
|
+
_loadNative = (path13) => __require(path13);
|
|
414
1277
|
log = (...args) => {
|
|
415
1278
|
if (process.env.DEBUG?.includes("compiler:native")) {
|
|
416
1279
|
console.log("[compiler:native]", ...args);
|
|
@@ -437,11 +1300,10 @@ var init_nativeBridge = __esm({
|
|
|
437
1300
|
bridgeLoadAttempted = true;
|
|
438
1301
|
try {
|
|
439
1302
|
const runtimeDir = resolveRuntimeDir(void 0, import.meta.url);
|
|
440
|
-
const require3 = createRequire(import.meta.url);
|
|
441
1303
|
const result = resolveNativeBinary(runtimeDir);
|
|
442
1304
|
if (result.path && result.path.endsWith(".node")) {
|
|
443
1305
|
try {
|
|
444
|
-
const binding =
|
|
1306
|
+
const binding = _loadNative(result.path);
|
|
445
1307
|
if (isValidNativeBridge(binding)) {
|
|
446
1308
|
nativeBridge = binding;
|
|
447
1309
|
log("Native bridge loaded successfully from:", result.path);
|
|
@@ -473,6 +1335,7 @@ Tried paths: ${result.tried.join("\n")}`);
|
|
|
473
1335
|
var tailwindEngine_exports = {};
|
|
474
1336
|
__export(tailwindEngine_exports, {
|
|
475
1337
|
generateRawCss: () => generateRawCss,
|
|
1338
|
+
processTailwindCssWithTargets: () => processTailwindCssWithTargets,
|
|
476
1339
|
runCssPipeline: () => runCssPipeline,
|
|
477
1340
|
runCssPipelineSync: () => runCssPipelineSync
|
|
478
1341
|
});
|
|
@@ -500,12 +1363,11 @@ function generateRawCss(classes) {
|
|
|
500
1363
|
function postProcessWithLightning(rawCss) {
|
|
501
1364
|
if (!rawCss) return "";
|
|
502
1365
|
const native = getNativeBridge();
|
|
503
|
-
if (typeof native.processTailwindCssLightning
|
|
504
|
-
|
|
505
|
-
return result?.css ?? rawCss;
|
|
1366
|
+
if (typeof native.processTailwindCssLightning !== "function") {
|
|
1367
|
+
throw new Error("FATAL: Native binding 'processTailwindCssLightning' is required but not available.");
|
|
506
1368
|
}
|
|
507
|
-
|
|
508
|
-
return rawCss;
|
|
1369
|
+
const result = native.processTailwindCssLightning(rawCss);
|
|
1370
|
+
return result?.css ?? rawCss;
|
|
509
1371
|
}
|
|
510
1372
|
async function runCssPipeline(classes) {
|
|
511
1373
|
const unique = [...new Set(classes.filter(Boolean))];
|
|
@@ -539,6 +1401,14 @@ function runCssPipelineSync(classes) {
|
|
|
539
1401
|
optimized: hasLightning
|
|
540
1402
|
};
|
|
541
1403
|
}
|
|
1404
|
+
function processTailwindCssWithTargets(css, targets) {
|
|
1405
|
+
const native = getNativeBridge();
|
|
1406
|
+
if (!native?.processTailwindCssWithTargets) {
|
|
1407
|
+
throw new Error("FATAL: Native binding 'processTailwindCssWithTargets' is required but not available.");
|
|
1408
|
+
}
|
|
1409
|
+
const result = native.processTailwindCssWithTargets(css, targets ?? null);
|
|
1410
|
+
return (result?.css ?? css).trim();
|
|
1411
|
+
}
|
|
542
1412
|
var require2, _twEngine, _twEngineError;
|
|
543
1413
|
var init_tailwindEngine = __esm({
|
|
544
1414
|
"packages/domain/compiler/src/tailwindEngine.ts"() {
|
|
@@ -552,14 +1422,26 @@ var init_tailwindEngine = __esm({
|
|
|
552
1422
|
// packages/domain/scanner/src/native-bridge.ts
|
|
553
1423
|
var native_bridge_exports = {};
|
|
554
1424
|
__export(native_bridge_exports, {
|
|
1425
|
+
batchExtractClassesNative: () => batchExtractClassesNative,
|
|
555
1426
|
cachePriorityNative: () => cachePriorityNative,
|
|
556
1427
|
cacheReadNative: () => cacheReadNative,
|
|
557
1428
|
cacheWriteNative: () => cacheWriteNative,
|
|
1429
|
+
collectFilesNative: () => collectFilesNative,
|
|
1430
|
+
computeCacheStatsNative: () => computeCacheStatsNative,
|
|
558
1431
|
extractClassesNative: () => extractClassesNative,
|
|
1432
|
+
generateSubComponentTypesNative: () => generateSubComponentTypesNative,
|
|
559
1433
|
hasNativeScannerBinding: () => hasNativeScannerBinding,
|
|
560
1434
|
hashContentNative: () => hashContentNative,
|
|
561
1435
|
isRustCacheAvailable: () => isRustCacheAvailable,
|
|
1436
|
+
pruneStaleEntriesNative: () => pruneStaleEntriesNative,
|
|
1437
|
+
rebuildWorkspaceResultNative: () => rebuildWorkspaceResultNative,
|
|
562
1438
|
resetScannerBridgeCache: () => resetScannerBridgeCache,
|
|
1439
|
+
scanCacheGet: () => scanCacheGet,
|
|
1440
|
+
scanCacheInvalidate: () => scanCacheInvalidate,
|
|
1441
|
+
scanCachePut: () => scanCachePut,
|
|
1442
|
+
scanCacheStats: () => scanCacheStats,
|
|
1443
|
+
scanFileNative: () => scanFileNative,
|
|
1444
|
+
scanFilesBatchNative: () => scanFilesBatchNative,
|
|
563
1445
|
scanWorkspaceNative: () => scanWorkspaceNative
|
|
564
1446
|
});
|
|
565
1447
|
function getDirname2() {
|
|
@@ -567,7 +1449,7 @@ function getDirname2() {
|
|
|
567
1449
|
return __dirname;
|
|
568
1450
|
}
|
|
569
1451
|
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
570
|
-
return
|
|
1452
|
+
return path6__default.dirname(fileURLToPath(import.meta.url));
|
|
571
1453
|
}
|
|
572
1454
|
return process.cwd();
|
|
573
1455
|
}
|
|
@@ -648,6 +1530,95 @@ function cachePriorityNative(mtimeMs, size, cachedMtimeMs, cachedSize, cachedHit
|
|
|
648
1530
|
}
|
|
649
1531
|
return result;
|
|
650
1532
|
}
|
|
1533
|
+
function batchExtractClassesNative(filePaths) {
|
|
1534
|
+
const binding = scannerGetBinding();
|
|
1535
|
+
if (!binding.batchExtractClasses) {
|
|
1536
|
+
throw new Error("FATAL: Native binding 'batchExtractClasses' is required but not available.");
|
|
1537
|
+
}
|
|
1538
|
+
return binding.batchExtractClasses(filePaths) ?? [];
|
|
1539
|
+
}
|
|
1540
|
+
function scanCacheGet(filePath, contentHash) {
|
|
1541
|
+
const binding = scannerGetBinding();
|
|
1542
|
+
if (!binding.scanCacheGet) {
|
|
1543
|
+
throw new Error("FATAL: Native binding 'scanCacheGet' is required but not available.");
|
|
1544
|
+
}
|
|
1545
|
+
return binding.scanCacheGet(filePath, contentHash) ?? null;
|
|
1546
|
+
}
|
|
1547
|
+
function scanCachePut(filePath, contentHash, classes, mtimeMs, size) {
|
|
1548
|
+
const binding = scannerGetBinding();
|
|
1549
|
+
if (!binding.scanCachePut) {
|
|
1550
|
+
throw new Error("FATAL: Native binding 'scanCachePut' is required but not available.");
|
|
1551
|
+
}
|
|
1552
|
+
binding.scanCachePut(filePath, contentHash, classes, mtimeMs, size);
|
|
1553
|
+
}
|
|
1554
|
+
function scanCacheInvalidate(filePath) {
|
|
1555
|
+
const binding = scannerGetBinding();
|
|
1556
|
+
if (!binding.scanCacheInvalidate) {
|
|
1557
|
+
throw new Error("FATAL: Native binding 'scanCacheInvalidate' is required but not available.");
|
|
1558
|
+
}
|
|
1559
|
+
binding.scanCacheInvalidate(filePath);
|
|
1560
|
+
}
|
|
1561
|
+
function scanCacheStats() {
|
|
1562
|
+
const binding = scannerGetBinding();
|
|
1563
|
+
if (!binding.scanCacheStats) {
|
|
1564
|
+
throw new Error("FATAL: Native binding 'scanCacheStats' is required but not available.");
|
|
1565
|
+
}
|
|
1566
|
+
return binding.scanCacheStats();
|
|
1567
|
+
}
|
|
1568
|
+
function scanFileNative(filePath) {
|
|
1569
|
+
const binding = scannerGetBinding();
|
|
1570
|
+
if (!binding.scanFile) {
|
|
1571
|
+
throw new Error("FATAL: Native binding 'scanFile' is required but not available.");
|
|
1572
|
+
}
|
|
1573
|
+
return binding.scanFile(filePath);
|
|
1574
|
+
}
|
|
1575
|
+
function collectFilesNative(root, extensions, ignoreDirs) {
|
|
1576
|
+
const binding = scannerGetBinding();
|
|
1577
|
+
if (!binding.collectFiles) return null;
|
|
1578
|
+
return binding.collectFiles(root, extensions, ignoreDirs);
|
|
1579
|
+
}
|
|
1580
|
+
function scanFilesBatchNative(filePaths) {
|
|
1581
|
+
const binding = scannerGetBinding();
|
|
1582
|
+
if (!binding.scanFilesBatch) {
|
|
1583
|
+
return filePaths.map((fp) => {
|
|
1584
|
+
try {
|
|
1585
|
+
const r = binding.scanFile?.(fp);
|
|
1586
|
+
return r ? { file: r.file, classes: r.classes, hash: r.hash ?? "" } : { file: fp, classes: [], hash: "" };
|
|
1587
|
+
} catch {
|
|
1588
|
+
return { file: fp, classes: [], hash: "" };
|
|
1589
|
+
}
|
|
1590
|
+
});
|
|
1591
|
+
}
|
|
1592
|
+
return binding.scanFilesBatch(filePaths);
|
|
1593
|
+
}
|
|
1594
|
+
function generateSubComponentTypesNative(root, outputPath) {
|
|
1595
|
+
const binding = scannerGetBinding();
|
|
1596
|
+
if (!binding.generateSubComponentTypes) return null;
|
|
1597
|
+
return binding.generateSubComponentTypes(root, outputPath ?? null);
|
|
1598
|
+
}
|
|
1599
|
+
function pruneStaleEntriesNative(entries, maxAgeMs, checkExists) {
|
|
1600
|
+
const binding = scannerGetBinding();
|
|
1601
|
+
if (!binding.pruneStaleEntries) return null;
|
|
1602
|
+
return binding.pruneStaleEntries(
|
|
1603
|
+
entries.map((e) => ({ file: e.file, lastSeenMs: e.lastSeenMs ?? 0 })),
|
|
1604
|
+
maxAgeMs ?? null,
|
|
1605
|
+
checkExists ?? null
|
|
1606
|
+
);
|
|
1607
|
+
}
|
|
1608
|
+
function rebuildWorkspaceResultNative(files) {
|
|
1609
|
+
const binding = scannerBridgeLoader.get();
|
|
1610
|
+
if (!binding?.rebuildWorkspaceResult) return null;
|
|
1611
|
+
try {
|
|
1612
|
+
return binding.rebuildWorkspaceResult(files);
|
|
1613
|
+
} catch {
|
|
1614
|
+
return null;
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
function computeCacheStatsNative(filesClasses, sizes, top) {
|
|
1618
|
+
const binding = scannerGetBinding();
|
|
1619
|
+
if (!binding.computeCacheStats) return null;
|
|
1620
|
+
return binding.computeCacheStats(filesClasses, sizes, top ?? null);
|
|
1621
|
+
}
|
|
651
1622
|
var log2, isValidScannerBinding, createScannerBridgeLoader, scannerBridgeLoader, scannerGetBinding, resetScannerBridgeCache;
|
|
652
1623
|
var init_native_bridge = __esm({
|
|
653
1624
|
"packages/domain/scanner/src/native-bridge.ts"() {
|
|
@@ -731,74 +1702,9 @@ var init_native_bridge = __esm({
|
|
|
731
1702
|
resetScannerBridgeCache = scannerBridgeLoader.reset;
|
|
732
1703
|
}
|
|
733
1704
|
});
|
|
734
|
-
|
|
735
|
-
// packages/domain/compiler/src/index.ts
|
|
736
|
-
init_nativeBridge();
|
|
737
|
-
var transformSource = (source, opts) => {
|
|
738
|
-
const native = getNativeBridge();
|
|
739
|
-
if (!native?.transformSource) {
|
|
740
|
-
throw new Error("FATAL: Native binding 'transformSource' is required but not available.");
|
|
741
|
-
}
|
|
742
|
-
const result = native.transformSource(source, opts);
|
|
743
|
-
if (!result) {
|
|
744
|
-
throw new Error("FATAL: transformSource returned null");
|
|
745
|
-
}
|
|
746
|
-
return result;
|
|
747
|
-
};
|
|
748
|
-
var generateCssForClasses = async (classes, _tailwindConfig, _root) => {
|
|
749
|
-
const { runCssPipeline: runCssPipeline2 } = await Promise.resolve().then(() => (init_tailwindEngine(), tailwindEngine_exports));
|
|
750
|
-
const result = await runCssPipeline2(classes);
|
|
751
|
-
return result.css;
|
|
752
|
-
};
|
|
753
|
-
var mergeClassesStatic = (classes) => {
|
|
754
|
-
const result = normalizeAndDedupClasses(classes);
|
|
755
|
-
return result?.normalized || "";
|
|
756
|
-
};
|
|
757
|
-
function normalizeAndDedupClassesJs(raw) {
|
|
758
|
-
const seen = /* @__PURE__ */ new Set();
|
|
759
|
-
const result = [];
|
|
760
|
-
let duplicatesRemoved = 0;
|
|
761
|
-
for (const token of raw.split(/\s+/)) {
|
|
762
|
-
if (token.length === 0) continue;
|
|
763
|
-
if (seen.has(token)) {
|
|
764
|
-
duplicatesRemoved++;
|
|
765
|
-
} else {
|
|
766
|
-
seen.add(token);
|
|
767
|
-
result.push(token);
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
return {
|
|
771
|
-
normalized: result.join(" "),
|
|
772
|
-
duplicatesRemoved,
|
|
773
|
-
uniqueCount: result.length
|
|
774
|
-
};
|
|
775
|
-
}
|
|
776
|
-
var normalizeAndDedupClasses = (raw) => {
|
|
777
|
-
const native = getNativeBridge();
|
|
778
|
-
if (!native?.normalizeAndDedupClasses) {
|
|
779
|
-
return normalizeAndDedupClassesJs(raw);
|
|
780
|
-
}
|
|
781
|
-
const result = native.normalizeAndDedupClasses(raw);
|
|
782
|
-
return result || { normalized: "", duplicatesRemoved: 0, uniqueCount: 0 };
|
|
783
|
-
};
|
|
784
|
-
var runLoaderTransform = (ctx) => {
|
|
785
|
-
const { filepath, source, options } = ctx;
|
|
786
|
-
const result = transformSource(source, { filename: filepath, ...options });
|
|
787
|
-
return {
|
|
788
|
-
code: result?.code || "",
|
|
789
|
-
changed: result?.changed || false,
|
|
790
|
-
classes: result?.classes || []
|
|
791
|
-
};
|
|
792
|
-
};
|
|
793
|
-
|
|
794
|
-
// packages/domain/scanner/src/index.ts
|
|
795
|
-
init_src();
|
|
796
|
-
|
|
797
|
-
// packages/domain/scanner/src/cache-native.ts
|
|
798
|
-
init_native_bridge();
|
|
799
1705
|
function defaultCachePath(rootDir, cacheDir) {
|
|
800
|
-
const dir = cacheDir ?
|
|
801
|
-
return
|
|
1706
|
+
const dir = cacheDir ? path6__default.resolve(rootDir, cacheDir) : path6__default.join(process.cwd(), ".cache", "tailwind-styled");
|
|
1707
|
+
return path6__default.join(dir, "scanner-cache.json");
|
|
802
1708
|
}
|
|
803
1709
|
function readCache(rootDir, cacheDir) {
|
|
804
1710
|
const cachePath = defaultCachePath(rootDir, cacheDir);
|
|
@@ -834,158 +1740,219 @@ function filePriority(mtimeMs, size, cached, nowMs = Date.now()) {
|
|
|
834
1740
|
nowMs
|
|
835
1741
|
);
|
|
836
1742
|
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
init_native_bridge();
|
|
840
|
-
|
|
841
|
-
// packages/domain/scanner/src/schemas.ts
|
|
842
|
-
init_src();
|
|
843
|
-
var formatIssuePath2 = (path11) => path11.length > 0 ? path11.map(
|
|
844
|
-
(segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
|
|
845
|
-
).join(".") : "<root>";
|
|
846
|
-
var formatIssues = (error) => error.issues.map((issue) => {
|
|
847
|
-
const path11 = formatIssuePath2(issue.path);
|
|
848
|
-
return `${path11}: ${issue.message}`;
|
|
849
|
-
}).join("; ");
|
|
850
|
-
var parseWithSchema = (schema, data, label) => {
|
|
851
|
-
const parsed = schema.safeParse(data);
|
|
852
|
-
if (parsed.success) return parsed.data;
|
|
853
|
-
const details = formatIssues(parsed.error);
|
|
854
|
-
throw new TwError(
|
|
855
|
-
"validation",
|
|
856
|
-
"SCHEMA_VALIDATION_FAILED",
|
|
857
|
-
details ? `${label}: ${details}` : label,
|
|
858
|
-
parsed.error
|
|
859
|
-
);
|
|
860
|
-
};
|
|
861
|
-
var NonNegativeIntegerSchema = z.number().int().min(0);
|
|
862
|
-
var ScanWorkspaceOptionsSchema = z.object({
|
|
863
|
-
includeExtensions: z.array(z.string()).optional(),
|
|
864
|
-
ignoreDirectories: z.array(z.string()).optional(),
|
|
865
|
-
useCache: z.boolean().optional(),
|
|
866
|
-
cacheDir: z.string().min(1).optional(),
|
|
867
|
-
smartInvalidation: z.boolean().optional()
|
|
868
|
-
});
|
|
869
|
-
var ScanFileResultSchema = z.object({
|
|
870
|
-
file: z.string(),
|
|
871
|
-
classes: z.array(z.string()),
|
|
872
|
-
hash: z.string().optional()
|
|
873
|
-
});
|
|
874
|
-
var ScanWorkspaceResultSchema = z.object({
|
|
875
|
-
files: z.array(ScanFileResultSchema),
|
|
876
|
-
totalFiles: NonNegativeIntegerSchema,
|
|
877
|
-
uniqueClasses: z.array(z.string())
|
|
878
|
-
}).refine((value) => value.totalFiles === value.files.length, {
|
|
879
|
-
message: "scan result totalFiles must match files.length",
|
|
880
|
-
path: ["totalFiles"]
|
|
881
|
-
});
|
|
882
|
-
z.object({
|
|
883
|
-
rootDir: z.string().min(1),
|
|
884
|
-
options: ScanWorkspaceOptionsSchema.optional()
|
|
1743
|
+
var init_cache_native = __esm({
|
|
1744
|
+
"packages/domain/scanner/src/cache-native.ts"() {
|
|
1745
|
+
init_native_bridge();
|
|
1746
|
+
}
|
|
885
1747
|
});
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
1748
|
+
function collectFiles(rootDir, extensions, ignoreDirs) {
|
|
1749
|
+
const native = collectFilesNative(rootDir, extensions, ignoreDirs);
|
|
1750
|
+
if (native !== null) return native;
|
|
1751
|
+
const files = [];
|
|
1752
|
+
function walk(dir) {
|
|
1753
|
+
let entries;
|
|
1754
|
+
try {
|
|
1755
|
+
entries = fs4__default.readdirSync(dir, { withFileTypes: true });
|
|
1756
|
+
} catch {
|
|
1757
|
+
return;
|
|
1758
|
+
}
|
|
1759
|
+
for (const entry of entries) {
|
|
1760
|
+
const fullPath = path6__default.join(dir, entry.name);
|
|
1761
|
+
const rel = path6__default.relative(rootDir, fullPath);
|
|
1762
|
+
if (entry.isDirectory()) {
|
|
1763
|
+
const ignored = ignoreDirs.some((d) => entry.name === d || rel.startsWith(d + path6__default.sep));
|
|
1764
|
+
if (!ignored) walk(fullPath);
|
|
1765
|
+
} else if (isScannableFile(entry.name, extensions)) {
|
|
1766
|
+
files.push(fullPath);
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
walk(rootDir);
|
|
1771
|
+
return files;
|
|
1772
|
+
}
|
|
1773
|
+
function mergeResults(batchResults) {
|
|
1774
|
+
const files = batchResults.map((r) => ({
|
|
1775
|
+
file: r.file,
|
|
1776
|
+
classes: r.classes,
|
|
1777
|
+
hash: r.content_hash
|
|
1778
|
+
}));
|
|
1779
|
+
const native = rebuildWorkspaceResultNative(files);
|
|
1780
|
+
if (native) return native;
|
|
1781
|
+
const unique = new Set(files.flatMap((f) => f.classes));
|
|
1782
|
+
return { files, totalFiles: files.length, uniqueClasses: Array.from(unique).sort() };
|
|
1783
|
+
}
|
|
1784
|
+
function runChunkInWorker(filePaths) {
|
|
1785
|
+
return new Promise((resolve2, reject) => {
|
|
1786
|
+
const worker = new Worker(_workerFilename, {
|
|
1787
|
+
workerData: { filePaths }
|
|
1788
|
+
});
|
|
1789
|
+
worker.once("message", (payload) => {
|
|
1790
|
+
if (payload.ok) {
|
|
1791
|
+
resolve2(payload.results);
|
|
1792
|
+
} else {
|
|
1793
|
+
reject(new Error(payload.error ?? "parallel-scanner worker failed"));
|
|
1794
|
+
}
|
|
1795
|
+
});
|
|
1796
|
+
worker.once("error", reject);
|
|
1797
|
+
worker.once("exit", (code) => {
|
|
1798
|
+
if (code !== 0) reject(new Error(`parallel-scanner worker exited with code ${code}`));
|
|
1799
|
+
});
|
|
1800
|
+
});
|
|
1801
|
+
}
|
|
1802
|
+
async function scanWorkspaceParallel(rootDir, options = {}) {
|
|
1803
|
+
const {
|
|
1804
|
+
extensions = DEFAULT_EXTENSIONS,
|
|
1805
|
+
ignoreDirs = DEFAULT_IGNORES,
|
|
1806
|
+
maxWorkers = Math.max(1, availableParallelism() - 1),
|
|
1807
|
+
chunkSize = DEFAULT_CHUNK_SIZE
|
|
1808
|
+
} = options;
|
|
1809
|
+
const files = collectFiles(path6__default.resolve(rootDir), extensions, ignoreDirs);
|
|
1810
|
+
if (files.length < PARALLEL_THRESHOLD) {
|
|
1811
|
+
return mergeResults(batchExtractClassesNative(files));
|
|
1812
|
+
}
|
|
1813
|
+
const chunks = [];
|
|
1814
|
+
for (let i = 0; i < files.length; i += chunkSize) {
|
|
1815
|
+
chunks.push(files.slice(i, i + chunkSize));
|
|
1816
|
+
}
|
|
1817
|
+
const allResults = [];
|
|
1818
|
+
for (let i = 0; i < chunks.length; i += maxWorkers) {
|
|
1819
|
+
const batch = chunks.slice(i, i + maxWorkers);
|
|
1820
|
+
const batchResults = await Promise.all(batch.map(runChunkInWorker));
|
|
1821
|
+
allResults.push(...batchResults.flat());
|
|
1822
|
+
}
|
|
1823
|
+
return mergeResults(allResults);
|
|
1824
|
+
}
|
|
1825
|
+
var PARALLEL_THRESHOLD, DEFAULT_CHUNK_SIZE, _workerFilename;
|
|
1826
|
+
var init_parallel_scanner = __esm({
|
|
1827
|
+
"packages/domain/scanner/src/parallel-scanner.ts"() {
|
|
1828
|
+
init_src2();
|
|
1829
|
+
init_native_bridge();
|
|
1830
|
+
PARALLEL_THRESHOLD = 50;
|
|
1831
|
+
DEFAULT_CHUNK_SIZE = 150;
|
|
1832
|
+
if (!isMainThread && parentPort) {
|
|
1833
|
+
const { filePaths } = workerData;
|
|
1834
|
+
try {
|
|
1835
|
+
const results = batchExtractClassesNative(filePaths);
|
|
1836
|
+
const msg = { ok: true, results };
|
|
1837
|
+
parentPort.postMessage(msg);
|
|
1838
|
+
} catch (error) {
|
|
1839
|
+
const msg = {
|
|
1840
|
+
ok: false,
|
|
1841
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1842
|
+
};
|
|
1843
|
+
parentPort.postMessage(msg);
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
_workerFilename = typeof __filename !== "undefined" ? __filename : fileURLToPath(import.meta.url);
|
|
1847
|
+
}
|
|
889
1848
|
});
|
|
890
|
-
var ScannerWorkerErrorMessageSchema
|
|
891
|
-
|
|
892
|
-
|
|
1849
|
+
var formatIssuePath2, formatIssues, parseWithSchema, NonNegativeIntegerSchema, ScanWorkspaceOptionsSchema, ScanFileResultSchema, ScanWorkspaceResultSchema, ScannerWorkerSuccessMessageSchema, ScannerWorkerErrorMessageSchema, ScannerWorkerMessageSchema, parseScanWorkspaceOptions, parseScanWorkspaceResult, parseScannerWorkerMessage;
|
|
1850
|
+
var init_schemas = __esm({
|
|
1851
|
+
"packages/domain/scanner/src/schemas.ts"() {
|
|
1852
|
+
init_src();
|
|
1853
|
+
formatIssuePath2 = (path13) => path13.length > 0 ? path13.map(
|
|
1854
|
+
(segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
|
|
1855
|
+
).join(".") : "<root>";
|
|
1856
|
+
formatIssues = (error) => error.issues.map((issue) => {
|
|
1857
|
+
const path13 = formatIssuePath2(issue.path);
|
|
1858
|
+
return `${path13}: ${issue.message}`;
|
|
1859
|
+
}).join("; ");
|
|
1860
|
+
parseWithSchema = (schema, data, label) => {
|
|
1861
|
+
const parsed = schema.safeParse(data);
|
|
1862
|
+
if (parsed.success) return parsed.data;
|
|
1863
|
+
const details = formatIssues(parsed.error);
|
|
1864
|
+
throw new TwError(
|
|
1865
|
+
"validation",
|
|
1866
|
+
"SCHEMA_VALIDATION_FAILED",
|
|
1867
|
+
details ? `${label}: ${details}` : label,
|
|
1868
|
+
parsed.error
|
|
1869
|
+
);
|
|
1870
|
+
};
|
|
1871
|
+
NonNegativeIntegerSchema = z.number().int().min(0);
|
|
1872
|
+
ScanWorkspaceOptionsSchema = z.object({
|
|
1873
|
+
includeExtensions: z.array(z.string()).optional(),
|
|
1874
|
+
ignoreDirectories: z.array(z.string()).optional(),
|
|
1875
|
+
useCache: z.boolean().optional(),
|
|
1876
|
+
cacheDir: z.string().min(1).optional(),
|
|
1877
|
+
smartInvalidation: z.boolean().optional()
|
|
1878
|
+
});
|
|
1879
|
+
ScanFileResultSchema = z.object({
|
|
1880
|
+
file: z.string(),
|
|
1881
|
+
classes: z.array(z.string()),
|
|
1882
|
+
hash: z.string().optional()
|
|
1883
|
+
});
|
|
1884
|
+
ScanWorkspaceResultSchema = z.object({
|
|
1885
|
+
files: z.array(ScanFileResultSchema),
|
|
1886
|
+
totalFiles: NonNegativeIntegerSchema,
|
|
1887
|
+
uniqueClasses: z.array(z.string())
|
|
1888
|
+
}).refine((value) => value.totalFiles === value.files.length, {
|
|
1889
|
+
message: "scan result totalFiles must match files.length",
|
|
1890
|
+
path: ["totalFiles"]
|
|
1891
|
+
});
|
|
1892
|
+
z.object({
|
|
1893
|
+
rootDir: z.string().min(1),
|
|
1894
|
+
options: ScanWorkspaceOptionsSchema.optional()
|
|
1895
|
+
});
|
|
1896
|
+
ScannerWorkerSuccessMessageSchema = z.object({
|
|
1897
|
+
ok: z.literal(true),
|
|
1898
|
+
result: ScanWorkspaceResultSchema
|
|
1899
|
+
});
|
|
1900
|
+
ScannerWorkerErrorMessageSchema = z.object({
|
|
1901
|
+
ok: z.literal(false),
|
|
1902
|
+
error: z.string().optional()
|
|
1903
|
+
});
|
|
1904
|
+
ScannerWorkerMessageSchema = z.union([
|
|
1905
|
+
ScannerWorkerSuccessMessageSchema,
|
|
1906
|
+
ScannerWorkerErrorMessageSchema
|
|
1907
|
+
]);
|
|
1908
|
+
parseScanWorkspaceOptions = (options) => parseWithSchema(ScanWorkspaceOptionsSchema, options ?? {}, "scanner options are invalid");
|
|
1909
|
+
parseScanWorkspaceResult = (result) => parseWithSchema(ScanWorkspaceResultSchema, result, "scanner workspace result is invalid");
|
|
1910
|
+
parseScannerWorkerMessage = (message) => parseWithSchema(ScannerWorkerMessageSchema, message, "scanner worker message is invalid");
|
|
1911
|
+
}
|
|
893
1912
|
});
|
|
894
|
-
var ScannerWorkerMessageSchema = z.union([
|
|
895
|
-
ScannerWorkerSuccessMessageSchema,
|
|
896
|
-
ScannerWorkerErrorMessageSchema
|
|
897
|
-
]);
|
|
898
|
-
var parseScanWorkspaceOptions = (options) => parseWithSchema(ScanWorkspaceOptionsSchema, options ?? {}, "scanner options are invalid");
|
|
899
|
-
var parseScanWorkspaceResult = (result) => parseWithSchema(ScanWorkspaceResultSchema, result, "scanner workspace result is invalid");
|
|
900
|
-
var parseScannerWorkerMessage = (message) => parseWithSchema(ScannerWorkerMessageSchema, message, "scanner worker message is invalid");
|
|
901
1913
|
|
|
902
1914
|
// packages/domain/scanner/src/index.ts
|
|
903
|
-
var
|
|
904
|
-
|
|
1915
|
+
var src_exports2 = {};
|
|
1916
|
+
__export(src_exports2, {
|
|
1917
|
+
DEFAULT_EXTENSIONS: () => DEFAULT_EXTENSIONS,
|
|
1918
|
+
DEFAULT_IGNORES: () => DEFAULT_IGNORES,
|
|
1919
|
+
batchExtractClassesNative: () => batchExtractClassesNative,
|
|
1920
|
+
extractClassesNative: () => extractClassesNative,
|
|
1921
|
+
isScannableFile: () => isScannableFile,
|
|
1922
|
+
parseScanWorkspaceOptions: () => parseScanWorkspaceOptions,
|
|
1923
|
+
parseScanWorkspaceResult: () => parseScanWorkspaceResult,
|
|
1924
|
+
parseScannerWorkerMessage: () => parseScannerWorkerMessage,
|
|
1925
|
+
scanFile: () => scanFile,
|
|
1926
|
+
scanSource: () => scanSource,
|
|
1927
|
+
scanWorkspace: () => scanWorkspace,
|
|
1928
|
+
scanWorkspaceAsync: () => scanWorkspaceAsync
|
|
1929
|
+
});
|
|
905
1930
|
function getRuntimeDir() {
|
|
906
1931
|
if (typeof __dirname !== "undefined" && __dirname.length > 0) {
|
|
907
1932
|
return __dirname;
|
|
908
1933
|
}
|
|
909
1934
|
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
910
|
-
return
|
|
1935
|
+
return path6__default.dirname(fileURLToPath(import.meta.url));
|
|
911
1936
|
}
|
|
912
1937
|
return process.cwd();
|
|
913
|
-
}
|
|
914
|
-
var createNativeParserLoader = () => {
|
|
915
|
-
const _state = {
|
|
916
|
-
binding: void 0,
|
|
917
|
-
initError: null
|
|
918
|
-
};
|
|
919
|
-
const debugNative = (message) => {
|
|
920
|
-
log3.debug(`[native] ${message}`);
|
|
921
|
-
};
|
|
922
|
-
const loadNativeParserBinding = () => {
|
|
923
|
-
if (_state.binding !== void 0) return _state.binding;
|
|
924
|
-
const runtimeDir = getRuntimeDir();
|
|
925
|
-
const req = createRequire(path3.join(runtimeDir, "noop.cjs"));
|
|
926
|
-
const candidates = [
|
|
927
|
-
path3.resolve(process.cwd(), "native/tailwind_styled_parser.node"),
|
|
928
|
-
path3.resolve(process.cwd(), "native/build/Release/tailwind_styled_parser.node"),
|
|
929
|
-
path3.resolve(runtimeDir, "..", "..", "..", "native", "tailwind_styled_parser.node"),
|
|
930
|
-
path3.resolve(
|
|
931
|
-
runtimeDir,
|
|
932
|
-
"..",
|
|
933
|
-
"..",
|
|
934
|
-
"..",
|
|
935
|
-
"native",
|
|
936
|
-
"build",
|
|
937
|
-
"Release",
|
|
938
|
-
"tailwind_styled_parser.node"
|
|
939
|
-
)
|
|
940
|
-
];
|
|
941
|
-
for (const fullPath of candidates) {
|
|
942
|
-
if (!fs.existsSync(fullPath)) continue;
|
|
943
|
-
try {
|
|
944
|
-
const required = req(fullPath);
|
|
945
|
-
if (required && (typeof required.extractClassesFromSource === "function" || typeof required.parseClasses === "function" || typeof required.parse_classes === "function")) {
|
|
946
|
-
_state.binding = required;
|
|
947
|
-
debugNative(`using native parser from ${fullPath}`);
|
|
948
|
-
return _state.binding;
|
|
949
|
-
}
|
|
950
|
-
} catch (error) {
|
|
951
|
-
_state.initError = error instanceof Error ? error.message : String(error);
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
_state.binding = null;
|
|
955
|
-
if (!_state.initError) {
|
|
956
|
-
_state.initError = "native .node binding not found";
|
|
957
|
-
}
|
|
958
|
-
debugNative(`native binding not available: ${_state.initError}`);
|
|
959
|
-
return _state.binding;
|
|
960
|
-
};
|
|
961
|
-
return {
|
|
962
|
-
get: loadNativeParserBinding,
|
|
963
|
-
reset: () => {
|
|
964
|
-
_state.binding = void 0;
|
|
965
|
-
_state.initError = null;
|
|
966
|
-
}
|
|
967
|
-
};
|
|
968
|
-
};
|
|
969
|
-
var nativeParserLoader = createNativeParserLoader();
|
|
970
|
-
var DEFAULT_EXTENSIONS = [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
971
|
-
var DEFAULT_IGNORES = ["node_modules", ".git", ".next", "dist", "out", ".turbo", ".cache"];
|
|
1938
|
+
}
|
|
972
1939
|
function resolveScannerWorkerModulePath() {
|
|
973
1940
|
const runtimeDir = (() => {
|
|
974
1941
|
if (typeof __dirname !== "undefined" && __dirname.length > 0) {
|
|
975
1942
|
return __dirname;
|
|
976
1943
|
}
|
|
977
1944
|
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
978
|
-
return
|
|
1945
|
+
return path6__default.dirname(fileURLToPath(import.meta.url));
|
|
979
1946
|
}
|
|
980
1947
|
return process.cwd();
|
|
981
1948
|
})();
|
|
982
1949
|
const candidates = [
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1950
|
+
path6__default.resolve(runtimeDir, "worker.cjs"),
|
|
1951
|
+
path6__default.resolve(runtimeDir, "worker.js"),
|
|
1952
|
+
path6__default.resolve(runtimeDir, "worker.ts")
|
|
986
1953
|
];
|
|
987
1954
|
for (const candidate of candidates) {
|
|
988
|
-
if (
|
|
1955
|
+
if (fs4__default.existsSync(candidate)) return candidate;
|
|
989
1956
|
}
|
|
990
1957
|
return null;
|
|
991
1958
|
}
|
|
@@ -995,7 +1962,7 @@ function scanWorkspaceInWorker(rootDir, options) {
|
|
|
995
1962
|
if (!modulePath) {
|
|
996
1963
|
return Promise.reject(new Error("scanner worker module path could not be resolved"));
|
|
997
1964
|
}
|
|
998
|
-
return new Promise((
|
|
1965
|
+
return new Promise((resolve2, reject) => {
|
|
999
1966
|
const settleState = { settled: false };
|
|
1000
1967
|
const worker = new Worker(modulePath, { workerData: { rootDir, options: normalizedOptions } });
|
|
1001
1968
|
const timeout = setTimeout(() => {
|
|
@@ -1015,7 +1982,7 @@ function scanWorkspaceInWorker(rootDir, options) {
|
|
|
1015
1982
|
const message = parseScannerWorkerMessage(payload);
|
|
1016
1983
|
finish(() => {
|
|
1017
1984
|
if (message?.ok) {
|
|
1018
|
-
|
|
1985
|
+
resolve2(parseScanWorkspaceResult(message.result));
|
|
1019
1986
|
return;
|
|
1020
1987
|
}
|
|
1021
1988
|
reject(new Error(message?.error ?? "scanner worker failed without an error message"));
|
|
@@ -1042,19 +2009,19 @@ function collectCandidates(rootDir, ignoreDirectories, extensionSet) {
|
|
|
1042
2009
|
if (!currentDir) continue;
|
|
1043
2010
|
const entries = (() => {
|
|
1044
2011
|
try {
|
|
1045
|
-
return
|
|
2012
|
+
return fs4__default.readdirSync(currentDir, { withFileTypes: true });
|
|
1046
2013
|
} catch {
|
|
1047
2014
|
return [];
|
|
1048
2015
|
}
|
|
1049
2016
|
})();
|
|
1050
2017
|
for (const entry of entries) {
|
|
1051
|
-
const fullPath =
|
|
2018
|
+
const fullPath = path6__default.join(currentDir, entry.name);
|
|
1052
2019
|
if (entry.isDirectory()) {
|
|
1053
2020
|
if (!ignoreDirectories.has(entry.name)) directories.push(fullPath);
|
|
1054
2021
|
continue;
|
|
1055
2022
|
}
|
|
1056
2023
|
if (!entry.isFile()) continue;
|
|
1057
|
-
if (!extensionSet.has(
|
|
2024
|
+
if (!extensionSet.has(path6__default.extname(entry.name))) continue;
|
|
1058
2025
|
candidates.push(fullPath);
|
|
1059
2026
|
}
|
|
1060
2027
|
}
|
|
@@ -1068,9 +2035,12 @@ function toCacheSize(size) {
|
|
|
1068
2035
|
function scanSource(source) {
|
|
1069
2036
|
const nativeBinding = nativeParserLoader.get();
|
|
1070
2037
|
if (nativeBinding?.extractClassesFromSource) {
|
|
1071
|
-
const
|
|
1072
|
-
if (Array.isArray(
|
|
1073
|
-
return Array.from(new Set(
|
|
2038
|
+
const result = nativeBinding.extractClassesFromSource(source);
|
|
2039
|
+
if (Array.isArray(result)) {
|
|
2040
|
+
return Array.from(new Set(result.filter(Boolean)));
|
|
2041
|
+
}
|
|
2042
|
+
if (result !== null && result !== void 0 && Array.isArray(result.classes)) {
|
|
2043
|
+
return Array.from(new Set(result.classes.filter(Boolean)));
|
|
1074
2044
|
}
|
|
1075
2045
|
}
|
|
1076
2046
|
throw new Error(
|
|
@@ -1078,15 +2048,18 @@ function scanSource(source) {
|
|
|
1078
2048
|
);
|
|
1079
2049
|
}
|
|
1080
2050
|
function isScannableFile(filePath, includeExtensions = DEFAULT_EXTENSIONS) {
|
|
1081
|
-
return includeExtensions.includes(
|
|
2051
|
+
return includeExtensions.includes(path6__default.extname(filePath));
|
|
1082
2052
|
}
|
|
1083
2053
|
function scanFile(filePath) {
|
|
1084
|
-
const
|
|
1085
|
-
const
|
|
2054
|
+
const { scanFileNative: scanFileNative2 } = (init_native_bridge(), __toCommonJS(native_bridge_exports));
|
|
2055
|
+
const result = scanFileNative2(filePath);
|
|
2056
|
+
if (!result.ok) {
|
|
2057
|
+
throw new Error(`scanFile failed for ${filePath}: ${result.error ?? "unknown error"}`);
|
|
2058
|
+
}
|
|
1086
2059
|
return {
|
|
1087
|
-
file:
|
|
1088
|
-
classes:
|
|
1089
|
-
...hash ? { hash } : {}
|
|
2060
|
+
file: result.file,
|
|
2061
|
+
classes: result.classes,
|
|
2062
|
+
...result.hash ? { hash: result.hash } : {}
|
|
1090
2063
|
};
|
|
1091
2064
|
}
|
|
1092
2065
|
function scanWorkspace(rootDir, options = {}) {
|
|
@@ -1135,7 +2108,7 @@ function scanWorkspace(rootDir, options = {}) {
|
|
|
1135
2108
|
for (const filePath of candidates) {
|
|
1136
2109
|
const stat = (() => {
|
|
1137
2110
|
try {
|
|
1138
|
-
return
|
|
2111
|
+
return fs4__default.statSync(filePath);
|
|
1139
2112
|
} catch {
|
|
1140
2113
|
return null;
|
|
1141
2114
|
}
|
|
@@ -1161,7 +2134,7 @@ function scanWorkspace(rootDir, options = {}) {
|
|
|
1161
2134
|
for (const { filePath, stat, size, cached } of ranked) {
|
|
1162
2135
|
const content = (() => {
|
|
1163
2136
|
try {
|
|
1164
|
-
return
|
|
2137
|
+
return fs4__default.readFileSync(filePath, "utf8");
|
|
1165
2138
|
} catch {
|
|
1166
2139
|
return null;
|
|
1167
2140
|
}
|
|
@@ -1223,18 +2196,245 @@ function scanWorkspace(rootDir, options = {}) {
|
|
|
1223
2196
|
}
|
|
1224
2197
|
async function scanWorkspaceAsync(rootDir, options = {}) {
|
|
1225
2198
|
const normalizedOptions = parseScanWorkspaceOptions(options);
|
|
1226
|
-
|
|
1227
|
-
return
|
|
2199
|
+
try {
|
|
2200
|
+
return await scanWorkspaceParallel(rootDir, {
|
|
2201
|
+
extensions: normalizedOptions.includeExtensions,
|
|
2202
|
+
ignoreDirs: normalizedOptions.ignoreDirectories
|
|
2203
|
+
});
|
|
2204
|
+
} catch (parallelError) {
|
|
2205
|
+
log3.debug(
|
|
2206
|
+
`parallel scan failed, retrying with single worker: ${parallelError instanceof Error ? parallelError.message : String(parallelError)}`
|
|
2207
|
+
);
|
|
1228
2208
|
}
|
|
1229
2209
|
try {
|
|
1230
2210
|
return await scanWorkspaceInWorker(rootDir, normalizedOptions);
|
|
1231
2211
|
} catch (error) {
|
|
1232
2212
|
log3.debug(
|
|
1233
|
-
`worker scan failed,
|
|
2213
|
+
`worker scan failed, retrying with sync native scanner: ${error instanceof Error ? error.message : String(error)}`
|
|
1234
2214
|
);
|
|
1235
2215
|
return scanWorkspace(rootDir, normalizedOptions);
|
|
1236
2216
|
}
|
|
1237
2217
|
}
|
|
2218
|
+
var log3, SCAN_WORKER_TIMEOUT_MS, createNativeParserLoader, nativeParserLoader, DEFAULT_EXTENSIONS, DEFAULT_IGNORES;
|
|
2219
|
+
var init_src2 = __esm({
|
|
2220
|
+
"packages/domain/scanner/src/index.ts"() {
|
|
2221
|
+
init_src();
|
|
2222
|
+
init_cache_native();
|
|
2223
|
+
init_native_bridge();
|
|
2224
|
+
init_parallel_scanner();
|
|
2225
|
+
init_schemas();
|
|
2226
|
+
init_schemas();
|
|
2227
|
+
init_native_bridge();
|
|
2228
|
+
log3 = createLogger("scanner");
|
|
2229
|
+
SCAN_WORKER_TIMEOUT_MS = 12e4;
|
|
2230
|
+
createNativeParserLoader = () => {
|
|
2231
|
+
const _state = {
|
|
2232
|
+
binding: void 0,
|
|
2233
|
+
initError: null
|
|
2234
|
+
};
|
|
2235
|
+
const debugNative = (message) => {
|
|
2236
|
+
log3.debug(`[native] ${message}`);
|
|
2237
|
+
};
|
|
2238
|
+
const loadNativeParserBinding = () => {
|
|
2239
|
+
if (_state.binding !== void 0) return _state.binding;
|
|
2240
|
+
const runtimeDir = getRuntimeDir();
|
|
2241
|
+
const req = createRequire(path6__default.join(runtimeDir, "noop.cjs"));
|
|
2242
|
+
const candidates = [
|
|
2243
|
+
// ── binaryName baru: tailwind-styled-native (napi-rs naming) ──
|
|
2244
|
+
// cwd = repo root saat run dari root, atau package dir saat workspaces
|
|
2245
|
+
path6__default.resolve(process.cwd(), "native", "tailwind-styled-native.node"),
|
|
2246
|
+
path6__default.resolve(process.cwd(), "native", `tailwind-styled-native.${process.platform}-${process.arch}.node`),
|
|
2247
|
+
path6__default.resolve(process.cwd(), "native", `tailwind-styled-native.${process.platform}-${process.arch}-gnu.node`),
|
|
2248
|
+
// runtimeDir = dist/ → naik 4 level ke repo root
|
|
2249
|
+
path6__default.resolve(runtimeDir, "..", "..", "..", "..", "native", "tailwind-styled-native.node"),
|
|
2250
|
+
path6__default.resolve(runtimeDir, "..", "..", "..", "..", "native", `tailwind-styled-native.${process.platform}-${process.arch}-gnu.node`),
|
|
2251
|
+
// 3 level fallback (jika package di-nest lebih dangkal)
|
|
2252
|
+
path6__default.resolve(runtimeDir, "..", "..", "..", "native", "tailwind-styled-native.node"),
|
|
2253
|
+
path6__default.resolve(runtimeDir, "..", "..", "..", "native", `tailwind-styled-native.${process.platform}-${process.arch}-gnu.node`),
|
|
2254
|
+
// ── binaryName lama: tailwind_styled_parser (backward compat) ──
|
|
2255
|
+
path6__default.resolve(process.cwd(), "native/tailwind_styled_parser.node"),
|
|
2256
|
+
path6__default.resolve(process.cwd(), "native/build/Release/tailwind_styled_parser.node"),
|
|
2257
|
+
path6__default.resolve(runtimeDir, "..", "..", "..", "..", "native", "tailwind_styled_parser.node"),
|
|
2258
|
+
path6__default.resolve(runtimeDir, "..", "..", "..", "native", "tailwind_styled_parser.node"),
|
|
2259
|
+
path6__default.resolve(
|
|
2260
|
+
runtimeDir,
|
|
2261
|
+
"..",
|
|
2262
|
+
"..",
|
|
2263
|
+
"..",
|
|
2264
|
+
"native",
|
|
2265
|
+
"build",
|
|
2266
|
+
"Release",
|
|
2267
|
+
"tailwind_styled_parser.node"
|
|
2268
|
+
)
|
|
2269
|
+
];
|
|
2270
|
+
for (const fullPath of candidates) {
|
|
2271
|
+
if (!fs4__default.existsSync(fullPath)) continue;
|
|
2272
|
+
try {
|
|
2273
|
+
const required = req(fullPath);
|
|
2274
|
+
if (required && (typeof required.extractClassesFromSource === "function" || typeof required.parseClasses === "function" || typeof required.parse_classes === "function")) {
|
|
2275
|
+
_state.binding = required;
|
|
2276
|
+
debugNative(`using native parser from ${fullPath}`);
|
|
2277
|
+
return _state.binding;
|
|
2278
|
+
}
|
|
2279
|
+
} catch (error) {
|
|
2280
|
+
_state.initError = error instanceof Error ? error.message : String(error);
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2283
|
+
_state.binding = null;
|
|
2284
|
+
if (!_state.initError) {
|
|
2285
|
+
_state.initError = "native .node binding not found";
|
|
2286
|
+
}
|
|
2287
|
+
debugNative(`native binding not available: ${_state.initError}`);
|
|
2288
|
+
return _state.binding;
|
|
2289
|
+
};
|
|
2290
|
+
return {
|
|
2291
|
+
get: loadNativeParserBinding,
|
|
2292
|
+
reset: () => {
|
|
2293
|
+
_state.binding = void 0;
|
|
2294
|
+
_state.initError = null;
|
|
2295
|
+
}
|
|
2296
|
+
};
|
|
2297
|
+
};
|
|
2298
|
+
nativeParserLoader = createNativeParserLoader();
|
|
2299
|
+
DEFAULT_EXTENSIONS = [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
2300
|
+
DEFAULT_IGNORES = ["node_modules", ".git", ".next", "dist", "out", ".turbo", ".cache"];
|
|
2301
|
+
}
|
|
2302
|
+
});
|
|
2303
|
+
|
|
2304
|
+
// packages/domain/engine/src/native-bridge.ts
|
|
2305
|
+
function getDirname3() {
|
|
2306
|
+
if (typeof __dirname !== "undefined") return __dirname;
|
|
2307
|
+
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
2308
|
+
return getDirname(import.meta.url);
|
|
2309
|
+
}
|
|
2310
|
+
return process.cwd();
|
|
2311
|
+
}
|
|
2312
|
+
function getNativeEngineBinding() {
|
|
2313
|
+
return engineBindingLoader.get();
|
|
2314
|
+
}
|
|
2315
|
+
var log4, isValidEngineBinding, createEngineBindingLoader, engineBindingLoader;
|
|
2316
|
+
var init_native_bridge2 = __esm({
|
|
2317
|
+
"packages/domain/engine/src/native-bridge.ts"() {
|
|
2318
|
+
init_src();
|
|
2319
|
+
log4 = createDebugLogger("engine:native");
|
|
2320
|
+
isValidEngineBinding = (module) => {
|
|
2321
|
+
const candidate = module;
|
|
2322
|
+
return !!(candidate && (candidate.computeIncrementalDiff || candidate.processFileChange || candidate.hashFileContent));
|
|
2323
|
+
};
|
|
2324
|
+
createEngineBindingLoader = () => {
|
|
2325
|
+
const _state = {
|
|
2326
|
+
binding: void 0,
|
|
2327
|
+
loadError: null,
|
|
2328
|
+
candidatePaths: []
|
|
2329
|
+
};
|
|
2330
|
+
const throwNativeBindingError = () => {
|
|
2331
|
+
const lines = [
|
|
2332
|
+
"FATAL: Native engine binding not found.",
|
|
2333
|
+
"",
|
|
2334
|
+
"This package requires the Rust native binding 'tailwind_styled_parser.node'.",
|
|
2335
|
+
"The binding was not found in any of these paths:",
|
|
2336
|
+
..._state.candidatePaths.map((p) => ` - ${p}`),
|
|
2337
|
+
""
|
|
2338
|
+
];
|
|
2339
|
+
if (_state.loadError) {
|
|
2340
|
+
lines.push("Load error:", ` ${_state.loadError}`, "");
|
|
2341
|
+
}
|
|
2342
|
+
lines.push(
|
|
2343
|
+
"To fix this, run:",
|
|
2344
|
+
" npm run build:rust",
|
|
2345
|
+
"",
|
|
2346
|
+
"This will build the native Rust module from the 'native/' directory.",
|
|
2347
|
+
"If you're using this package in a CI/CD environment, ensure Rust toolchain is installed",
|
|
2348
|
+
"and 'npm run build:rust' is executed before running tests or building."
|
|
2349
|
+
);
|
|
2350
|
+
throw new TwError("rust", "ENGINE_NATIVE_BINDING_NOT_FOUND", lines.join("\n"));
|
|
2351
|
+
};
|
|
2352
|
+
const getBinding = () => {
|
|
2353
|
+
const cached = _state.binding;
|
|
2354
|
+
if (cached !== void 0) {
|
|
2355
|
+
if (cached === null) {
|
|
2356
|
+
return throwNativeBindingError();
|
|
2357
|
+
}
|
|
2358
|
+
return cached;
|
|
2359
|
+
}
|
|
2360
|
+
const runtimeDir = getDirname3();
|
|
2361
|
+
const candidates = resolveNativeBindingCandidates({
|
|
2362
|
+
runtimeDir,
|
|
2363
|
+
includeDefaultCandidates: true
|
|
2364
|
+
});
|
|
2365
|
+
_state.candidatePaths = candidates;
|
|
2366
|
+
const { binding, loadErrors } = loadNativeBinding({
|
|
2367
|
+
runtimeDir,
|
|
2368
|
+
candidates,
|
|
2369
|
+
isValid: isValidEngineBinding,
|
|
2370
|
+
invalidExportMessage: "Module loaded but missing expected engine binding functions"
|
|
2371
|
+
});
|
|
2372
|
+
if (binding) {
|
|
2373
|
+
log4(`engine native binding loaded successfully`);
|
|
2374
|
+
_state.binding = binding;
|
|
2375
|
+
return binding;
|
|
2376
|
+
}
|
|
2377
|
+
if (loadErrors.length > 0) {
|
|
2378
|
+
_state.loadError = loadErrors.map((e) => `${e.path}: ${e.message}`).join("; ");
|
|
2379
|
+
}
|
|
2380
|
+
_state.binding = null;
|
|
2381
|
+
return throwNativeBindingError();
|
|
2382
|
+
};
|
|
2383
|
+
return {
|
|
2384
|
+
get: getBinding,
|
|
2385
|
+
reset: () => {
|
|
2386
|
+
_state.binding = void 0;
|
|
2387
|
+
_state.loadError = null;
|
|
2388
|
+
_state.candidatePaths = [];
|
|
2389
|
+
}
|
|
2390
|
+
};
|
|
2391
|
+
};
|
|
2392
|
+
engineBindingLoader = createEngineBindingLoader();
|
|
2393
|
+
}
|
|
2394
|
+
});
|
|
2395
|
+
|
|
2396
|
+
// packages/domain/compiler/src/index.ts
|
|
2397
|
+
init_nativeBridge();
|
|
2398
|
+
var transformSource = (source, opts) => {
|
|
2399
|
+
const native = getNativeBridge();
|
|
2400
|
+
if (!native?.transformSource) {
|
|
2401
|
+
throw new Error("FATAL: Native binding 'transformSource' is required but not available.");
|
|
2402
|
+
}
|
|
2403
|
+
const result = native.transformSource(source, opts);
|
|
2404
|
+
if (!result) {
|
|
2405
|
+
throw new Error("FATAL: transformSource returned null");
|
|
2406
|
+
}
|
|
2407
|
+
return result;
|
|
2408
|
+
};
|
|
2409
|
+
var generateCssForClasses = async (classes, _tailwindConfig, _root) => {
|
|
2410
|
+
const { runCssPipeline: runCssPipeline2 } = await Promise.resolve().then(() => (init_tailwindEngine(), tailwindEngine_exports));
|
|
2411
|
+
const result = await runCssPipeline2(classes);
|
|
2412
|
+
return result.css;
|
|
2413
|
+
};
|
|
2414
|
+
var mergeClassesStatic = (classes) => {
|
|
2415
|
+
const result = normalizeAndDedupClasses(classes);
|
|
2416
|
+
return result?.normalized || "";
|
|
2417
|
+
};
|
|
2418
|
+
var normalizeAndDedupClasses = (raw) => {
|
|
2419
|
+
const native = getNativeBridge();
|
|
2420
|
+
if (!native?.normalizeAndDedupClasses) {
|
|
2421
|
+
throw new Error("FATAL: Native binding 'normalizeAndDedupClasses' is required but not available.");
|
|
2422
|
+
}
|
|
2423
|
+
const result = native.normalizeAndDedupClasses(raw);
|
|
2424
|
+
return result || { normalized: "", duplicatesRemoved: 0, uniqueCount: 0 };
|
|
2425
|
+
};
|
|
2426
|
+
var runLoaderTransform = (ctx) => {
|
|
2427
|
+
const { filepath, source, options } = ctx;
|
|
2428
|
+
const result = transformSource(source, { filename: filepath, ...options });
|
|
2429
|
+
return {
|
|
2430
|
+
code: result?.code || "",
|
|
2431
|
+
changed: result?.changed || false,
|
|
2432
|
+
classes: result?.classes || []
|
|
2433
|
+
};
|
|
2434
|
+
};
|
|
2435
|
+
|
|
2436
|
+
// packages/domain/analyzer/src/analyzeWorkspace.ts
|
|
2437
|
+
init_src2();
|
|
1238
2438
|
|
|
1239
2439
|
// packages/domain/analyzer/src/binding.ts
|
|
1240
2440
|
init_src();
|
|
@@ -1244,7 +2444,7 @@ init_src();
|
|
|
1244
2444
|
var DEFAULT_TOP_LIMIT = 10;
|
|
1245
2445
|
var DEFAULT_FREQUENT_THRESHOLD = 2;
|
|
1246
2446
|
var DEBUG_NAMESPACE = "tailwind-styled:analyzer";
|
|
1247
|
-
function
|
|
2447
|
+
function formatErrorMessage2(error) {
|
|
1248
2448
|
return error instanceof Error ? error.message : String(error);
|
|
1249
2449
|
}
|
|
1250
2450
|
function isRecord(value) {
|
|
@@ -1254,7 +2454,7 @@ function isRecord(value) {
|
|
|
1254
2454
|
}
|
|
1255
2455
|
async function pathExists(filePath) {
|
|
1256
2456
|
try {
|
|
1257
|
-
await
|
|
2457
|
+
await fs4__default.promises.access(filePath, fs4__default.constants.F_OK);
|
|
1258
2458
|
return true;
|
|
1259
2459
|
} catch {
|
|
1260
2460
|
return false;
|
|
@@ -1317,6 +2517,9 @@ var createAnalyzerBindingLoader = () => {
|
|
|
1317
2517
|
};
|
|
1318
2518
|
};
|
|
1319
2519
|
var analyzerBindingLoader = createAnalyzerBindingLoader();
|
|
2520
|
+
async function getNativeBinding() {
|
|
2521
|
+
return analyzerBindingLoader.get();
|
|
2522
|
+
}
|
|
1320
2523
|
async function requireNativeBinding() {
|
|
1321
2524
|
const binding = await analyzerBindingLoader.get();
|
|
1322
2525
|
if (binding?.analyzeClasses) return binding;
|
|
@@ -1350,7 +2553,7 @@ async function requireNativeBinding() {
|
|
|
1350
2553
|
|
|
1351
2554
|
// packages/domain/analyzer/src/schemas.ts
|
|
1352
2555
|
init_src();
|
|
1353
|
-
var formatIssuePath3 = (
|
|
2556
|
+
var formatIssuePath3 = (path13) => path13.length > 0 ? path13.map(
|
|
1354
2557
|
(segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
|
|
1355
2558
|
).join(".") : "<root>";
|
|
1356
2559
|
var isPlainObject = (value) => {
|
|
@@ -1359,8 +2562,8 @@ var isPlainObject = (value) => {
|
|
|
1359
2562
|
return proto === Object.prototype || proto === null;
|
|
1360
2563
|
};
|
|
1361
2564
|
var formatIssues2 = (error) => error.issues.map((issue) => {
|
|
1362
|
-
const
|
|
1363
|
-
return `${
|
|
2565
|
+
const path13 = formatIssuePath3(issue.path);
|
|
2566
|
+
return `${path13}: ${issue.message}`;
|
|
1364
2567
|
}).join("; ");
|
|
1365
2568
|
var parseWithSchema2 = (schema, data, label) => {
|
|
1366
2569
|
const parsed = schema.safeParse(data);
|
|
@@ -1449,183 +2652,29 @@ z.object({
|
|
|
1449
2652
|
var parseAnalyzerOptions = (options) => parseWithSchema2(AnalyzerOptionsSchema, options ?? {}, "analyzeWorkspace options are invalid");
|
|
1450
2653
|
var parseNativeReport = (report) => parseWithSchema2(NativeReportSchema, report, "Native analyzer report is invalid");
|
|
1451
2654
|
var SUPPORTED_TAILWIND_CONFIG_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".js", ".cjs", ".mjs"]);
|
|
1452
|
-
var KNOWN_UTILITY_PREFIXES = /* @__PURE__ */ new Set([
|
|
1453
|
-
"absolute",
|
|
1454
|
-
"align",
|
|
1455
|
-
"animate",
|
|
1456
|
-
"arbitrary",
|
|
1457
|
-
"aspect",
|
|
1458
|
-
"backdrop",
|
|
1459
|
-
"basis",
|
|
1460
|
-
"bg",
|
|
1461
|
-
"block",
|
|
1462
|
-
"border",
|
|
1463
|
-
"bottom",
|
|
1464
|
-
"col",
|
|
1465
|
-
"container",
|
|
1466
|
-
"contents",
|
|
1467
|
-
"cursor",
|
|
1468
|
-
"dark",
|
|
1469
|
-
"display",
|
|
1470
|
-
"divide",
|
|
1471
|
-
"fill",
|
|
1472
|
-
"fixed",
|
|
1473
|
-
"flex",
|
|
1474
|
-
"float",
|
|
1475
|
-
"font",
|
|
1476
|
-
"from",
|
|
1477
|
-
"gap",
|
|
1478
|
-
"grid",
|
|
1479
|
-
"grow",
|
|
1480
|
-
"h",
|
|
1481
|
-
"hidden",
|
|
1482
|
-
"inset",
|
|
1483
|
-
"inline",
|
|
1484
|
-
"isolate",
|
|
1485
|
-
"items",
|
|
1486
|
-
"justify",
|
|
1487
|
-
"left",
|
|
1488
|
-
"leading",
|
|
1489
|
-
"line",
|
|
1490
|
-
"list",
|
|
1491
|
-
"m",
|
|
1492
|
-
"max-h",
|
|
1493
|
-
"max-w",
|
|
1494
|
-
"mb",
|
|
1495
|
-
"min-h",
|
|
1496
|
-
"min-w",
|
|
1497
|
-
"ml",
|
|
1498
|
-
"mr",
|
|
1499
|
-
"mt",
|
|
1500
|
-
"mx",
|
|
1501
|
-
"my",
|
|
1502
|
-
"object",
|
|
1503
|
-
"opacity",
|
|
1504
|
-
"order",
|
|
1505
|
-
"origin",
|
|
1506
|
-
"outline",
|
|
1507
|
-
"overflow",
|
|
1508
|
-
"overscroll",
|
|
1509
|
-
"p",
|
|
1510
|
-
"pb",
|
|
1511
|
-
"pe",
|
|
1512
|
-
"perspective",
|
|
1513
|
-
"place",
|
|
1514
|
-
"pl",
|
|
1515
|
-
"pointer",
|
|
1516
|
-
"position",
|
|
1517
|
-
"pr",
|
|
1518
|
-
"ps",
|
|
1519
|
-
"pt",
|
|
1520
|
-
"px",
|
|
1521
|
-
"py",
|
|
1522
|
-
"relative",
|
|
1523
|
-
"right",
|
|
1524
|
-
"ring",
|
|
1525
|
-
"rotate",
|
|
1526
|
-
"rounded",
|
|
1527
|
-
"row",
|
|
1528
|
-
"scale",
|
|
1529
|
-
"shadow",
|
|
1530
|
-
"shrink",
|
|
1531
|
-
"size",
|
|
1532
|
-
"skew",
|
|
1533
|
-
"snap",
|
|
1534
|
-
"space-x",
|
|
1535
|
-
"space-y",
|
|
1536
|
-
"sr",
|
|
1537
|
-
"start",
|
|
1538
|
-
"static",
|
|
1539
|
-
"sticky",
|
|
1540
|
-
"stroke",
|
|
1541
|
-
"table",
|
|
1542
|
-
"text",
|
|
1543
|
-
"to",
|
|
1544
|
-
"top",
|
|
1545
|
-
"touch",
|
|
1546
|
-
"tracking",
|
|
1547
|
-
"transform",
|
|
1548
|
-
"transition",
|
|
1549
|
-
"translate",
|
|
1550
|
-
"truncate",
|
|
1551
|
-
"underline",
|
|
1552
|
-
"via",
|
|
1553
|
-
"visible",
|
|
1554
|
-
"w",
|
|
1555
|
-
"whitespace",
|
|
1556
|
-
"z"
|
|
1557
|
-
]);
|
|
1558
2655
|
var tailwindConfigCache = /* @__PURE__ */ new Map();
|
|
1559
|
-
var
|
|
1560
|
-
const
|
|
1561
|
-
if (
|
|
1562
|
-
|
|
1563
|
-
return { variantKey: parts.join(":"), base };
|
|
1564
|
-
};
|
|
1565
|
-
var isArbitraryUtility = (baseClass) => {
|
|
1566
|
-
return baseClass.includes("[") && baseClass.includes("]");
|
|
1567
|
-
};
|
|
1568
|
-
var resolveConflictGroup = (base) => {
|
|
1569
|
-
if (isArbitraryUtility(base)) return null;
|
|
1570
|
-
if (["block", "inline", "inline-block", "inline-flex", "flex", "grid", "hidden"].includes(base))
|
|
1571
|
-
return "display";
|
|
1572
|
-
if (base.startsWith("bg-")) return "bg";
|
|
1573
|
-
if (base.startsWith("text-")) return "text";
|
|
1574
|
-
if (base.startsWith("font-")) return "font";
|
|
1575
|
-
if (base.startsWith("rounded")) return "rounded";
|
|
1576
|
-
if (base.startsWith("shadow")) return "shadow";
|
|
1577
|
-
if (base.startsWith("border-")) return "border";
|
|
1578
|
-
if (base.startsWith("opacity-")) return "opacity";
|
|
1579
|
-
if (base.startsWith("w-") || base.startsWith("min-w-") || base.startsWith("max-w-"))
|
|
1580
|
-
return "width";
|
|
1581
|
-
if (base.startsWith("h-") || base.startsWith("min-h-") || base.startsWith("max-h-"))
|
|
1582
|
-
return "height";
|
|
1583
|
-
if (base.startsWith("p-") || base.startsWith("px-") || base.startsWith("py-")) return "padding";
|
|
1584
|
-
if (base.startsWith("m-") || base.startsWith("mx-") || base.startsWith("my-")) return "margin";
|
|
1585
|
-
return null;
|
|
1586
|
-
};
|
|
1587
|
-
var detectConflicts = (usages) => {
|
|
1588
|
-
const buckets = /* @__PURE__ */ new Map();
|
|
1589
|
-
for (const usage of usages) {
|
|
1590
|
-
const { variantKey, base } = splitVariantAndBase(usage.name);
|
|
1591
|
-
const group = resolveConflictGroup(base);
|
|
1592
|
-
if (!group) continue;
|
|
1593
|
-
const key = `${variantKey}::${group}`;
|
|
1594
|
-
const bucket = buckets.get(key) ?? {
|
|
1595
|
-
variantKey,
|
|
1596
|
-
group,
|
|
1597
|
-
classes: /* @__PURE__ */ new Set()
|
|
1598
|
-
};
|
|
1599
|
-
bucket.classes.add(usage.name);
|
|
1600
|
-
buckets.set(key, bucket);
|
|
1601
|
-
}
|
|
1602
|
-
const conflicts = [];
|
|
1603
|
-
const conflictedClassNames = /* @__PURE__ */ new Set();
|
|
1604
|
-
for (const bucket of buckets.values()) {
|
|
1605
|
-
if (bucket.classes.size <= 1) continue;
|
|
1606
|
-
const classes = Array.from(bucket.classes).sort();
|
|
1607
|
-
for (const className of classes) conflictedClassNames.add(className);
|
|
1608
|
-
const variantLabel = bucket.variantKey.length > 0 ? bucket.variantKey : "base";
|
|
1609
|
-
conflicts.push({
|
|
1610
|
-
className: bucket.group,
|
|
1611
|
-
variants: bucket.variantKey.length > 0 ? bucket.variantKey.split(":") : [],
|
|
1612
|
-
classes,
|
|
1613
|
-
message: `Multiple ${bucket.group} utilities detected for "${variantLabel}".`
|
|
1614
|
-
});
|
|
2656
|
+
var detectConflicts = async (usages) => {
|
|
2657
|
+
const native = await getNativeBinding();
|
|
2658
|
+
if (!native?.detectClassConflicts) {
|
|
2659
|
+
throw new Error("FATAL: Native binding 'detectClassConflicts' is required but not available.");
|
|
1615
2660
|
}
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
2661
|
+
const result = native.detectClassConflicts(JSON.stringify(usages.map((u) => ({ name: u.name, count: u.count }))));
|
|
2662
|
+
return {
|
|
2663
|
+
conflicts: result.conflicts.map((c) => ({
|
|
2664
|
+
className: c.group,
|
|
2665
|
+
variants: c.variantKey.length > 0 ? c.variantKey.split(":") : [],
|
|
2666
|
+
classes: c.classes,
|
|
2667
|
+
message: c.message
|
|
2668
|
+
})),
|
|
2669
|
+
conflictedClassNames: new Set(result.conflictedClassNames)
|
|
2670
|
+
};
|
|
1622
2671
|
};
|
|
1623
2672
|
var isSupportedTailwindConfigPath = (configPath) => {
|
|
1624
|
-
return SUPPORTED_TAILWIND_CONFIG_EXTENSIONS.has(
|
|
2673
|
+
return SUPPORTED_TAILWIND_CONFIG_EXTENSIONS.has(path6__default.extname(configPath).toLowerCase());
|
|
1625
2674
|
};
|
|
1626
2675
|
var resolveTailwindConfigPath = async (root, explicitPath) => {
|
|
1627
2676
|
if (explicitPath) {
|
|
1628
|
-
const resolved =
|
|
2677
|
+
const resolved = path6__default.resolve(root, explicitPath);
|
|
1629
2678
|
if (!await pathExists(resolved)) return null;
|
|
1630
2679
|
return resolved;
|
|
1631
2680
|
}
|
|
@@ -1636,7 +2685,7 @@ var resolveTailwindConfigPath = async (root, explicitPath) => {
|
|
|
1636
2685
|
"tailwind.config.mjs"
|
|
1637
2686
|
];
|
|
1638
2687
|
for (const candidate of candidates) {
|
|
1639
|
-
const fullPath =
|
|
2688
|
+
const fullPath = path6__default.resolve(root, candidate);
|
|
1640
2689
|
if (await pathExists(fullPath)) return fullPath;
|
|
1641
2690
|
}
|
|
1642
2691
|
return null;
|
|
@@ -1690,15 +2739,19 @@ var collectCustomUtilities = (config) => {
|
|
|
1690
2739
|
return out;
|
|
1691
2740
|
};
|
|
1692
2741
|
var collectSafelistFromSource = async (configPath) => {
|
|
1693
|
-
const source = await
|
|
1694
|
-
const
|
|
1695
|
-
|
|
1696
|
-
const
|
|
1697
|
-
|
|
2742
|
+
const source = await fs4__default.promises.readFile(configPath, "utf8");
|
|
2743
|
+
const { extractClassesNative: extractClassesNative2 } = await Promise.resolve().then(() => (init_src2(), src_exports2));
|
|
2744
|
+
const allTokens = extractClassesNative2(source);
|
|
2745
|
+
const hasSafelist = source.includes("safelist");
|
|
2746
|
+
if (!hasSafelist) return [];
|
|
2747
|
+
const safelistMatch = source.match(/safelist\s*:\s*\[([\s\S]*?)\]/m)?.[1];
|
|
2748
|
+
if (!safelistMatch) return [];
|
|
2749
|
+
const safelistSet = /* @__PURE__ */ new Set();
|
|
2750
|
+
for (const token of safelistMatch.matchAll(/["'`]([^"'`]+)["'`]/g)) {
|
|
1698
2751
|
const value = token[1].trim();
|
|
1699
|
-
if (value.length > 0)
|
|
2752
|
+
if (value.length > 0) safelistSet.add(value);
|
|
1700
2753
|
}
|
|
1701
|
-
return
|
|
2754
|
+
return allTokens.filter((t) => safelistSet.has(t));
|
|
1702
2755
|
};
|
|
1703
2756
|
var loadTailwindConfig = async (root, semanticOption) => {
|
|
1704
2757
|
const startMs = Date.now();
|
|
@@ -1713,7 +2766,7 @@ var loadTailwindConfig = async (root, semanticOption) => {
|
|
|
1713
2766
|
customUtilities: /* @__PURE__ */ new Set()
|
|
1714
2767
|
};
|
|
1715
2768
|
}
|
|
1716
|
-
const configStat = await
|
|
2769
|
+
const configStat = await fs4__default.promises.stat(configPath).catch(() => null);
|
|
1717
2770
|
if (configStat) {
|
|
1718
2771
|
const cached = tailwindConfigCache.get(configPath);
|
|
1719
2772
|
if (cached && cached.mtimeMs === configStat.mtimeMs && cached.size === configStat.size) {
|
|
@@ -1742,7 +2795,7 @@ var loadTailwindConfig = async (root, semanticOption) => {
|
|
|
1742
2795
|
warning: "Tailwind config export must be an object or a function returning an object."
|
|
1743
2796
|
};
|
|
1744
2797
|
} catch (error) {
|
|
1745
|
-
return { config: null, warning:
|
|
2798
|
+
return { config: null, warning: formatErrorMessage2(error) };
|
|
1746
2799
|
}
|
|
1747
2800
|
})();
|
|
1748
2801
|
const { config, warning } = result;
|
|
@@ -1757,7 +2810,7 @@ var loadTailwindConfig = async (root, semanticOption) => {
|
|
|
1757
2810
|
for (const item of await collectSafelistFromSource(configPath)) safelist.add(item);
|
|
1758
2811
|
} catch (error) {
|
|
1759
2812
|
debugLog(
|
|
1760
|
-
`failed to parse safelist from source at "${configPath}": ${
|
|
2813
|
+
`failed to parse safelist from source at "${configPath}": ${formatErrorMessage2(error)}`
|
|
1761
2814
|
);
|
|
1762
2815
|
}
|
|
1763
2816
|
}
|
|
@@ -1780,40 +2833,27 @@ var loadTailwindConfig = async (root, semanticOption) => {
|
|
|
1780
2833
|
);
|
|
1781
2834
|
return loaded;
|
|
1782
2835
|
};
|
|
1783
|
-
var utilityPrefix = (baseClass) => {
|
|
1784
|
-
const normalized = baseClass.startsWith("-") ? baseClass.slice(1) : baseClass;
|
|
1785
|
-
if (normalized.includes("[") && normalized.includes("]")) return "arbitrary";
|
|
1786
|
-
if (normalized.startsWith("min-w-")) return "min-w";
|
|
1787
|
-
if (normalized.startsWith("max-w-")) return "max-w";
|
|
1788
|
-
if (normalized.startsWith("min-h-")) return "min-h";
|
|
1789
|
-
if (normalized.startsWith("max-h-")) return "max-h";
|
|
1790
|
-
if (normalized.startsWith("space-x-")) return "space-x";
|
|
1791
|
-
if (normalized.startsWith("space-y-")) return "space-y";
|
|
1792
|
-
if (normalized.startsWith("inline-")) return "inline";
|
|
1793
|
-
if (normalized.startsWith("border-")) return "border";
|
|
1794
|
-
if (normalized.startsWith("text-")) return "text";
|
|
1795
|
-
if (normalized.startsWith("bg-")) return "bg";
|
|
1796
|
-
if (normalized.startsWith("rounded")) return "rounded";
|
|
1797
|
-
if (normalized.startsWith("shadow")) return "shadow";
|
|
1798
|
-
const hyphen = normalized.indexOf("-");
|
|
1799
|
-
if (hyphen < 0) return normalized;
|
|
1800
|
-
return normalized.slice(0, hyphen);
|
|
1801
|
-
};
|
|
1802
|
-
var isKnownTailwindClass = (className, safelist, customUtilities) => {
|
|
1803
|
-
if (safelist.has(className) || customUtilities.has(className)) return true;
|
|
1804
|
-
const { base } = splitVariantAndBase(className);
|
|
1805
|
-
if (customUtilities.has(base)) return true;
|
|
1806
|
-
const prefix = utilityPrefix(base);
|
|
1807
|
-
return KNOWN_UTILITY_PREFIXES.has(prefix);
|
|
1808
|
-
};
|
|
1809
2836
|
var buildSemanticReport = async (usages, root, semanticOption) => {
|
|
1810
2837
|
const loadedConfig = await loadTailwindConfig(root, semanticOption);
|
|
1811
2838
|
const safelist = loadedConfig?.safelist ?? /* @__PURE__ */ new Set();
|
|
1812
2839
|
const customUtilities = loadedConfig?.customUtilities ?? /* @__PURE__ */ new Set();
|
|
1813
2840
|
const usageNames = new Set(usages.map((usage) => usage.name));
|
|
1814
2841
|
const unusedClasses = Array.from(safelist).filter((className) => !usageNames.has(className)).sort().map((className) => ({ name: className, count: 0, isUnused: true }));
|
|
1815
|
-
const
|
|
1816
|
-
|
|
2842
|
+
const native = await getNativeBinding();
|
|
2843
|
+
if (!native?.classifyKnownClasses) {
|
|
2844
|
+
throw new Error("FATAL: Native binding 'classifyKnownClasses' is required but not available.");
|
|
2845
|
+
}
|
|
2846
|
+
const classNames = usages.map((u) => u.name);
|
|
2847
|
+
const results = native.classifyKnownClasses(
|
|
2848
|
+
classNames,
|
|
2849
|
+
Array.from(safelist),
|
|
2850
|
+
Array.from(customUtilities)
|
|
2851
|
+
);
|
|
2852
|
+
const unknownSet = new Set(
|
|
2853
|
+
results.filter((r) => !r.isKnown).map((r) => r.className)
|
|
2854
|
+
);
|
|
2855
|
+
const unknownClasses = usages.filter((usage) => unknownSet.has(usage.name)).map((usage) => ({ ...usage, isUnused: true }));
|
|
2856
|
+
const { conflicts } = await detectConflicts(usages);
|
|
1817
2857
|
return {
|
|
1818
2858
|
unusedClasses,
|
|
1819
2859
|
unknownClasses,
|
|
@@ -1849,13 +2889,17 @@ function normalizeScan(scan, includeClass) {
|
|
|
1849
2889
|
uniqueClasses: Array.from(unique).sort()
|
|
1850
2890
|
};
|
|
1851
2891
|
}
|
|
1852
|
-
function collectClassCounts(scan) {
|
|
1853
|
-
const
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
counts.set(className, (counts.get(className) ?? 0) + 1);
|
|
1857
|
-
}
|
|
2892
|
+
async function collectClassCounts(scan) {
|
|
2893
|
+
const native = await requireNativeBinding();
|
|
2894
|
+
if (!native?.collectClassCounts) {
|
|
2895
|
+
throw new Error("FATAL: Native binding 'collectClassCounts' is required but not available.");
|
|
1858
2896
|
}
|
|
2897
|
+
const filesJson = JSON.stringify(
|
|
2898
|
+
scan.files.map((f) => ({ file: f.file ?? "", classes: f.classes }))
|
|
2899
|
+
);
|
|
2900
|
+
const result = native.collectClassCounts(filesJson);
|
|
2901
|
+
const counts = /* @__PURE__ */ new Map();
|
|
2902
|
+
for (const entry of result) counts.set(entry.name, entry.count);
|
|
1859
2903
|
return counts;
|
|
1860
2904
|
}
|
|
1861
2905
|
function buildClassUsage(counts) {
|
|
@@ -1864,29 +2908,24 @@ function buildClassUsage(counts) {
|
|
|
1864
2908
|
return left.name.localeCompare(right.name);
|
|
1865
2909
|
});
|
|
1866
2910
|
}
|
|
1867
|
-
function buildDistribution(usages) {
|
|
1868
|
-
const
|
|
1869
|
-
|
|
1870
|
-
"
|
|
1871
|
-
"4-7": 0,
|
|
1872
|
-
"8+": 0
|
|
1873
|
-
};
|
|
1874
|
-
for (const usage of usages) {
|
|
1875
|
-
if (usage.count === 1) {
|
|
1876
|
-
distribution["1"] += 1;
|
|
1877
|
-
} else if (usage.count <= 3) {
|
|
1878
|
-
distribution["2-3"] += 1;
|
|
1879
|
-
} else if (usage.count <= 7) {
|
|
1880
|
-
distribution["4-7"] += 1;
|
|
1881
|
-
} else {
|
|
1882
|
-
distribution["8+"] += 1;
|
|
1883
|
-
}
|
|
2911
|
+
async function buildDistribution(usages, native) {
|
|
2912
|
+
const binding = native ?? await requireNativeBinding();
|
|
2913
|
+
if (!binding?.buildDistribution) {
|
|
2914
|
+
throw new Error("FATAL: Native binding 'buildDistribution' is required but not available.");
|
|
1884
2915
|
}
|
|
1885
|
-
|
|
2916
|
+
const result = binding.buildDistribution(
|
|
2917
|
+
JSON.stringify(usages.map((u) => ({ name: u.name, count: u.count })))
|
|
2918
|
+
);
|
|
2919
|
+
return {
|
|
2920
|
+
"1": result.once,
|
|
2921
|
+
"2-3": result.few,
|
|
2922
|
+
"4-7": result.moderate,
|
|
2923
|
+
"8+": result.frequent
|
|
2924
|
+
};
|
|
1886
2925
|
}
|
|
1887
2926
|
async function analyzeWorkspace(root, options = {}) {
|
|
1888
2927
|
const startedAtMs = Date.now();
|
|
1889
|
-
const resolvedRoot =
|
|
2928
|
+
const resolvedRoot = path6__default.resolve(root);
|
|
1890
2929
|
const normalizedOptions = parseAnalyzerOptions(options);
|
|
1891
2930
|
const scan = await (async () => {
|
|
1892
2931
|
const scanStartedAtMs = Date.now();
|
|
@@ -1898,7 +2937,7 @@ async function analyzeWorkspace(root, options = {}) {
|
|
|
1898
2937
|
return result;
|
|
1899
2938
|
} catch (error) {
|
|
1900
2939
|
throw new Error(
|
|
1901
|
-
`Failed to scan workspace at "${resolvedRoot}": ${
|
|
2940
|
+
`Failed to scan workspace at "${resolvedRoot}": ${formatErrorMessage2(error)}`,
|
|
1902
2941
|
{
|
|
1903
2942
|
cause: error
|
|
1904
2943
|
}
|
|
@@ -1923,14 +2962,14 @@ async function analyzeWorkspace(root, options = {}) {
|
|
|
1923
2962
|
return parseNativeReport(report);
|
|
1924
2963
|
} catch (error) {
|
|
1925
2964
|
throw new Error(
|
|
1926
|
-
`Native analyzer failed for "${resolvedRoot}": ${
|
|
2965
|
+
`Native analyzer failed for "${resolvedRoot}": ${formatErrorMessage2(error)}`,
|
|
1927
2966
|
{
|
|
1928
2967
|
cause: error
|
|
1929
2968
|
}
|
|
1930
2969
|
);
|
|
1931
2970
|
}
|
|
1932
2971
|
})();
|
|
1933
|
-
const counts = collectClassCounts(normalizedScan);
|
|
2972
|
+
const counts = await collectClassCounts(normalizedScan);
|
|
1934
2973
|
const baseAll = buildClassUsage(counts);
|
|
1935
2974
|
const { all, semanticReport } = await (async () => {
|
|
1936
2975
|
if (!normalizedOptions.semantic) {
|
|
@@ -1951,18 +2990,24 @@ async function analyzeWorkspace(root, options = {}) {
|
|
|
1951
2990
|
return { all: updatedAll, semanticReport: report };
|
|
1952
2991
|
} catch (error) {
|
|
1953
2992
|
throw new Error(
|
|
1954
|
-
`Failed to build semantic report for "${resolvedRoot}": ${
|
|
2993
|
+
`Failed to build semantic report for "${resolvedRoot}": ${formatErrorMessage2(error)}`,
|
|
1955
2994
|
{ cause: error }
|
|
1956
2995
|
);
|
|
1957
2996
|
}
|
|
1958
2997
|
})();
|
|
1959
|
-
const
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
2998
|
+
const classStatsNative = binding?.computeClassStats?.(
|
|
2999
|
+
JSON.stringify(all),
|
|
3000
|
+
topLimit,
|
|
3001
|
+
frequentThreshold
|
|
3002
|
+
);
|
|
3003
|
+
const top = classStatsNative ? JSON.parse(classStatsNative.topJson) : all.slice(0, topLimit);
|
|
3004
|
+
const frequent = classStatsNative ? JSON.parse(classStatsNative.frequentJson) : all.filter((usage) => usage.count >= frequentThreshold).slice(0, topLimit);
|
|
3005
|
+
const unique = classStatsNative ? JSON.parse(classStatsNative.uniqueJson) : all.filter((usage) => usage.count === 1);
|
|
3006
|
+
const totalClassOccurrences = classStatsNative ? classStatsNative.totalClassOccurrences : all.reduce((sum, usage) => sum + usage.count, 0);
|
|
1963
3007
|
debugLog(
|
|
1964
3008
|
`analyzeWorkspace completed in ${Date.now() - startedAtMs}ms (files=${normalizedScan.totalFiles}, uniqueClasses=${all.length})`
|
|
1965
3009
|
);
|
|
3010
|
+
const distribution = await buildDistribution(all, binding);
|
|
1966
3011
|
return {
|
|
1967
3012
|
root: nativeReport.root || resolvedRoot,
|
|
1968
3013
|
totalFiles: nativeReport.totalFiles,
|
|
@@ -1973,138 +3018,57 @@ async function analyzeWorkspace(root, options = {}) {
|
|
|
1973
3018
|
top,
|
|
1974
3019
|
frequent,
|
|
1975
3020
|
unique,
|
|
1976
|
-
distribution
|
|
3021
|
+
distribution
|
|
1977
3022
|
},
|
|
3023
|
+
// topClasses — alias for classStats.top (test contract & backward compat)
|
|
3024
|
+
topClasses: top,
|
|
1978
3025
|
safelist: all.map((usage) => usage.name),
|
|
1979
3026
|
...semanticReport ? { semantic: semanticReport } : {}
|
|
1980
3027
|
};
|
|
1981
3028
|
}
|
|
1982
3029
|
|
|
1983
3030
|
// packages/domain/engine/src/index.ts
|
|
3031
|
+
init_src2();
|
|
1984
3032
|
init_src();
|
|
1985
|
-
init_src();
|
|
1986
|
-
|
|
1987
|
-
// packages/domain/engine/src/native-bridge.ts
|
|
1988
|
-
init_src();
|
|
1989
|
-
var log4 = createDebugLogger("engine:native");
|
|
1990
|
-
function getDirname3() {
|
|
1991
|
-
if (typeof __dirname !== "undefined") return __dirname;
|
|
1992
|
-
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
1993
|
-
return getDirname(import.meta.url);
|
|
1994
|
-
}
|
|
1995
|
-
return process.cwd();
|
|
1996
|
-
}
|
|
1997
|
-
var isValidEngineBinding = (module) => {
|
|
1998
|
-
const candidate = module;
|
|
1999
|
-
return !!(candidate && (candidate.computeIncrementalDiff || candidate.processFileChange || candidate.hashFileContent));
|
|
2000
|
-
};
|
|
2001
|
-
var createEngineBindingLoader = () => {
|
|
2002
|
-
const _state = {
|
|
2003
|
-
binding: void 0,
|
|
2004
|
-
loadError: null,
|
|
2005
|
-
candidatePaths: []
|
|
2006
|
-
};
|
|
2007
|
-
const throwNativeBindingError = () => {
|
|
2008
|
-
const lines = [
|
|
2009
|
-
"FATAL: Native engine binding not found.",
|
|
2010
|
-
"",
|
|
2011
|
-
"This package requires the Rust native binding 'tailwind_styled_parser.node'.",
|
|
2012
|
-
"The binding was not found in any of these paths:",
|
|
2013
|
-
..._state.candidatePaths.map((p) => ` - ${p}`),
|
|
2014
|
-
""
|
|
2015
|
-
];
|
|
2016
|
-
if (_state.loadError) {
|
|
2017
|
-
lines.push("Load error:", ` ${_state.loadError}`, "");
|
|
2018
|
-
}
|
|
2019
|
-
lines.push(
|
|
2020
|
-
"To fix this, run:",
|
|
2021
|
-
" npm run build:rust",
|
|
2022
|
-
"",
|
|
2023
|
-
"This will build the native Rust module from the 'native/' directory.",
|
|
2024
|
-
"If you're using this package in a CI/CD environment, ensure Rust toolchain is installed",
|
|
2025
|
-
"and 'npm run build:rust' is executed before running tests or building."
|
|
2026
|
-
);
|
|
2027
|
-
throw new TwError("rust", "ENGINE_NATIVE_BINDING_NOT_FOUND", lines.join("\n"));
|
|
2028
|
-
};
|
|
2029
|
-
const getBinding = () => {
|
|
2030
|
-
const cached = _state.binding;
|
|
2031
|
-
if (cached !== void 0) {
|
|
2032
|
-
if (cached === null) {
|
|
2033
|
-
return throwNativeBindingError();
|
|
2034
|
-
}
|
|
2035
|
-
return cached;
|
|
2036
|
-
}
|
|
2037
|
-
const runtimeDir = getDirname3();
|
|
2038
|
-
const candidates = resolveNativeBindingCandidates({
|
|
2039
|
-
runtimeDir,
|
|
2040
|
-
includeDefaultCandidates: true
|
|
2041
|
-
});
|
|
2042
|
-
_state.candidatePaths = candidates;
|
|
2043
|
-
const { binding, loadErrors } = loadNativeBinding({
|
|
2044
|
-
runtimeDir,
|
|
2045
|
-
candidates,
|
|
2046
|
-
isValid: isValidEngineBinding,
|
|
2047
|
-
invalidExportMessage: "Module loaded but missing expected engine binding functions"
|
|
2048
|
-
});
|
|
2049
|
-
if (binding) {
|
|
2050
|
-
log4(`engine native binding loaded successfully`);
|
|
2051
|
-
_state.binding = binding;
|
|
2052
|
-
return binding;
|
|
2053
|
-
}
|
|
2054
|
-
if (loadErrors.length > 0) {
|
|
2055
|
-
_state.loadError = loadErrors.map((e) => `${e.path}: ${e.message}`).join("; ");
|
|
2056
|
-
}
|
|
2057
|
-
_state.binding = null;
|
|
2058
|
-
return throwNativeBindingError();
|
|
2059
|
-
};
|
|
2060
|
-
return {
|
|
2061
|
-
get: getBinding,
|
|
2062
|
-
reset: () => {
|
|
2063
|
-
_state.binding = void 0;
|
|
2064
|
-
_state.loadError = null;
|
|
2065
|
-
_state.candidatePaths = [];
|
|
2066
|
-
}
|
|
2067
|
-
};
|
|
2068
|
-
};
|
|
2069
|
-
var engineBindingLoader = createEngineBindingLoader();
|
|
2070
|
-
function getNativeEngineBinding() {
|
|
2071
|
-
return engineBindingLoader.get();
|
|
2072
|
-
}
|
|
2073
3033
|
|
|
2074
3034
|
// packages/domain/engine/src/incremental.ts
|
|
3035
|
+
init_src2();
|
|
3036
|
+
init_src();
|
|
3037
|
+
init_native_bridge2();
|
|
2075
3038
|
var DEFAULT_EXTENSIONS2 = [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
2076
3039
|
var log5 = createLogger("engine:incremental");
|
|
2077
3040
|
function rebuildWorkspaceResult(byFile) {
|
|
2078
3041
|
const files = Array.from(byFile.values());
|
|
2079
|
-
const
|
|
2080
|
-
|
|
2081
|
-
|
|
3042
|
+
const native = getNativeEngineBinding();
|
|
3043
|
+
if (native?.rebuildWorkspaceResult) {
|
|
3044
|
+
const result = native.rebuildWorkspaceResult(files);
|
|
3045
|
+
return {
|
|
3046
|
+
files: result.files,
|
|
3047
|
+
totalFiles: result.totalFiles,
|
|
3048
|
+
uniqueClasses: result.uniqueClasses
|
|
3049
|
+
};
|
|
2082
3050
|
}
|
|
2083
|
-
|
|
2084
|
-
files,
|
|
2085
|
-
totalFiles: files.length,
|
|
2086
|
-
uniqueClasses: Array.from(unique).sort()
|
|
2087
|
-
};
|
|
3051
|
+
throw new Error("FATAL: Native binding 'rebuildWorkspaceResult' is required but not available.");
|
|
2088
3052
|
}
|
|
2089
3053
|
function applyClassDiff(existing, added, removed) {
|
|
2090
|
-
const
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
3054
|
+
const native = getNativeEngineBinding();
|
|
3055
|
+
if (native?.applyClassDiff) {
|
|
3056
|
+
return native.applyClassDiff(existing, added, removed);
|
|
3057
|
+
}
|
|
3058
|
+
throw new Error("FATAL: Native binding 'applyClassDiff' is required but not available.");
|
|
2094
3059
|
}
|
|
2095
3060
|
function areClassSetsEqual(a, b) {
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
if (!bSet.has(cls)) return false;
|
|
3061
|
+
const native = getNativeEngineBinding();
|
|
3062
|
+
if (native?.areClassSetsEqual) {
|
|
3063
|
+
return native.areClassSetsEqual(a, b);
|
|
2100
3064
|
}
|
|
2101
|
-
|
|
3065
|
+
throw new Error("FATAL: Native binding 'areClassSetsEqual' is required but not available.");
|
|
2102
3066
|
}
|
|
2103
3067
|
function applyIncrementalChange(previous, filePath, type, scanner) {
|
|
2104
3068
|
const includeExtensions = scanner?.includeExtensions ?? DEFAULT_EXTENSIONS2;
|
|
2105
3069
|
if (!isScannableFile(filePath, includeExtensions)) return previous;
|
|
2106
|
-
const byFile = new Map(previous.files.map((f) => [
|
|
2107
|
-
const normalizedPath =
|
|
3070
|
+
const byFile = new Map(previous.files.map((f) => [path6__default.resolve(f.file), f]));
|
|
3071
|
+
const normalizedPath = path6__default.resolve(filePath);
|
|
2108
3072
|
const native = getNativeEngineBinding();
|
|
2109
3073
|
if (!native?.processFileChange) {
|
|
2110
3074
|
throw new Error(
|
|
@@ -2120,7 +3084,7 @@ function applyIncrementalChange(previous, filePath, type, scanner) {
|
|
|
2120
3084
|
}
|
|
2121
3085
|
log5.debug(`native change ${normalizedPath}`);
|
|
2122
3086
|
const scanned = scanFile(normalizedPath);
|
|
2123
|
-
const content =
|
|
3087
|
+
const content = fs4__default.readFileSync(normalizedPath, "utf8");
|
|
2124
3088
|
const diff = native.processFileChange(normalizedPath, scanned.classes, content);
|
|
2125
3089
|
const existing = byFile.get(normalizedPath);
|
|
2126
3090
|
if (diff && existing) {
|
|
@@ -2189,8 +3153,8 @@ var METRICS_FILE_NAME = "metrics.json";
|
|
|
2189
3153
|
var CACHE_DIR = ".tw-cache";
|
|
2190
3154
|
function writeMetrics(metrics, cwd = process.cwd()) {
|
|
2191
3155
|
try {
|
|
2192
|
-
const cacheDir =
|
|
2193
|
-
|
|
3156
|
+
const cacheDir = path6__default.join(cwd, CACHE_DIR);
|
|
3157
|
+
fs4__default.mkdirSync(cacheDir, { recursive: true });
|
|
2194
3158
|
const mem = process.memoryUsage();
|
|
2195
3159
|
const data = {
|
|
2196
3160
|
...metrics,
|
|
@@ -2201,7 +3165,7 @@ function writeMetrics(metrics, cwd = process.cwd()) {
|
|
|
2201
3165
|
},
|
|
2202
3166
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2203
3167
|
};
|
|
2204
|
-
|
|
3168
|
+
fs4__default.writeFileSync(path6__default.join(cacheDir, METRICS_FILE_NAME), JSON.stringify(data, null, 2));
|
|
2205
3169
|
} catch {
|
|
2206
3170
|
}
|
|
2207
3171
|
}
|
|
@@ -2306,96 +3270,78 @@ z.object({
|
|
|
2306
3270
|
});
|
|
2307
3271
|
var parseEngineOptions = (options) => parseWithSchema3(EngineOptionsSchema, options ?? {}, "engine options are invalid");
|
|
2308
3272
|
var parseEngineWatchOptions = (options) => parseWithSchema3(EngineWatchOptionsSchema, options ?? {}, "engine watch options are invalid");
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
3273
|
+
|
|
3274
|
+
// packages/domain/engine/src/watch.ts
|
|
3275
|
+
var _native = null;
|
|
3276
|
+
function getNativeWatcher() {
|
|
3277
|
+
if (_native !== null) return _native;
|
|
3278
|
+
try {
|
|
3279
|
+
const { resolveNativeBinary: resolveNativeBinary2 } = (init_src(), __toCommonJS(src_exports));
|
|
3280
|
+
const { path: binPath } = resolveNativeBinary2(__dirname);
|
|
3281
|
+
if (binPath) {
|
|
3282
|
+
_native = __require(binPath);
|
|
3283
|
+
}
|
|
3284
|
+
} catch {
|
|
3285
|
+
_native = {};
|
|
3286
|
+
}
|
|
3287
|
+
return _native;
|
|
3288
|
+
}
|
|
3289
|
+
function watchWorkspaceNative(rootDir, onEvent, options) {
|
|
3290
|
+
const native = getNativeWatcher();
|
|
3291
|
+
if (!native?.startWatch || !native?.pollWatchEvents || !native?.stopWatch) {
|
|
3292
|
+
return null;
|
|
3293
|
+
}
|
|
3294
|
+
const result = native.startWatch(rootDir);
|
|
3295
|
+
if (!result || result.status !== "ok") {
|
|
3296
|
+
return null;
|
|
3297
|
+
}
|
|
3298
|
+
const { handleId } = result;
|
|
3299
|
+
const pollMs = options.pollIntervalMs ?? 200;
|
|
2315
3300
|
const pending = /* @__PURE__ */ new Map();
|
|
2316
|
-
const
|
|
2317
|
-
|
|
2318
|
-
return parts.some((part) => ignoreDirectories.has(part));
|
|
2319
|
-
};
|
|
2320
|
-
const enqueue = (event) => {
|
|
3301
|
+
const debounceMs = options.debounceMs ?? 100;
|
|
3302
|
+
function enqueue(event) {
|
|
2321
3303
|
const key = `${event.type}:${event.filePath}`;
|
|
2322
3304
|
const existing = pending.get(key);
|
|
2323
|
-
if (existing) clearTimeout(existing);
|
|
3305
|
+
if (existing) clearTimeout(existing.timer);
|
|
2324
3306
|
const timer = setTimeout(() => {
|
|
2325
3307
|
pending.delete(key);
|
|
2326
3308
|
onEvent(event);
|
|
2327
3309
|
}, debounceMs);
|
|
2328
|
-
pending.set(key, timer);
|
|
2329
|
-
}
|
|
2330
|
-
const
|
|
2331
|
-
const watcher = watchers.get(dir);
|
|
2332
|
-
if (!watcher) return;
|
|
2333
|
-
try {
|
|
2334
|
-
watcher.close();
|
|
2335
|
-
} catch {
|
|
2336
|
-
}
|
|
2337
|
-
watchers.delete(dir);
|
|
2338
|
-
};
|
|
2339
|
-
const scheduleRestart = (dir) => {
|
|
2340
|
-
const previous = restartTimers.get(dir);
|
|
2341
|
-
if (previous) clearTimeout(previous);
|
|
2342
|
-
const timer = setTimeout(() => {
|
|
2343
|
-
restartTimers.delete(dir);
|
|
2344
|
-
watchDir(dir);
|
|
2345
|
-
}, 250);
|
|
2346
|
-
restartTimers.set(dir, timer);
|
|
2347
|
-
};
|
|
2348
|
-
const watchDir = (dir) => {
|
|
2349
|
-
if (watchers.has(dir) || shouldIgnore(dir) || !fs.existsSync(dir)) return;
|
|
3310
|
+
pending.set(key, { event, timer });
|
|
3311
|
+
}
|
|
3312
|
+
const intervalId = setInterval(() => {
|
|
2350
3313
|
try {
|
|
2351
|
-
const
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
}
|
|
2356
|
-
const watcher = fs.watch(dir, { persistent: true }, (_eventType, fileName) => {
|
|
2357
|
-
if (!fileName) return;
|
|
2358
|
-
const fullPath = path3.join(dir, fileName.toString());
|
|
2359
|
-
if (shouldIgnore(fullPath)) return;
|
|
2360
|
-
if (fs.existsSync(fullPath)) {
|
|
2361
|
-
try {
|
|
2362
|
-
const stat = fs.lstatSync(fullPath);
|
|
2363
|
-
if (stat.isSymbolicLink()) return;
|
|
2364
|
-
if (stat.isDirectory()) {
|
|
2365
|
-
watchDir(fullPath);
|
|
2366
|
-
return;
|
|
2367
|
-
}
|
|
2368
|
-
enqueue({ type: "change", filePath: fullPath });
|
|
2369
|
-
return;
|
|
2370
|
-
} catch {
|
|
2371
|
-
}
|
|
3314
|
+
const events = native.pollWatchEvents(handleId);
|
|
3315
|
+
for (const ev of events) {
|
|
3316
|
+
const type = ev.kind === "unlink" ? "unlink" : "change";
|
|
3317
|
+
enqueue({ type, filePath: ev.path });
|
|
2372
3318
|
}
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
options.onError?.(watcherError, dir);
|
|
2379
|
-
scheduleRestart(dir);
|
|
2380
|
-
});
|
|
2381
|
-
watchers.set(dir, watcher);
|
|
2382
|
-
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
2383
|
-
if (!entry.isDirectory()) continue;
|
|
2384
|
-
watchDir(path3.join(dir, entry.name));
|
|
3319
|
+
} catch (err) {
|
|
3320
|
+
options.onError?.(
|
|
3321
|
+
err instanceof Error ? err : new Error(String(err)),
|
|
3322
|
+
rootDir
|
|
3323
|
+
);
|
|
2385
3324
|
}
|
|
2386
|
-
};
|
|
2387
|
-
watchDir(path3.resolve(rootDir));
|
|
3325
|
+
}, pollMs);
|
|
2388
3326
|
return {
|
|
2389
3327
|
close() {
|
|
2390
|
-
|
|
3328
|
+
clearInterval(intervalId);
|
|
3329
|
+
for (const { timer } of pending.values()) clearTimeout(timer);
|
|
2391
3330
|
pending.clear();
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
3331
|
+
try {
|
|
3332
|
+
native.stopWatch(handleId);
|
|
3333
|
+
} catch {
|
|
3334
|
+
}
|
|
2396
3335
|
}
|
|
2397
3336
|
};
|
|
2398
3337
|
}
|
|
3338
|
+
function watchWorkspace(rootDir, onEvent, options = {}) {
|
|
3339
|
+
const nativeWatcher = watchWorkspaceNative(rootDir, onEvent, options);
|
|
3340
|
+
if (!nativeWatcher) {
|
|
3341
|
+
throw new Error("FATAL: Native watcher is required but not available. Build the native module: npm run build:rust");
|
|
3342
|
+
}
|
|
3343
|
+
return nativeWatcher;
|
|
3344
|
+
}
|
|
2399
3345
|
|
|
2400
3346
|
// packages/domain/engine/src/index.ts
|
|
2401
3347
|
var DEFAULT_LARGE_FILE_THRESHOLD_BYTES = 10 * 1024 * 1024;
|
|
@@ -2418,8 +3364,8 @@ var configState = {
|
|
|
2418
3364
|
var log6 = createLogger("engine");
|
|
2419
3365
|
async function loadTailwindConfigFromPath(root, tailwindConfigPath) {
|
|
2420
3366
|
if (!tailwindConfigPath) return void 0;
|
|
2421
|
-
const configPath =
|
|
2422
|
-
if (!
|
|
3367
|
+
const configPath = path6__default.resolve(root, tailwindConfigPath);
|
|
3368
|
+
if (!fs4__default.existsSync(configPath)) {
|
|
2423
3369
|
throw TwError.fromIo("CONFIG_NOT_FOUND", `tailwindConfigPath not found: ${configPath}`);
|
|
2424
3370
|
}
|
|
2425
3371
|
const imported = await import(pathToFileURL(configPath).href);
|
|
@@ -2482,11 +3428,11 @@ async function buildFromScan(scan, root, options, tailwindConfig) {
|
|
|
2482
3428
|
};
|
|
2483
3429
|
}
|
|
2484
3430
|
function countWorkspacePackages(root) {
|
|
2485
|
-
const packagesDir =
|
|
2486
|
-
if (!
|
|
3431
|
+
const packagesDir = path6__default.join(root, "packages");
|
|
3432
|
+
if (!fs4__default.existsSync(packagesDir)) return 0;
|
|
2487
3433
|
try {
|
|
2488
|
-
return
|
|
2489
|
-
(entry) => entry.isDirectory() &&
|
|
3434
|
+
return fs4__default.readdirSync(packagesDir, { withFileTypes: true }).filter(
|
|
3435
|
+
(entry) => entry.isDirectory() && fs4__default.existsSync(path6__default.join(packagesDir, entry.name, "package.json"))
|
|
2490
3436
|
).length;
|
|
2491
3437
|
} catch {
|
|
2492
3438
|
return 0;
|
|
@@ -2522,7 +3468,7 @@ function writeDashboardMetrics(root, mode, result, metrics) {
|
|
|
2522
3468
|
async function createEngine(rawOptions = {}) {
|
|
2523
3469
|
const options = parseEngineOptions(rawOptions);
|
|
2524
3470
|
const root = options.root ?? process.cwd();
|
|
2525
|
-
const resolvedRoot =
|
|
3471
|
+
const resolvedRoot = path6__default.resolve(root);
|
|
2526
3472
|
const plugins = rawOptions.plugins ?? [];
|
|
2527
3473
|
const getTailwindConfig = async () => {
|
|
2528
3474
|
if (configState.isLoaded()) return configState.getConfig();
|
|
@@ -2669,7 +3615,7 @@ async function createEngine(rawOptions = {}) {
|
|
|
2669
3615
|
const shouldForceFullRescan = (event) => {
|
|
2670
3616
|
if (event.type === "unlink") return false;
|
|
2671
3617
|
try {
|
|
2672
|
-
const stat =
|
|
3618
|
+
const stat = fs4__default.statSync(event.filePath);
|
|
2673
3619
|
if (stat.size > largeFileThreshold) {
|
|
2674
3620
|
metrics.markSkippedLargeFile();
|
|
2675
3621
|
return true;
|
|
@@ -2788,7 +3734,7 @@ async function createEngine(rawOptions = {}) {
|
|
|
2788
3734
|
|
|
2789
3735
|
// packages/presentation/vite/src/schemas.ts
|
|
2790
3736
|
init_src();
|
|
2791
|
-
var formatIssuePath4 = (
|
|
3737
|
+
var formatIssuePath4 = (path13) => path13.length > 0 ? path13.map(
|
|
2792
3738
|
(segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
|
|
2793
3739
|
).join(".") : "<root>";
|
|
2794
3740
|
var formatIssues4 = (error) => error.issues.map((issue) => {
|
|
@@ -2834,14 +3780,14 @@ function warnDeprecated(options, key, message) {
|
|
|
2834
3780
|
}
|
|
2835
3781
|
}
|
|
2836
3782
|
function isInsideDirectory(filePath, directory) {
|
|
2837
|
-
const relative =
|
|
2838
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
3783
|
+
const relative = path6__default.relative(directory, filePath);
|
|
3784
|
+
return relative === "" || !relative.startsWith("..") && !path6__default.isAbsolute(relative);
|
|
2839
3785
|
}
|
|
2840
3786
|
function filterScanToDirs(scan, root, scanDirs) {
|
|
2841
|
-
const resolvedDirs = scanDirs.map((dir) =>
|
|
3787
|
+
const resolvedDirs = scanDirs.map((dir) => path6__default.resolve(root, dir));
|
|
2842
3788
|
if (resolvedDirs.length === 0) return scan;
|
|
2843
3789
|
const files = scan.files.filter((file) => {
|
|
2844
|
-
const absoluteFile =
|
|
3790
|
+
const absoluteFile = path6__default.resolve(file.file);
|
|
2845
3791
|
return resolvedDirs.some((directory) => isInsideDirectory(absoluteFile, directory));
|
|
2846
3792
|
});
|
|
2847
3793
|
const uniqueClasses = Array.from(new Set(files.flatMap((file) => file.classes))).sort();
|
|
@@ -2852,9 +3798,9 @@ function filterScanToDirs(scan, root, scanDirs) {
|
|
|
2852
3798
|
};
|
|
2853
3799
|
}
|
|
2854
3800
|
function writeJsonArtifact(root, relativePath, value) {
|
|
2855
|
-
const outputPath =
|
|
2856
|
-
|
|
2857
|
-
|
|
3801
|
+
const outputPath = path6__default.resolve(root, relativePath);
|
|
3802
|
+
fs4__default.mkdirSync(path6__default.dirname(outputPath), { recursive: true });
|
|
3803
|
+
fs4__default.writeFileSync(outputPath, `${JSON.stringify(value, null, 2)}
|
|
2858
3804
|
`);
|
|
2859
3805
|
}
|
|
2860
3806
|
function tailwindStyledPlugin(opts = {}) {
|