@csszyx/unplugin 0.6.0 → 0.7.0

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.
@@ -2,6 +2,303 @@ import {
2
2
  mangleCSSSync
3
3
  } from "./chunk-4M7CPGP7.js";
4
4
 
5
+ // src/rsc-boundary.ts
6
+ import * as fs from "fs";
7
+ import * as path from "path";
8
+ var SERVER_DIRECTIVE_RE = /^['"]use server['"];?$/;
9
+ var CLIENT_DIRECTIVE_RE = /^['"]use client['"];?$/;
10
+ var RUNTIME_MODULES = /* @__PURE__ */ new Set([
11
+ "@csszyx/runtime",
12
+ "@csszyx/runtime/lite",
13
+ "csszyx",
14
+ "csszyx/lite"
15
+ ]);
16
+ var FORBIDDEN_SYMBOLS = /* @__PURE__ */ new Set([
17
+ "_sz",
18
+ "_sz2",
19
+ "_sz3",
20
+ "_szIf",
21
+ "_szMerge",
22
+ "_szSwitch",
23
+ "__csszyx_runtime__"
24
+ ]);
25
+ function hasUseServerDirective(code) {
26
+ for (const statement of readDirectivePrologue(code)) {
27
+ if (SERVER_DIRECTIVE_RE.test(statement)) {
28
+ return true;
29
+ }
30
+ if (CLIENT_DIRECTIVE_RE.test(statement)) {
31
+ return false;
32
+ }
33
+ }
34
+ return false;
35
+ }
36
+ function hasUseClientDirective(code) {
37
+ for (const statement of readDirectivePrologue(code)) {
38
+ if (CLIENT_DIRECTIVE_RE.test(statement)) {
39
+ return true;
40
+ }
41
+ if (SERVER_DIRECTIVE_RE.test(statement)) {
42
+ return false;
43
+ }
44
+ }
45
+ return false;
46
+ }
47
+ function isRSCServerModule(code, id) {
48
+ if (hasUseServerDirective(code)) {
49
+ return true;
50
+ }
51
+ if (hasUseClientDirective(code)) {
52
+ return false;
53
+ }
54
+ return isNextAppRouterEntry(id);
55
+ }
56
+ function findRSCBoundaryViolation(code, id) {
57
+ if (!isRSCServerModule(code, id)) {
58
+ return null;
59
+ }
60
+ for (const imported of findRuntimeImports(code)) {
61
+ for (const symbol of imported.symbols) {
62
+ if (FORBIDDEN_SYMBOLS.has(symbol)) {
63
+ return {
64
+ symbol,
65
+ path: id,
66
+ importChain: [id, imported.source]
67
+ };
68
+ }
69
+ }
70
+ }
71
+ return null;
72
+ }
73
+ function createRSCModuleRecord(code, id) {
74
+ const normalized = normalizeModuleId(id);
75
+ return {
76
+ id: normalized,
77
+ isServer: isRSCServerModule(code, normalized),
78
+ isClient: hasUseClientDirective(code),
79
+ imports: findLocalImportSources(code).map((source) => resolveLocalModule(normalized, source)).filter((resolved) => resolved !== null),
80
+ runtimeImports: findRuntimeImports(code).filter((imported) => imported.symbols.some((symbol) => FORBIDDEN_SYMBOLS.has(symbol)))
81
+ };
82
+ }
83
+ function findRSCGraphViolation(records) {
84
+ for (const root of records.values()) {
85
+ if (!root.isServer) {
86
+ continue;
87
+ }
88
+ const violation = walkRSCGraph(root, records, [root.id], /* @__PURE__ */ new Set([root.id]));
89
+ if (violation) {
90
+ return {
91
+ symbol: violation.symbol,
92
+ path: root.id,
93
+ importChain: violation.importChain
94
+ };
95
+ }
96
+ }
97
+ return null;
98
+ }
99
+ function assertNoRSCGraphViolation(records) {
100
+ const violation = findRSCGraphViolation(records);
101
+ if (!violation) {
102
+ return;
103
+ }
104
+ throw new Error(formatRSCViolation(violation));
105
+ }
106
+ function isNextAppRouterEntry(id) {
107
+ const clean = id.split("?")[0]?.replace(/\\/g, "/") ?? id;
108
+ return /(^|\/)app\/.*\/?(?:page|layout|template|loading|error|not-found|global-error|default|route)\.[cm]?[tj]sx?$/.test(clean);
109
+ }
110
+ function assertNoRSCBoundaryViolation(code, id) {
111
+ const violation = findRSCBoundaryViolation(code, id);
112
+ if (!violation) {
113
+ return;
114
+ }
115
+ throw new Error(formatRSCViolation(violation));
116
+ }
117
+ function formatRSCViolation(violation) {
118
+ return `csszyxRSCViolation: ${violation.symbol} imported in Server Component ${violation.path}
119
+ Import chain: ${violation.importChain.join(" -> ")}`;
120
+ }
121
+ function walkRSCGraph(current, records, chain, seen) {
122
+ if (current.isClient) {
123
+ return null;
124
+ }
125
+ const runtime = current.runtimeImports[0];
126
+ const symbol = runtime?.symbols.find((s) => FORBIDDEN_SYMBOLS.has(s));
127
+ if (runtime && symbol) {
128
+ return {
129
+ symbol,
130
+ path: chain[0] ?? current.id,
131
+ importChain: [...chain, runtime.source]
132
+ };
133
+ }
134
+ for (const importedId of current.imports) {
135
+ if (seen.has(importedId)) {
136
+ continue;
137
+ }
138
+ const next = records.get(importedId);
139
+ if (!next) {
140
+ continue;
141
+ }
142
+ seen.add(importedId);
143
+ const violation = walkRSCGraph(next, records, [...chain, importedId], seen);
144
+ if (violation) {
145
+ return violation;
146
+ }
147
+ }
148
+ return null;
149
+ }
150
+ function readDirectivePrologue(code) {
151
+ const out = [];
152
+ let i = code.charCodeAt(0) === 65279 ? 1 : 0;
153
+ while (i < code.length) {
154
+ i = skipWhitespaceAndComments(code, i);
155
+ const quote = code[i];
156
+ if (quote !== '"' && quote !== "'") {
157
+ break;
158
+ }
159
+ let j = i + 1;
160
+ let escaped = false;
161
+ while (j < code.length) {
162
+ const ch = code[j];
163
+ if (escaped) {
164
+ escaped = false;
165
+ } else if (ch === "\\") {
166
+ escaped = true;
167
+ } else if (ch === quote) {
168
+ break;
169
+ }
170
+ j++;
171
+ }
172
+ if (j >= code.length) {
173
+ break;
174
+ }
175
+ let end = j + 1;
176
+ while (end < code.length && /[ \t\r\n]/.test(code[end])) {
177
+ end++;
178
+ }
179
+ if (code[end] === ";") {
180
+ end++;
181
+ }
182
+ out.push(code.slice(i, end).trim());
183
+ i = end;
184
+ }
185
+ return out;
186
+ }
187
+ function skipWhitespaceAndComments(code, start) {
188
+ let i = start;
189
+ while (i < code.length) {
190
+ while (i < code.length && /\s/.test(code[i])) {
191
+ i++;
192
+ }
193
+ if (code.startsWith("//", i)) {
194
+ const next = code.indexOf("\n", i + 2);
195
+ i = next === -1 ? code.length : next + 1;
196
+ continue;
197
+ }
198
+ if (code.startsWith("/*", i)) {
199
+ const next = code.indexOf("*/", i + 2);
200
+ i = next === -1 ? code.length : next + 2;
201
+ continue;
202
+ }
203
+ break;
204
+ }
205
+ return i;
206
+ }
207
+ function findRuntimeImports(code) {
208
+ const imports = [];
209
+ const staticImportRe = /import\s+(?!type\b)([\s\S]*?)\s+from\s+['"]([^'"]+)['"]/g;
210
+ const sideEffectImportRe = /import\s+['"]([^'"]+)['"]/g;
211
+ const dynamicImportRe = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
212
+ let match;
213
+ while ((match = staticImportRe.exec(code)) !== null) {
214
+ const clause = match[1];
215
+ const source = match[2];
216
+ if (!RUNTIME_MODULES.has(source)) {
217
+ continue;
218
+ }
219
+ imports.push({ source, symbols: readImportedSymbols(clause) });
220
+ }
221
+ while ((match = sideEffectImportRe.exec(code)) !== null) {
222
+ const source = match[1];
223
+ if (RUNTIME_MODULES.has(source)) {
224
+ imports.push({ source, symbols: [] });
225
+ }
226
+ }
227
+ while ((match = dynamicImportRe.exec(code)) !== null) {
228
+ const source = match[1];
229
+ if (RUNTIME_MODULES.has(source)) {
230
+ imports.push({ source, symbols: Array.from(FORBIDDEN_SYMBOLS) });
231
+ }
232
+ }
233
+ return imports;
234
+ }
235
+ function findLocalImportSources(code) {
236
+ const out = [];
237
+ const staticImportRe = /import\s+(?!type\b)(?:[\s\S]*?\s+from\s+)?['"]([^'"]+)['"]/g;
238
+ const exportFromRe = /export\s+(?!type\b)(?:[\s\S]*?)\s+from\s+['"]([^'"]+)['"]/g;
239
+ const dynamicImportRe = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
240
+ let match;
241
+ for (const re of [staticImportRe, exportFromRe, dynamicImportRe]) {
242
+ while ((match = re.exec(code)) !== null) {
243
+ const source = match[1];
244
+ if (source.startsWith(".") || source.startsWith("/")) {
245
+ out.push(source);
246
+ }
247
+ }
248
+ }
249
+ return out;
250
+ }
251
+ function normalizeModuleId(id) {
252
+ const clean = id.split("?")[0] ?? id;
253
+ try {
254
+ return fs.realpathSync.native(clean).replace(/\\/g, "/");
255
+ } catch {
256
+ return path.resolve(clean).replace(/\\/g, "/");
257
+ }
258
+ }
259
+ function resolveLocalModule(importer, source) {
260
+ const base = source.startsWith("/") ? source : path.resolve(path.dirname(importer), source);
261
+ const candidates = [
262
+ base,
263
+ `${base}.tsx`,
264
+ `${base}.ts`,
265
+ `${base}.jsx`,
266
+ `${base}.js`,
267
+ `${base}.mjs`,
268
+ `${base}.cjs`,
269
+ path.join(base, "index.tsx"),
270
+ path.join(base, "index.ts"),
271
+ path.join(base, "index.jsx"),
272
+ path.join(base, "index.js")
273
+ ];
274
+ for (const candidate of candidates) {
275
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
276
+ return normalizeModuleId(candidate);
277
+ }
278
+ }
279
+ return null;
280
+ }
281
+ function readImportedSymbols(clause) {
282
+ const symbols = [];
283
+ const named = clause.match(/\{([\s\S]*?)\}/);
284
+ if (named) {
285
+ for (const part of named[1].split(",")) {
286
+ const trimmed = part.trim();
287
+ if (!trimmed || trimmed.startsWith("type ")) {
288
+ continue;
289
+ }
290
+ const sourceName = trimmed.replace(/^type\s+/, "").split(/\s+as\s+/)[0]?.trim();
291
+ if (sourceName) {
292
+ symbols.push(sourceName);
293
+ }
294
+ }
295
+ }
296
+ if (/\*\s+as\s+\w+/.test(clause)) {
297
+ symbols.push(...FORBIDDEN_SYMBOLS);
298
+ }
299
+ return symbols;
300
+ }
301
+
5
302
  // src/theme-scanner.ts
6
303
  var EMPTY_THEME = { colors: [], spacings: [], fonts: [], radii: [], shadows: [] };
7
304
  function stripLayerWrappers(css) {
@@ -145,8 +442,8 @@ function hasTokens(theme) {
145
442
  }
146
443
 
147
444
  // src/unplugin.ts
148
- import * as fs from "fs";
149
- import * as path from "path";
445
+ import * as fs2 from "fs";
446
+ import * as path2 from "path";
150
447
  import { transform, transformSourceCode } from "@csszyx/compiler";
151
448
  import { compute_mangle_checksum, encode } from "@csszyx/core";
152
449
  import { preprocess as sveltePreprocess } from "@csszyx/svelte-adapter";
@@ -214,7 +511,7 @@ function injectHydrationData(html, mangleMap, checksum, options = {}) {
214
511
  function transformIndexHtml(html, mangleMap, checksum, options = {}) {
215
512
  return injectHydrationData(html, mangleMap, checksum, options);
216
513
  }
217
- function buildRecoveryManifest(tokens, options = {}) {
514
+ function buildRecoveryManifest(tokens, options) {
218
515
  const stripped = options.production === true;
219
516
  const strippedDevOnlyPaths = [];
220
517
  const sorted = {};
@@ -228,14 +525,14 @@ function buildRecoveryManifest(tokens, options = {}) {
228
525
  strippedDevOnlyPaths.push(data.path);
229
526
  continue;
230
527
  }
231
- sorted[key] = data;
528
+ sorted[key] = stripped ? { mode: data.mode, component: data.component, path: "" } : data;
232
529
  }
233
530
  const serialised = JSON.stringify(sorted);
234
531
  const fullChecksum = createHash("sha256").update(serialised).digest("hex");
235
532
  const checksum = fullChecksum.substring(0, 16);
236
533
  const buildId = `${Date.now().toString(36)}-${fullChecksum.substring(0, 6)}`;
237
534
  return {
238
- manifest: { buildId, checksum, tokens: sorted },
535
+ manifest: { buildId, checksum, mangleChecksum: options.mangleChecksum, tokens: sorted },
239
536
  strippedDevOnlyPaths
240
537
  };
241
538
  }
@@ -257,7 +554,7 @@ function injectRecoveryManifest(html, manifest) {
257
554
 
258
555
  // src/theme-type-writer.ts
259
556
  import { mkdirSync, writeFileSync } from "fs";
260
- import { dirname } from "path";
557
+ import { dirname as dirname2 } from "path";
261
558
  function generateThemeDts(opts) {
262
559
  const { theme, sourceFiles } = opts;
263
560
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
@@ -300,7 +597,7 @@ function generateThemeDts(opts) {
300
597
  }
301
598
  function writeThemeDts(opts) {
302
599
  const content = generateThemeDts(opts);
303
- mkdirSync(dirname(opts.outputPath), { recursive: true });
600
+ mkdirSync(dirname2(opts.outputPath), { recursive: true });
304
601
  writeFileSync(opts.outputPath, content, "utf-8");
305
602
  }
306
603
 
@@ -364,8 +661,8 @@ function runThemeScan(rootDir, scanCss) {
364
661
  const patterns = Array.isArray(scanCss) ? scanCss : [scanCss];
365
662
  const sourceFiles = [];
366
663
  for (const pattern of patterns) {
367
- const resolved = path.isAbsolute(pattern) ? pattern : path.join(rootDir, pattern);
368
- if (fs.existsSync(resolved)) {
664
+ const resolved = path2.isAbsolute(pattern) ? pattern : path2.join(rootDir, pattern);
665
+ if (fs2.existsSync(resolved)) {
369
666
  sourceFiles.push(resolved);
370
667
  }
371
668
  }
@@ -374,20 +671,20 @@ function runThemeScan(rootDir, scanCss) {
374
671
  }
375
672
  const themes = sourceFiles.map((f) => {
376
673
  try {
377
- return parseThemeBlocks(fs.readFileSync(f, "utf-8"));
674
+ return parseThemeBlocks(fs2.readFileSync(f, "utf-8"));
378
675
  } catch {
379
676
  return null;
380
677
  }
381
678
  }).filter((t) => t !== null);
382
679
  const merged = mergeThemes(themes);
383
- const outputPath = path.join(rootDir, ".csszyx", "theme.d.ts");
680
+ const outputPath = path2.join(rootDir, ".csszyx", "theme.d.ts");
384
681
  writeThemeDts({ outputPath, theme: merged, sourceFiles });
385
682
  if (!_hasWarnedTsConfig) {
386
683
  _hasWarnedTsConfig = true;
387
684
  try {
388
685
  const checkFile = (cfgPath) => {
389
- if (fs.existsSync(cfgPath)) {
390
- const content = fs.readFileSync(cfgPath, "utf-8");
686
+ if (fs2.existsSync(cfgPath)) {
687
+ const content = fs2.readFileSync(cfgPath, "utf-8");
391
688
  if (!content.includes(".csszyx")) {
392
689
  console.warn(`
393
690
  \x1B[33m\u26A0\uFE0F CSSzyx: Theme Auto-Scan enabled, but TypeScript isn't configured. Run "npx @csszyx/cli init" to fix.\x1B[0m
@@ -397,8 +694,8 @@ function runThemeScan(rootDir, scanCss) {
397
694
  }
398
695
  return false;
399
696
  };
400
- if (!checkFile(path.join(rootDir, "tsconfig.json"))) {
401
- checkFile(path.join(rootDir, "tsconfig.app.json"));
697
+ if (!checkFile(path2.join(rootDir, "tsconfig.json"))) {
698
+ checkFile(path2.join(rootDir, "tsconfig.app.json"));
402
699
  }
403
700
  } catch {
404
701
  }
@@ -578,13 +875,15 @@ function mangleCodeClassesSync(code, mangleMap) {
578
875
  }
579
876
  function createCsszyxPlugins(options = {}) {
580
877
  const manglingEnabled = options.production?.mangle !== false;
878
+ const astBudgetOverride = options.build?.astBudgetLimit;
581
879
  const state = {
582
880
  classes: /* @__PURE__ */ new Set(),
583
881
  mangleMap: {},
584
882
  checksum: "",
585
883
  finalized: false,
586
884
  rootDir: process.cwd(),
587
- recoveryTokens: /* @__PURE__ */ new Map()
885
+ recoveryTokens: /* @__PURE__ */ new Map(),
886
+ rscModules: /* @__PURE__ */ new Map()
588
887
  };
589
888
  const SAFELIST_FILENAME = "csszyx-classes.html";
590
889
  const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".tsx", ".jsx", ".ts", ".js"]);
@@ -593,16 +892,16 @@ function createCsszyxPlugins(options = {}) {
593
892
  if (classes.size === 0) {
594
893
  return;
595
894
  }
596
- const safelistPath = path.join(state.rootDir, SAFELIST_FILENAME);
895
+ const safelistPath = path2.join(state.rootDir, SAFELIST_FILENAME);
597
896
  const classList = Array.from(classes).join(" ");
598
897
  const content = `<!-- Auto-generated by csszyx \u2014 DO NOT EDIT -->
599
898
  <!-- Tailwind CSS scans this file for class name detection -->
600
899
  <div class="${classList}"><div class="${classList}">x</div><div class="${classList}">x</div></div>
601
900
  `;
602
901
  try {
603
- const existing = fs.existsSync(safelistPath) ? fs.readFileSync(safelistPath, "utf-8") : "";
902
+ const existing = fs2.existsSync(safelistPath) ? fs2.readFileSync(safelistPath, "utf-8") : "";
604
903
  if (existing !== content) {
605
- fs.writeFileSync(safelistPath, content);
904
+ fs2.writeFileSync(safelistPath, content);
606
905
  }
607
906
  } catch {
608
907
  }
@@ -613,23 +912,23 @@ function createCsszyxPlugins(options = {}) {
613
912
  function scanDir(dir) {
614
913
  let entries;
615
914
  try {
616
- entries = fs.readdirSync(dir, { withFileTypes: true });
915
+ entries = fs2.readdirSync(dir, { withFileTypes: true });
617
916
  } catch {
618
917
  return;
619
918
  }
620
919
  for (const entry of entries) {
621
920
  if (entry.isDirectory()) {
622
921
  if (!IGNORE_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
623
- scanDir(path.join(dir, entry.name));
922
+ scanDir(path2.join(dir, entry.name));
624
923
  }
625
- } else if (SOURCE_EXTENSIONS.has(path.extname(entry.name))) {
626
- const filePath = path.join(dir, entry.name);
924
+ } else if (SOURCE_EXTENSIONS.has(path2.extname(entry.name))) {
925
+ const filePath = path2.join(dir, entry.name);
627
926
  try {
628
- const content = fs.readFileSync(filePath, "utf-8");
927
+ const content = fs2.readFileSync(filePath, "utf-8");
629
928
  if (!content.includes("sz=") && !content.includes("sz:")) {
630
929
  continue;
631
930
  }
632
- const result = transformSourceCode(content, filePath);
931
+ const result = transformSourceCode(content, filePath, { astBudget: astBudgetOverride });
633
932
  if (!result.transformed) {
634
933
  continue;
635
934
  }
@@ -817,14 +1116,17 @@ function createCsszyxPlugins(options = {}) {
817
1116
  * @returns transformed code with source map, or null if no changes were made
818
1117
  */
819
1118
  transform(code, id) {
1119
+ if (/\.[tj]sx?(\?.*)?$/.test(id)) {
1120
+ assertNoRSCBoundaryViolation(code, id);
1121
+ }
820
1122
  if (/\.css(\?.*)?$/.test(id)) {
821
1123
  const hasTailwindImport = code.includes('@import "tailwindcss') || code.includes("@import 'tailwindcss");
822
1124
  if (hasTailwindImport && state.classes.size > 0) {
823
1125
  const candidates = Array.from(state.classes).filter((c) => c.length >= 2 && /^[a-z]/.test(c)).join(" ");
824
1126
  if (candidates) {
825
- const safelistPath = path.join(state.rootDir, SAFELIST_FILENAME).replace(/\\/g, "/");
826
- const cssDir = path.dirname(id).replace(/\\/g, "/");
827
- let relPath = path.posix.relative(cssDir, safelistPath);
1127
+ const safelistPath = path2.join(state.rootDir, SAFELIST_FILENAME).replace(/\\/g, "/");
1128
+ const cssDir = path2.dirname(id).replace(/\\/g, "/");
1129
+ let relPath = path2.posix.relative(cssDir, safelistPath);
828
1130
  if (!relPath.startsWith(".")) {
829
1131
  relPath = "./" + relPath;
830
1132
  }
@@ -863,7 +1165,7 @@ ${sourceDirective}`
863
1165
  transformed = true;
864
1166
  }
865
1167
  } else {
866
- const result = transformSourceCode(code, id);
1168
+ const result = transformSourceCode(code, id, { astBudget: astBudgetOverride });
867
1169
  transformedCode = result.code;
868
1170
  usesRuntime = result.usesRuntime;
869
1171
  usesMerge = result.usesMerge;
@@ -928,6 +1230,11 @@ ${sourceDirective}`
928
1230
  transformed = true;
929
1231
  }
930
1232
  }
1233
+ if (/\.[tj]sx?(\?.*)?$/.test(id)) {
1234
+ assertNoRSCBoundaryViolation(transformedCode, id);
1235
+ const record = createRSCModuleRecord(transformedCode, id);
1236
+ state.rscModules.set(record.id, record);
1237
+ }
931
1238
  if (transformed || transformedCode.includes("class=") || transformedCode.includes("className=")) {
932
1239
  if (szClasses !== void 0) {
933
1240
  for (const cls of szClasses) {
@@ -943,6 +1250,7 @@ ${sourceDirective}`
943
1250
  /** Finalizes the mangle map after all source modules have been processed. */
944
1251
  buildEnd() {
945
1252
  finalizeMangleMap();
1253
+ assertNoRSCGraphViolation(state.rscModules);
946
1254
  if (manglingEnabled && Object.keys(state.mangleMap).length > 0) {
947
1255
  globalThis.__csszyx_ssr_mangle_map = state.mangleMap;
948
1256
  }
@@ -965,8 +1273,8 @@ ${sourceDirective}`
965
1273
  compiler.hooks.thisCompilation.tap("csszyx:theme-deps", (compilation) => {
966
1274
  const root = compiler.context || process.cwd();
967
1275
  for (const pattern of patterns) {
968
- const resolved = path.isAbsolute(pattern) ? pattern : path.join(root, pattern);
969
- if (fs.existsSync(resolved)) {
1276
+ const resolved = path2.isAbsolute(pattern) ? pattern : path2.join(root, pattern);
1277
+ if (fs2.existsSync(resolved)) {
970
1278
  compilation.fileDependencies.add(resolved);
971
1279
  }
972
1280
  }
@@ -996,14 +1304,14 @@ ${sourceDirective}`
996
1304
  const patterns = Array.isArray(scanCss) ? scanCss : [scanCss];
997
1305
  const root = ctx.server.config.root || process.cwd();
998
1306
  const isWatched = patterns.some((p) => {
999
- const resolved = path.isAbsolute(p) ? p : path.join(root, p);
1307
+ const resolved = path2.isAbsolute(p) ? p : path2.join(root, p);
1000
1308
  return ctx.file === resolved;
1001
1309
  });
1002
1310
  if (isWatched) {
1003
1311
  runThemeScan(root, scanCss);
1004
1312
  }
1005
1313
  }
1006
- if (!SOURCE_EXTENSIONS.has(path.extname(ctx.file))) {
1314
+ if (!SOURCE_EXTENSIONS.has(path2.extname(ctx.file))) {
1007
1315
  return;
1008
1316
  }
1009
1317
  if (ctx.file.includes("node_modules")) {
@@ -1011,7 +1319,7 @@ ${sourceDirective}`
1011
1319
  }
1012
1320
  let fileContent, result;
1013
1321
  try {
1014
- fileContent = fs.readFileSync(ctx.file, "utf-8");
1322
+ fileContent = fs2.readFileSync(ctx.file, "utf-8");
1015
1323
  } catch {
1016
1324
  return;
1017
1325
  }
@@ -1019,7 +1327,7 @@ ${sourceDirective}`
1019
1327
  return;
1020
1328
  }
1021
1329
  try {
1022
- result = transformSourceCode(fileContent, ctx.file);
1330
+ result = transformSourceCode(fileContent, ctx.file, { astBudget: astBudgetOverride });
1023
1331
  } catch {
1024
1332
  return;
1025
1333
  }
@@ -1035,7 +1343,7 @@ ${sourceDirective}`
1035
1343
  }
1036
1344
  if (state.classes.size > sizeBefore) {
1037
1345
  writeSafelistFile(state.classes);
1038
- const safelistPath = path.join(state.rootDir, SAFELIST_FILENAME);
1346
+ const safelistPath = path2.join(state.rootDir, SAFELIST_FILENAME);
1039
1347
  ctx.server.watcher.emit("change", safelistPath);
1040
1348
  }
1041
1349
  },
@@ -1057,7 +1365,10 @@ ${sourceDirective}`
1057
1365
  const isProduction = process.env.NODE_ENV === "production";
1058
1366
  const { manifest, strippedDevOnlyPaths } = buildRecoveryManifest(
1059
1367
  state.recoveryTokens,
1060
- { production: isProduction }
1368
+ {
1369
+ production: isProduction,
1370
+ mangleChecksum: state.checksum
1371
+ }
1061
1372
  );
1062
1373
  if (strippedDevOnlyPaths.length > 0) {
1063
1374
  console.warn(
@@ -1271,6 +1582,14 @@ var esbuildPlugin = (options = {}) => {
1271
1582
  };
1272
1583
 
1273
1584
  export {
1585
+ hasUseServerDirective,
1586
+ hasUseClientDirective,
1587
+ isRSCServerModule,
1588
+ findRSCBoundaryViolation,
1589
+ createRSCModuleRecord,
1590
+ findRSCGraphViolation,
1591
+ assertNoRSCGraphViolation,
1592
+ assertNoRSCBoundaryViolation,
1274
1593
  parseThemeBlocks,
1275
1594
  mergeThemes,
1276
1595
  hasTokens,