tailwind-styled-v4 5.0.11 → 5.0.12
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/dist/{analyzeWorkspace-DDOQdzzI.d.ts → analyzeWorkspace-CopJNGmi.d.ts} +2 -0
- package/dist/{analyzeWorkspace-BS5O4rhC.d.mts → analyzeWorkspace-DpVPccjz.d.mts} +2 -0
- package/dist/analyzer.d.mts +4 -4
- package/dist/analyzer.d.ts +4 -4
- package/dist/analyzer.js +34 -69
- package/dist/analyzer.js.map +1 -1
- package/dist/analyzer.mjs +33 -68
- package/dist/analyzer.mjs.map +1 -1
- package/dist/animate.js +11 -11
- package/dist/animate.js.map +1 -1
- package/dist/animate.mjs +11 -11
- package/dist/animate.mjs.map +1 -1
- package/dist/atomic.js +16 -7
- package/dist/atomic.js.map +1 -1
- package/dist/atomic.mjs +16 -7
- package/dist/atomic.mjs.map +1 -1
- package/dist/cli.js +262 -190
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +259 -187
- package/dist/cli.mjs.map +1 -1
- package/dist/compiler.d.mts +2543 -109
- package/dist/compiler.d.ts +2543 -109
- package/dist/compiler.js +1962 -435
- package/dist/compiler.js.map +1 -1
- package/dist/compiler.mjs +1816 -382
- package/dist/compiler.mjs.map +1 -1
- package/dist/devtools.js +17 -4
- package/dist/devtools.js.map +1 -1
- package/dist/devtools.mjs +17 -4
- package/dist/devtools.mjs.map +1 -1
- package/dist/engine.d.mts +11 -470
- package/dist/engine.d.ts +11 -470
- package/dist/engine.js +1442 -417
- package/dist/engine.js.map +1 -1
- package/dist/engine.mjs +1442 -417
- package/dist/engine.mjs.map +1 -1
- package/dist/index-BDQw13kn.d.ts +464 -0
- package/dist/index-DJv28Uzq.d.mts +464 -0
- package/dist/index.browser.mjs +143 -255
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.d.mts +23 -39
- package/dist/index.d.ts +23 -39
- package/dist/index.js +6000 -1463
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5995 -1458
- package/dist/index.mjs.map +1 -1
- package/dist/next.d.mts +44 -1
- package/dist/next.d.ts +44 -1
- package/dist/next.js +3197 -1128
- package/dist/next.js.map +1 -1
- package/dist/next.mjs +3196 -1129
- package/dist/next.mjs.map +1 -1
- package/dist/rspack.d.mts +9 -0
- package/dist/rspack.d.ts +9 -0
- package/dist/rspack.js +99 -61
- package/dist/rspack.js.map +1 -1
- package/dist/rspack.mjs +99 -61
- package/dist/rspack.mjs.map +1 -1
- package/dist/runtime-css.d.mts +8 -0
- package/dist/runtime-css.d.ts +8 -0
- package/dist/runtime-css.js +23 -7
- package/dist/runtime-css.js.map +1 -1
- package/dist/runtime-css.mjs +23 -7
- package/dist/runtime-css.mjs.map +1 -1
- package/dist/scanner.js +16 -37
- package/dist/scanner.js.map +1 -1
- package/dist/scanner.mjs +15 -36
- package/dist/scanner.mjs.map +1 -1
- package/dist/shared.d.mts +107 -1
- package/dist/shared.d.ts +107 -1
- package/dist/shared.js +1627 -376
- package/dist/shared.js.map +1 -1
- package/dist/shared.mjs +1620 -354
- package/dist/shared.mjs.map +1 -1
- package/dist/svelte.js +39 -35
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +38 -34
- package/dist/svelte.mjs.map +1 -1
- package/dist/theme.js +85 -76
- package/dist/theme.js.map +1 -1
- package/dist/theme.mjs +83 -74
- package/dist/theme.mjs.map +1 -1
- package/dist/turbopackLoader.js +943 -76
- package/dist/turbopackLoader.js.map +1 -1
- package/dist/turbopackLoader.mjs +943 -76
- package/dist/turbopackLoader.mjs.map +1 -1
- package/dist/tw.js +262 -190
- package/dist/tw.js.map +1 -1
- package/dist/tw.mjs +259 -187
- package/dist/tw.mjs.map +1 -1
- package/dist/vite.js +1336 -296
- package/dist/vite.js.map +1 -1
- package/dist/vite.mjs +1336 -296
- package/dist/vite.mjs.map +1 -1
- package/dist/vue.js +39 -35
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +38 -34
- package/dist/vue.mjs.map +1 -1
- package/dist/webpackLoader.js +140 -34
- package/dist/webpackLoader.js.map +1 -1
- package/dist/webpackLoader.mjs +140 -34
- package/dist/webpackLoader.mjs.map +1 -1
- package/native/index.node +0 -0
- package/native/tailwind-styled-native.node +0 -0
- package/native/tailwind-styled-native.win32-x64-msvc.node +0 -0
- package/package.json +9 -4
- package/CHANGELOG.md +0 -285
package/dist/engine.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
|
-
import * as
|
|
4
|
-
import
|
|
5
|
-
import * as
|
|
6
|
-
import
|
|
3
|
+
import * as fs3 from 'fs';
|
|
4
|
+
import fs3__default from 'fs';
|
|
5
|
+
import * as path9 from 'path';
|
|
6
|
+
import path9__default from 'path';
|
|
7
7
|
import { createHash } from 'crypto';
|
|
8
8
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
9
9
|
import { Worker, isMainThread, parentPort, workerData } from 'worker_threads';
|
|
@@ -220,9 +220,9 @@ function parseNative(schema, data, context) {
|
|
|
220
220
|
const result = schema.safeParse(data);
|
|
221
221
|
if (!result.success) {
|
|
222
222
|
const first = result.error.issues[0];
|
|
223
|
-
const
|
|
223
|
+
const path16 = first?.path?.join(".") ?? "(root)";
|
|
224
224
|
throw new Error(
|
|
225
|
-
`[${context}] Native binding returned unexpected data: ${
|
|
225
|
+
`[${context}] Native binding returned unexpected data: ${path16}: ${first?.message ?? "validation failed"}`
|
|
226
226
|
);
|
|
227
227
|
}
|
|
228
228
|
return result.data;
|
|
@@ -615,11 +615,11 @@ function resolvePath(...segments) {
|
|
|
615
615
|
return segments.join("/").replace(/\/+/g, "/");
|
|
616
616
|
}
|
|
617
617
|
}
|
|
618
|
-
function existsSync(
|
|
618
|
+
function existsSync(path16) {
|
|
619
619
|
if (isBrowser2) return false;
|
|
620
620
|
try {
|
|
621
621
|
const nodeFs = __require(NODE_FS);
|
|
622
|
-
return nodeFs.existsSync(
|
|
622
|
+
return nodeFs.existsSync(path16);
|
|
623
623
|
} catch {
|
|
624
624
|
return false;
|
|
625
625
|
}
|
|
@@ -849,12 +849,12 @@ function resolveNativeBinary(runtimeDir) {
|
|
|
849
849
|
if (isBrowser3) {
|
|
850
850
|
return { path: null, source: "not-found", platform, tried: ["not available in browser"] };
|
|
851
851
|
}
|
|
852
|
-
if (process.env.TWS_DISABLE_NATIVE === "1") {
|
|
852
|
+
if (process.env.TWS_NO_NATIVE === "1" || process.env.TWS_DISABLE_NATIVE === "1") {
|
|
853
853
|
return { path: null, source: "not-found", platform, tried: [] };
|
|
854
854
|
}
|
|
855
855
|
const envPath = process.env.TW_NATIVE_PATH?.trim();
|
|
856
856
|
if (envPath) {
|
|
857
|
-
if (
|
|
857
|
+
if (fs3.existsSync(envPath)) {
|
|
858
858
|
return { path: envPath, source: "env", platform, tried };
|
|
859
859
|
}
|
|
860
860
|
tried.push(`env:${envPath} (not found)`);
|
|
@@ -863,7 +863,7 @@ function resolveNativeBinary(runtimeDir) {
|
|
|
863
863
|
for (const pkg of prebuiltPkgs) {
|
|
864
864
|
try {
|
|
865
865
|
const candidate = _require.resolve(`${pkg}/tailwind_styled_parser.node`);
|
|
866
|
-
if (
|
|
866
|
+
if (fs3.existsSync(candidate)) {
|
|
867
867
|
return { path: candidate, source: "prebuilt", platform, tried };
|
|
868
868
|
}
|
|
869
869
|
tried.push(`prebuilt:${pkg} (resolved but missing)`);
|
|
@@ -874,13 +874,13 @@ function resolveNativeBinary(runtimeDir) {
|
|
|
874
874
|
const napiPlatform = platform === "linux-x64" ? "linux-x64-gnu" : platform === "linux-arm64" ? "linux-arm64-gnu" : platform;
|
|
875
875
|
const BINARY_NAMES_SELF = ["tailwind-styled-native", "tailwind_styled_parser"];
|
|
876
876
|
if (runtimeDir) {
|
|
877
|
-
for (const depth of ["..",
|
|
878
|
-
const pkgRoot =
|
|
877
|
+
for (const depth of ["..", path9.join("..", ".."), path9.join("..", "..", "..")]) {
|
|
878
|
+
const pkgRoot = path9.resolve(runtimeDir, depth);
|
|
879
879
|
for (const bin of BINARY_NAMES_SELF) {
|
|
880
880
|
for (const suffix of ["", `.${platform}`, `.${napiPlatform}`]) {
|
|
881
|
-
const candidate =
|
|
881
|
+
const candidate = path9.resolve(pkgRoot, "native", `${bin}${suffix}.node`);
|
|
882
882
|
tried.push(`self-bundled:${candidate}`);
|
|
883
|
-
if (
|
|
883
|
+
if (fs3.existsSync(candidate)) {
|
|
884
884
|
return { path: candidate, source: "prebuilt", platform, tried };
|
|
885
885
|
}
|
|
886
886
|
}
|
|
@@ -892,29 +892,29 @@ function resolveNativeBinary(runtimeDir) {
|
|
|
892
892
|
const BINARY_NAMES = ["tailwind-styled-native", "tailwind_styled_parser"];
|
|
893
893
|
const localCandidates = [];
|
|
894
894
|
for (const bin of BINARY_NAMES) {
|
|
895
|
-
localCandidates.push(
|
|
896
|
-
localCandidates.push(
|
|
897
|
-
localCandidates.push(
|
|
898
|
-
localCandidates.push(
|
|
895
|
+
localCandidates.push(path9.resolve(base, `${bin}.node`));
|
|
896
|
+
localCandidates.push(path9.resolve(base, "..", `${bin}.node`));
|
|
897
|
+
localCandidates.push(path9.resolve(base, `${bin}.${platform}.node`));
|
|
898
|
+
localCandidates.push(path9.resolve(base, `${bin}.${napiPlatform}.node`));
|
|
899
899
|
}
|
|
900
900
|
for (const startDir of [cwd, base]) {
|
|
901
901
|
let dir = startDir;
|
|
902
902
|
for (let i = 0; i < 6; i++) {
|
|
903
|
-
const nativeDir =
|
|
903
|
+
const nativeDir = path9.resolve(dir, "native");
|
|
904
904
|
for (const bin of BINARY_NAMES) {
|
|
905
|
-
localCandidates.push(
|
|
906
|
-
localCandidates.push(
|
|
907
|
-
localCandidates.push(
|
|
908
|
-
localCandidates.push(
|
|
905
|
+
localCandidates.push(path9.resolve(nativeDir, `${bin}.node`));
|
|
906
|
+
localCandidates.push(path9.resolve(nativeDir, `${bin}.${platform}.node`));
|
|
907
|
+
localCandidates.push(path9.resolve(nativeDir, `${bin}.${napiPlatform}.node`));
|
|
908
|
+
localCandidates.push(path9.resolve(nativeDir, "target", "release", `${bin}.node`));
|
|
909
909
|
}
|
|
910
|
-
const parent =
|
|
910
|
+
const parent = path9.resolve(dir, "..");
|
|
911
911
|
if (parent === dir) break;
|
|
912
912
|
dir = parent;
|
|
913
913
|
}
|
|
914
914
|
}
|
|
915
915
|
for (const candidate of localCandidates) {
|
|
916
916
|
tried.push(`local:${candidate}`);
|
|
917
|
-
if (
|
|
917
|
+
if (fs3.existsSync(candidate)) {
|
|
918
918
|
return { path: candidate, source: "local", platform, tried };
|
|
919
919
|
}
|
|
920
920
|
}
|
|
@@ -953,9 +953,9 @@ var init_native_resolution = __esm({
|
|
|
953
953
|
// packages/domain/shared/src/observability.ts
|
|
954
954
|
function createObservabilityClient(opts = {}) {
|
|
955
955
|
const { baseUrl = "http://localhost:7421", timeoutMs = 3e3 } = opts;
|
|
956
|
-
async function fetchJson(
|
|
956
|
+
async function fetchJson(path16) {
|
|
957
957
|
try {
|
|
958
|
-
const res = await fetch(`${baseUrl}${
|
|
958
|
+
const res = await fetch(`${baseUrl}${path16}`, {
|
|
959
959
|
signal: AbortSignal.timeout(timeoutMs)
|
|
960
960
|
});
|
|
961
961
|
if (!res.ok) return null;
|
|
@@ -987,6 +987,1182 @@ var init_observability = __esm({
|
|
|
987
987
|
}
|
|
988
988
|
});
|
|
989
989
|
|
|
990
|
+
// packages/domain/compiler/src/nativeBridge.ts
|
|
991
|
+
var _loadNative, log, NATIVE_UNAVAILABLE_MESSAGE, nativeBridge, bridgeLoadAttempted, bridgeLoadError, isValidNativeBridge, getNativeBridge, adaptNativeResult;
|
|
992
|
+
var init_nativeBridge = __esm({
|
|
993
|
+
"packages/domain/compiler/src/nativeBridge.ts"() {
|
|
994
|
+
init_src2();
|
|
995
|
+
_loadNative = (path16) => __require(path16);
|
|
996
|
+
log = (...args) => {
|
|
997
|
+
if (process.env.DEBUG?.includes("compiler:native")) {
|
|
998
|
+
console.log("[compiler:native]", ...args);
|
|
999
|
+
}
|
|
1000
|
+
};
|
|
1001
|
+
NATIVE_UNAVAILABLE_MESSAGE = "[tailwind-styled/compiler v5] Native binding is required but not available.\nThis package requires native Rust bindings. There is no JavaScript fallback.\nPlease ensure:\n 1. The native module is properly installed\n 2. You have run: npm run build:rust (or use prebuilt binary)\n\nFor help, see: https://tailwind-styled.dev/docs/install";
|
|
1002
|
+
nativeBridge = null;
|
|
1003
|
+
bridgeLoadAttempted = false;
|
|
1004
|
+
bridgeLoadError = null;
|
|
1005
|
+
isValidNativeBridge = (mod) => {
|
|
1006
|
+
const m = mod;
|
|
1007
|
+
return !!(typeof m.transformSource === "function" || typeof m.extractAllClasses === "function" || typeof m.hasTwUsage === "function");
|
|
1008
|
+
};
|
|
1009
|
+
getNativeBridge = () => {
|
|
1010
|
+
if (nativeBridge) {
|
|
1011
|
+
return nativeBridge;
|
|
1012
|
+
}
|
|
1013
|
+
if (bridgeLoadAttempted) {
|
|
1014
|
+
if (bridgeLoadError) {
|
|
1015
|
+
throw bridgeLoadError;
|
|
1016
|
+
}
|
|
1017
|
+
throw new Error(NATIVE_UNAVAILABLE_MESSAGE);
|
|
1018
|
+
}
|
|
1019
|
+
bridgeLoadAttempted = true;
|
|
1020
|
+
try {
|
|
1021
|
+
const runtimeDir = resolveRuntimeDir(void 0, import.meta.url);
|
|
1022
|
+
const result = resolveNativeBinary(runtimeDir);
|
|
1023
|
+
if (result.path && result.path.endsWith(".node")) {
|
|
1024
|
+
try {
|
|
1025
|
+
const binding = _loadNative(result.path);
|
|
1026
|
+
if (isValidNativeBridge(binding)) {
|
|
1027
|
+
nativeBridge = binding;
|
|
1028
|
+
log("Native bridge loaded successfully from:", result.path);
|
|
1029
|
+
return nativeBridge;
|
|
1030
|
+
}
|
|
1031
|
+
} catch (e) {
|
|
1032
|
+
log("Failed to require native binding:", e);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
throw new Error(`${NATIVE_UNAVAILABLE_MESSAGE}
|
|
1036
|
+
|
|
1037
|
+
Tried paths: ${result.tried.join("\n")}`);
|
|
1038
|
+
} catch (err) {
|
|
1039
|
+
bridgeLoadError = err instanceof Error ? err : new Error(String(err));
|
|
1040
|
+
log("Failed to load native bridge:", bridgeLoadError.message);
|
|
1041
|
+
throw bridgeLoadError;
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
adaptNativeResult = (raw) => {
|
|
1045
|
+
return {
|
|
1046
|
+
code: raw.code ?? "",
|
|
1047
|
+
classes: raw.classes ?? [],
|
|
1048
|
+
changed: raw.changed ?? false,
|
|
1049
|
+
rsc: raw.rscJson ? JSON.parse(raw.rscJson) : void 0,
|
|
1050
|
+
metadata: raw.metadataJson ? JSON.parse(raw.metadataJson) : void 0
|
|
1051
|
+
};
|
|
1052
|
+
};
|
|
1053
|
+
if (typeof process !== "undefined" && !bridgeLoadAttempted) {
|
|
1054
|
+
try {
|
|
1055
|
+
getNativeBridge();
|
|
1056
|
+
} catch {
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
});
|
|
1061
|
+
|
|
1062
|
+
// packages/domain/compiler/src/tailwindEngine.ts
|
|
1063
|
+
var tailwindEngine_exports = {};
|
|
1064
|
+
__export(tailwindEngine_exports, {
|
|
1065
|
+
clearCache: () => clearCache,
|
|
1066
|
+
generateRawCss: () => generateRawCss,
|
|
1067
|
+
getCacheStats: () => getCacheStats,
|
|
1068
|
+
processTailwindCssWithTargets: () => processTailwindCssWithTargets,
|
|
1069
|
+
runCssPipeline: () => runCssPipeline,
|
|
1070
|
+
runCssPipelineSync: () => runCssPipelineSync
|
|
1071
|
+
});
|
|
1072
|
+
function _getCacheKey(classes, minify, cssEntry, root) {
|
|
1073
|
+
const sorted = [...classes].sort().join(",");
|
|
1074
|
+
const flags = `${minify ? "1" : "0"}${cssEntry ? "1" : "0"}${root ? "1" : "0"}`;
|
|
1075
|
+
return `${sorted}|${flags}`;
|
|
1076
|
+
}
|
|
1077
|
+
function _evictOldestIfNeeded() {
|
|
1078
|
+
if (_cssCache.size >= MAX_CACHE_SIZE) {
|
|
1079
|
+
const firstKey = _cssCache.keys().next().value;
|
|
1080
|
+
if (firstKey !== void 0) {
|
|
1081
|
+
_cssCache.delete(firstKey);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
function getCacheStats() {
|
|
1086
|
+
const total = _cacheHits + _cacheMisses;
|
|
1087
|
+
return {
|
|
1088
|
+
hits: _cacheHits,
|
|
1089
|
+
misses: _cacheMisses,
|
|
1090
|
+
hitRate: total > 0 ? _cacheHits / total : 0,
|
|
1091
|
+
size: _cssCache.size,
|
|
1092
|
+
maxSize: MAX_CACHE_SIZE
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
function clearCache() {
|
|
1096
|
+
_cssCache.clear();
|
|
1097
|
+
_cacheHits = 0;
|
|
1098
|
+
_cacheMisses = 0;
|
|
1099
|
+
}
|
|
1100
|
+
function loadTailwindEngine() {
|
|
1101
|
+
if (_twEngine) return _twEngine;
|
|
1102
|
+
if (_twEngineError) throw _twEngineError;
|
|
1103
|
+
try {
|
|
1104
|
+
const tw = require2("tailwindcss");
|
|
1105
|
+
if (typeof tw.compile !== "function") {
|
|
1106
|
+
throw new Error("tailwindcss v4 not found \u2014 compile() API missing. Check tailwindcss version >= 4.");
|
|
1107
|
+
}
|
|
1108
|
+
_twEngine = tw;
|
|
1109
|
+
return _twEngine;
|
|
1110
|
+
} catch (e) {
|
|
1111
|
+
_twEngineError = e instanceof Error ? e : new Error(String(e));
|
|
1112
|
+
throw _twEngineError;
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
async function generateRawCss(classes, cssEntryContent, root) {
|
|
1116
|
+
if (classes.length === 0) return "";
|
|
1117
|
+
const tw = loadTailwindEngine();
|
|
1118
|
+
const input = cssEntryContent ?? "@import 'tailwindcss';";
|
|
1119
|
+
const { readFileSync, existsSync: existsSync3 } = await import('fs');
|
|
1120
|
+
const { dirname, resolve: resolve2 } = await import('path');
|
|
1121
|
+
const projectRoot = root ?? process.cwd();
|
|
1122
|
+
const req = createRequire(resolve2(projectRoot, "package.json"));
|
|
1123
|
+
const loadStylesheet = async (id, base) => {
|
|
1124
|
+
try {
|
|
1125
|
+
const cssId = id === "tailwindcss" ? "tailwindcss/index.css" : id === "tailwindcss/preflight" ? "tailwindcss/preflight.css" : id === "tailwindcss/utilities" ? "tailwindcss/utilities.css" : id === "tailwindcss/theme" ? "tailwindcss/theme.css" : id;
|
|
1126
|
+
const pkgPath = req.resolve(cssId);
|
|
1127
|
+
return { content: readFileSync(pkgPath, "utf-8"), base: dirname(pkgPath) };
|
|
1128
|
+
} catch {
|
|
1129
|
+
try {
|
|
1130
|
+
const absPath = resolve2(base, id);
|
|
1131
|
+
if (existsSync3(absPath)) {
|
|
1132
|
+
return { content: readFileSync(absPath, "utf-8"), base: dirname(absPath) };
|
|
1133
|
+
}
|
|
1134
|
+
} catch {
|
|
1135
|
+
}
|
|
1136
|
+
return { content: "", base };
|
|
1137
|
+
}
|
|
1138
|
+
};
|
|
1139
|
+
const compiler = await Promise.resolve(tw.compile(input, { loadStylesheet }));
|
|
1140
|
+
return compiler.build(classes);
|
|
1141
|
+
}
|
|
1142
|
+
function getThemeConfig() {
|
|
1143
|
+
return {
|
|
1144
|
+
colors: {
|
|
1145
|
+
slate: {
|
|
1146
|
+
"50": "#f8fafc",
|
|
1147
|
+
"100": "#f1f5f9",
|
|
1148
|
+
"200": "#e2e8f0",
|
|
1149
|
+
"300": "#cbd5e1",
|
|
1150
|
+
"400": "#94a3b8",
|
|
1151
|
+
"500": "#64748b",
|
|
1152
|
+
"600": "#475569",
|
|
1153
|
+
"700": "#334155",
|
|
1154
|
+
"800": "#1e293b",
|
|
1155
|
+
"900": "#0f172a"
|
|
1156
|
+
},
|
|
1157
|
+
gray: {
|
|
1158
|
+
"50": "#f9fafb",
|
|
1159
|
+
"100": "#f3f4f6",
|
|
1160
|
+
"200": "#e5e7eb",
|
|
1161
|
+
"300": "#d1d5db",
|
|
1162
|
+
"400": "#9ca3af",
|
|
1163
|
+
"500": "#6b7280",
|
|
1164
|
+
"600": "#4b5563",
|
|
1165
|
+
"700": "#374151",
|
|
1166
|
+
"800": "#1f2937",
|
|
1167
|
+
"900": "#111827"
|
|
1168
|
+
},
|
|
1169
|
+
white: "#ffffff",
|
|
1170
|
+
black: "#000000",
|
|
1171
|
+
red: {
|
|
1172
|
+
"500": "#ef4444",
|
|
1173
|
+
"600": "#dc2626"
|
|
1174
|
+
},
|
|
1175
|
+
blue: {
|
|
1176
|
+
"500": "#3b82f6",
|
|
1177
|
+
"600": "#1e40af"
|
|
1178
|
+
}
|
|
1179
|
+
},
|
|
1180
|
+
spacing: {
|
|
1181
|
+
"0": "0px",
|
|
1182
|
+
"1": "0.25rem",
|
|
1183
|
+
"2": "0.5rem",
|
|
1184
|
+
"3": "0.75rem",
|
|
1185
|
+
"4": "1rem",
|
|
1186
|
+
"5": "1.25rem",
|
|
1187
|
+
"6": "1.5rem",
|
|
1188
|
+
"8": "2rem",
|
|
1189
|
+
"10": "2.5rem",
|
|
1190
|
+
"12": "3rem",
|
|
1191
|
+
"16": "4rem",
|
|
1192
|
+
"20": "5rem",
|
|
1193
|
+
"24": "6rem"
|
|
1194
|
+
},
|
|
1195
|
+
breakpoints: {
|
|
1196
|
+
"sm": "640px",
|
|
1197
|
+
"md": "768px",
|
|
1198
|
+
"lg": "1024px",
|
|
1199
|
+
"xl": "1280px",
|
|
1200
|
+
"2xl": "1536px"
|
|
1201
|
+
}
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
function postProcessWithLightning(rawCss) {
|
|
1205
|
+
if (!rawCss) return "";
|
|
1206
|
+
const native = getNativeBridge();
|
|
1207
|
+
if (!native?.processTailwindCssLightning) {
|
|
1208
|
+
throw new Error("FATAL: Native binding 'processTailwindCssLightning' is required but not available.");
|
|
1209
|
+
}
|
|
1210
|
+
const result = native.processTailwindCssLightning(rawCss);
|
|
1211
|
+
if (!result?.css) {
|
|
1212
|
+
throw new Error("FATAL: processTailwindCssLightning returned null");
|
|
1213
|
+
}
|
|
1214
|
+
return result.css;
|
|
1215
|
+
}
|
|
1216
|
+
async function runCssPipeline(classes, cssEntryContent, root, minify = true) {
|
|
1217
|
+
const filtered = classes.filter(Boolean);
|
|
1218
|
+
const uniqueMap = /* @__PURE__ */ new Map();
|
|
1219
|
+
filtered.forEach((cls) => uniqueMap.set(cls, cls));
|
|
1220
|
+
const unique = Array.from(uniqueMap.values());
|
|
1221
|
+
if (unique.length === 0) {
|
|
1222
|
+
return { css: "", classes: [], sizeBytes: 0, optimized: false };
|
|
1223
|
+
}
|
|
1224
|
+
const cacheKey = _getCacheKey(unique, minify, cssEntryContent, root);
|
|
1225
|
+
const cached = _cssCache.get(cacheKey);
|
|
1226
|
+
if (cached) {
|
|
1227
|
+
_cacheHits++;
|
|
1228
|
+
if (process.env.DEBUG?.includes("compiler")) {
|
|
1229
|
+
console.log(
|
|
1230
|
+
`[Compiler] Cache HIT: ${unique.length} classes (hit rate: ${(getCacheStats().hitRate * 100).toFixed(1)}%)`
|
|
1231
|
+
);
|
|
1232
|
+
}
|
|
1233
|
+
return cached;
|
|
1234
|
+
}
|
|
1235
|
+
_cacheMisses++;
|
|
1236
|
+
let rawCss;
|
|
1237
|
+
let usedRustCompiler = false;
|
|
1238
|
+
try {
|
|
1239
|
+
const theme = getThemeConfig();
|
|
1240
|
+
rawCss = await generateCssNative(unique, {
|
|
1241
|
+
theme,
|
|
1242
|
+
fallbackToJs: true,
|
|
1243
|
+
logFallback: process.env.DEBUG?.includes("compiler") === true
|
|
1244
|
+
});
|
|
1245
|
+
usedRustCompiler = true;
|
|
1246
|
+
} catch (error) {
|
|
1247
|
+
if (process.env.DEBUG?.includes("compiler")) {
|
|
1248
|
+
console.warn("[Compiler] Rust compiler failed, using JavaScript Tailwind:", error);
|
|
1249
|
+
}
|
|
1250
|
+
rawCss = await generateRawCss(unique, cssEntryContent, root);
|
|
1251
|
+
}
|
|
1252
|
+
const finalCss = minify ? postProcessWithLightning(rawCss) : rawCss;
|
|
1253
|
+
if (process.env.DEBUG?.includes("compiler")) {
|
|
1254
|
+
console.log(
|
|
1255
|
+
`[Compiler] Generated CSS from ${unique.length} classes (${usedRustCompiler ? "Rust" : "JavaScript"})`,
|
|
1256
|
+
`Size: ${finalCss.length} bytes`
|
|
1257
|
+
);
|
|
1258
|
+
}
|
|
1259
|
+
const result = {
|
|
1260
|
+
css: finalCss,
|
|
1261
|
+
classes: unique,
|
|
1262
|
+
sizeBytes: finalCss.length,
|
|
1263
|
+
optimized: minify
|
|
1264
|
+
};
|
|
1265
|
+
_evictOldestIfNeeded();
|
|
1266
|
+
_cssCache.set(cacheKey, result);
|
|
1267
|
+
return result;
|
|
1268
|
+
}
|
|
1269
|
+
function runCssPipelineSync(_classes) {
|
|
1270
|
+
return { css: "", classes: [], sizeBytes: 0, optimized: false };
|
|
1271
|
+
}
|
|
1272
|
+
function processTailwindCssWithTargets(css, targets) {
|
|
1273
|
+
const native = getNativeBridge();
|
|
1274
|
+
if (!native?.processTailwindCssWithTargets) {
|
|
1275
|
+
throw new Error("FATAL: Native binding 'processTailwindCssWithTargets' is required but not available.");
|
|
1276
|
+
}
|
|
1277
|
+
const result = native.processTailwindCssWithTargets(css, targets ?? null);
|
|
1278
|
+
if (!result?.css) {
|
|
1279
|
+
throw new Error("FATAL: processTailwindCssWithTargets returned null");
|
|
1280
|
+
}
|
|
1281
|
+
return result.css;
|
|
1282
|
+
}
|
|
1283
|
+
var require2, _cssCache, _cacheHits, _cacheMisses, MAX_CACHE_SIZE, _twEngine, _twEngineError;
|
|
1284
|
+
var init_tailwindEngine = __esm({
|
|
1285
|
+
"packages/domain/compiler/src/tailwindEngine.ts"() {
|
|
1286
|
+
init_nativeBridge();
|
|
1287
|
+
init_cssGeneratorNative();
|
|
1288
|
+
require2 = createRequire(import.meta.url);
|
|
1289
|
+
_cssCache = /* @__PURE__ */ new Map();
|
|
1290
|
+
_cacheHits = 0;
|
|
1291
|
+
_cacheMisses = 0;
|
|
1292
|
+
MAX_CACHE_SIZE = 100;
|
|
1293
|
+
_twEngine = null;
|
|
1294
|
+
_twEngineError = null;
|
|
1295
|
+
}
|
|
1296
|
+
});
|
|
1297
|
+
|
|
1298
|
+
// packages/domain/compiler/src/cssGeneratorNative.ts
|
|
1299
|
+
async function generateCssNative(classes, options) {
|
|
1300
|
+
const {
|
|
1301
|
+
theme,
|
|
1302
|
+
fallbackToJs = true,
|
|
1303
|
+
logFallback = false
|
|
1304
|
+
} = options;
|
|
1305
|
+
try {
|
|
1306
|
+
const native = getNativeBridge();
|
|
1307
|
+
if (!native?.generateCssNative) {
|
|
1308
|
+
throw new Error("generateCssNative not available in native binding");
|
|
1309
|
+
}
|
|
1310
|
+
const themeJson = JSON.stringify(theme);
|
|
1311
|
+
const css = native.generateCssNative(classes, themeJson);
|
|
1312
|
+
return css;
|
|
1313
|
+
} catch (error) {
|
|
1314
|
+
if (!fallbackToJs) {
|
|
1315
|
+
throw error;
|
|
1316
|
+
}
|
|
1317
|
+
if (logFallback) {
|
|
1318
|
+
console.warn(
|
|
1319
|
+
"[CSS Compiler] Rust CSS generator unavailable, falling back to JavaScript Tailwind",
|
|
1320
|
+
error instanceof Error ? error.message : String(error)
|
|
1321
|
+
);
|
|
1322
|
+
}
|
|
1323
|
+
return generateRawCss(classes);
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
var init_cssGeneratorNative = __esm({
|
|
1327
|
+
"packages/domain/compiler/src/cssGeneratorNative.ts"() {
|
|
1328
|
+
init_nativeBridge();
|
|
1329
|
+
init_tailwindEngine();
|
|
1330
|
+
}
|
|
1331
|
+
});
|
|
1332
|
+
function _layoutClassesToCss(classes) {
|
|
1333
|
+
const native = getNativeBridge();
|
|
1334
|
+
if (!native?.layoutClassesToCss) {
|
|
1335
|
+
throw new Error("FATAL: Native binding 'layoutClassesToCss' is required but not available.");
|
|
1336
|
+
}
|
|
1337
|
+
return native.layoutClassesToCss(classes);
|
|
1338
|
+
}
|
|
1339
|
+
function _hashContainer(tag, containerJson, name) {
|
|
1340
|
+
const sortedKey = tag + (name ?? "") + containerJson;
|
|
1341
|
+
const native = getNativeBridge();
|
|
1342
|
+
if (!native?.hashContent) {
|
|
1343
|
+
throw new Error("FATAL: Native binding 'hashContent' is required but not available.");
|
|
1344
|
+
}
|
|
1345
|
+
return `tw-cq-${native.hashContent(sortedKey, "fnv", 6)}`;
|
|
1346
|
+
}
|
|
1347
|
+
function extractContainerCssFromSource(source) {
|
|
1348
|
+
const native = getNativeBridge();
|
|
1349
|
+
if (!native?.extractTwContainerConfigs) {
|
|
1350
|
+
throw new Error("FATAL: Native binding 'extractTwContainerConfigs' is required but not available.");
|
|
1351
|
+
}
|
|
1352
|
+
const configs = native.extractTwContainerConfigs(source);
|
|
1353
|
+
const rules = [];
|
|
1354
|
+
for (const cfg of configs) {
|
|
1355
|
+
const id = _hashContainer(cfg.tag, cfg.containerJson, cfg.containerName);
|
|
1356
|
+
for (const { key, classes } of cfg.breakpoints) {
|
|
1357
|
+
const minWidth = _CONTAINER_BREAKPOINTS[key] ?? key;
|
|
1358
|
+
const css = _layoutClassesToCss(classes);
|
|
1359
|
+
if (!css) continue;
|
|
1360
|
+
const query = cfg.containerName ? `@container ${cfg.containerName} (min-width: ${minWidth})` : `@container (min-width: ${minWidth})`;
|
|
1361
|
+
rules.push(`${query}{.${id}{${css}}}`);
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
return rules.join("\n");
|
|
1365
|
+
}
|
|
1366
|
+
var transformSource, hasTwUsage, isAlreadyTransformed, shouldProcess, compileCssFromClasses, buildStyleTag, compileCssNative, generateCssForClasses, extractAllClasses, extractClassesFromSource, astExtractClasses, parseClasses, normalizeClasses, mergeClassesStatic, normalizeAndDedupClasses, eliminateDeadCss, findDeadVariants, runElimination, optimizeCss, scanProjectUsage, extractComponentUsage, diffClassLists, batchExtractClasses, checkAgainstSafelist, hoistComponents, compileVariantTable, compileVariants, classifyAndSortClasses, mergeCssDeclarations, analyzeClassUsage, analyzeRsc, analyzeFile, analyzeVariantUsage, injectClientDirective, injectServerOnlyComment, analyzeClasses, generateSafelist, loadSafelist, loadTailwindConfig, getContentPaths, _CONTAINER_BREAKPOINTS, runLoaderTransform, shouldSkipFile, fileToRoute, getAllRoutes, getRouteClasses, registerFileClasses, registerGlobalClasses, _incrementalEngineInstance, getIncrementalEngine, resetIncrementalEngine, IncrementalEngine, getBucketEngine, resetBucketEngine, classifyNode, detectConflicts, bucketSort, extractTwStateConfigs, generateStaticStateCss, extractAndGenerateStateCss;
|
|
1367
|
+
var init_src = __esm({
|
|
1368
|
+
"packages/domain/compiler/src/index.ts"() {
|
|
1369
|
+
init_nativeBridge();
|
|
1370
|
+
transformSource = (source, opts) => {
|
|
1371
|
+
const native = getNativeBridge();
|
|
1372
|
+
if (!native?.transformSource) {
|
|
1373
|
+
throw new Error("FATAL: Native binding 'transformSource' is required but not available.");
|
|
1374
|
+
}
|
|
1375
|
+
const result = native.transformSource(source, opts);
|
|
1376
|
+
if (!result) {
|
|
1377
|
+
throw new Error("FATAL: transformSource returned null");
|
|
1378
|
+
}
|
|
1379
|
+
return result;
|
|
1380
|
+
};
|
|
1381
|
+
hasTwUsage = (source) => {
|
|
1382
|
+
const native = getNativeBridge();
|
|
1383
|
+
if (!native?.hasTwUsage) {
|
|
1384
|
+
throw new Error("FATAL: Native binding 'hasTwUsage' is required but not available.");
|
|
1385
|
+
}
|
|
1386
|
+
return native.hasTwUsage(source);
|
|
1387
|
+
};
|
|
1388
|
+
isAlreadyTransformed = (source) => {
|
|
1389
|
+
const native = getNativeBridge();
|
|
1390
|
+
if (!native?.isAlreadyTransformed) {
|
|
1391
|
+
throw new Error("FATAL: Native binding 'isAlreadyTransformed' is required but not available.");
|
|
1392
|
+
}
|
|
1393
|
+
return native.isAlreadyTransformed(source);
|
|
1394
|
+
};
|
|
1395
|
+
shouldProcess = (source) => {
|
|
1396
|
+
return hasTwUsage(source) && !isAlreadyTransformed(source);
|
|
1397
|
+
};
|
|
1398
|
+
compileCssFromClasses = (classes, prefix) => {
|
|
1399
|
+
const native = getNativeBridge();
|
|
1400
|
+
if (!native?.transformSource) {
|
|
1401
|
+
throw new Error("FATAL: Native binding 'transformSource' is required but not available.");
|
|
1402
|
+
}
|
|
1403
|
+
const result = native.transformSource(classes.join(" "), { prefix: prefix ?? "" });
|
|
1404
|
+
if (!result) {
|
|
1405
|
+
throw new Error("FATAL: transformSource returned null");
|
|
1406
|
+
}
|
|
1407
|
+
return result;
|
|
1408
|
+
};
|
|
1409
|
+
buildStyleTag = (classes) => {
|
|
1410
|
+
const result = compileCssFromClasses(classes);
|
|
1411
|
+
return result?.code ? `<style data-tailwind-styled>${result.code}</style>` : "";
|
|
1412
|
+
};
|
|
1413
|
+
compileCssNative = (classes, prefix = null) => {
|
|
1414
|
+
return compileCssFromClasses(classes, prefix);
|
|
1415
|
+
};
|
|
1416
|
+
generateCssForClasses = async (classes, _tailwindConfig, root, cssEntryContent, minify = false) => {
|
|
1417
|
+
const { runCssPipeline: runCssPipeline2 } = await Promise.resolve().then(() => (init_tailwindEngine(), tailwindEngine_exports));
|
|
1418
|
+
const result = await runCssPipeline2(classes, cssEntryContent, root, minify);
|
|
1419
|
+
return result.css;
|
|
1420
|
+
};
|
|
1421
|
+
extractAllClasses = (source) => {
|
|
1422
|
+
const native = getNativeBridge();
|
|
1423
|
+
if (!native?.extractAllClasses) {
|
|
1424
|
+
throw new Error("FATAL: Native binding 'extractAllClasses' is required but not available.");
|
|
1425
|
+
}
|
|
1426
|
+
return native.extractAllClasses(source) || [];
|
|
1427
|
+
};
|
|
1428
|
+
extractClassesFromSource = (source) => {
|
|
1429
|
+
const native = getNativeBridge();
|
|
1430
|
+
if (!native?.extractClassesFromSource) {
|
|
1431
|
+
throw new Error("FATAL: Native binding 'extractClassesFromSource' is required but not available.");
|
|
1432
|
+
}
|
|
1433
|
+
const result = native.extractClassesFromSource(source);
|
|
1434
|
+
return Array.isArray(result) ? result.join(" ") : String(result || "");
|
|
1435
|
+
};
|
|
1436
|
+
astExtractClasses = (source, _filename) => {
|
|
1437
|
+
const native = getNativeBridge();
|
|
1438
|
+
if (!native?.extractClassesFromSource) {
|
|
1439
|
+
throw new Error("FATAL: Native binding 'extractClassesFromSource' is required but not available.");
|
|
1440
|
+
}
|
|
1441
|
+
return native.extractClassesFromSource(source) || [];
|
|
1442
|
+
};
|
|
1443
|
+
parseClasses = (raw) => {
|
|
1444
|
+
const native = getNativeBridge();
|
|
1445
|
+
if (!native?.parseClasses) {
|
|
1446
|
+
throw new Error("FATAL: Native binding 'parseClasses' is required but not available.");
|
|
1447
|
+
}
|
|
1448
|
+
return native.parseClasses(raw) || [];
|
|
1449
|
+
};
|
|
1450
|
+
normalizeClasses = (raw) => {
|
|
1451
|
+
const result = normalizeAndDedupClasses(raw);
|
|
1452
|
+
return result?.normalized || "";
|
|
1453
|
+
};
|
|
1454
|
+
mergeClassesStatic = (classes) => {
|
|
1455
|
+
const result = normalizeAndDedupClasses(classes);
|
|
1456
|
+
return result?.normalized || "";
|
|
1457
|
+
};
|
|
1458
|
+
normalizeAndDedupClasses = (raw) => {
|
|
1459
|
+
const native = getNativeBridge();
|
|
1460
|
+
if (!native?.normalizeAndDedupClasses) {
|
|
1461
|
+
throw new Error("FATAL: Native binding 'normalizeAndDedupClasses' is required but not available.");
|
|
1462
|
+
}
|
|
1463
|
+
const result = native.normalizeAndDedupClasses(raw);
|
|
1464
|
+
return result || { normalized: "", duplicatesRemoved: 0, uniqueCount: 0 };
|
|
1465
|
+
};
|
|
1466
|
+
eliminateDeadCss = (css, deadClasses) => {
|
|
1467
|
+
const native = getNativeBridge();
|
|
1468
|
+
if (!native?.eliminateDeadCss) {
|
|
1469
|
+
throw new Error("FATAL: Native binding 'eliminateDeadCss' is required but not available.");
|
|
1470
|
+
}
|
|
1471
|
+
return native.eliminateDeadCss(css, Array.from(deadClasses));
|
|
1472
|
+
};
|
|
1473
|
+
findDeadVariants = (variantConfig, usage) => {
|
|
1474
|
+
const unused = [];
|
|
1475
|
+
const configs = Array.isArray(variantConfig) ? variantConfig : [{ name: "__root__", variants: variantConfig }];
|
|
1476
|
+
for (const component of configs) {
|
|
1477
|
+
const componentUsage = usage[component.name] ?? /* @__PURE__ */ new Set();
|
|
1478
|
+
const variants = component.variants;
|
|
1479
|
+
for (const [key, values] of Object.entries(variants)) {
|
|
1480
|
+
for (const [value] of Object.entries(values)) {
|
|
1481
|
+
if (!componentUsage.has(`${key}:${value}`)) {
|
|
1482
|
+
unused.push(`${component.name !== "__root__" ? `${component.name}/` : ""}${key}:${value}`);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
return { unusedCount: unused.length, unused };
|
|
1488
|
+
};
|
|
1489
|
+
runElimination = (css, scanResult) => {
|
|
1490
|
+
const native = getNativeBridge();
|
|
1491
|
+
if (!native?.detectDeadCode) {
|
|
1492
|
+
throw new Error("FATAL: Native binding 'detectDeadCode' is required but not available.");
|
|
1493
|
+
}
|
|
1494
|
+
const dead = native.detectDeadCode(JSON.stringify(scanResult), css);
|
|
1495
|
+
return eliminateDeadCss(css, new Set(dead.deadInCss ?? []));
|
|
1496
|
+
};
|
|
1497
|
+
optimizeCss = (css) => {
|
|
1498
|
+
const native = getNativeBridge();
|
|
1499
|
+
if (!native?.optimizeCss) {
|
|
1500
|
+
throw new Error("FATAL: Native binding 'optimizeCss' is required but not available.");
|
|
1501
|
+
}
|
|
1502
|
+
return native.optimizeCss(css);
|
|
1503
|
+
};
|
|
1504
|
+
scanProjectUsage = (dirs, cwd) => {
|
|
1505
|
+
const files = dirs.map((dir) => path9__default.resolve(cwd, dir));
|
|
1506
|
+
const results = batchExtractClasses(files) || [];
|
|
1507
|
+
const combined = {};
|
|
1508
|
+
for (const result of results) {
|
|
1509
|
+
if (result.ok && result.classes) {
|
|
1510
|
+
for (const cls of result.classes) {
|
|
1511
|
+
if (!combined[cls]) combined[cls] = {};
|
|
1512
|
+
combined[cls][result.file] = /* @__PURE__ */ new Set([cls]);
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
return combined;
|
|
1517
|
+
};
|
|
1518
|
+
extractComponentUsage = (source) => {
|
|
1519
|
+
const native = getNativeBridge();
|
|
1520
|
+
if (!native?.extractComponentUsage) {
|
|
1521
|
+
throw new Error("FATAL: Native binding 'extractComponentUsage' is required but not available.");
|
|
1522
|
+
}
|
|
1523
|
+
return native.extractComponentUsage(source) || [];
|
|
1524
|
+
};
|
|
1525
|
+
diffClassLists = (previous, current) => {
|
|
1526
|
+
const native = getNativeBridge();
|
|
1527
|
+
if (!native?.diffClassLists) {
|
|
1528
|
+
throw new Error("FATAL: Native binding 'diffClassLists' is required but not available.");
|
|
1529
|
+
}
|
|
1530
|
+
return native.diffClassLists(previous, current) || { added: [], removed: [], unchanged: [], hasChanges: false };
|
|
1531
|
+
};
|
|
1532
|
+
batchExtractClasses = (filePaths) => {
|
|
1533
|
+
const native = getNativeBridge();
|
|
1534
|
+
if (!native?.batchExtractClasses) {
|
|
1535
|
+
throw new Error("FATAL: Native binding 'batchExtractClasses' is required but not available.");
|
|
1536
|
+
}
|
|
1537
|
+
return native.batchExtractClasses(filePaths) || [];
|
|
1538
|
+
};
|
|
1539
|
+
checkAgainstSafelist = (classes, safelist) => {
|
|
1540
|
+
const native = getNativeBridge();
|
|
1541
|
+
if (!native?.checkAgainstSafelist) {
|
|
1542
|
+
throw new Error("FATAL: Native binding 'checkAgainstSafelist' is required but not available.");
|
|
1543
|
+
}
|
|
1544
|
+
return native.checkAgainstSafelist(classes, safelist) || { matched: [], unmatched: [], safelistSize: 0 };
|
|
1545
|
+
};
|
|
1546
|
+
hoistComponents = (source) => {
|
|
1547
|
+
const native = getNativeBridge();
|
|
1548
|
+
if (!native?.hoistComponents) {
|
|
1549
|
+
throw new Error("FATAL: Native binding 'hoistComponents' is required but not available.");
|
|
1550
|
+
}
|
|
1551
|
+
return native.hoistComponents(source) || { code: source, hoisted: [], warnings: [] };
|
|
1552
|
+
};
|
|
1553
|
+
compileVariantTable = (configJson) => {
|
|
1554
|
+
const native = getNativeBridge();
|
|
1555
|
+
if (!native?.compileVariantTable) {
|
|
1556
|
+
throw new Error("FATAL: Native binding 'compileVariantTable' is required but not available.");
|
|
1557
|
+
}
|
|
1558
|
+
return native.compileVariantTable(configJson) || { id: "", tableJson: "{}", keys: [], defaultKey: "", combinations: 0 };
|
|
1559
|
+
};
|
|
1560
|
+
compileVariants = (componentId, config) => {
|
|
1561
|
+
return compileVariantTable(JSON.stringify({ componentId, ...config }));
|
|
1562
|
+
};
|
|
1563
|
+
classifyAndSortClasses = (classes) => {
|
|
1564
|
+
const native = getNativeBridge();
|
|
1565
|
+
if (!native?.classifyAndSortClasses) {
|
|
1566
|
+
throw new Error("FATAL: Native binding 'classifyAndSortClasses' is required but not available.");
|
|
1567
|
+
}
|
|
1568
|
+
return native.classifyAndSortClasses(classes) || [];
|
|
1569
|
+
};
|
|
1570
|
+
mergeCssDeclarations = (cssChunks) => {
|
|
1571
|
+
const native = getNativeBridge();
|
|
1572
|
+
if (!native?.mergeCssDeclarations) {
|
|
1573
|
+
throw new Error("FATAL: Native binding 'mergeCssDeclarations' is required but not available.");
|
|
1574
|
+
}
|
|
1575
|
+
return native.mergeCssDeclarations(cssChunks) || { declarationsJson: "{}", declarationString: "", count: 0 };
|
|
1576
|
+
};
|
|
1577
|
+
analyzeClassUsage = (classes, scanResultJson, css) => {
|
|
1578
|
+
const native = getNativeBridge();
|
|
1579
|
+
if (!native?.analyzeClassUsage) {
|
|
1580
|
+
throw new Error("FATAL: Native binding 'analyzeClassUsage' is required but not available.");
|
|
1581
|
+
}
|
|
1582
|
+
return native.analyzeClassUsage(classes, scanResultJson, css) || [];
|
|
1583
|
+
};
|
|
1584
|
+
analyzeRsc = (source, filename) => {
|
|
1585
|
+
const native = getNativeBridge();
|
|
1586
|
+
if (!native?.analyzeRsc) {
|
|
1587
|
+
throw new Error("FATAL: Native binding 'analyzeRsc' is required but not available.");
|
|
1588
|
+
}
|
|
1589
|
+
return native.analyzeRsc(source, filename) || { isServer: true, needsClientDirective: false, clientReasons: [] };
|
|
1590
|
+
};
|
|
1591
|
+
analyzeFile = (source, filename) => {
|
|
1592
|
+
const rsc = analyzeRsc(source, filename);
|
|
1593
|
+
return {
|
|
1594
|
+
isServer: rsc?.isServer ?? true,
|
|
1595
|
+
needsClientDirective: rsc?.needsClientDirective ?? false,
|
|
1596
|
+
clientReasons: rsc?.clientReasons ?? [],
|
|
1597
|
+
interactiveClasses: [],
|
|
1598
|
+
canStaticResolveVariants: true
|
|
1599
|
+
};
|
|
1600
|
+
};
|
|
1601
|
+
analyzeVariantUsage = (_source, _componentName, _variantKeys) => {
|
|
1602
|
+
return { resolved: {}, dynamic: [] };
|
|
1603
|
+
};
|
|
1604
|
+
injectClientDirective = (source) => {
|
|
1605
|
+
if (!source.includes('"use client"') && !source.includes("'use client'")) {
|
|
1606
|
+
return '"use client";\n' + source;
|
|
1607
|
+
}
|
|
1608
|
+
return source;
|
|
1609
|
+
};
|
|
1610
|
+
injectServerOnlyComment = (source) => {
|
|
1611
|
+
return `/* @server-only */
|
|
1612
|
+
${source}`;
|
|
1613
|
+
};
|
|
1614
|
+
analyzeClasses = (filesJson, cwd, flags) => {
|
|
1615
|
+
const native = getNativeBridge();
|
|
1616
|
+
if (!native?.analyzeClasses) {
|
|
1617
|
+
throw new Error("FATAL: Native binding 'analyzeClasses' is required but not available.");
|
|
1618
|
+
}
|
|
1619
|
+
return native.analyzeClasses(filesJson, cwd, flags);
|
|
1620
|
+
};
|
|
1621
|
+
generateSafelist = (scanDirs, outputPath, cwd) => {
|
|
1622
|
+
const classes = scanProjectUsage(scanDirs, cwd || process.cwd());
|
|
1623
|
+
const allClasses = Object.keys(classes).sort();
|
|
1624
|
+
if (outputPath) {
|
|
1625
|
+
fs3__default.writeFileSync(outputPath, JSON.stringify(allClasses, null, 2));
|
|
1626
|
+
}
|
|
1627
|
+
return allClasses;
|
|
1628
|
+
};
|
|
1629
|
+
loadSafelist = (safelistPath) => {
|
|
1630
|
+
try {
|
|
1631
|
+
const content = fs3__default.readFileSync(safelistPath, "utf-8");
|
|
1632
|
+
return JSON.parse(content);
|
|
1633
|
+
} catch {
|
|
1634
|
+
return [];
|
|
1635
|
+
}
|
|
1636
|
+
};
|
|
1637
|
+
loadTailwindConfig = (cwd = process.cwd()) => {
|
|
1638
|
+
const configFiles = [
|
|
1639
|
+
"tailwind.config.ts",
|
|
1640
|
+
"tailwind.config.js",
|
|
1641
|
+
"tailwind.config.mjs",
|
|
1642
|
+
"tailwind.config.cjs"
|
|
1643
|
+
];
|
|
1644
|
+
for (const file of configFiles) {
|
|
1645
|
+
const fullPath = path9__default.join(cwd, file);
|
|
1646
|
+
if (fs3__default.existsSync(fullPath)) {
|
|
1647
|
+
const mod = __require(fullPath);
|
|
1648
|
+
return mod.default || mod;
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
return {};
|
|
1652
|
+
};
|
|
1653
|
+
getContentPaths = (cwd = process.cwd()) => {
|
|
1654
|
+
return {
|
|
1655
|
+
content: [
|
|
1656
|
+
path9__default.join(cwd, "src/**/*.{js,ts,jsx,tsx}"),
|
|
1657
|
+
path9__default.join(cwd, "app/**/*.{js,ts,jsx,tsx}"),
|
|
1658
|
+
path9__default.join(cwd, "pages/**/*.{js,ts,jsx,tsx}")
|
|
1659
|
+
]
|
|
1660
|
+
};
|
|
1661
|
+
};
|
|
1662
|
+
_CONTAINER_BREAKPOINTS = {
|
|
1663
|
+
xs: "240px",
|
|
1664
|
+
sm: "320px",
|
|
1665
|
+
md: "640px",
|
|
1666
|
+
lg: "1024px",
|
|
1667
|
+
xl: "1280px",
|
|
1668
|
+
"2xl": "1536px"
|
|
1669
|
+
};
|
|
1670
|
+
runLoaderTransform = (ctx) => {
|
|
1671
|
+
const { filepath, source, options } = ctx;
|
|
1672
|
+
const result = transformSource(source, { filename: filepath, ...options });
|
|
1673
|
+
let staticCss;
|
|
1674
|
+
try {
|
|
1675
|
+
const cssChunks = [];
|
|
1676
|
+
const stateRules = extractAndGenerateStateCss(source, filepath);
|
|
1677
|
+
if (stateRules.length > 0) {
|
|
1678
|
+
cssChunks.push(stateRules.map((r) => r.cssRule).join("\n"));
|
|
1679
|
+
}
|
|
1680
|
+
const containerCss = extractContainerCssFromSource(source);
|
|
1681
|
+
if (containerCss) cssChunks.push(containerCss);
|
|
1682
|
+
const combined = cssChunks.join("\n").trim();
|
|
1683
|
+
if (combined) staticCss = combined;
|
|
1684
|
+
} catch {
|
|
1685
|
+
}
|
|
1686
|
+
return {
|
|
1687
|
+
code: result?.code || "",
|
|
1688
|
+
changed: result?.changed || false,
|
|
1689
|
+
classes: result?.classes || [],
|
|
1690
|
+
staticCss
|
|
1691
|
+
};
|
|
1692
|
+
};
|
|
1693
|
+
shouldSkipFile = (filepath) => {
|
|
1694
|
+
const SKIP_PATHS = ["node_modules", ".next", ".rspack-dist", ".turbo", "dist/", "out/"];
|
|
1695
|
+
const skipExtensions = [".css", ".json", ".md", ".txt", ".yaml", ".yml"];
|
|
1696
|
+
for (const p of SKIP_PATHS) {
|
|
1697
|
+
if (filepath.includes(p)) return true;
|
|
1698
|
+
}
|
|
1699
|
+
for (const ext of skipExtensions) {
|
|
1700
|
+
if (filepath.endsWith(ext)) return true;
|
|
1701
|
+
}
|
|
1702
|
+
return false;
|
|
1703
|
+
};
|
|
1704
|
+
fileToRoute = (filepath) => {
|
|
1705
|
+
const normalized = filepath.replace(/\\/g, "/");
|
|
1706
|
+
if (normalized.includes("/layout.") || normalized.includes("/loading.") || normalized.includes("/error.")) {
|
|
1707
|
+
return "__global";
|
|
1708
|
+
}
|
|
1709
|
+
const pageMatch = normalized.match(/\/app\/(.+?)\/page\.[tj]sx?$/);
|
|
1710
|
+
if (pageMatch) return `/${pageMatch[1]}`;
|
|
1711
|
+
const rootPage = normalized.match(/\/app\/page\.[tj]sx?$/);
|
|
1712
|
+
if (rootPage) return "/";
|
|
1713
|
+
return null;
|
|
1714
|
+
};
|
|
1715
|
+
getAllRoutes = () => {
|
|
1716
|
+
const native = getNativeBridge();
|
|
1717
|
+
if (!native?.analyzeClasses) {
|
|
1718
|
+
throw new Error("FATAL: Native binding 'analyzeClasses' is required but not available.");
|
|
1719
|
+
}
|
|
1720
|
+
return ["/", "__global"];
|
|
1721
|
+
};
|
|
1722
|
+
getRouteClasses = (_route) => /* @__PURE__ */ new Set();
|
|
1723
|
+
registerFileClasses = (_filepath, _classes) => {
|
|
1724
|
+
};
|
|
1725
|
+
registerGlobalClasses = (_classes) => {
|
|
1726
|
+
};
|
|
1727
|
+
_incrementalEngineInstance = null;
|
|
1728
|
+
getIncrementalEngine = () => {
|
|
1729
|
+
if (!_incrementalEngineInstance) {
|
|
1730
|
+
_incrementalEngineInstance = new IncrementalEngine();
|
|
1731
|
+
}
|
|
1732
|
+
return _incrementalEngineInstance;
|
|
1733
|
+
};
|
|
1734
|
+
resetIncrementalEngine = () => {
|
|
1735
|
+
_incrementalEngineInstance = null;
|
|
1736
|
+
};
|
|
1737
|
+
IncrementalEngine = class {
|
|
1738
|
+
compile(source) {
|
|
1739
|
+
return transformSource(source);
|
|
1740
|
+
}
|
|
1741
|
+
};
|
|
1742
|
+
getBucketEngine = () => {
|
|
1743
|
+
const native = getNativeBridge();
|
|
1744
|
+
if (!native?.classifyAndSortClasses) {
|
|
1745
|
+
throw new Error("FATAL: Native binding 'classifyAndSortClasses' is required but not available.");
|
|
1746
|
+
}
|
|
1747
|
+
return {
|
|
1748
|
+
add: (className) => className,
|
|
1749
|
+
get: (_bucket) => []
|
|
1750
|
+
};
|
|
1751
|
+
};
|
|
1752
|
+
resetBucketEngine = () => {
|
|
1753
|
+
};
|
|
1754
|
+
classifyNode = (_node) => {
|
|
1755
|
+
const native = getNativeBridge();
|
|
1756
|
+
if (!native?.classifyAndSortClasses) {
|
|
1757
|
+
throw new Error("FATAL: Native binding 'classifyAndSortClasses' is required but not available.");
|
|
1758
|
+
}
|
|
1759
|
+
return "unknown";
|
|
1760
|
+
};
|
|
1761
|
+
detectConflicts = (_classes) => {
|
|
1762
|
+
const native = getNativeBridge();
|
|
1763
|
+
if (!native?.analyzeClassUsage) {
|
|
1764
|
+
throw new Error("FATAL: Native binding 'analyzeClassUsage' is required but not available.");
|
|
1765
|
+
}
|
|
1766
|
+
return [];
|
|
1767
|
+
};
|
|
1768
|
+
bucketSort = (classes) => {
|
|
1769
|
+
return classifyAndSortClasses(classes).map((c) => c.raw ?? c);
|
|
1770
|
+
};
|
|
1771
|
+
extractTwStateConfigs = (source, filename) => {
|
|
1772
|
+
const native = getNativeBridge();
|
|
1773
|
+
if (!native?.extractTwStateConfigs) {
|
|
1774
|
+
throw new Error("FATAL: Native binding 'extractTwStateConfigs' is required but not available.");
|
|
1775
|
+
}
|
|
1776
|
+
return native.extractTwStateConfigs(source, filename);
|
|
1777
|
+
};
|
|
1778
|
+
generateStaticStateCss = (inputs, resolvedCss = null) => {
|
|
1779
|
+
const native = getNativeBridge();
|
|
1780
|
+
if (!native?.generateStaticStateCss) {
|
|
1781
|
+
throw new Error("FATAL: Native binding 'generateStaticStateCss' is required but not available.");
|
|
1782
|
+
}
|
|
1783
|
+
return native.generateStaticStateCss(inputs, resolvedCss);
|
|
1784
|
+
};
|
|
1785
|
+
extractAndGenerateStateCss = (source, filename) => {
|
|
1786
|
+
const native = getNativeBridge();
|
|
1787
|
+
if (!native?.extractAndGenerateStateCss) {
|
|
1788
|
+
const configs = extractTwStateConfigs(source, filename);
|
|
1789
|
+
if (configs.length === 0) return [];
|
|
1790
|
+
return generateStaticStateCss(
|
|
1791
|
+
configs.map((c) => ({ tag: c.tag, componentName: c.componentName, statesJson: c.statesJson }))
|
|
1792
|
+
);
|
|
1793
|
+
}
|
|
1794
|
+
return native.extractAndGenerateStateCss(source, filename);
|
|
1795
|
+
};
|
|
1796
|
+
}
|
|
1797
|
+
});
|
|
1798
|
+
|
|
1799
|
+
// packages/domain/compiler/src/internal.ts
|
|
1800
|
+
var internal_exports = {};
|
|
1801
|
+
__export(internal_exports, {
|
|
1802
|
+
adaptNativeResult: () => adaptNativeResult,
|
|
1803
|
+
analyzeClassUsage: () => analyzeClassUsage,
|
|
1804
|
+
analyzeClasses: () => analyzeClasses,
|
|
1805
|
+
analyzeFile: () => analyzeFile,
|
|
1806
|
+
analyzeRsc: () => analyzeRsc,
|
|
1807
|
+
analyzeVariantUsage: () => analyzeVariantUsage,
|
|
1808
|
+
astExtractClasses: () => astExtractClasses,
|
|
1809
|
+
batchExtractClasses: () => batchExtractClasses,
|
|
1810
|
+
bucketSort: () => bucketSort,
|
|
1811
|
+
buildStyleTag: () => buildStyleTag,
|
|
1812
|
+
checkAgainstSafelist: () => checkAgainstSafelist,
|
|
1813
|
+
classifyAndSortClasses: () => classifyAndSortClasses,
|
|
1814
|
+
classifyNode: () => classifyNode,
|
|
1815
|
+
clearCache: () => clearCache,
|
|
1816
|
+
compileCssFromClasses: () => compileCssFromClasses,
|
|
1817
|
+
compileCssNative: () => compileCssNative,
|
|
1818
|
+
compileVariantTable: () => compileVariantTable,
|
|
1819
|
+
compileVariants: () => compileVariants,
|
|
1820
|
+
detectConflicts: () => detectConflicts,
|
|
1821
|
+
diffClassLists: () => diffClassLists,
|
|
1822
|
+
eliminateDeadCss: () => eliminateDeadCss,
|
|
1823
|
+
extractAllClasses: () => extractAllClasses,
|
|
1824
|
+
extractAndGenerateStateCss: () => extractAndGenerateStateCss,
|
|
1825
|
+
extractClassesFromSource: () => extractClassesFromSource,
|
|
1826
|
+
extractComponentUsage: () => extractComponentUsage,
|
|
1827
|
+
extractContainerCssFromSource: () => extractContainerCssFromSource,
|
|
1828
|
+
extractTwStateConfigs: () => extractTwStateConfigs,
|
|
1829
|
+
fileToRoute: () => fileToRoute,
|
|
1830
|
+
findDeadVariants: () => findDeadVariants,
|
|
1831
|
+
generateCssForClasses: () => generateCssForClasses,
|
|
1832
|
+
generateRawCss: () => generateRawCss,
|
|
1833
|
+
generateSafelist: () => generateSafelist,
|
|
1834
|
+
generateStaticStateCss: () => generateStaticStateCss,
|
|
1835
|
+
getAllRoutes: () => getAllRoutes,
|
|
1836
|
+
getBucketEngine: () => getBucketEngine,
|
|
1837
|
+
getCacheStats: () => getCacheStats,
|
|
1838
|
+
getContentPaths: () => getContentPaths,
|
|
1839
|
+
getIncrementalEngine: () => getIncrementalEngine,
|
|
1840
|
+
getNativeBridge: () => getNativeBridge,
|
|
1841
|
+
getRouteClasses: () => getRouteClasses,
|
|
1842
|
+
hasTwUsage: () => hasTwUsage,
|
|
1843
|
+
hoistComponents: () => hoistComponents,
|
|
1844
|
+
injectClientDirective: () => injectClientDirective,
|
|
1845
|
+
injectServerOnlyComment: () => injectServerOnlyComment,
|
|
1846
|
+
isAlreadyTransformed: () => isAlreadyTransformed,
|
|
1847
|
+
loadSafelist: () => loadSafelist,
|
|
1848
|
+
loadTailwindConfig: () => loadTailwindConfig,
|
|
1849
|
+
mergeClassesStatic: () => mergeClassesStatic,
|
|
1850
|
+
mergeCssDeclarations: () => mergeCssDeclarations,
|
|
1851
|
+
normalizeAndDedupClasses: () => normalizeAndDedupClasses,
|
|
1852
|
+
normalizeClasses: () => normalizeClasses,
|
|
1853
|
+
optimizeCss: () => optimizeCss,
|
|
1854
|
+
parseClasses: () => parseClasses,
|
|
1855
|
+
registerFileClasses: () => registerFileClasses,
|
|
1856
|
+
registerGlobalClasses: () => registerGlobalClasses,
|
|
1857
|
+
resetBucketEngine: () => resetBucketEngine,
|
|
1858
|
+
resetIncrementalEngine: () => resetIncrementalEngine,
|
|
1859
|
+
runCssPipeline: () => runCssPipeline,
|
|
1860
|
+
runCssPipelineSync: () => runCssPipelineSync,
|
|
1861
|
+
runElimination: () => runElimination,
|
|
1862
|
+
runLoaderTransform: () => runLoaderTransform,
|
|
1863
|
+
scanProjectUsage: () => scanProjectUsage,
|
|
1864
|
+
shouldProcess: () => shouldProcess,
|
|
1865
|
+
shouldSkipFile: () => shouldSkipFile,
|
|
1866
|
+
transformSource: () => transformSource
|
|
1867
|
+
});
|
|
1868
|
+
var init_internal = __esm({
|
|
1869
|
+
"packages/domain/compiler/src/internal.ts"() {
|
|
1870
|
+
init_src();
|
|
1871
|
+
init_tailwindEngine();
|
|
1872
|
+
}
|
|
1873
|
+
});
|
|
1874
|
+
function getNative() {
|
|
1875
|
+
if (_native) return _native;
|
|
1876
|
+
try {
|
|
1877
|
+
const mod = (init_internal(), __toCommonJS(internal_exports));
|
|
1878
|
+
if (typeof mod?.extractTwStateConfigs !== "function" || typeof mod?.generateStaticStateCss !== "function") {
|
|
1879
|
+
return null;
|
|
1880
|
+
}
|
|
1881
|
+
_native = {
|
|
1882
|
+
extractTwStateConfigs: mod.extractTwStateConfigs,
|
|
1883
|
+
generateStaticStateCss: mod.generateStaticStateCss,
|
|
1884
|
+
extractAndGenerateStateCss: mod.extractAndGenerateStateCss ?? // Fallback jika extractAndGenerateStateCss belum di-export
|
|
1885
|
+
((source, filename) => {
|
|
1886
|
+
const configs = mod.extractTwStateConfigs(source, filename);
|
|
1887
|
+
if (configs.length === 0) return [];
|
|
1888
|
+
return mod.generateStaticStateCss(configs.map((c) => ({
|
|
1889
|
+
tag: c.tag,
|
|
1890
|
+
componentName: c.componentName,
|
|
1891
|
+
statesJson: c.statesJson
|
|
1892
|
+
})));
|
|
1893
|
+
})
|
|
1894
|
+
};
|
|
1895
|
+
return _native;
|
|
1896
|
+
} catch {
|
|
1897
|
+
return null;
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
function* walkSourceFiles(dir) {
|
|
1901
|
+
let entries;
|
|
1902
|
+
try {
|
|
1903
|
+
entries = fs3__default.readdirSync(dir, { withFileTypes: true });
|
|
1904
|
+
} catch {
|
|
1905
|
+
return;
|
|
1906
|
+
}
|
|
1907
|
+
for (const entry of entries) {
|
|
1908
|
+
const fullPath = path9__default.join(dir, entry.name);
|
|
1909
|
+
if (entry.isDirectory()) {
|
|
1910
|
+
if (IGNORE_PATTERNS.some((p) => entry.name === p || entry.name.startsWith(p))) continue;
|
|
1911
|
+
yield* walkSourceFiles(fullPath);
|
|
1912
|
+
} else if (entry.isFile()) {
|
|
1913
|
+
const ext = path9__default.extname(entry.name);
|
|
1914
|
+
if (SOURCE_EXTENSIONS.has(ext)) yield fullPath;
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
function buildCssHeader(result) {
|
|
1919
|
+
return [
|
|
1920
|
+
"/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
1921
|
+
" * tw-state-static.css \u2014 Auto-generated by staticStateExtractor.ts",
|
|
1922
|
+
" * DO NOT EDIT. Re-generated on each build.",
|
|
1923
|
+
" *",
|
|
1924
|
+
` * Files scanned: ${result.filesScanned}`,
|
|
1925
|
+
` * Files with states: ${result.filesWithStates}`,
|
|
1926
|
+
` * Components found: ${result.componentsFound}`,
|
|
1927
|
+
` * Rules generated: ${result.rulesGenerated}`,
|
|
1928
|
+
` * Rules skipped: ${result.rulesSkipped} (akan di-inject runtime sebagai fallback)`,
|
|
1929
|
+
" *",
|
|
1930
|
+
' * Selector format: .tw-s-[hash][data-stateName="true"] { ... }',
|
|
1931
|
+
" * Hash identik dengan yang dibuat oleh stateEngine.ts di runtime.",
|
|
1932
|
+
" * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */",
|
|
1933
|
+
""
|
|
1934
|
+
].join("\n");
|
|
1935
|
+
}
|
|
1936
|
+
function extractStaticStateCss(srcDir, options = {}) {
|
|
1937
|
+
const { verbose = false, maxFiles = Infinity } = options;
|
|
1938
|
+
const native = getNative();
|
|
1939
|
+
if (!native) {
|
|
1940
|
+
if (verbose) {
|
|
1941
|
+
process.stderr.write(
|
|
1942
|
+
"[tw:static-state] native module tidak tersedia \u2014 skip static CSS pre-generation\n"
|
|
1943
|
+
);
|
|
1944
|
+
}
|
|
1945
|
+
return {
|
|
1946
|
+
filesScanned: 0,
|
|
1947
|
+
filesWithStates: 0,
|
|
1948
|
+
componentsFound: 0,
|
|
1949
|
+
rulesGenerated: 0,
|
|
1950
|
+
rulesSkipped: 0,
|
|
1951
|
+
generatedCss: "",
|
|
1952
|
+
rules: []
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1955
|
+
const allConfigs = [];
|
|
1956
|
+
let filesScanned = 0;
|
|
1957
|
+
let filesWithStates = 0;
|
|
1958
|
+
if (native.walkAndPrefilterSourceFiles) {
|
|
1959
|
+
const prefiltered = native.walkAndPrefilterSourceFiles(
|
|
1960
|
+
srcDir,
|
|
1961
|
+
[".ts", ".tsx", ".js", ".jsx", ".mts", ".mjs"],
|
|
1962
|
+
["node_modules", ".next", "dist", "build", ".git", "coverage", "__tests__"],
|
|
1963
|
+
// Required substrings — AND logic, identik dengan JS pre-filter di bawah
|
|
1964
|
+
["states:", "tw."],
|
|
1965
|
+
maxFiles === Infinity ? null : maxFiles,
|
|
1966
|
+
null
|
|
1967
|
+
// sequential — parallel mode opsional untuk large monorepo
|
|
1968
|
+
);
|
|
1969
|
+
for (const { path: filePath, content: source } of prefiltered) {
|
|
1970
|
+
filesScanned++;
|
|
1971
|
+
const configs = native.extractTwStateConfigs(source, filePath);
|
|
1972
|
+
if (configs.length > 0) {
|
|
1973
|
+
filesWithStates++;
|
|
1974
|
+
allConfigs.push(...configs);
|
|
1975
|
+
if (verbose) {
|
|
1976
|
+
process.stderr.write(
|
|
1977
|
+
`[tw:static-state] ${path9__default.relative(srcDir, filePath)}: ${configs.length} komponen
|
|
1978
|
+
`
|
|
1979
|
+
);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
} else {
|
|
1984
|
+
for (const filePath of walkSourceFiles(srcDir)) {
|
|
1985
|
+
if (filesScanned >= maxFiles) break;
|
|
1986
|
+
let source;
|
|
1987
|
+
try {
|
|
1988
|
+
source = fs3__default.readFileSync(filePath, "utf-8");
|
|
1989
|
+
} catch {
|
|
1990
|
+
continue;
|
|
1991
|
+
}
|
|
1992
|
+
filesScanned++;
|
|
1993
|
+
if (!source.includes("states:") && !source.includes("states :")) continue;
|
|
1994
|
+
if (!source.includes("tw.") && !source.includes("tailwind-styled")) continue;
|
|
1995
|
+
const configs = native.extractTwStateConfigs(source, filePath);
|
|
1996
|
+
if (configs.length > 0) {
|
|
1997
|
+
filesWithStates++;
|
|
1998
|
+
allConfigs.push(...configs);
|
|
1999
|
+
if (verbose) {
|
|
2000
|
+
process.stderr.write(
|
|
2001
|
+
`[tw:static-state] ${path9__default.relative(srcDir, filePath)}: ${configs.length} komponen
|
|
2002
|
+
`
|
|
2003
|
+
);
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
if (allConfigs.length === 0) {
|
|
2009
|
+
return {
|
|
2010
|
+
filesScanned,
|
|
2011
|
+
filesWithStates: 0,
|
|
2012
|
+
componentsFound: 0,
|
|
2013
|
+
rulesGenerated: 0,
|
|
2014
|
+
rulesSkipped: 0,
|
|
2015
|
+
generatedCss: "",
|
|
2016
|
+
rules: []
|
|
2017
|
+
};
|
|
2018
|
+
}
|
|
2019
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2020
|
+
const uniqueConfigs = [];
|
|
2021
|
+
for (const config of allConfigs) {
|
|
2022
|
+
const key = `${config.tag}::${config.statesJson}`;
|
|
2023
|
+
if (!seen.has(key)) {
|
|
2024
|
+
seen.add(key);
|
|
2025
|
+
uniqueConfigs.push({
|
|
2026
|
+
tag: config.tag,
|
|
2027
|
+
componentName: config.componentName,
|
|
2028
|
+
statesJson: config.statesJson
|
|
2029
|
+
});
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
const allRules = native.generateStaticStateCss(uniqueConfigs, options.resolvedCss ?? null);
|
|
2033
|
+
const rulesSkipped = uniqueConfigs.reduce((total, cfg) => {
|
|
2034
|
+
try {
|
|
2035
|
+
const stateMap = JSON.parse(cfg.statesJson);
|
|
2036
|
+
return total + Object.keys(stateMap).length;
|
|
2037
|
+
} catch {
|
|
2038
|
+
return total;
|
|
2039
|
+
}
|
|
2040
|
+
}, 0) - allRules.length;
|
|
2041
|
+
const byComponent = /* @__PURE__ */ new Map();
|
|
2042
|
+
for (const rule of allRules) {
|
|
2043
|
+
const existing = byComponent.get(rule.componentName) ?? [];
|
|
2044
|
+
existing.push(rule);
|
|
2045
|
+
byComponent.set(rule.componentName, existing);
|
|
2046
|
+
}
|
|
2047
|
+
const cssBlocks = [];
|
|
2048
|
+
for (const [componentName, rules] of byComponent) {
|
|
2049
|
+
cssBlocks.push(`/* ${componentName} */`);
|
|
2050
|
+
for (const rule of rules) {
|
|
2051
|
+
cssBlocks.push(`/* state: ${rule.stateName} */`);
|
|
2052
|
+
cssBlocks.push(rule.cssRule);
|
|
2053
|
+
}
|
|
2054
|
+
cssBlocks.push("");
|
|
2055
|
+
}
|
|
2056
|
+
const result = {
|
|
2057
|
+
filesScanned,
|
|
2058
|
+
filesWithStates,
|
|
2059
|
+
componentsFound: allConfigs.length,
|
|
2060
|
+
rulesGenerated: allRules.length,
|
|
2061
|
+
rulesSkipped: Math.max(0, rulesSkipped),
|
|
2062
|
+
generatedCss: cssBlocks.join("\n"),
|
|
2063
|
+
rules: allRules
|
|
2064
|
+
};
|
|
2065
|
+
result.generatedCss = buildCssHeader(result) + result.generatedCss;
|
|
2066
|
+
return result;
|
|
2067
|
+
}
|
|
2068
|
+
function appendStaticStateCssToSafelist(srcDir, safelistPath, options = {}) {
|
|
2069
|
+
const result = extractStaticStateCss(srcDir, options);
|
|
2070
|
+
const twClassesDir = path9__default.join(path9__default.dirname(safelistPath), "tw-classes");
|
|
2071
|
+
fs3__default.mkdirSync(twClassesDir, { recursive: true });
|
|
2072
|
+
const stateFilePath = path9__default.join(twClassesDir, TW_STATE_STATIC_FILENAME);
|
|
2073
|
+
if (result.rulesGenerated === 0) {
|
|
2074
|
+
try {
|
|
2075
|
+
fs3__default.writeFileSync(
|
|
2076
|
+
stateFilePath,
|
|
2077
|
+
"/* tw-state-static.css \u2014 tidak ada state rules yang di-generate */\n",
|
|
2078
|
+
"utf-8"
|
|
2079
|
+
);
|
|
2080
|
+
} catch {
|
|
2081
|
+
}
|
|
2082
|
+
return `[tw:static-state] tidak ada state rules yang di-generate (${result.filesScanned} files di-scan)`;
|
|
2083
|
+
}
|
|
2084
|
+
try {
|
|
2085
|
+
fs3__default.writeFileSync(stateFilePath, result.generatedCss, "utf-8");
|
|
2086
|
+
return [
|
|
2087
|
+
`[tw:static-state] ${result.rulesGenerated} static state rules di-generate`,
|
|
2088
|
+
` \u2192 ${result.filesScanned} files scanned, ${result.filesWithStates} dengan states`,
|
|
2089
|
+
` \u2192 ${result.componentsFound} components, ${result.rulesSkipped} rules skipped (fallback ke runtime)`,
|
|
2090
|
+
` \u2192 ditulis ke tw-classes/${TW_STATE_STATIC_FILENAME}`
|
|
2091
|
+
].join("\n");
|
|
2092
|
+
} catch (writeErr) {
|
|
2093
|
+
const msg = writeErr instanceof Error ? writeErr.message : String(writeErr);
|
|
2094
|
+
return `[tw:static-state] gagal tulis state CSS: ${msg}`;
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
var SOURCE_EXTENSIONS, IGNORE_PATTERNS, _native, TW_STATE_STATIC_FILENAME;
|
|
2098
|
+
var init_staticStateExtractor = __esm({
|
|
2099
|
+
"packages/domain/shared/src/staticStateExtractor.ts"() {
|
|
2100
|
+
SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mts", ".mjs"]);
|
|
2101
|
+
IGNORE_PATTERNS = ["node_modules", ".next", "dist", "build", ".git", "coverage", "__tests__"];
|
|
2102
|
+
_native = null;
|
|
2103
|
+
TW_STATE_STATIC_FILENAME = "_tw-state-static.css";
|
|
2104
|
+
}
|
|
2105
|
+
});
|
|
2106
|
+
function getEnvLevel() {
|
|
2107
|
+
const env = process.env.TWS_LOG_LEVEL?.toLowerCase();
|
|
2108
|
+
if (env && env in LEVELS) return env;
|
|
2109
|
+
return process.env.TWS_DEBUG_SCANNER === "1" ? "debug" : "info";
|
|
2110
|
+
}
|
|
2111
|
+
function setGlobalLogFile(filePath) {
|
|
2112
|
+
_globalLogFile = filePath;
|
|
2113
|
+
_logFileInitialized = false;
|
|
2114
|
+
try {
|
|
2115
|
+
fs3__default.mkdirSync(path9__default.dirname(filePath), { recursive: true });
|
|
2116
|
+
fs3__default.writeFileSync(
|
|
2117
|
+
filePath,
|
|
2118
|
+
`# tailwind-styled build log \u2014 ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
2119
|
+
`,
|
|
2120
|
+
"utf-8"
|
|
2121
|
+
);
|
|
2122
|
+
_logFileInitialized = true;
|
|
2123
|
+
} catch {
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
function writeToFile(line) {
|
|
2127
|
+
if (!_globalLogFile || !_logFileInitialized) return;
|
|
2128
|
+
try {
|
|
2129
|
+
fs3__default.appendFileSync(_globalLogFile, line);
|
|
2130
|
+
} catch {
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
function createLogger(prefix, level) {
|
|
2134
|
+
const loggerState = {
|
|
2135
|
+
currentLevel: getEnvLevel(),
|
|
2136
|
+
setLevel(l) {
|
|
2137
|
+
this.currentLevel = l;
|
|
2138
|
+
}
|
|
2139
|
+
};
|
|
2140
|
+
const log8 = (msgLevel, stream, args) => {
|
|
2141
|
+
if (LEVELS[msgLevel] > LEVELS[loggerState.currentLevel]) return;
|
|
2142
|
+
const line = `[${prefix}] ${args.map(String).join(" ")}
|
|
2143
|
+
`;
|
|
2144
|
+
process[stream].write(line);
|
|
2145
|
+
writeToFile(line);
|
|
2146
|
+
};
|
|
2147
|
+
return {
|
|
2148
|
+
error: (...a) => log8("error", "stderr", a),
|
|
2149
|
+
warn: (...a) => log8("warn", "stderr", a),
|
|
2150
|
+
info: (...a) => log8("info", "stdout", a),
|
|
2151
|
+
debug: (...a) => log8("debug", "stderr", a),
|
|
2152
|
+
setLevel: loggerState.setLevel,
|
|
2153
|
+
setLogFile: (filePath) => setGlobalLogFile(filePath)
|
|
2154
|
+
};
|
|
2155
|
+
}
|
|
2156
|
+
var LEVELS, _globalLogFile, _logFileInitialized;
|
|
2157
|
+
var init_logger = __esm({
|
|
2158
|
+
"packages/domain/shared/src/logger.ts"() {
|
|
2159
|
+
LEVELS = { silent: 0, error: 1, warn: 2, info: 3, debug: 4 };
|
|
2160
|
+
_globalLogFile = null;
|
|
2161
|
+
_logFileInitialized = false;
|
|
2162
|
+
createLogger("tailwind-styled");
|
|
2163
|
+
}
|
|
2164
|
+
});
|
|
2165
|
+
|
|
990
2166
|
// packages/domain/shared/src/index.ts
|
|
991
2167
|
var src_exports = {};
|
|
992
2168
|
__export(src_exports, {
|
|
@@ -1005,18 +2181,21 @@ __export(src_exports, {
|
|
|
1005
2181
|
RegistryPluginEntrySchema: () => RegistryPluginEntrySchema,
|
|
1006
2182
|
ScanCacheClassEntrySchema: () => ScanCacheClassEntrySchema,
|
|
1007
2183
|
ScanCacheSchema: () => ScanCacheSchema,
|
|
2184
|
+
TW_STATE_STATIC_FILENAME: () => TW_STATE_STATIC_FILENAME,
|
|
1008
2185
|
TailwindConfigSchema: () => TailwindConfigSchema,
|
|
1009
2186
|
TelemetryCollector: () => TelemetryCollector,
|
|
1010
2187
|
TwError: () => TwError,
|
|
2188
|
+
appendStaticStateCssToSafelist: () => appendStaticStateCssToSafelist,
|
|
1011
2189
|
assertTailwindV4: () => assertTailwindV4,
|
|
1012
2190
|
calculateHealth: () => calculateHealth,
|
|
1013
2191
|
createBuildTimer: () => createBuildTimer,
|
|
1014
2192
|
createDebugLogger: () => createDebugLogger,
|
|
1015
2193
|
createEsmRequire: () => createEsmRequire,
|
|
1016
|
-
createLogger: () =>
|
|
2194
|
+
createLogger: () => createLogger2,
|
|
1017
2195
|
createObservabilityClient: () => createObservabilityClient,
|
|
1018
2196
|
createTraceSnapshot: () => createTraceSnapshot,
|
|
1019
2197
|
detectTailwind: () => detectTailwind,
|
|
2198
|
+
extractStaticStateCss: () => extractStaticStateCss,
|
|
1020
2199
|
formatDuration: () => formatDuration,
|
|
1021
2200
|
formatErrorCode: () => formatErrorCode,
|
|
1022
2201
|
formatErrorMessage: () => formatErrorMessage,
|
|
@@ -1052,10 +2231,11 @@ __export(src_exports, {
|
|
|
1052
2231
|
resolveRuntimeDir: () => resolveRuntimeDir,
|
|
1053
2232
|
resolveWorkerPath: () => resolveWorkerPath,
|
|
1054
2233
|
safeParseNative: () => safeParseNative,
|
|
2234
|
+
setGlobalLogFile: () => setGlobalLogFile,
|
|
1055
2235
|
tryRequire: () => tryRequire,
|
|
1056
2236
|
wrapUnknownError: () => wrapUnknownError
|
|
1057
2237
|
});
|
|
1058
|
-
function
|
|
2238
|
+
function createLogger2(namespace) {
|
|
1059
2239
|
const prefix = `[${namespace}]`;
|
|
1060
2240
|
return {
|
|
1061
2241
|
warn(...args) {
|
|
@@ -1084,9 +2264,9 @@ function createDebugLogger(namespace, label) {
|
|
|
1084
2264
|
}
|
|
1085
2265
|
};
|
|
1086
2266
|
}
|
|
1087
|
-
function formatIssuePath(
|
|
1088
|
-
if (!
|
|
1089
|
-
return
|
|
2267
|
+
function formatIssuePath(path16) {
|
|
2268
|
+
if (!path16 || path16.length === 0) return "(root)";
|
|
2269
|
+
return path16.map(
|
|
1090
2270
|
(segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
|
|
1091
2271
|
).join(".");
|
|
1092
2272
|
}
|
|
@@ -1100,9 +2280,9 @@ function loadNativeBinding(options) {
|
|
|
1100
2280
|
const { runtimeDir, candidates, isValid } = options;
|
|
1101
2281
|
const loadErrors = [];
|
|
1102
2282
|
for (const candidate of candidates) {
|
|
1103
|
-
const candidatePath =
|
|
2283
|
+
const candidatePath = path9__default.resolve(runtimeDir, candidate);
|
|
1104
2284
|
try {
|
|
1105
|
-
if (!
|
|
2285
|
+
if (!fs3__default.existsSync(candidatePath) && !fs3__default.existsSync(candidatePath + ".node")) {
|
|
1106
2286
|
continue;
|
|
1107
2287
|
}
|
|
1108
2288
|
const mod = requireNativeModule(candidatePath);
|
|
@@ -1134,9 +2314,9 @@ function resolveNativeBindingCandidates(options) {
|
|
|
1134
2314
|
}
|
|
1135
2315
|
}
|
|
1136
2316
|
if (!includeDefaultCandidates) return candidates;
|
|
1137
|
-
if (
|
|
2317
|
+
if (fs3__default.existsSync(runtimeDir)) {
|
|
1138
2318
|
try {
|
|
1139
|
-
for (const entry of
|
|
2319
|
+
for (const entry of fs3__default.readdirSync(runtimeDir)) {
|
|
1140
2320
|
if (entry.endsWith(".node")) candidates.push(entry);
|
|
1141
2321
|
}
|
|
1142
2322
|
} catch {
|
|
@@ -1145,22 +2325,22 @@ function resolveNativeBindingCandidates(options) {
|
|
|
1145
2325
|
const BINARY_NAMES = ["tailwind-styled-native", "tailwind_styled_parser"];
|
|
1146
2326
|
const napiPlatform = process.platform === "linux" && process.arch === "x64" ? "linux-x64-gnu" : process.platform === "linux" && process.arch === "arm64" ? "linux-arm64-gnu" : `${process.platform}-${process.arch}`;
|
|
1147
2327
|
for (const bin of BINARY_NAMES) {
|
|
1148
|
-
candidates.push(
|
|
1149
|
-
candidates.push(
|
|
1150
|
-
candidates.push(
|
|
1151
|
-
candidates.push(
|
|
1152
|
-
candidates.push(
|
|
1153
|
-
candidates.push(
|
|
1154
|
-
candidates.push(
|
|
1155
|
-
candidates.push(
|
|
1156
|
-
candidates.push(
|
|
2328
|
+
candidates.push(path9__default.resolve(runtimeDir, `${bin}.node`));
|
|
2329
|
+
candidates.push(path9__default.resolve(runtimeDir, `${bin}.${napiPlatform}.node`));
|
|
2330
|
+
candidates.push(path9__default.resolve(runtimeDir, "..", "native", `${bin}.node`));
|
|
2331
|
+
candidates.push(path9__default.resolve(runtimeDir, "..", "native", `${bin}.${napiPlatform}.node`));
|
|
2332
|
+
candidates.push(path9__default.resolve(process.cwd(), "native", `${bin}.node`));
|
|
2333
|
+
candidates.push(path9__default.resolve(process.cwd(), "native", `${bin}.${napiPlatform}.node`));
|
|
2334
|
+
candidates.push(path9__default.resolve(runtimeDir, "..", "..", "..", "..", "native", `${bin}.node`));
|
|
2335
|
+
candidates.push(path9__default.resolve(runtimeDir, "..", "..", "..", "..", "native", `${bin}.${napiPlatform}.node`));
|
|
2336
|
+
candidates.push(path9__default.resolve(runtimeDir, "..", "..", "..", "native", `${bin}.node`));
|
|
1157
2337
|
}
|
|
1158
2338
|
return Array.from(new Set(candidates));
|
|
1159
2339
|
}
|
|
1160
2340
|
function resolveRuntimeDir(dir, importMetaUrl) {
|
|
1161
|
-
if (dir) return
|
|
2341
|
+
if (dir) return path9__default.resolve(dir);
|
|
1162
2342
|
try {
|
|
1163
|
-
return
|
|
2343
|
+
return path9__default.dirname(fileURLToPath(importMetaUrl));
|
|
1164
2344
|
} catch {
|
|
1165
2345
|
return process.cwd();
|
|
1166
2346
|
}
|
|
@@ -1175,7 +2355,7 @@ function formatErrorMessage(error) {
|
|
|
1175
2355
|
return String(error);
|
|
1176
2356
|
}
|
|
1177
2357
|
var TwError, _require2, LRUCache;
|
|
1178
|
-
var
|
|
2358
|
+
var init_src2 = __esm({
|
|
1179
2359
|
"packages/domain/shared/src/index.ts"() {
|
|
1180
2360
|
init_trace();
|
|
1181
2361
|
init_error_codes();
|
|
@@ -1188,6 +2368,8 @@ var init_src = __esm({
|
|
|
1188
2368
|
init_codegen();
|
|
1189
2369
|
init_native_resolution();
|
|
1190
2370
|
init_observability();
|
|
2371
|
+
init_staticStateExtractor();
|
|
2372
|
+
init_logger();
|
|
1191
2373
|
TwError = class _TwError extends Error {
|
|
1192
2374
|
/** @deprecated Gunakan source */
|
|
1193
2375
|
domain;
|
|
@@ -1221,8 +2403,8 @@ var init_src = __esm({
|
|
|
1221
2403
|
/** Buat TwError dari ZodError — dukung shape Zod v3 (`errors`) dan v4 (`issues`). */
|
|
1222
2404
|
static fromZod(err) {
|
|
1223
2405
|
const first = err.issues?.[0] ?? err.errors?.[0];
|
|
1224
|
-
const
|
|
1225
|
-
const message = first ? `${
|
|
2406
|
+
const path16 = formatIssuePath(first?.path);
|
|
2407
|
+
const message = first ? `${path16}: ${first.message}` : "Schema validation failed";
|
|
1226
2408
|
return new _TwError("validation", "SCHEMA_VALIDATION_FAILED", message, err);
|
|
1227
2409
|
}
|
|
1228
2410
|
static wrap(source, code, err) {
|
|
@@ -1319,7 +2501,7 @@ function getDirname2() {
|
|
|
1319
2501
|
return __dirname;
|
|
1320
2502
|
}
|
|
1321
2503
|
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
1322
|
-
return
|
|
2504
|
+
return path9__default.dirname(fileURLToPath(import.meta.url));
|
|
1323
2505
|
}
|
|
1324
2506
|
return process.cwd();
|
|
1325
2507
|
}
|
|
@@ -1524,11 +2706,11 @@ function hasNativeWatchBinding() {
|
|
|
1524
2706
|
return false;
|
|
1525
2707
|
}
|
|
1526
2708
|
}
|
|
1527
|
-
var
|
|
2709
|
+
var log2, isValidScannerBinding, createScannerBridgeLoader, scannerBridgeLoader, scannerGetBinding, resetScannerBridgeCache;
|
|
1528
2710
|
var init_native_bridge = __esm({
|
|
1529
2711
|
"packages/domain/scanner/src/native-bridge.ts"() {
|
|
1530
|
-
|
|
1531
|
-
|
|
2712
|
+
init_src2();
|
|
2713
|
+
log2 = createDebugLogger("scanner:native");
|
|
1532
2714
|
isValidScannerBinding = (module) => {
|
|
1533
2715
|
const candidate = module;
|
|
1534
2716
|
return !!(candidate && (candidate.scanWorkspace || candidate.extractClassesFromSource || candidate.hashFileContent || candidate.cacheRead || candidate.cacheWrite));
|
|
@@ -1582,7 +2764,7 @@ var init_native_bridge = __esm({
|
|
|
1582
2764
|
invalidExportMessage: "Module loaded but missing expected scanner binding functions"
|
|
1583
2765
|
});
|
|
1584
2766
|
if (binding) {
|
|
1585
|
-
|
|
2767
|
+
log2(`scanner native binding loaded successfully`);
|
|
1586
2768
|
_state.binding = binding;
|
|
1587
2769
|
return _state.binding;
|
|
1588
2770
|
}
|
|
@@ -1608,12 +2790,12 @@ var init_native_bridge = __esm({
|
|
|
1608
2790
|
}
|
|
1609
2791
|
});
|
|
1610
2792
|
function defaultCachePath(rootDir, cacheDir) {
|
|
1611
|
-
const dir = cacheDir ?
|
|
1612
|
-
return
|
|
2793
|
+
const dir = cacheDir ? path9__default.resolve(rootDir, cacheDir) : path9__default.join(process.cwd(), ".cache", "tailwind-styled");
|
|
2794
|
+
return path9__default.join(dir, "scanner-cache.json");
|
|
1613
2795
|
}
|
|
1614
2796
|
function readCache(rootDir, cacheDir) {
|
|
1615
2797
|
const cachePath = defaultCachePath(rootDir, cacheDir);
|
|
1616
|
-
|
|
2798
|
+
fs3__default.mkdirSync(path9__default.dirname(cachePath), { recursive: true });
|
|
1617
2799
|
const result = cacheReadNative(cachePath);
|
|
1618
2800
|
if (!result) return [];
|
|
1619
2801
|
return result.entries.map((e) => ({
|
|
@@ -1628,7 +2810,7 @@ function readCache(rootDir, cacheDir) {
|
|
|
1628
2810
|
}
|
|
1629
2811
|
function writeCache(rootDir, entries, cacheDir) {
|
|
1630
2812
|
const cachePath = defaultCachePath(rootDir, cacheDir);
|
|
1631
|
-
|
|
2813
|
+
fs3__default.mkdirSync(path9__default.dirname(cachePath), { recursive: true });
|
|
1632
2814
|
const success = cacheWriteNative(cachePath, entries);
|
|
1633
2815
|
if (!success) {
|
|
1634
2816
|
throw new Error(
|
|
@@ -1655,27 +2837,7 @@ var init_cache_native = __esm({
|
|
|
1655
2837
|
function collectFiles(rootDir, extensions, ignoreDirs) {
|
|
1656
2838
|
const native = collectFilesNative(rootDir, extensions, ignoreDirs);
|
|
1657
2839
|
if (native !== null) return native;
|
|
1658
|
-
|
|
1659
|
-
function walk(dir) {
|
|
1660
|
-
let entries;
|
|
1661
|
-
try {
|
|
1662
|
-
entries = fs5__default.readdirSync(dir, { withFileTypes: true });
|
|
1663
|
-
} catch {
|
|
1664
|
-
return;
|
|
1665
|
-
}
|
|
1666
|
-
for (const entry of entries) {
|
|
1667
|
-
const fullPath = path6__default.join(dir, entry.name);
|
|
1668
|
-
const rel = path6__default.relative(rootDir, fullPath);
|
|
1669
|
-
if (entry.isDirectory()) {
|
|
1670
|
-
const ignored = ignoreDirs.some((d) => entry.name === d || rel.startsWith(d + path6__default.sep));
|
|
1671
|
-
if (!ignored) walk(fullPath);
|
|
1672
|
-
} else if (isScannableFile(entry.name, extensions)) {
|
|
1673
|
-
files.push(fullPath);
|
|
1674
|
-
}
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
walk(rootDir);
|
|
1678
|
-
return files;
|
|
2840
|
+
throw new Error("FATAL: Native binding 'collectFiles' is required but not available.");
|
|
1679
2841
|
}
|
|
1680
2842
|
function mergeResults(batchResults) {
|
|
1681
2843
|
const files = batchResults.map((r) => ({
|
|
@@ -1685,8 +2847,7 @@ function mergeResults(batchResults) {
|
|
|
1685
2847
|
}));
|
|
1686
2848
|
const native = rebuildWorkspaceResultNative(files);
|
|
1687
2849
|
if (native) return native;
|
|
1688
|
-
|
|
1689
|
-
return { files, totalFiles: files.length, uniqueClasses: Array.from(unique).sort() };
|
|
2850
|
+
throw new Error("FATAL: Native binding 'rebuildWorkspaceResult' is required but not available.");
|
|
1690
2851
|
}
|
|
1691
2852
|
function runChunkInWorker(filePaths) {
|
|
1692
2853
|
return new Promise((resolve2, reject) => {
|
|
@@ -1713,7 +2874,7 @@ async function scanWorkspaceParallel(rootDir, options = {}) {
|
|
|
1713
2874
|
maxWorkers = Math.max(1, availableParallelism() - 1),
|
|
1714
2875
|
chunkSize = DEFAULT_CHUNK_SIZE
|
|
1715
2876
|
} = options;
|
|
1716
|
-
const files = collectFiles(
|
|
2877
|
+
const files = collectFiles(path9__default.resolve(rootDir), extensions, ignoreDirs);
|
|
1717
2878
|
if (files.length < PARALLEL_THRESHOLD) {
|
|
1718
2879
|
return mergeResults(batchExtractClassesNative(files));
|
|
1719
2880
|
}
|
|
@@ -1732,7 +2893,7 @@ async function scanWorkspaceParallel(rootDir, options = {}) {
|
|
|
1732
2893
|
var PARALLEL_THRESHOLD, DEFAULT_CHUNK_SIZE, _workerFilename;
|
|
1733
2894
|
var init_parallel_scanner = __esm({
|
|
1734
2895
|
"packages/domain/scanner/src/parallel-scanner.ts"() {
|
|
1735
|
-
|
|
2896
|
+
init_src3();
|
|
1736
2897
|
init_native_bridge();
|
|
1737
2898
|
PARALLEL_THRESHOLD = 50;
|
|
1738
2899
|
DEFAULT_CHUNK_SIZE = 150;
|
|
@@ -1756,13 +2917,13 @@ var init_parallel_scanner = __esm({
|
|
|
1756
2917
|
var formatIssuePath2, formatIssues, parseWithSchema, NonNegativeIntegerSchema, ScanWorkspaceOptionsSchema, ScanFileResultSchema, ScanWorkspaceResultSchema, ScannerWorkerSuccessMessageSchema, ScannerWorkerErrorMessageSchema, ScannerWorkerMessageSchema, parseScanWorkspaceOptions, parseScanWorkspaceResult, parseScannerWorkerMessage;
|
|
1757
2918
|
var init_schemas = __esm({
|
|
1758
2919
|
"packages/domain/scanner/src/schemas.ts"() {
|
|
1759
|
-
|
|
1760
|
-
formatIssuePath2 = (
|
|
2920
|
+
init_src2();
|
|
2921
|
+
formatIssuePath2 = (path16) => path16.length > 0 ? path16.map(
|
|
1761
2922
|
(segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
|
|
1762
2923
|
).join(".") : "<root>";
|
|
1763
2924
|
formatIssues = (error) => error.issues.map((issue) => {
|
|
1764
|
-
const
|
|
1765
|
-
return `${
|
|
2925
|
+
const path16 = formatIssuePath2(issue.path);
|
|
2926
|
+
return `${path16}: ${issue.message}`;
|
|
1766
2927
|
}).join("; ");
|
|
1767
2928
|
parseWithSchema = (schema, data, label) => {
|
|
1768
2929
|
const parsed = schema.safeParse(data);
|
|
@@ -1825,7 +2986,7 @@ __export(src_exports2, {
|
|
|
1825
2986
|
DEFAULT_IGNORES: () => DEFAULT_IGNORES,
|
|
1826
2987
|
batchExtractClassesNative: () => batchExtractClassesNative,
|
|
1827
2988
|
extractClassesNative: () => extractClassesNative,
|
|
1828
|
-
isScannableFile: () =>
|
|
2989
|
+
isScannableFile: () => isScannableFile2,
|
|
1829
2990
|
parseScanWorkspaceOptions: () => parseScanWorkspaceOptions,
|
|
1830
2991
|
parseScanWorkspaceResult: () => parseScanWorkspaceResult,
|
|
1831
2992
|
parseScannerWorkerMessage: () => parseScannerWorkerMessage,
|
|
@@ -1839,7 +3000,7 @@ function getRuntimeDir() {
|
|
|
1839
3000
|
return __dirname;
|
|
1840
3001
|
}
|
|
1841
3002
|
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
1842
|
-
return
|
|
3003
|
+
return path9__default.dirname(fileURLToPath(import.meta.url));
|
|
1843
3004
|
}
|
|
1844
3005
|
return process.cwd();
|
|
1845
3006
|
}
|
|
@@ -1849,17 +3010,17 @@ function resolveScannerWorkerModulePath() {
|
|
|
1849
3010
|
return __dirname;
|
|
1850
3011
|
}
|
|
1851
3012
|
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
1852
|
-
return
|
|
3013
|
+
return path9__default.dirname(fileURLToPath(import.meta.url));
|
|
1853
3014
|
}
|
|
1854
3015
|
return process.cwd();
|
|
1855
3016
|
})();
|
|
1856
3017
|
const candidates = [
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
3018
|
+
path9__default.resolve(runtimeDir, "worker.cjs"),
|
|
3019
|
+
path9__default.resolve(runtimeDir, "worker.js"),
|
|
3020
|
+
path9__default.resolve(runtimeDir, "worker.ts")
|
|
1860
3021
|
];
|
|
1861
3022
|
for (const candidate of candidates) {
|
|
1862
|
-
if (
|
|
3023
|
+
if (fs3__default.existsSync(candidate)) return candidate;
|
|
1863
3024
|
}
|
|
1864
3025
|
return null;
|
|
1865
3026
|
}
|
|
@@ -1916,19 +3077,19 @@ function collectCandidates(rootDir, ignoreDirectories, extensionSet) {
|
|
|
1916
3077
|
if (!currentDir) continue;
|
|
1917
3078
|
const entries = (() => {
|
|
1918
3079
|
try {
|
|
1919
|
-
return
|
|
3080
|
+
return fs3__default.readdirSync(currentDir, { withFileTypes: true });
|
|
1920
3081
|
} catch {
|
|
1921
3082
|
return [];
|
|
1922
3083
|
}
|
|
1923
3084
|
})();
|
|
1924
3085
|
for (const entry of entries) {
|
|
1925
|
-
const fullPath =
|
|
3086
|
+
const fullPath = path9__default.join(currentDir, entry.name);
|
|
1926
3087
|
if (entry.isDirectory()) {
|
|
1927
3088
|
if (!ignoreDirectories.has(entry.name)) directories.push(fullPath);
|
|
1928
3089
|
continue;
|
|
1929
3090
|
}
|
|
1930
3091
|
if (!entry.isFile()) continue;
|
|
1931
|
-
if (!extensionSet.has(
|
|
3092
|
+
if (!extensionSet.has(path9__default.extname(entry.name))) continue;
|
|
1932
3093
|
candidates.push(fullPath);
|
|
1933
3094
|
}
|
|
1934
3095
|
}
|
|
@@ -1954,8 +3115,8 @@ function scanSource(source) {
|
|
|
1954
3115
|
"FATAL: Native parser binding is required but not available.\nThis package requires native Rust bindings.\n\nResolution steps:\n1. Build the native Rust module: npm run build:rust"
|
|
1955
3116
|
);
|
|
1956
3117
|
}
|
|
1957
|
-
function
|
|
1958
|
-
return includeExtensions.includes(
|
|
3118
|
+
function isScannableFile2(filePath, includeExtensions = DEFAULT_EXTENSIONS) {
|
|
3119
|
+
return includeExtensions.includes(path9__default.extname(filePath));
|
|
1959
3120
|
}
|
|
1960
3121
|
function scanFile(filePath) {
|
|
1961
3122
|
const { scanFileNative: scanFileNative2 } = (init_native_bridge(), __toCommonJS(native_bridge_exports));
|
|
@@ -2003,7 +3164,7 @@ function scanWorkspace(rootDir, options = {}) {
|
|
|
2003
3164
|
try {
|
|
2004
3165
|
return readCache(rootDir, normalizedOptions.cacheDir);
|
|
2005
3166
|
} catch (error) {
|
|
2006
|
-
|
|
3167
|
+
log3.debug(
|
|
2007
3168
|
`cache read failed, continuing without persisted cache: ${error instanceof Error ? error.message : String(error)}`
|
|
2008
3169
|
);
|
|
2009
3170
|
return [];
|
|
@@ -2015,7 +3176,7 @@ function scanWorkspace(rootDir, options = {}) {
|
|
|
2015
3176
|
for (const filePath of candidates) {
|
|
2016
3177
|
const stat = (() => {
|
|
2017
3178
|
try {
|
|
2018
|
-
return
|
|
3179
|
+
return fs3__default.statSync(filePath);
|
|
2019
3180
|
} catch {
|
|
2020
3181
|
return null;
|
|
2021
3182
|
}
|
|
@@ -2041,7 +3202,7 @@ function scanWorkspace(rootDir, options = {}) {
|
|
|
2041
3202
|
for (const { filePath, stat, size, cached } of ranked) {
|
|
2042
3203
|
const content = (() => {
|
|
2043
3204
|
try {
|
|
2044
|
-
return
|
|
3205
|
+
return fs3__default.readFileSync(filePath, "utf8");
|
|
2045
3206
|
} catch {
|
|
2046
3207
|
return null;
|
|
2047
3208
|
}
|
|
@@ -2049,7 +3210,7 @@ function scanWorkspace(rootDir, options = {}) {
|
|
|
2049
3210
|
if (!content) continue;
|
|
2050
3211
|
const hash = hashContentNative(content);
|
|
2051
3212
|
if (cached && cached.hash === hash && cached.mtimeMs === stat.mtimeMs && cached.size === size) {
|
|
2052
|
-
|
|
3213
|
+
log3.debug(`cache HIT ${filePath}`);
|
|
2053
3214
|
processResult({ file: filePath, classes: cached.classes });
|
|
2054
3215
|
updatedEntries.push({
|
|
2055
3216
|
file: filePath,
|
|
@@ -2061,7 +3222,7 @@ function scanWorkspace(rootDir, options = {}) {
|
|
|
2061
3222
|
});
|
|
2062
3223
|
continue;
|
|
2063
3224
|
}
|
|
2064
|
-
|
|
3225
|
+
log3.debug(`cache MISS ${filePath}`);
|
|
2065
3226
|
const classes = scanSource(content);
|
|
2066
3227
|
processResult({ file: filePath, classes });
|
|
2067
3228
|
updatedEntries.push({
|
|
@@ -2076,7 +3237,7 @@ function scanWorkspace(rootDir, options = {}) {
|
|
|
2076
3237
|
try {
|
|
2077
3238
|
writeCache(rootDir, updatedEntries, normalizedOptions.cacheDir);
|
|
2078
3239
|
} catch (error) {
|
|
2079
|
-
|
|
3240
|
+
log3.debug(`cache write failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
2080
3241
|
}
|
|
2081
3242
|
return parseScanWorkspaceResult({
|
|
2082
3243
|
files,
|
|
@@ -2109,30 +3270,30 @@ async function scanWorkspaceAsync(rootDir, options = {}) {
|
|
|
2109
3270
|
ignoreDirs: normalizedOptions.ignoreDirectories
|
|
2110
3271
|
});
|
|
2111
3272
|
} catch (parallelError) {
|
|
2112
|
-
|
|
3273
|
+
log3.debug(
|
|
2113
3274
|
`parallel scan failed, retrying with single worker: ${parallelError instanceof Error ? parallelError.message : String(parallelError)}`
|
|
2114
3275
|
);
|
|
2115
3276
|
}
|
|
2116
3277
|
try {
|
|
2117
3278
|
return await scanWorkspaceInWorker(rootDir, normalizedOptions);
|
|
2118
3279
|
} catch (error) {
|
|
2119
|
-
|
|
3280
|
+
log3.debug(
|
|
2120
3281
|
`worker scan failed, retrying with sync native scanner: ${error instanceof Error ? error.message : String(error)}`
|
|
2121
3282
|
);
|
|
2122
3283
|
return scanWorkspace(rootDir, normalizedOptions);
|
|
2123
3284
|
}
|
|
2124
3285
|
}
|
|
2125
|
-
var
|
|
2126
|
-
var
|
|
3286
|
+
var log3, SCAN_WORKER_TIMEOUT_MS, createNativeParserLoader, nativeParserLoader, DEFAULT_EXTENSIONS, DEFAULT_IGNORES;
|
|
3287
|
+
var init_src3 = __esm({
|
|
2127
3288
|
"packages/domain/scanner/src/index.ts"() {
|
|
2128
|
-
|
|
3289
|
+
init_src2();
|
|
2129
3290
|
init_cache_native();
|
|
2130
3291
|
init_native_bridge();
|
|
2131
3292
|
init_parallel_scanner();
|
|
2132
3293
|
init_schemas();
|
|
2133
3294
|
init_schemas();
|
|
2134
3295
|
init_native_bridge();
|
|
2135
|
-
|
|
3296
|
+
log3 = createLogger2("scanner");
|
|
2136
3297
|
SCAN_WORKER_TIMEOUT_MS = 12e4;
|
|
2137
3298
|
createNativeParserLoader = () => {
|
|
2138
3299
|
const _state = {
|
|
@@ -2140,12 +3301,12 @@ var init_src2 = __esm({
|
|
|
2140
3301
|
initError: null
|
|
2141
3302
|
};
|
|
2142
3303
|
const debugNative = (message) => {
|
|
2143
|
-
|
|
3304
|
+
log3.debug(`[native] ${message}`);
|
|
2144
3305
|
};
|
|
2145
3306
|
const loadNativeParserBinding = () => {
|
|
2146
3307
|
if (_state.binding !== void 0) return _state.binding;
|
|
2147
3308
|
const runtimeDir = getRuntimeDir();
|
|
2148
|
-
const req = createRequire(
|
|
3309
|
+
const req = createRequire(path9__default.join(runtimeDir, "noop.cjs"));
|
|
2149
3310
|
const _platform = process.platform;
|
|
2150
3311
|
const _arch = process.arch;
|
|
2151
3312
|
const _platformArch = `${_platform}-${_arch}`;
|
|
@@ -2153,27 +3314,27 @@ var init_src2 = __esm({
|
|
|
2153
3314
|
const candidates = [
|
|
2154
3315
|
// ── binaryName baru: tailwind-styled-native (napi-rs naming) ──
|
|
2155
3316
|
// cwd = repo root saat run dari root, atau package dir saat workspaces
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
3317
|
+
path9__default.resolve(process.cwd(), "native", "tailwind-styled-native.node"),
|
|
3318
|
+
path9__default.resolve(process.cwd(), "native", `tailwind-styled-native.${_platformArch}.node`),
|
|
3319
|
+
path9__default.resolve(process.cwd(), "native", `tailwind-styled-native.${_platformArchGnu}.node`),
|
|
2159
3320
|
// runtimeDir = dist/ → naik 1 level ke package root (npm install case)
|
|
2160
3321
|
// e.g. node_modules/tailwind-styled-v4/dist/ → node_modules/tailwind-styled-v4/native/
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
3322
|
+
path9__default.resolve(runtimeDir, "..", "native", "tailwind-styled-native.node"),
|
|
3323
|
+
path9__default.resolve(runtimeDir, "..", "native", `tailwind-styled-native.${_platformArch}.node`),
|
|
3324
|
+
path9__default.resolve(runtimeDir, "..", "native", `tailwind-styled-native.${_platformArchGnu}.node`),
|
|
2164
3325
|
// runtimeDir = dist/ → naik 4 level ke repo root (monorepo dev case)
|
|
2165
|
-
|
|
2166
|
-
|
|
3326
|
+
path9__default.resolve(runtimeDir, "..", "..", "..", "..", "native", "tailwind-styled-native.node"),
|
|
3327
|
+
path9__default.resolve(runtimeDir, "..", "..", "..", "..", "native", `tailwind-styled-native.${_platformArchGnu}.node`),
|
|
2167
3328
|
// 3 level fallback (jika package di-nest lebih dangkal)
|
|
2168
|
-
|
|
2169
|
-
|
|
3329
|
+
path9__default.resolve(runtimeDir, "..", "..", "..", "native", "tailwind-styled-native.node"),
|
|
3330
|
+
path9__default.resolve(runtimeDir, "..", "..", "..", "native", `tailwind-styled-native.${_platformArchGnu}.node`),
|
|
2170
3331
|
// ── binaryName lama: tailwind_styled_parser (backward compat) ──
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
3332
|
+
path9__default.resolve(process.cwd(), "native/tailwind_styled_parser.node"),
|
|
3333
|
+
path9__default.resolve(process.cwd(), "native/build/Release/tailwind_styled_parser.node"),
|
|
3334
|
+
path9__default.resolve(runtimeDir, "..", "native", "tailwind_styled_parser.node"),
|
|
3335
|
+
path9__default.resolve(runtimeDir, "..", "..", "..", "..", "native", "tailwind_styled_parser.node"),
|
|
3336
|
+
path9__default.resolve(runtimeDir, "..", "..", "..", "native", "tailwind_styled_parser.node"),
|
|
3337
|
+
path9__default.resolve(
|
|
2177
3338
|
runtimeDir,
|
|
2178
3339
|
"..",
|
|
2179
3340
|
"..",
|
|
@@ -2185,7 +3346,7 @@ var init_src2 = __esm({
|
|
|
2185
3346
|
)
|
|
2186
3347
|
];
|
|
2187
3348
|
for (const fullPath of candidates) {
|
|
2188
|
-
if (!
|
|
3349
|
+
if (!fs3__default.existsSync(fullPath)) continue;
|
|
2189
3350
|
try {
|
|
2190
3351
|
const required = req(fullPath);
|
|
2191
3352
|
if (required && (typeof required.extractClassesFromSource === "function" || typeof required.parseClasses === "function" || typeof required.parse_classes === "function")) {
|
|
@@ -2218,168 +3379,6 @@ var init_src2 = __esm({
|
|
|
2218
3379
|
}
|
|
2219
3380
|
});
|
|
2220
3381
|
|
|
2221
|
-
// packages/domain/compiler/src/nativeBridge.ts
|
|
2222
|
-
var _loadNative, log3, NATIVE_UNAVAILABLE_MESSAGE, nativeBridge, bridgeLoadAttempted, bridgeLoadError, isValidNativeBridge, getNativeBridge;
|
|
2223
|
-
var init_nativeBridge = __esm({
|
|
2224
|
-
"packages/domain/compiler/src/nativeBridge.ts"() {
|
|
2225
|
-
init_src();
|
|
2226
|
-
_loadNative = (path13) => __require(path13);
|
|
2227
|
-
log3 = (...args) => {
|
|
2228
|
-
if (process.env.DEBUG?.includes("compiler:native")) {
|
|
2229
|
-
console.log("[compiler:native]", ...args);
|
|
2230
|
-
}
|
|
2231
|
-
};
|
|
2232
|
-
NATIVE_UNAVAILABLE_MESSAGE = "[tailwind-styled/compiler v5] Native binding is required but not available.\nThis package requires native Rust bindings. There is no JavaScript fallback.\nPlease ensure:\n 1. The native module is properly installed\n 2. You have run: npm run build:rust (or use prebuilt binary)\n\nFor help, see: https://tailwind-styled.dev/docs/install";
|
|
2233
|
-
nativeBridge = null;
|
|
2234
|
-
bridgeLoadAttempted = false;
|
|
2235
|
-
bridgeLoadError = null;
|
|
2236
|
-
isValidNativeBridge = (mod) => {
|
|
2237
|
-
const m = mod;
|
|
2238
|
-
return !!(typeof m.transformSource === "function" || typeof m.extractAllClasses === "function" || typeof m.hasTwUsage === "function");
|
|
2239
|
-
};
|
|
2240
|
-
getNativeBridge = () => {
|
|
2241
|
-
if (nativeBridge) {
|
|
2242
|
-
return nativeBridge;
|
|
2243
|
-
}
|
|
2244
|
-
if (bridgeLoadAttempted) {
|
|
2245
|
-
if (bridgeLoadError) {
|
|
2246
|
-
throw bridgeLoadError;
|
|
2247
|
-
}
|
|
2248
|
-
throw new Error(NATIVE_UNAVAILABLE_MESSAGE);
|
|
2249
|
-
}
|
|
2250
|
-
bridgeLoadAttempted = true;
|
|
2251
|
-
try {
|
|
2252
|
-
const runtimeDir = resolveRuntimeDir(void 0, import.meta.url);
|
|
2253
|
-
const result = resolveNativeBinary(runtimeDir);
|
|
2254
|
-
if (result.path && result.path.endsWith(".node")) {
|
|
2255
|
-
try {
|
|
2256
|
-
const binding = _loadNative(result.path);
|
|
2257
|
-
if (isValidNativeBridge(binding)) {
|
|
2258
|
-
nativeBridge = binding;
|
|
2259
|
-
log3("Native bridge loaded successfully from:", result.path);
|
|
2260
|
-
return nativeBridge;
|
|
2261
|
-
}
|
|
2262
|
-
} catch (e) {
|
|
2263
|
-
log3("Failed to require native binding:", e);
|
|
2264
|
-
}
|
|
2265
|
-
}
|
|
2266
|
-
throw new Error(`${NATIVE_UNAVAILABLE_MESSAGE}
|
|
2267
|
-
|
|
2268
|
-
Tried paths: ${result.tried.join("\n")}`);
|
|
2269
|
-
} catch (err) {
|
|
2270
|
-
bridgeLoadError = err instanceof Error ? err : new Error(String(err));
|
|
2271
|
-
log3("Failed to load native bridge:", bridgeLoadError.message);
|
|
2272
|
-
throw bridgeLoadError;
|
|
2273
|
-
}
|
|
2274
|
-
};
|
|
2275
|
-
if (typeof process !== "undefined" && !bridgeLoadAttempted) {
|
|
2276
|
-
try {
|
|
2277
|
-
getNativeBridge();
|
|
2278
|
-
} catch {
|
|
2279
|
-
}
|
|
2280
|
-
}
|
|
2281
|
-
}
|
|
2282
|
-
});
|
|
2283
|
-
|
|
2284
|
-
// packages/domain/compiler/src/tailwindEngine.ts
|
|
2285
|
-
var tailwindEngine_exports = {};
|
|
2286
|
-
__export(tailwindEngine_exports, {
|
|
2287
|
-
generateRawCss: () => generateRawCss,
|
|
2288
|
-
processTailwindCssWithTargets: () => processTailwindCssWithTargets,
|
|
2289
|
-
runCssPipeline: () => runCssPipeline,
|
|
2290
|
-
runCssPipelineSync: () => runCssPipelineSync
|
|
2291
|
-
});
|
|
2292
|
-
function loadTailwindEngine() {
|
|
2293
|
-
if (_twEngine) return _twEngine;
|
|
2294
|
-
if (_twEngineError) throw _twEngineError;
|
|
2295
|
-
try {
|
|
2296
|
-
const tw = require2("tailwindcss");
|
|
2297
|
-
if (typeof tw.compile !== "function") {
|
|
2298
|
-
throw new Error("tailwindcss v4 not found \u2014 compile() API missing. Check tailwindcss version >= 4.");
|
|
2299
|
-
}
|
|
2300
|
-
_twEngine = tw;
|
|
2301
|
-
return _twEngine;
|
|
2302
|
-
} catch (e) {
|
|
2303
|
-
_twEngineError = e instanceof Error ? e : new Error(String(e));
|
|
2304
|
-
throw _twEngineError;
|
|
2305
|
-
}
|
|
2306
|
-
}
|
|
2307
|
-
async function generateRawCss(classes, cssEntryContent, root) {
|
|
2308
|
-
if (classes.length === 0) return "";
|
|
2309
|
-
const tw = loadTailwindEngine();
|
|
2310
|
-
const input = cssEntryContent ?? "@import 'tailwindcss';";
|
|
2311
|
-
const { readFileSync, existsSync: existsSync3 } = await import('fs');
|
|
2312
|
-
const { dirname, resolve: resolve2 } = await import('path');
|
|
2313
|
-
const projectRoot = root ?? process.cwd();
|
|
2314
|
-
const req = createRequire(resolve2(projectRoot, "package.json"));
|
|
2315
|
-
const loadStylesheet = async (id, base) => {
|
|
2316
|
-
try {
|
|
2317
|
-
const cssId = id === "tailwindcss" ? "tailwindcss/index.css" : id === "tailwindcss/preflight" ? "tailwindcss/preflight.css" : id === "tailwindcss/utilities" ? "tailwindcss/utilities.css" : id === "tailwindcss/theme" ? "tailwindcss/theme.css" : id;
|
|
2318
|
-
const pkgPath = req.resolve(cssId);
|
|
2319
|
-
return {
|
|
2320
|
-
content: readFileSync(pkgPath, "utf-8"),
|
|
2321
|
-
base: dirname(pkgPath)
|
|
2322
|
-
};
|
|
2323
|
-
} catch {
|
|
2324
|
-
try {
|
|
2325
|
-
const absPath = resolve2(base, id);
|
|
2326
|
-
if (existsSync3(absPath)) {
|
|
2327
|
-
return { content: readFileSync(absPath, "utf-8"), base: dirname(absPath) };
|
|
2328
|
-
}
|
|
2329
|
-
} catch {
|
|
2330
|
-
}
|
|
2331
|
-
return { content: "", base };
|
|
2332
|
-
}
|
|
2333
|
-
};
|
|
2334
|
-
const compiler = await Promise.resolve(tw.compile(input, { loadStylesheet }));
|
|
2335
|
-
return compiler.build(classes);
|
|
2336
|
-
}
|
|
2337
|
-
function postProcessWithLightning(rawCss) {
|
|
2338
|
-
if (!rawCss) return "";
|
|
2339
|
-
const native = getNativeBridge();
|
|
2340
|
-
if (typeof native.processTailwindCssLightning !== "function") {
|
|
2341
|
-
throw new Error("FATAL: Native binding 'processTailwindCssLightning' is required but not available.");
|
|
2342
|
-
}
|
|
2343
|
-
const result = native.processTailwindCssLightning(rawCss);
|
|
2344
|
-
return result?.css ?? rawCss;
|
|
2345
|
-
}
|
|
2346
|
-
async function runCssPipeline(classes, cssEntryContent, root, minify = true) {
|
|
2347
|
-
const unique = [...new Set(classes.filter(Boolean))];
|
|
2348
|
-
if (unique.length === 0) {
|
|
2349
|
-
return { css: "", classes: [], sizeBytes: 0, optimized: false };
|
|
2350
|
-
}
|
|
2351
|
-
const rawCss = await generateRawCss(unique, cssEntryContent, root);
|
|
2352
|
-
const native = getNativeBridge();
|
|
2353
|
-
const hasLightning = minify && typeof native.processTailwindCssLightning === "function";
|
|
2354
|
-
const finalCss = hasLightning ? postProcessWithLightning(rawCss) : rawCss;
|
|
2355
|
-
return {
|
|
2356
|
-
css: finalCss,
|
|
2357
|
-
classes: unique,
|
|
2358
|
-
sizeBytes: finalCss.length,
|
|
2359
|
-
optimized: hasLightning
|
|
2360
|
-
};
|
|
2361
|
-
}
|
|
2362
|
-
function runCssPipelineSync(_classes) {
|
|
2363
|
-
return { css: "", classes: [], sizeBytes: 0, optimized: false };
|
|
2364
|
-
}
|
|
2365
|
-
function processTailwindCssWithTargets(css, targets) {
|
|
2366
|
-
const native = getNativeBridge();
|
|
2367
|
-
if (!native?.processTailwindCssWithTargets) {
|
|
2368
|
-
throw new Error("FATAL: Native binding 'processTailwindCssWithTargets' is required but not available.");
|
|
2369
|
-
}
|
|
2370
|
-
const result = native.processTailwindCssWithTargets(css, targets ?? null);
|
|
2371
|
-
return (result?.css ?? css).trim();
|
|
2372
|
-
}
|
|
2373
|
-
var require2, _twEngine, _twEngineError;
|
|
2374
|
-
var init_tailwindEngine = __esm({
|
|
2375
|
-
"packages/domain/compiler/src/tailwindEngine.ts"() {
|
|
2376
|
-
init_nativeBridge();
|
|
2377
|
-
require2 = createRequire(import.meta.url);
|
|
2378
|
-
_twEngine = null;
|
|
2379
|
-
_twEngineError = null;
|
|
2380
|
-
}
|
|
2381
|
-
});
|
|
2382
|
-
|
|
2383
3382
|
// packages/domain/engine/src/native-bridge.ts
|
|
2384
3383
|
function getDirname3() {
|
|
2385
3384
|
if (typeof __dirname !== "undefined") return __dirname;
|
|
@@ -2394,7 +3393,7 @@ function getNativeEngineBinding() {
|
|
|
2394
3393
|
var log4, isValidEngineBinding, createEngineBindingLoader, engineBindingLoader;
|
|
2395
3394
|
var init_native_bridge2 = __esm({
|
|
2396
3395
|
"packages/domain/engine/src/native-bridge.ts"() {
|
|
2397
|
-
|
|
3396
|
+
init_src2();
|
|
2398
3397
|
log4 = createDebugLogger("engine:native");
|
|
2399
3398
|
isValidEngineBinding = (module) => {
|
|
2400
3399
|
const candidate = module;
|
|
@@ -2475,47 +3474,38 @@ var init_native_bridge2 = __esm({
|
|
|
2475
3474
|
// packages/domain/engine/src/ir.ts
|
|
2476
3475
|
function registerPropertyName(id, name) {
|
|
2477
3476
|
const native = getNativeEngineBinding();
|
|
2478
|
-
if (native?.registerPropertyName) {
|
|
2479
|
-
|
|
2480
|
-
return;
|
|
3477
|
+
if (!native?.registerPropertyName) {
|
|
3478
|
+
throw new Error("FATAL: Native binding 'registerPropertyName' is required but not available.");
|
|
2481
3479
|
}
|
|
2482
|
-
|
|
3480
|
+
native.registerPropertyName(id.value, name);
|
|
2483
3481
|
}
|
|
2484
3482
|
function registerValueName(id, name) {
|
|
2485
3483
|
const native = getNativeEngineBinding();
|
|
2486
|
-
if (native?.registerValueName) {
|
|
2487
|
-
|
|
2488
|
-
return;
|
|
3484
|
+
if (!native?.registerValueName) {
|
|
3485
|
+
throw new Error("FATAL: Native binding 'registerValueName' is required but not available.");
|
|
2489
3486
|
}
|
|
2490
|
-
|
|
3487
|
+
native.registerValueName(id.value, name);
|
|
2491
3488
|
}
|
|
2492
3489
|
function propertyIdToString(id) {
|
|
2493
3490
|
const native = getNativeEngineBinding();
|
|
2494
|
-
if (native?.propertyIdToString) {
|
|
2495
|
-
|
|
3491
|
+
if (!native?.propertyIdToString) {
|
|
3492
|
+
throw new Error("FATAL: Native binding 'propertyIdToString' is required but not available.");
|
|
2496
3493
|
}
|
|
2497
|
-
return
|
|
3494
|
+
return native.propertyIdToString(id.value);
|
|
2498
3495
|
}
|
|
2499
3496
|
function valueIdToString(id) {
|
|
2500
3497
|
const native = getNativeEngineBinding();
|
|
2501
|
-
if (native?.valueIdToString) {
|
|
2502
|
-
|
|
3498
|
+
if (!native?.valueIdToString) {
|
|
3499
|
+
throw new Error("FATAL: Native binding 'valueIdToString' is required but not available.");
|
|
2503
3500
|
}
|
|
2504
|
-
return
|
|
2505
|
-
}
|
|
2506
|
-
function createFingerprintFallback(parts) {
|
|
2507
|
-
const hash = parts.reduce(
|
|
2508
|
-
(acc, part) => part.split("").reduce((h, char) => (h << 5) - h + char.charCodeAt(0) & h, acc),
|
|
2509
|
-
0
|
|
2510
|
-
);
|
|
2511
|
-
return Math.abs(hash).toString(36);
|
|
3501
|
+
return native.valueIdToString(id.value);
|
|
2512
3502
|
}
|
|
2513
3503
|
function createFingerprint(parts) {
|
|
2514
3504
|
const native = getNativeEngineBinding();
|
|
2515
|
-
if (native?.createFingerprint) {
|
|
2516
|
-
|
|
3505
|
+
if (!native?.createFingerprint) {
|
|
3506
|
+
throw new Error("FATAL: Native binding 'createFingerprint' is required but not available.");
|
|
2517
3507
|
}
|
|
2518
|
-
return
|
|
3508
|
+
return native.createFingerprint(parts);
|
|
2519
3509
|
}
|
|
2520
3510
|
function createResolutionReason(causes, finalDecision) {
|
|
2521
3511
|
return {
|
|
@@ -2523,7 +3513,7 @@ function createResolutionReason(causes, finalDecision) {
|
|
|
2523
3513
|
finalDecision
|
|
2524
3514
|
};
|
|
2525
3515
|
}
|
|
2526
|
-
var RuleId, SelectorId, VariantChainId, PropertyId, ValueId, LayerId, ConditionId, CascadeResolutionId,
|
|
3516
|
+
var RuleId, SelectorId, VariantChainId, PropertyId, ValueId, LayerId, ConditionId, CascadeResolutionId, Origin, Importance, ConditionResult, CascadeStage;
|
|
2527
3517
|
var init_ir = __esm({
|
|
2528
3518
|
"packages/domain/engine/src/ir.ts"() {
|
|
2529
3519
|
init_native_bridge2();
|
|
@@ -2611,8 +3601,6 @@ var init_ir = __esm({
|
|
|
2611
3601
|
return `R${this.value}`;
|
|
2612
3602
|
}
|
|
2613
3603
|
};
|
|
2614
|
-
_propertyNamesFallback = /* @__PURE__ */ new Map();
|
|
2615
|
-
_valueNamesFallback = /* @__PURE__ */ new Map();
|
|
2616
3604
|
Origin = /* @__PURE__ */ ((Origin2) => {
|
|
2617
3605
|
Origin2[Origin2["UserAgent"] = 0] = "UserAgent";
|
|
2618
3606
|
Origin2[Origin2["UserNormal"] = 1] = "UserNormal";
|
|
@@ -2826,14 +3814,68 @@ function detectLayerFromClassName(className) {
|
|
|
2826
3814
|
return null;
|
|
2827
3815
|
}
|
|
2828
3816
|
function parseCssToIr(css, options = {}) {
|
|
2829
|
-
|
|
3817
|
+
const native = getNativeEngineBinding();
|
|
3818
|
+
const prefix = options.prefix ?? "";
|
|
3819
|
+
if (native?.assembleCssIr) {
|
|
3820
|
+
return _parseCssToIrFast(native.assembleCssIr(css, prefix || null));
|
|
3821
|
+
}
|
|
3822
|
+
return _parseCssToIrFallback(css, prefix, native);
|
|
3823
|
+
}
|
|
3824
|
+
function _parseCssToIrFast(assembled) {
|
|
3825
|
+
const native = getNativeEngineBinding();
|
|
2830
3826
|
layerMap.clear();
|
|
2831
3827
|
layerOrderMap.clear();
|
|
2832
|
-
const
|
|
3828
|
+
for (const le of assembled.layers) {
|
|
3829
|
+
const lid = new LayerId(le.layerId);
|
|
3830
|
+
layerMap.set(le.name, lid);
|
|
3831
|
+
layerOrderMap.set(le.name, le.order);
|
|
3832
|
+
}
|
|
3833
|
+
const rules = assembled.rules.map((r) => {
|
|
3834
|
+
const propertyId = new PropertyId(r.propertyId);
|
|
3835
|
+
const valueId = new ValueId(r.valueId);
|
|
3836
|
+
if (native?.registerPropertyName) {
|
|
3837
|
+
native.registerPropertyName(r.propertyId, r.propertyName);
|
|
3838
|
+
} else {
|
|
3839
|
+
registerPropertyName(propertyId, r.propertyName);
|
|
3840
|
+
}
|
|
3841
|
+
if (native?.registerValueName) {
|
|
3842
|
+
native.registerValueName(r.valueId, r.valueName);
|
|
3843
|
+
} else {
|
|
3844
|
+
registerValueName(valueId, r.valueName);
|
|
3845
|
+
}
|
|
3846
|
+
return {
|
|
3847
|
+
id: new RuleId(r.ruleId),
|
|
3848
|
+
selector: new SelectorId(r.selectorId),
|
|
3849
|
+
variantChain: new VariantChainId(0),
|
|
3850
|
+
property: propertyId,
|
|
3851
|
+
value: valueId,
|
|
3852
|
+
origin: r.origin,
|
|
3853
|
+
importance: r.importance,
|
|
3854
|
+
layer: r.layerId >= 0 ? new LayerId(r.layerId) : null,
|
|
3855
|
+
layerOrder: r.layerOrder,
|
|
3856
|
+
specificity: r.specificity,
|
|
3857
|
+
condition: r.conditionId >= 0 ? new ConditionId(r.conditionId) : null,
|
|
3858
|
+
conditionResult: r.conditionResult,
|
|
3859
|
+
insertionOrder: r.insertionOrder,
|
|
3860
|
+
fingerprint: r.fingerprint,
|
|
3861
|
+
source: { file: "", line: 1, column: 1 }
|
|
3862
|
+
};
|
|
3863
|
+
});
|
|
3864
|
+
const classToRuleIds = new Map(
|
|
3865
|
+
assembled.classToRuleIds.map((m) => [
|
|
3866
|
+
m.className,
|
|
3867
|
+
m.ruleIds.map((id) => new RuleId(id))
|
|
3868
|
+
])
|
|
3869
|
+
);
|
|
3870
|
+
return { rules, classToRuleIds };
|
|
3871
|
+
}
|
|
3872
|
+
function _parseCssToIrFallback(css, prefix, native) {
|
|
2833
3873
|
if (!native?.parseCssRules) {
|
|
2834
3874
|
throw new Error("FATAL: Native binding 'parseCssRules' is required but not available.");
|
|
2835
3875
|
}
|
|
2836
|
-
|
|
3876
|
+
resetIdGenerator();
|
|
3877
|
+
layerMap.clear();
|
|
3878
|
+
layerOrderMap.clear();
|
|
2837
3879
|
const rules = [];
|
|
2838
3880
|
const classToRuleIds = /* @__PURE__ */ new Map();
|
|
2839
3881
|
const parsed = native.parseCssRules(css);
|
|
@@ -2848,7 +3890,7 @@ function parseCssToIr(css, options = {}) {
|
|
|
2848
3890
|
const valueId = generateValueId(r.value);
|
|
2849
3891
|
const hasMedia = r.variants.some((v) => v.startsWith("@") || v === "dark" || v === "print");
|
|
2850
3892
|
const conditionId = hasMedia ? generateConditionId() : null;
|
|
2851
|
-
const conditionResult =
|
|
3893
|
+
const conditionResult = 2 /* Unknown */;
|
|
2852
3894
|
const ruleId = generateRuleId();
|
|
2853
3895
|
const fingerprint = createFingerprint([className, r.property, r.value]);
|
|
2854
3896
|
const rule = {
|
|
@@ -2862,7 +3904,6 @@ function parseCssToIr(css, options = {}) {
|
|
|
2862
3904
|
layer,
|
|
2863
3905
|
layerOrder,
|
|
2864
3906
|
specificity: r.specificity,
|
|
2865
|
-
// from native — no JS recalculation
|
|
2866
3907
|
condition: conditionId,
|
|
2867
3908
|
conditionResult,
|
|
2868
3909
|
insertionOrder: getNextInsertionOrder(),
|
|
@@ -3016,13 +4057,13 @@ var init_trace2 = __esm({
|
|
|
3016
4057
|
});
|
|
3017
4058
|
|
|
3018
4059
|
// packages/domain/analyzer/src/analyzeWorkspace.ts
|
|
3019
|
-
|
|
4060
|
+
init_src3();
|
|
3020
4061
|
|
|
3021
4062
|
// packages/domain/analyzer/src/binding.ts
|
|
3022
|
-
|
|
4063
|
+
init_src2();
|
|
3023
4064
|
|
|
3024
4065
|
// packages/domain/analyzer/src/utils.ts
|
|
3025
|
-
|
|
4066
|
+
init_src2();
|
|
3026
4067
|
var DEFAULT_TOP_LIMIT = 10;
|
|
3027
4068
|
var DEFAULT_FREQUENT_THRESHOLD = 2;
|
|
3028
4069
|
var DEBUG_NAMESPACE = "tailwind-styled:analyzer";
|
|
@@ -3036,7 +4077,7 @@ function isRecord(value) {
|
|
|
3036
4077
|
}
|
|
3037
4078
|
async function pathExists(filePath) {
|
|
3038
4079
|
try {
|
|
3039
|
-
await
|
|
4080
|
+
await fs3__default.promises.access(filePath, fs3__default.constants.F_OK);
|
|
3040
4081
|
return true;
|
|
3041
4082
|
} catch {
|
|
3042
4083
|
return false;
|
|
@@ -3134,8 +4175,8 @@ async function requireNativeBinding() {
|
|
|
3134
4175
|
}
|
|
3135
4176
|
|
|
3136
4177
|
// packages/domain/analyzer/src/schemas.ts
|
|
3137
|
-
|
|
3138
|
-
var formatIssuePath3 = (
|
|
4178
|
+
init_src2();
|
|
4179
|
+
var formatIssuePath3 = (path16) => path16.length > 0 ? path16.map(
|
|
3139
4180
|
(segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
|
|
3140
4181
|
).join(".") : "<root>";
|
|
3141
4182
|
var isPlainObject = (value) => {
|
|
@@ -3144,8 +4185,8 @@ var isPlainObject = (value) => {
|
|
|
3144
4185
|
return proto === Object.prototype || proto === null;
|
|
3145
4186
|
};
|
|
3146
4187
|
var formatIssues2 = (error) => error.issues.map((issue) => {
|
|
3147
|
-
const
|
|
3148
|
-
return `${
|
|
4188
|
+
const path16 = formatIssuePath3(issue.path);
|
|
4189
|
+
return `${path16}: ${issue.message}`;
|
|
3149
4190
|
}).join("; ");
|
|
3150
4191
|
var parseWithSchema2 = (schema, data, label) => {
|
|
3151
4192
|
const parsed = schema.safeParse(data);
|
|
@@ -3235,7 +4276,7 @@ var parseAnalyzerOptions = (options) => parseWithSchema2(AnalyzerOptionsSchema,
|
|
|
3235
4276
|
var parseNativeReport = (report) => parseWithSchema2(NativeReportSchema, report, "Native analyzer report is invalid");
|
|
3236
4277
|
var SUPPORTED_TAILWIND_CONFIG_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".js", ".cjs", ".mjs"]);
|
|
3237
4278
|
var tailwindConfigCache = /* @__PURE__ */ new Map();
|
|
3238
|
-
var
|
|
4279
|
+
var detectConflicts2 = async (usages) => {
|
|
3239
4280
|
const native = await getNativeBinding();
|
|
3240
4281
|
if (!native?.detectClassConflicts) {
|
|
3241
4282
|
throw new Error("FATAL: Native binding 'detectClassConflicts' is required but not available.");
|
|
@@ -3252,11 +4293,11 @@ var detectConflicts = async (usages) => {
|
|
|
3252
4293
|
};
|
|
3253
4294
|
};
|
|
3254
4295
|
var isSupportedTailwindConfigPath = (configPath) => {
|
|
3255
|
-
return SUPPORTED_TAILWIND_CONFIG_EXTENSIONS.has(
|
|
4296
|
+
return SUPPORTED_TAILWIND_CONFIG_EXTENSIONS.has(path9__default.extname(configPath).toLowerCase());
|
|
3256
4297
|
};
|
|
3257
4298
|
var resolveTailwindConfigPath = async (root, explicitPath) => {
|
|
3258
4299
|
if (explicitPath) {
|
|
3259
|
-
const resolved =
|
|
4300
|
+
const resolved = path9__default.resolve(root, explicitPath);
|
|
3260
4301
|
if (!await pathExists(resolved)) return null;
|
|
3261
4302
|
return resolved;
|
|
3262
4303
|
}
|
|
@@ -3267,7 +4308,7 @@ var resolveTailwindConfigPath = async (root, explicitPath) => {
|
|
|
3267
4308
|
"tailwind.config.mjs"
|
|
3268
4309
|
];
|
|
3269
4310
|
for (const candidate of candidates) {
|
|
3270
|
-
const fullPath =
|
|
4311
|
+
const fullPath = path9__default.resolve(root, candidate);
|
|
3271
4312
|
if (await pathExists(fullPath)) return fullPath;
|
|
3272
4313
|
}
|
|
3273
4314
|
return null;
|
|
@@ -3321,8 +4362,8 @@ var collectCustomUtilities = (config) => {
|
|
|
3321
4362
|
return out;
|
|
3322
4363
|
};
|
|
3323
4364
|
var collectSafelistFromSource = async (configPath) => {
|
|
3324
|
-
const source = await
|
|
3325
|
-
const { extractClassesNative: extractClassesNative2 } = await Promise.resolve().then(() => (
|
|
4365
|
+
const source = await fs3__default.promises.readFile(configPath, "utf8");
|
|
4366
|
+
const { extractClassesNative: extractClassesNative2 } = await Promise.resolve().then(() => (init_src3(), src_exports2));
|
|
3326
4367
|
const allTokens = extractClassesNative2(source);
|
|
3327
4368
|
const hasSafelist = source.includes("safelist");
|
|
3328
4369
|
if (!hasSafelist) return [];
|
|
@@ -3335,7 +4376,7 @@ var collectSafelistFromSource = async (configPath) => {
|
|
|
3335
4376
|
}
|
|
3336
4377
|
return allTokens.filter((t) => safelistSet.has(t));
|
|
3337
4378
|
};
|
|
3338
|
-
var
|
|
4379
|
+
var loadTailwindConfig2 = async (root, semanticOption) => {
|
|
3339
4380
|
const startMs = Date.now();
|
|
3340
4381
|
const configPath = await resolveTailwindConfigPath(root, semanticOption?.tailwindConfigPath);
|
|
3341
4382
|
if (!configPath) return null;
|
|
@@ -3348,7 +4389,7 @@ var loadTailwindConfig = async (root, semanticOption) => {
|
|
|
3348
4389
|
customUtilities: /* @__PURE__ */ new Set()
|
|
3349
4390
|
};
|
|
3350
4391
|
}
|
|
3351
|
-
const configStat = await
|
|
4392
|
+
const configStat = await fs3__default.promises.stat(configPath).catch(() => null);
|
|
3352
4393
|
if (configStat) {
|
|
3353
4394
|
const cached = tailwindConfigCache.get(configPath);
|
|
3354
4395
|
if (cached && cached.mtimeMs === configStat.mtimeMs && cached.size === configStat.size) {
|
|
@@ -3416,7 +4457,7 @@ var loadTailwindConfig = async (root, semanticOption) => {
|
|
|
3416
4457
|
return loaded;
|
|
3417
4458
|
};
|
|
3418
4459
|
var buildSemanticReport = async (usages, root, semanticOption) => {
|
|
3419
|
-
const loadedConfig = await
|
|
4460
|
+
const loadedConfig = await loadTailwindConfig2(root, semanticOption);
|
|
3420
4461
|
const safelist = loadedConfig?.safelist ?? /* @__PURE__ */ new Set();
|
|
3421
4462
|
const customUtilities = loadedConfig?.customUtilities ?? /* @__PURE__ */ new Set();
|
|
3422
4463
|
const usageNames = new Set(usages.map((usage) => usage.name));
|
|
@@ -3435,7 +4476,7 @@ var buildSemanticReport = async (usages, root, semanticOption) => {
|
|
|
3435
4476
|
results.filter((r) => !r.isKnown).map((r) => r.className)
|
|
3436
4477
|
);
|
|
3437
4478
|
const unknownClasses = usages.filter((usage) => unknownSet.has(usage.name)).map((usage) => ({ ...usage, isUnused: true }));
|
|
3438
|
-
const { conflicts } = await
|
|
4479
|
+
const { conflicts } = await detectConflicts2(usages);
|
|
3439
4480
|
return {
|
|
3440
4481
|
unusedClasses,
|
|
3441
4482
|
unknownClasses,
|
|
@@ -3507,7 +4548,7 @@ async function buildDistribution(usages, native) {
|
|
|
3507
4548
|
}
|
|
3508
4549
|
async function analyzeWorkspace(root, options = {}) {
|
|
3509
4550
|
const startedAtMs = Date.now();
|
|
3510
|
-
const resolvedRoot =
|
|
4551
|
+
const resolvedRoot = path9__default.resolve(root);
|
|
3511
4552
|
const normalizedOptions = parseAnalyzerOptions(options);
|
|
3512
4553
|
const scan = await (async () => {
|
|
3513
4554
|
const scanStartedAtMs = Date.now();
|
|
@@ -3609,36 +4650,17 @@ async function analyzeWorkspace(root, options = {}) {
|
|
|
3609
4650
|
};
|
|
3610
4651
|
}
|
|
3611
4652
|
|
|
3612
|
-
// packages/domain/compiler/src/index.ts
|
|
3613
|
-
init_nativeBridge();
|
|
3614
|
-
var generateCssForClasses = async (classes, _tailwindConfig, root, cssEntryContent, minify = false) => {
|
|
3615
|
-
const { runCssPipeline: runCssPipeline2 } = await Promise.resolve().then(() => (init_tailwindEngine(), tailwindEngine_exports));
|
|
3616
|
-
const result = await runCssPipeline2(classes, cssEntryContent, root, minify);
|
|
3617
|
-
return result.css;
|
|
3618
|
-
};
|
|
3619
|
-
var mergeClassesStatic = (classes) => {
|
|
3620
|
-
const result = normalizeAndDedupClasses(classes);
|
|
3621
|
-
return result?.normalized || "";
|
|
3622
|
-
};
|
|
3623
|
-
var normalizeAndDedupClasses = (raw) => {
|
|
3624
|
-
const native = getNativeBridge();
|
|
3625
|
-
if (!native?.normalizeAndDedupClasses) {
|
|
3626
|
-
throw new Error("FATAL: Native binding 'normalizeAndDedupClasses' is required but not available.");
|
|
3627
|
-
}
|
|
3628
|
-
const result = native.normalizeAndDedupClasses(raw);
|
|
3629
|
-
return result || { normalized: "", duplicatesRemoved: 0, uniqueCount: 0 };
|
|
3630
|
-
};
|
|
3631
|
-
|
|
3632
4653
|
// packages/domain/engine/src/index.ts
|
|
4654
|
+
init_internal();
|
|
4655
|
+
init_src3();
|
|
3633
4656
|
init_src2();
|
|
3634
|
-
init_src();
|
|
3635
4657
|
|
|
3636
4658
|
// packages/domain/engine/src/incremental.ts
|
|
4659
|
+
init_src3();
|
|
3637
4660
|
init_src2();
|
|
3638
|
-
init_src();
|
|
3639
4661
|
init_native_bridge2();
|
|
3640
4662
|
var DEFAULT_EXTENSIONS2 = [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
3641
|
-
var log5 =
|
|
4663
|
+
var log5 = createLogger2("engine:incremental");
|
|
3642
4664
|
function rebuildWorkspaceResult(byFile) {
|
|
3643
4665
|
const files = Array.from(byFile.values());
|
|
3644
4666
|
const native = getNativeEngineBinding();
|
|
@@ -3668,9 +4690,9 @@ function areClassSetsEqual(a, b) {
|
|
|
3668
4690
|
}
|
|
3669
4691
|
function applyIncrementalChange(previous, filePath, type, scanner) {
|
|
3670
4692
|
const includeExtensions = scanner?.includeExtensions ?? DEFAULT_EXTENSIONS2;
|
|
3671
|
-
if (!
|
|
3672
|
-
const byFile = new Map(previous.files.map((f) => [
|
|
3673
|
-
const normalizedPath =
|
|
4693
|
+
if (!isScannableFile2(filePath, includeExtensions)) return previous;
|
|
4694
|
+
const byFile = new Map(previous.files.map((f) => [path9__default.resolve(f.file), f]));
|
|
4695
|
+
const normalizedPath = path9__default.resolve(filePath);
|
|
3674
4696
|
const native = getNativeEngineBinding();
|
|
3675
4697
|
if (!native?.processFileChange) {
|
|
3676
4698
|
throw new Error(
|
|
@@ -3686,7 +4708,7 @@ function applyIncrementalChange(previous, filePath, type, scanner) {
|
|
|
3686
4708
|
}
|
|
3687
4709
|
log5.debug(`native change ${normalizedPath}`);
|
|
3688
4710
|
const scanned = scanFile(normalizedPath);
|
|
3689
|
-
const content =
|
|
4711
|
+
const content = fs3__default.readFileSync(normalizedPath, "utf8");
|
|
3690
4712
|
const diff = native.processFileChange(normalizedPath, scanned.classes, content);
|
|
3691
4713
|
const existing = byFile.get(normalizedPath);
|
|
3692
4714
|
if (diff && existing) {
|
|
@@ -4031,13 +5053,13 @@ var EngineMetricsCollector = class {
|
|
|
4031
5053
|
};
|
|
4032
5054
|
|
|
4033
5055
|
// packages/domain/engine/src/metricsWriter.ts
|
|
4034
|
-
|
|
5056
|
+
init_src2();
|
|
4035
5057
|
var METRICS_FILE_NAME = "metrics.json";
|
|
4036
5058
|
var CACHE_DIR = ".tw-cache";
|
|
4037
5059
|
function writeMetrics(metrics, cwd = process.cwd()) {
|
|
4038
5060
|
try {
|
|
4039
|
-
const cacheDir =
|
|
4040
|
-
|
|
5061
|
+
const cacheDir = path9__default.join(cwd, CACHE_DIR);
|
|
5062
|
+
fs3__default.mkdirSync(cacheDir, { recursive: true });
|
|
4041
5063
|
const mem = process.memoryUsage();
|
|
4042
5064
|
const data = {
|
|
4043
5065
|
...metrics,
|
|
@@ -4048,7 +5070,7 @@ function writeMetrics(metrics, cwd = process.cwd()) {
|
|
|
4048
5070
|
},
|
|
4049
5071
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4050
5072
|
};
|
|
4051
|
-
|
|
5073
|
+
fs3__default.writeFileSync(path9__default.join(cacheDir, METRICS_FILE_NAME), JSON.stringify(data, null, 2));
|
|
4052
5074
|
} catch {
|
|
4053
5075
|
}
|
|
4054
5076
|
}
|
|
@@ -4155,19 +5177,19 @@ var parseEngineOptions = (options) => parseWithSchema3(EngineOptionsSchema, opti
|
|
|
4155
5177
|
var parseEngineWatchOptions = (options) => parseWithSchema3(EngineWatchOptionsSchema, options ?? {}, "engine watch options are invalid");
|
|
4156
5178
|
|
|
4157
5179
|
// packages/domain/engine/src/watch.ts
|
|
4158
|
-
var
|
|
5180
|
+
var _native2 = null;
|
|
4159
5181
|
function getNativeWatcher() {
|
|
4160
|
-
if (
|
|
5182
|
+
if (_native2 !== null) return _native2;
|
|
4161
5183
|
try {
|
|
4162
|
-
const { resolveNativeBinary: resolveNativeBinary2 } = (
|
|
5184
|
+
const { resolveNativeBinary: resolveNativeBinary2 } = (init_src2(), __toCommonJS(src_exports));
|
|
4163
5185
|
const { path: binPath } = resolveNativeBinary2(__dirname);
|
|
4164
5186
|
if (binPath) {
|
|
4165
|
-
|
|
5187
|
+
_native2 = __require(binPath);
|
|
4166
5188
|
}
|
|
4167
5189
|
} catch {
|
|
4168
|
-
|
|
5190
|
+
_native2 = {};
|
|
4169
5191
|
}
|
|
4170
|
-
return
|
|
5192
|
+
return _native2;
|
|
4171
5193
|
}
|
|
4172
5194
|
function watchWorkspaceNative(rootDir, onEvent, options) {
|
|
4173
5195
|
const native = getNativeWatcher();
|
|
@@ -4231,7 +5253,7 @@ init_ir();
|
|
|
4231
5253
|
|
|
4232
5254
|
// packages/domain/engine/src/reverseLookup.ts
|
|
4233
5255
|
init_native_bridge2();
|
|
4234
|
-
function
|
|
5256
|
+
function getNative2() {
|
|
4235
5257
|
const native = getNativeEngineBinding();
|
|
4236
5258
|
if (!native?.reverseLookupFromCss || !native?.reverseLookupByProperty || !native?.reverseLookupFindDependents) {
|
|
4237
5259
|
throw new Error(
|
|
@@ -4256,15 +5278,15 @@ function normaliseNativeResults(raw) {
|
|
|
4256
5278
|
var ReverseLookup = class {
|
|
4257
5279
|
fromCSS(cssProperty, cssValue, css) {
|
|
4258
5280
|
if (!css || !cssProperty) return [];
|
|
4259
|
-
return normaliseNativeResults(
|
|
5281
|
+
return normaliseNativeResults(getNative2().reverseLookupFromCss(css, cssProperty, cssValue));
|
|
4260
5282
|
}
|
|
4261
5283
|
findByProperty(property, css) {
|
|
4262
5284
|
if (!css || !property) return [];
|
|
4263
|
-
return normaliseNativeResults(
|
|
5285
|
+
return normaliseNativeResults(getNative2().reverseLookupByProperty(css, property));
|
|
4264
5286
|
}
|
|
4265
5287
|
findDependents(className, css) {
|
|
4266
5288
|
if (!css || !className) return [];
|
|
4267
|
-
return
|
|
5289
|
+
return getNative2().reverseLookupFindDependents(css, className);
|
|
4268
5290
|
}
|
|
4269
5291
|
fromBundle(className, css) {
|
|
4270
5292
|
if (!css || !className) return [];
|
|
@@ -4309,7 +5331,7 @@ init_resolver();
|
|
|
4309
5331
|
init_cssToIr();
|
|
4310
5332
|
|
|
4311
5333
|
// packages/domain/engine/src/watch-native.ts
|
|
4312
|
-
|
|
5334
|
+
init_src2();
|
|
4313
5335
|
var watchBindingState = {
|
|
4314
5336
|
binding: void 0
|
|
4315
5337
|
};
|
|
@@ -4328,22 +5350,22 @@ var getBinding = () => {
|
|
|
4328
5350
|
const _paGnu = _pa === "linux-x64" ? "linux-x64-gnu" : _pa === "linux-arm64" ? "linux-arm64-gnu" : _pa;
|
|
4329
5351
|
const candidates = [
|
|
4330
5352
|
// new binary name: tailwind-styled-native
|
|
4331
|
-
|
|
4332
|
-
|
|
5353
|
+
path9__default.resolve(process.cwd(), "native", "tailwind-styled-native.node"),
|
|
5354
|
+
path9__default.resolve(process.cwd(), "native", `tailwind-styled-native.${_pa}.node`),
|
|
4333
5355
|
// npm install case: dist/../native/
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
5356
|
+
path9__default.resolve(runtimeDir, "..", "native", "tailwind-styled-native.node"),
|
|
5357
|
+
path9__default.resolve(runtimeDir, "..", "native", `tailwind-styled-native.${_pa}.node`),
|
|
5358
|
+
path9__default.resolve(runtimeDir, "..", "native", `tailwind-styled-native.${_paGnu}.node`),
|
|
4337
5359
|
// monorepo dev: 4-level up
|
|
4338
|
-
|
|
4339
|
-
|
|
5360
|
+
path9__default.resolve(runtimeDir, "..", "..", "..", "..", "native", "tailwind-styled-native.node"),
|
|
5361
|
+
path9__default.resolve(runtimeDir, "..", "..", "..", "..", "native", `tailwind-styled-native.${_paGnu}.node`),
|
|
4340
5362
|
// 3-level fallback
|
|
4341
|
-
|
|
5363
|
+
path9__default.resolve(runtimeDir, "..", "..", "..", "native", "tailwind-styled-native.node"),
|
|
4342
5364
|
// backward compat: tailwind_styled_parser
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
5365
|
+
path9__default.resolve(process.cwd(), "native", "tailwind_styled_parser.node"),
|
|
5366
|
+
path9__default.resolve(runtimeDir, "..", "native", "tailwind_styled_parser.node"),
|
|
5367
|
+
path9__default.resolve(runtimeDir, "..", "..", "..", "..", "native", "tailwind_styled_parser.node"),
|
|
5368
|
+
path9__default.resolve(runtimeDir, "..", "..", "..", "native", "tailwind_styled_parser.node")
|
|
4347
5369
|
];
|
|
4348
5370
|
for (const c of candidates) {
|
|
4349
5371
|
try {
|
|
@@ -4360,11 +5382,11 @@ var getBinding = () => {
|
|
|
4360
5382
|
"FATAL: Native watch binding not found in any candidate path.\nThis package requires native Rust bindings.\n\nCandidates checked:\n" + candidates.map((p) => ` - ${p}`).join("\n") + "\n\nResolution steps:\n1. Build the native Rust module: npm run build:rust"
|
|
4361
5383
|
);
|
|
4362
5384
|
};
|
|
4363
|
-
var log6 =
|
|
5385
|
+
var log6 = createLogger2("engine:watch-native");
|
|
4364
5386
|
function watchWorkspace2(rootDir, callback, options = {}) {
|
|
4365
5387
|
const binding = getBinding();
|
|
4366
5388
|
const pollMs = options.pollIntervalMs ?? 500;
|
|
4367
|
-
const resolvedRoot =
|
|
5389
|
+
const resolvedRoot = path9__default.resolve(rootDir);
|
|
4368
5390
|
const result = (() => {
|
|
4369
5391
|
try {
|
|
4370
5392
|
return binding.startWatch(resolvedRoot);
|
|
@@ -4401,7 +5423,7 @@ This package requires native Rust bindings.`
|
|
|
4401
5423
|
const deduped = /* @__PURE__ */ new Set();
|
|
4402
5424
|
const events = [];
|
|
4403
5425
|
for (const e of raw) {
|
|
4404
|
-
const absPath =
|
|
5426
|
+
const absPath = path9__default.isAbsolute(e.path) ? path9__default.normalize(e.path) : path9__default.resolve(resolvedRoot, e.path);
|
|
4405
5427
|
const kind = e.kind;
|
|
4406
5428
|
const key = `${kind}:${absPath}`;
|
|
4407
5429
|
if (deduped.has(key)) continue;
|
|
@@ -4438,11 +5460,11 @@ var configState = {
|
|
|
4438
5460
|
return this.tailwindConfigLoaded;
|
|
4439
5461
|
}
|
|
4440
5462
|
};
|
|
4441
|
-
var log7 =
|
|
5463
|
+
var log7 = createLogger2("engine");
|
|
4442
5464
|
async function loadTailwindConfigFromPath(root, tailwindConfigPath) {
|
|
4443
5465
|
if (!tailwindConfigPath) return void 0;
|
|
4444
|
-
const configPath =
|
|
4445
|
-
if (!
|
|
5466
|
+
const configPath = path9__default.resolve(root, tailwindConfigPath);
|
|
5467
|
+
if (!fs3__default.existsSync(configPath)) {
|
|
4446
5468
|
throw TwError.fromIo("CONFIG_NOT_FOUND", `tailwindConfigPath not found: ${configPath}`);
|
|
4447
5469
|
}
|
|
4448
5470
|
const imported = await import(pathToFileURL(configPath).href);
|
|
@@ -4508,13 +5530,14 @@ async function buildFromScan(scan, root, options, tailwindConfig) {
|
|
|
4508
5530
|
};
|
|
4509
5531
|
}
|
|
4510
5532
|
function countWorkspacePackages(root) {
|
|
4511
|
-
const packagesDir =
|
|
4512
|
-
if (!
|
|
5533
|
+
const packagesDir = path9__default.join(root, "packages");
|
|
5534
|
+
if (!fs3__default.existsSync(packagesDir)) return 0;
|
|
4513
5535
|
try {
|
|
4514
|
-
return
|
|
4515
|
-
(entry) => entry.isDirectory() &&
|
|
5536
|
+
return fs3__default.readdirSync(packagesDir, { withFileTypes: true }).filter(
|
|
5537
|
+
(entry) => entry.isDirectory() && fs3__default.existsSync(path9__default.join(packagesDir, entry.name, "package.json"))
|
|
4516
5538
|
).length;
|
|
4517
|
-
} catch {
|
|
5539
|
+
} catch (err) {
|
|
5540
|
+
log7.debug(`countWorkspacePackages: ${err instanceof Error ? err.message : String(err)}`);
|
|
4518
5541
|
return 0;
|
|
4519
5542
|
}
|
|
4520
5543
|
}
|
|
@@ -4548,7 +5571,7 @@ function writeDashboardMetrics(root, mode, result, metrics) {
|
|
|
4548
5571
|
async function createEngine(rawOptions = {}) {
|
|
4549
5572
|
const options = parseEngineOptions(rawOptions);
|
|
4550
5573
|
const root = options.root ?? process.cwd();
|
|
4551
|
-
const resolvedRoot =
|
|
5574
|
+
const resolvedRoot = path9__default.resolve(root);
|
|
4552
5575
|
const plugins = rawOptions.plugins ?? [];
|
|
4553
5576
|
const getTailwindConfig = async () => {
|
|
4554
5577
|
if (configState.isLoaded()) return configState.getConfig();
|
|
@@ -4695,12 +5718,13 @@ async function createEngine(rawOptions = {}) {
|
|
|
4695
5718
|
const shouldForceFullRescan = (event) => {
|
|
4696
5719
|
if (event.type === "unlink") return false;
|
|
4697
5720
|
try {
|
|
4698
|
-
const stat =
|
|
5721
|
+
const stat = fs3__default.statSync(event.filePath);
|
|
4699
5722
|
if (stat.size > largeFileThreshold) {
|
|
4700
5723
|
metrics.markSkippedLargeFile();
|
|
4701
5724
|
return true;
|
|
4702
5725
|
}
|
|
4703
|
-
} catch {
|
|
5726
|
+
} catch (statErr) {
|
|
5727
|
+
log7.debug(`stat failed for ${event.filePath}: ${statErr instanceof Error ? statErr.message : String(statErr)}`);
|
|
4704
5728
|
return false;
|
|
4705
5729
|
}
|
|
4706
5730
|
return false;
|
|
@@ -4812,14 +5836,14 @@ async function createEngine(rawOptions = {}) {
|
|
|
4812
5836
|
};
|
|
4813
5837
|
}
|
|
4814
5838
|
async function scanWorkspace2(opts = {}) {
|
|
4815
|
-
const root =
|
|
5839
|
+
const root = path9__default.resolve(opts.root ?? process.cwd());
|
|
4816
5840
|
return scanWorkspaceAsync(root, {
|
|
4817
5841
|
includeExtensions: opts.extensions,
|
|
4818
5842
|
ignoreDirectories: opts.ignoreDirectories
|
|
4819
5843
|
});
|
|
4820
5844
|
}
|
|
4821
5845
|
async function analyzeWorkspace2(opts = {}) {
|
|
4822
|
-
const root =
|
|
5846
|
+
const root = path9__default.resolve(opts.root ?? process.cwd());
|
|
4823
5847
|
return analyzeWorkspace(root, {
|
|
4824
5848
|
classStats: { top: opts.top ?? 20 }
|
|
4825
5849
|
});
|
|
@@ -4850,7 +5874,8 @@ async function traceClass(className, scanResult, css) {
|
|
|
4850
5874
|
resolver.registerClass(registeredClassName, ruleIds);
|
|
4851
5875
|
}
|
|
4852
5876
|
return trace2(className, resolver);
|
|
4853
|
-
} catch {
|
|
5877
|
+
} catch (traceErr) {
|
|
5878
|
+
log7.debug(`traceClass("${className}"): ${traceErr instanceof Error ? traceErr.message : String(traceErr)}`);
|
|
4854
5879
|
return null;
|
|
4855
5880
|
}
|
|
4856
5881
|
}
|