@csszyx/unplugin 0.9.9 → 0.9.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/next-prebuild.cjs +1 -1
- package/dist/next-prebuild.mjs +1 -1
- package/dist/next-turbo-loader.cjs +13 -2
- package/dist/next-turbo-loader.mjs +13 -2
- package/dist/next-watcher.cjs +1 -1
- package/dist/next-watcher.mjs +1 -1
- package/dist/shared/{unplugin.Dfao2VkS.cjs → unplugin.BT-U5kd1.cjs} +84 -38
- package/dist/shared/{unplugin.s62yJbu1.cjs → unplugin.Bo6Kx-T6.cjs} +46 -1
- package/dist/shared/{unplugin.BtQzlC2C.mjs → unplugin.VAel6lI0.mjs} +46 -1
- package/dist/shared/{unplugin.CMsKFZ-l.mjs → unplugin.jEasXLFM.mjs} +82 -36
- package/dist/vite.cjs +1 -1
- package/dist/vite.mjs +1 -1
- package/dist/webpack.cjs +1 -1
- package/dist/webpack.mjs +1 -1
- package/package.json +8 -8
package/dist/index.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
const cssMangler = require('./css-mangler.cjs');
|
|
6
|
-
const unplugin = require('./shared/unplugin.
|
|
6
|
+
const unplugin = require('./shared/unplugin.BT-U5kd1.cjs');
|
|
7
7
|
const types = require('@csszyx/types');
|
|
8
8
|
require('postcss');
|
|
9
9
|
require('postcss-selector-parser');
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createPostCSSPlugin, escapeCSSClassName, mangleCSS, mangleCSSSync, unescapeTailwindClass } from './css-mangler.mjs';
|
|
2
|
-
export { a as assertNoRSCBoundaryViolation, b as assertNoRSCGraphViolation, c as createGlobalVarAliasValidationOptions, d as createGlobalVarMapAssetSource, e as createGlobalVarScanCacheKey, f as createRSCModuleRecord, u as default, g as deleteRSCModuleRecord, h as esbuildPlugin, i as extractGlobalVarAliasesForManifest, j as findRSCBoundaryViolation, k as findRSCGraphViolation, l as hasTokens, m as hasUseClientDirective, n as hasUseServerDirective, o as isRSCServerModule, p as isTailwindReservedGlobalVar, q as mangleCodeClassesSync, r as mergeThemes, s as normalizeGlobalVarAliasesForCache, t as parseThemeBlocks, v as planGlobalVarAliases, w as readGlobalVarScanCache, x as resolveGlobalVarScanCacheDir, y as resolveNativeCacheIdentity, z as rewriteGlobalVarCssAliases, A as rollupPlugin, B as scanGlobalVarCss, u as unplugin, C as validateGlobalVarAliasInputs, D as vitePlugin, E as webpackPlugin, F as writeGlobalVarScanCache } from './shared/unplugin.
|
|
2
|
+
export { a as assertNoRSCBoundaryViolation, b as assertNoRSCGraphViolation, c as createGlobalVarAliasValidationOptions, d as createGlobalVarMapAssetSource, e as createGlobalVarScanCacheKey, f as createRSCModuleRecord, u as default, g as deleteRSCModuleRecord, h as esbuildPlugin, i as extractGlobalVarAliasesForManifest, j as findRSCBoundaryViolation, k as findRSCGraphViolation, l as hasTokens, m as hasUseClientDirective, n as hasUseServerDirective, o as isRSCServerModule, p as isTailwindReservedGlobalVar, q as mangleCodeClassesSync, r as mergeThemes, s as normalizeGlobalVarAliasesForCache, t as parseThemeBlocks, v as planGlobalVarAliases, w as readGlobalVarScanCache, x as resolveGlobalVarScanCacheDir, y as resolveNativeCacheIdentity, z as rewriteGlobalVarCssAliases, A as rollupPlugin, B as scanGlobalVarCss, u as unplugin, C as validateGlobalVarAliasInputs, D as vitePlugin, E as webpackPlugin, F as writeGlobalVarScanCache } from './shared/unplugin.jEasXLFM.mjs';
|
|
3
3
|
export { CSSZYX_GLOBAL_ALIAS_PREFIX, TAILWIND_RESERVED_PREFIXES } from '@csszyx/types';
|
|
4
4
|
import 'postcss';
|
|
5
5
|
import 'postcss-selector-parser';
|
package/dist/next-prebuild.cjs
CHANGED
|
@@ -4,7 +4,7 @@ const node_crypto = require('node:crypto');
|
|
|
4
4
|
const fs = require('node:fs');
|
|
5
5
|
const path = require('node:path');
|
|
6
6
|
const nextTransformMetadata = require('./shared/unplugin.DWtXPCGo.cjs');
|
|
7
|
-
const nextWatcherCycle = require('./shared/unplugin.
|
|
7
|
+
const nextWatcherCycle = require('./shared/unplugin.Bo6Kx-T6.cjs');
|
|
8
8
|
const transformCache = require('./shared/unplugin.pmTknYLy.cjs');
|
|
9
9
|
require('@csszyx/compiler');
|
|
10
10
|
require('node:os');
|
package/dist/next-prebuild.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { createHash } from 'node:crypto';
|
|
|
2
2
|
import { existsSync, readFileSync } from 'node:fs';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import { r as readPackageVersion, t as transformNextSource, c as collectNextTransformMetadata, a as createNextSafelistShardFromMetadata } from './shared/unplugin.C1N5i6Eg.mjs';
|
|
5
|
-
import { c as createNextStateContext, w as writeNextSafelistShard, r as runNextWatcherCycle } from './shared/unplugin.
|
|
5
|
+
import { c as createNextStateContext, w as writeNextSafelistShard, r as runNextWatcherCycle } from './shared/unplugin.VAel6lI0.mjs';
|
|
6
6
|
import { r as resolveTransformCacheDir } from './shared/unplugin.BpWUtI9U.mjs';
|
|
7
7
|
import '@csszyx/compiler';
|
|
8
8
|
import 'node:os';
|
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
const node_crypto = require('node:crypto');
|
|
6
6
|
const path = require('node:path');
|
|
7
|
-
const nextWatcherCycle = require('./shared/unplugin.
|
|
7
|
+
const nextWatcherCycle = require('./shared/unplugin.Bo6Kx-T6.cjs');
|
|
8
8
|
const nextTransformMetadata = require('./shared/unplugin.DWtXPCGo.cjs');
|
|
9
9
|
const transformCache = require('./shared/unplugin.pmTknYLy.cjs');
|
|
10
10
|
require('node:fs');
|
|
@@ -178,7 +178,18 @@ function assertProductionManifestReady(context, options) {
|
|
|
178
178
|
);
|
|
179
179
|
if (!validation.ok) {
|
|
180
180
|
throw new Error(
|
|
181
|
-
|
|
181
|
+
[
|
|
182
|
+
`[csszyx] Next Turbopack production cache is not ready for ${context.root}: ${validation.reason}.`,
|
|
183
|
+
"Production builds with Turbopack need the csszyx safelist seeded first:",
|
|
184
|
+
"",
|
|
185
|
+
" npx csszyx next prebuild 'app/**/*.tsx'",
|
|
186
|
+
"",
|
|
187
|
+
"Wire it into package.json so plain builds keep working:",
|
|
188
|
+
"",
|
|
189
|
+
` "build": "csszyx next prebuild 'app/**/*.tsx' && next build"`,
|
|
190
|
+
"",
|
|
191
|
+
"Docs: https://csszyx.com/docs/installation#nextjs-turbopack-setup"
|
|
192
|
+
].join("\n")
|
|
182
193
|
);
|
|
183
194
|
}
|
|
184
195
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
-
import { c as createNextStateContext, w as writeNextSafelistShard, r as runNextWatcherCycle, v as validateNextGenerationManifest, a as readNextGenerationManifest } from './shared/unplugin.
|
|
3
|
+
import { c as createNextStateContext, w as writeNextSafelistShard, r as runNextWatcherCycle, v as validateNextGenerationManifest, a as readNextGenerationManifest } from './shared/unplugin.VAel6lI0.mjs';
|
|
4
4
|
import { r as readPackageVersion, t as transformNextSource, c as collectNextTransformMetadata, a as createNextSafelistShardFromMetadata } from './shared/unplugin.C1N5i6Eg.mjs';
|
|
5
5
|
import { r as resolveTransformCacheDir } from './shared/unplugin.BpWUtI9U.mjs';
|
|
6
6
|
import 'node:fs';
|
|
@@ -159,7 +159,18 @@ function assertProductionManifestReady(context, options) {
|
|
|
159
159
|
);
|
|
160
160
|
if (!validation.ok) {
|
|
161
161
|
throw new Error(
|
|
162
|
-
|
|
162
|
+
[
|
|
163
|
+
`[csszyx] Next Turbopack production cache is not ready for ${context.root}: ${validation.reason}.`,
|
|
164
|
+
"Production builds with Turbopack need the csszyx safelist seeded first:",
|
|
165
|
+
"",
|
|
166
|
+
" npx csszyx next prebuild 'app/**/*.tsx'",
|
|
167
|
+
"",
|
|
168
|
+
"Wire it into package.json so plain builds keep working:",
|
|
169
|
+
"",
|
|
170
|
+
` "build": "csszyx next prebuild 'app/**/*.tsx' && next build"`,
|
|
171
|
+
"",
|
|
172
|
+
"Docs: https://csszyx.com/docs/installation#nextjs-turbopack-setup"
|
|
173
|
+
].join("\n")
|
|
163
174
|
);
|
|
164
175
|
}
|
|
165
176
|
}
|
package/dist/next-watcher.cjs
CHANGED
package/dist/next-watcher.mjs
CHANGED
|
@@ -1562,9 +1562,9 @@ const RUNTIME_HELPER_IMPORT_RE = {
|
|
|
1562
1562
|
};
|
|
1563
1563
|
let _hasWarnedTsConfig = false;
|
|
1564
1564
|
let _hasWarnedTransformCacheVersion = false;
|
|
1565
|
-
const requireFromHere = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/unplugin.
|
|
1565
|
+
const requireFromHere = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/unplugin.BT-U5kd1.cjs', document.baseURI).href)));
|
|
1566
1566
|
const PLUGIN_VERSION = findPackageVersionFromFile(
|
|
1567
|
-
node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/unplugin.
|
|
1567
|
+
node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/unplugin.BT-U5kd1.cjs', document.baseURI).href))),
|
|
1568
1568
|
UNKNOWN_PACKAGE_VERSION
|
|
1569
1569
|
);
|
|
1570
1570
|
const COMPILER_VERSION = findPackageVersionFromModule("@csszyx/compiler", UNKNOWN_PACKAGE_VERSION);
|
|
@@ -2055,6 +2055,45 @@ function mangleCodeClassesSync(code, mangleMap) {
|
|
|
2055
2055
|
}
|
|
2056
2056
|
return changed ? `className:\`${out}\`` : fullMatch;
|
|
2057
2057
|
});
|
|
2058
|
+
function scanClassExpression(source, from) {
|
|
2059
|
+
let depth = 0;
|
|
2060
|
+
let j = from;
|
|
2061
|
+
while (j < source.length) {
|
|
2062
|
+
const ch = source[j];
|
|
2063
|
+
if (ch === "(" || ch === "[") {
|
|
2064
|
+
depth++;
|
|
2065
|
+
} else if (ch === ")" || ch === "]") {
|
|
2066
|
+
if (depth === 0) {
|
|
2067
|
+
break;
|
|
2068
|
+
}
|
|
2069
|
+
depth--;
|
|
2070
|
+
} else if (depth === 0 && (ch === "," || ch === ";" || ch === "\n" || ch === "}")) {
|
|
2071
|
+
break;
|
|
2072
|
+
}
|
|
2073
|
+
j++;
|
|
2074
|
+
}
|
|
2075
|
+
return j;
|
|
2076
|
+
}
|
|
2077
|
+
function mangleTernaryClassStrings(expr) {
|
|
2078
|
+
const qIdx = expr.indexOf("?");
|
|
2079
|
+
if (qIdx === -1 || !expr.slice(qIdx).includes(":")) {
|
|
2080
|
+
return null;
|
|
2081
|
+
}
|
|
2082
|
+
let changed = false;
|
|
2083
|
+
const mangled = expr.replace(/"([^"]*)"/g, (qm, inner) => {
|
|
2084
|
+
const parts = inner.split(/\s+/).filter(Boolean);
|
|
2085
|
+
if (parts.length === 0) {
|
|
2086
|
+
return qm;
|
|
2087
|
+
}
|
|
2088
|
+
const mangledStr = parts.map((p) => mangleMap[p] || p).join(" ");
|
|
2089
|
+
if (mangledStr !== inner) {
|
|
2090
|
+
changed = true;
|
|
2091
|
+
return `"${mangledStr}"`;
|
|
2092
|
+
}
|
|
2093
|
+
return qm;
|
|
2094
|
+
});
|
|
2095
|
+
return changed ? mangled : null;
|
|
2096
|
+
}
|
|
2058
2097
|
{
|
|
2059
2098
|
const marker = "className:";
|
|
2060
2099
|
let searchFrom = 0;
|
|
@@ -2076,47 +2115,39 @@ function mangleCodeClassesSync(code, mangleMap) {
|
|
|
2076
2115
|
searchFrom = afterColon;
|
|
2077
2116
|
continue;
|
|
2078
2117
|
}
|
|
2079
|
-
|
|
2080
|
-
let j = afterColon;
|
|
2081
|
-
while (j < result.length) {
|
|
2082
|
-
const ch = result[j];
|
|
2083
|
-
if (ch === "(" || ch === "[") {
|
|
2084
|
-
depth++;
|
|
2085
|
-
} else if (ch === ")" || ch === "]") {
|
|
2086
|
-
if (depth === 0) {
|
|
2087
|
-
break;
|
|
2088
|
-
}
|
|
2089
|
-
depth--;
|
|
2090
|
-
} else if (depth === 0 && (ch === "," || ch === ";" || ch === "\n" || ch === "}")) {
|
|
2091
|
-
break;
|
|
2092
|
-
}
|
|
2093
|
-
j++;
|
|
2094
|
-
}
|
|
2118
|
+
const j = scanClassExpression(result, afterColon);
|
|
2095
2119
|
const expr = result.slice(afterColon, j);
|
|
2096
|
-
|
|
2097
|
-
if (qIdx === -1 || !expr.slice(qIdx).includes(":")) {
|
|
2098
|
-
out += expr;
|
|
2099
|
-
searchFrom = j;
|
|
2100
|
-
continue;
|
|
2101
|
-
}
|
|
2102
|
-
let changed = false;
|
|
2103
|
-
const mangled = expr.replace(/"([^"]*)"/g, (qm, inner) => {
|
|
2104
|
-
const parts = inner.split(/\s+/).filter(Boolean);
|
|
2105
|
-
if (parts.length === 0) {
|
|
2106
|
-
return qm;
|
|
2107
|
-
}
|
|
2108
|
-
const mangledStr = parts.map((p) => mangleMap[p] || p).join(" ");
|
|
2109
|
-
if (mangledStr !== inner) {
|
|
2110
|
-
changed = true;
|
|
2111
|
-
return `"${mangledStr}"`;
|
|
2112
|
-
}
|
|
2113
|
-
return qm;
|
|
2114
|
-
});
|
|
2115
|
-
out += changed ? mangled : expr;
|
|
2120
|
+
out += mangleTernaryClassStrings(expr) ?? expr;
|
|
2116
2121
|
searchFrom = j;
|
|
2117
2122
|
}
|
|
2118
2123
|
result = out;
|
|
2119
2124
|
}
|
|
2125
|
+
{
|
|
2126
|
+
const markerRe = /"class(?:Name)?"\s*,\s*/g;
|
|
2127
|
+
let out = "";
|
|
2128
|
+
let copiedTo = 0;
|
|
2129
|
+
let m = markerRe.exec(result);
|
|
2130
|
+
while (m !== null) {
|
|
2131
|
+
const exprStart = m.index + m[0].length;
|
|
2132
|
+
const firstChar = result[exprStart];
|
|
2133
|
+
if (firstChar === '"' || firstChar === "'" || firstChar === "`") {
|
|
2134
|
+
m = markerRe.exec(result);
|
|
2135
|
+
continue;
|
|
2136
|
+
}
|
|
2137
|
+
const j = scanClassExpression(result, exprStart);
|
|
2138
|
+
const expr = result.slice(exprStart, j);
|
|
2139
|
+
const mangled = mangleTernaryClassStrings(expr);
|
|
2140
|
+
if (mangled !== null) {
|
|
2141
|
+
out += result.slice(copiedTo, exprStart) + mangled;
|
|
2142
|
+
copiedTo = j;
|
|
2143
|
+
}
|
|
2144
|
+
markerRe.lastIndex = j;
|
|
2145
|
+
m = markerRe.exec(result);
|
|
2146
|
+
}
|
|
2147
|
+
if (copiedTo > 0) {
|
|
2148
|
+
result = out + result.slice(copiedTo);
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2120
2151
|
result = result.replace(/(?<=(?:[,(]|&&)\s*)"([^"]+)"/g, (match, inner) => {
|
|
2121
2152
|
const tokens = inner.split(/\s+/).filter(Boolean);
|
|
2122
2153
|
if (tokens.length === 0) {
|
|
@@ -2688,6 +2719,21 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2688
2719
|
}
|
|
2689
2720
|
return null;
|
|
2690
2721
|
},
|
|
2722
|
+
/**
|
|
2723
|
+
* Restricts the load hook to csszyx's own virtual modules.
|
|
2724
|
+
*
|
|
2725
|
+
* Without this, unplugin's webpack adapter registers its load
|
|
2726
|
+
* loader with `type: 'javascript/auto'` for every module (its
|
|
2727
|
+
* include defaults to all ids when no loadInclude exists). That
|
|
2728
|
+
* corrupts binary asset modules (images, fonts) in webpack apps —
|
|
2729
|
+
* Next.js builds fail with "not a valid image file" / "Module
|
|
2730
|
+
* parse failed" on assets that build fine without csszyx.
|
|
2731
|
+
* @param id - the module ID webpack is about to load
|
|
2732
|
+
* @returns true only for csszyx virtual modules
|
|
2733
|
+
*/
|
|
2734
|
+
loadInclude(id) {
|
|
2735
|
+
return id === RESOLVED_VIRTUAL_MODULE_ID || id === RESOLVED_VIRTUAL_CHECKSUM_ID;
|
|
2736
|
+
},
|
|
2691
2737
|
/**
|
|
2692
2738
|
* Loads virtual module content — generates mangle map or checksum module code.
|
|
2693
2739
|
* @param id - the resolved module ID to load
|
|
@@ -27,6 +27,7 @@ const lockfile__default = /*#__PURE__*/_interopDefaultCompat(lockfile);
|
|
|
27
27
|
const DEFAULT_RENAME_RETRIES = 5;
|
|
28
28
|
const DEFAULT_RENAME_RETRY_DELAY_MS = 10;
|
|
29
29
|
const DEFAULT_STALE_LOCK_MS = 3e4;
|
|
30
|
+
const STALE_RECOVERY_DISABLED_MS = 2147483647;
|
|
30
31
|
function resolveNextSafelistStatePaths(rootDir, cacheDir = ".csszyx/cache", outputFile = "csszyx-classes.html") {
|
|
31
32
|
const resolvedCacheDir = path__namespace.resolve(rootDir, cacheDir);
|
|
32
33
|
return {
|
|
@@ -81,11 +82,17 @@ function acquireNextSafelistStateLock(lockPath, pidOrOptions = {}) {
|
|
|
81
82
|
const metadata = createLockMetadata(options);
|
|
82
83
|
const staleAfterMs = options.staleAfterMs ?? DEFAULT_STALE_LOCK_MS;
|
|
83
84
|
fs__namespace.mkdirSync(path__namespace.dirname(lockPath), { recursive: true });
|
|
85
|
+
recoverStaleAdvisoryLock(lockPath, staleAfterMs);
|
|
84
86
|
let releaseAdvisory;
|
|
85
87
|
try {
|
|
86
88
|
releaseAdvisory = lockfile__default.lockSync(lockPath, {
|
|
87
89
|
realpath: false,
|
|
88
|
-
stale:
|
|
90
|
+
// Disable proper-lockfile's own stale recovery: its rmdir+remake is
|
|
91
|
+
// not single-winner under concurrent recovery. recoverStaleAdvisoryLock
|
|
92
|
+
// above clears stale locks with one elected winner, so here mkdir is a
|
|
93
|
+
// pure single-winner mutex. A live owner keeps the advisory mtime fresh
|
|
94
|
+
// via `update`, so staleness is still detected — just by us, not here.
|
|
95
|
+
stale: STALE_RECOVERY_DISABLED_MS,
|
|
89
96
|
update: Math.max(1e3, Math.floor(staleAfterMs / 2)),
|
|
90
97
|
retries: 0
|
|
91
98
|
});
|
|
@@ -289,6 +296,44 @@ function readLockMetadata(lockPath) {
|
|
|
289
296
|
return null;
|
|
290
297
|
}
|
|
291
298
|
}
|
|
299
|
+
function isAdvisoryLockStale(advisoryPath, staleAfterMs) {
|
|
300
|
+
try {
|
|
301
|
+
return fs__namespace.statSync(advisoryPath).mtimeMs < Date.now() - staleAfterMs;
|
|
302
|
+
} catch {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function recoverStaleAdvisoryLock(lockPath, staleAfterMs) {
|
|
307
|
+
const advisoryPath = `${lockPath}.lock`;
|
|
308
|
+
if (!isAdvisoryLockStale(advisoryPath, staleAfterMs)) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
const electionPath = `${lockPath}.recover`;
|
|
312
|
+
if (isAdvisoryLockStale(electionPath, staleAfterMs)) {
|
|
313
|
+
try {
|
|
314
|
+
fs__namespace.rmdirSync(electionPath);
|
|
315
|
+
} catch {
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
try {
|
|
319
|
+
fs__namespace.mkdirSync(electionPath);
|
|
320
|
+
} catch {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
try {
|
|
324
|
+
if (isAdvisoryLockStale(advisoryPath, staleAfterMs)) {
|
|
325
|
+
try {
|
|
326
|
+
fs__namespace.rmdirSync(advisoryPath);
|
|
327
|
+
} catch {
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
} finally {
|
|
331
|
+
try {
|
|
332
|
+
fs__namespace.rmdirSync(electionPath);
|
|
333
|
+
} catch {
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
292
337
|
function isLockLive(metadata, options) {
|
|
293
338
|
const staleAfterMs = options.staleAfterMs ?? DEFAULT_STALE_LOCK_MS;
|
|
294
339
|
const updatedAt = Date.parse(metadata.updatedAt);
|
|
@@ -7,6 +7,7 @@ import lockfile from 'proper-lockfile';
|
|
|
7
7
|
const DEFAULT_RENAME_RETRIES = 5;
|
|
8
8
|
const DEFAULT_RENAME_RETRY_DELAY_MS = 10;
|
|
9
9
|
const DEFAULT_STALE_LOCK_MS = 3e4;
|
|
10
|
+
const STALE_RECOVERY_DISABLED_MS = 2147483647;
|
|
10
11
|
function resolveNextSafelistStatePaths(rootDir, cacheDir = ".csszyx/cache", outputFile = "csszyx-classes.html") {
|
|
11
12
|
const resolvedCacheDir = path.resolve(rootDir, cacheDir);
|
|
12
13
|
return {
|
|
@@ -61,11 +62,17 @@ function acquireNextSafelistStateLock(lockPath, pidOrOptions = {}) {
|
|
|
61
62
|
const metadata = createLockMetadata(options);
|
|
62
63
|
const staleAfterMs = options.staleAfterMs ?? DEFAULT_STALE_LOCK_MS;
|
|
63
64
|
fs.mkdirSync(path.dirname(lockPath), { recursive: true });
|
|
65
|
+
recoverStaleAdvisoryLock(lockPath, staleAfterMs);
|
|
64
66
|
let releaseAdvisory;
|
|
65
67
|
try {
|
|
66
68
|
releaseAdvisory = lockfile.lockSync(lockPath, {
|
|
67
69
|
realpath: false,
|
|
68
|
-
stale:
|
|
70
|
+
// Disable proper-lockfile's own stale recovery: its rmdir+remake is
|
|
71
|
+
// not single-winner under concurrent recovery. recoverStaleAdvisoryLock
|
|
72
|
+
// above clears stale locks with one elected winner, so here mkdir is a
|
|
73
|
+
// pure single-winner mutex. A live owner keeps the advisory mtime fresh
|
|
74
|
+
// via `update`, so staleness is still detected — just by us, not here.
|
|
75
|
+
stale: STALE_RECOVERY_DISABLED_MS,
|
|
69
76
|
update: Math.max(1e3, Math.floor(staleAfterMs / 2)),
|
|
70
77
|
retries: 0
|
|
71
78
|
});
|
|
@@ -269,6 +276,44 @@ function readLockMetadata(lockPath) {
|
|
|
269
276
|
return null;
|
|
270
277
|
}
|
|
271
278
|
}
|
|
279
|
+
function isAdvisoryLockStale(advisoryPath, staleAfterMs) {
|
|
280
|
+
try {
|
|
281
|
+
return fs.statSync(advisoryPath).mtimeMs < Date.now() - staleAfterMs;
|
|
282
|
+
} catch {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function recoverStaleAdvisoryLock(lockPath, staleAfterMs) {
|
|
287
|
+
const advisoryPath = `${lockPath}.lock`;
|
|
288
|
+
if (!isAdvisoryLockStale(advisoryPath, staleAfterMs)) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
const electionPath = `${lockPath}.recover`;
|
|
292
|
+
if (isAdvisoryLockStale(electionPath, staleAfterMs)) {
|
|
293
|
+
try {
|
|
294
|
+
fs.rmdirSync(electionPath);
|
|
295
|
+
} catch {
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
try {
|
|
299
|
+
fs.mkdirSync(electionPath);
|
|
300
|
+
} catch {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
try {
|
|
304
|
+
if (isAdvisoryLockStale(advisoryPath, staleAfterMs)) {
|
|
305
|
+
try {
|
|
306
|
+
fs.rmdirSync(advisoryPath);
|
|
307
|
+
} catch {
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
} finally {
|
|
311
|
+
try {
|
|
312
|
+
fs.rmdirSync(electionPath);
|
|
313
|
+
} catch {
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
272
317
|
function isLockLive(metadata, options) {
|
|
273
318
|
const staleAfterMs = options.staleAfterMs ?? DEFAULT_STALE_LOCK_MS;
|
|
274
319
|
const updatedAt = Date.parse(metadata.updatedAt);
|
|
@@ -2035,6 +2035,45 @@ function mangleCodeClassesSync(code, mangleMap) {
|
|
|
2035
2035
|
}
|
|
2036
2036
|
return changed ? `className:\`${out}\`` : fullMatch;
|
|
2037
2037
|
});
|
|
2038
|
+
function scanClassExpression(source, from) {
|
|
2039
|
+
let depth = 0;
|
|
2040
|
+
let j = from;
|
|
2041
|
+
while (j < source.length) {
|
|
2042
|
+
const ch = source[j];
|
|
2043
|
+
if (ch === "(" || ch === "[") {
|
|
2044
|
+
depth++;
|
|
2045
|
+
} else if (ch === ")" || ch === "]") {
|
|
2046
|
+
if (depth === 0) {
|
|
2047
|
+
break;
|
|
2048
|
+
}
|
|
2049
|
+
depth--;
|
|
2050
|
+
} else if (depth === 0 && (ch === "," || ch === ";" || ch === "\n" || ch === "}")) {
|
|
2051
|
+
break;
|
|
2052
|
+
}
|
|
2053
|
+
j++;
|
|
2054
|
+
}
|
|
2055
|
+
return j;
|
|
2056
|
+
}
|
|
2057
|
+
function mangleTernaryClassStrings(expr) {
|
|
2058
|
+
const qIdx = expr.indexOf("?");
|
|
2059
|
+
if (qIdx === -1 || !expr.slice(qIdx).includes(":")) {
|
|
2060
|
+
return null;
|
|
2061
|
+
}
|
|
2062
|
+
let changed = false;
|
|
2063
|
+
const mangled = expr.replace(/"([^"]*)"/g, (qm, inner) => {
|
|
2064
|
+
const parts = inner.split(/\s+/).filter(Boolean);
|
|
2065
|
+
if (parts.length === 0) {
|
|
2066
|
+
return qm;
|
|
2067
|
+
}
|
|
2068
|
+
const mangledStr = parts.map((p) => mangleMap[p] || p).join(" ");
|
|
2069
|
+
if (mangledStr !== inner) {
|
|
2070
|
+
changed = true;
|
|
2071
|
+
return `"${mangledStr}"`;
|
|
2072
|
+
}
|
|
2073
|
+
return qm;
|
|
2074
|
+
});
|
|
2075
|
+
return changed ? mangled : null;
|
|
2076
|
+
}
|
|
2038
2077
|
{
|
|
2039
2078
|
const marker = "className:";
|
|
2040
2079
|
let searchFrom = 0;
|
|
@@ -2056,47 +2095,39 @@ function mangleCodeClassesSync(code, mangleMap) {
|
|
|
2056
2095
|
searchFrom = afterColon;
|
|
2057
2096
|
continue;
|
|
2058
2097
|
}
|
|
2059
|
-
|
|
2060
|
-
let j = afterColon;
|
|
2061
|
-
while (j < result.length) {
|
|
2062
|
-
const ch = result[j];
|
|
2063
|
-
if (ch === "(" || ch === "[") {
|
|
2064
|
-
depth++;
|
|
2065
|
-
} else if (ch === ")" || ch === "]") {
|
|
2066
|
-
if (depth === 0) {
|
|
2067
|
-
break;
|
|
2068
|
-
}
|
|
2069
|
-
depth--;
|
|
2070
|
-
} else if (depth === 0 && (ch === "," || ch === ";" || ch === "\n" || ch === "}")) {
|
|
2071
|
-
break;
|
|
2072
|
-
}
|
|
2073
|
-
j++;
|
|
2074
|
-
}
|
|
2098
|
+
const j = scanClassExpression(result, afterColon);
|
|
2075
2099
|
const expr = result.slice(afterColon, j);
|
|
2076
|
-
|
|
2077
|
-
if (qIdx === -1 || !expr.slice(qIdx).includes(":")) {
|
|
2078
|
-
out += expr;
|
|
2079
|
-
searchFrom = j;
|
|
2080
|
-
continue;
|
|
2081
|
-
}
|
|
2082
|
-
let changed = false;
|
|
2083
|
-
const mangled = expr.replace(/"([^"]*)"/g, (qm, inner) => {
|
|
2084
|
-
const parts = inner.split(/\s+/).filter(Boolean);
|
|
2085
|
-
if (parts.length === 0) {
|
|
2086
|
-
return qm;
|
|
2087
|
-
}
|
|
2088
|
-
const mangledStr = parts.map((p) => mangleMap[p] || p).join(" ");
|
|
2089
|
-
if (mangledStr !== inner) {
|
|
2090
|
-
changed = true;
|
|
2091
|
-
return `"${mangledStr}"`;
|
|
2092
|
-
}
|
|
2093
|
-
return qm;
|
|
2094
|
-
});
|
|
2095
|
-
out += changed ? mangled : expr;
|
|
2100
|
+
out += mangleTernaryClassStrings(expr) ?? expr;
|
|
2096
2101
|
searchFrom = j;
|
|
2097
2102
|
}
|
|
2098
2103
|
result = out;
|
|
2099
2104
|
}
|
|
2105
|
+
{
|
|
2106
|
+
const markerRe = /"class(?:Name)?"\s*,\s*/g;
|
|
2107
|
+
let out = "";
|
|
2108
|
+
let copiedTo = 0;
|
|
2109
|
+
let m = markerRe.exec(result);
|
|
2110
|
+
while (m !== null) {
|
|
2111
|
+
const exprStart = m.index + m[0].length;
|
|
2112
|
+
const firstChar = result[exprStart];
|
|
2113
|
+
if (firstChar === '"' || firstChar === "'" || firstChar === "`") {
|
|
2114
|
+
m = markerRe.exec(result);
|
|
2115
|
+
continue;
|
|
2116
|
+
}
|
|
2117
|
+
const j = scanClassExpression(result, exprStart);
|
|
2118
|
+
const expr = result.slice(exprStart, j);
|
|
2119
|
+
const mangled = mangleTernaryClassStrings(expr);
|
|
2120
|
+
if (mangled !== null) {
|
|
2121
|
+
out += result.slice(copiedTo, exprStart) + mangled;
|
|
2122
|
+
copiedTo = j;
|
|
2123
|
+
}
|
|
2124
|
+
markerRe.lastIndex = j;
|
|
2125
|
+
m = markerRe.exec(result);
|
|
2126
|
+
}
|
|
2127
|
+
if (copiedTo > 0) {
|
|
2128
|
+
result = out + result.slice(copiedTo);
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2100
2131
|
result = result.replace(/(?<=(?:[,(]|&&)\s*)"([^"]+)"/g, (match, inner) => {
|
|
2101
2132
|
const tokens = inner.split(/\s+/).filter(Boolean);
|
|
2102
2133
|
if (tokens.length === 0) {
|
|
@@ -2668,6 +2699,21 @@ function createCsszyxPlugins(options = {}) {
|
|
|
2668
2699
|
}
|
|
2669
2700
|
return null;
|
|
2670
2701
|
},
|
|
2702
|
+
/**
|
|
2703
|
+
* Restricts the load hook to csszyx's own virtual modules.
|
|
2704
|
+
*
|
|
2705
|
+
* Without this, unplugin's webpack adapter registers its load
|
|
2706
|
+
* loader with `type: 'javascript/auto'` for every module (its
|
|
2707
|
+
* include defaults to all ids when no loadInclude exists). That
|
|
2708
|
+
* corrupts binary asset modules (images, fonts) in webpack apps —
|
|
2709
|
+
* Next.js builds fail with "not a valid image file" / "Module
|
|
2710
|
+
* parse failed" on assets that build fine without csszyx.
|
|
2711
|
+
* @param id - the module ID webpack is about to load
|
|
2712
|
+
* @returns true only for csszyx virtual modules
|
|
2713
|
+
*/
|
|
2714
|
+
loadInclude(id) {
|
|
2715
|
+
return id === RESOLVED_VIRTUAL_MODULE_ID || id === RESOLVED_VIRTUAL_CHECKSUM_ID;
|
|
2716
|
+
},
|
|
2671
2717
|
/**
|
|
2672
2718
|
* Loads virtual module content — generates mangle map or checksum module code.
|
|
2673
2719
|
* @param id - the resolved module ID to load
|
package/dist/vite.cjs
CHANGED
package/dist/vite.mjs
CHANGED
package/dist/webpack.cjs
CHANGED
package/dist/webpack.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@csszyx/unplugin",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.10",
|
|
4
4
|
"description": "Vite and Webpack integration for csszyx",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"csszyx",
|
|
@@ -117,19 +117,19 @@
|
|
|
117
117
|
"postcss-value-parser": "^4.2.0",
|
|
118
118
|
"proper-lockfile": "^4.1.2",
|
|
119
119
|
"unplugin": "^1.10.1",
|
|
120
|
-
"@csszyx/compiler": "0.9.
|
|
121
|
-
"@csszyx/
|
|
122
|
-
"@csszyx/
|
|
123
|
-
"@csszyx/vue-adapter": "0.9.
|
|
124
|
-
"@csszyx/types": "0.9.
|
|
120
|
+
"@csszyx/compiler": "0.9.10",
|
|
121
|
+
"@csszyx/core": "0.9.10",
|
|
122
|
+
"@csszyx/svelte-adapter": "0.9.10",
|
|
123
|
+
"@csszyx/vue-adapter": "0.9.10",
|
|
124
|
+
"@csszyx/types": "0.9.10"
|
|
125
125
|
},
|
|
126
126
|
"peerDependencies": {
|
|
127
|
-
"@csszyx/runtime": "^0.9.
|
|
127
|
+
"@csszyx/runtime": "^0.9.10"
|
|
128
128
|
},
|
|
129
129
|
"devDependencies": {
|
|
130
130
|
"@types/node": "^20.11.0",
|
|
131
131
|
"@types/proper-lockfile": "^4.1.4",
|
|
132
|
-
"esbuild": "^0.
|
|
132
|
+
"esbuild": "^0.28.1",
|
|
133
133
|
"rollup": "^4.56.0",
|
|
134
134
|
"typescript": "^6.0.3",
|
|
135
135
|
"unbuild": "^3.6.1",
|