@csszyx/unplugin 0.6.2 → 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 = {};
@@ -235,7 +532,7 @@ function buildRecoveryManifest(tokens, options = {}) {
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
  }
@@ -585,7 +882,8 @@ function createCsszyxPlugins(options = {}) {
585
882
  checksum: "",
586
883
  finalized: false,
587
884
  rootDir: process.cwd(),
588
- recoveryTokens: /* @__PURE__ */ new Map()
885
+ recoveryTokens: /* @__PURE__ */ new Map(),
886
+ rscModules: /* @__PURE__ */ new Map()
589
887
  };
590
888
  const SAFELIST_FILENAME = "csszyx-classes.html";
591
889
  const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".tsx", ".jsx", ".ts", ".js"]);
@@ -594,16 +892,16 @@ function createCsszyxPlugins(options = {}) {
594
892
  if (classes.size === 0) {
595
893
  return;
596
894
  }
597
- const safelistPath = path.join(state.rootDir, SAFELIST_FILENAME);
895
+ const safelistPath = path2.join(state.rootDir, SAFELIST_FILENAME);
598
896
  const classList = Array.from(classes).join(" ");
599
897
  const content = `<!-- Auto-generated by csszyx \u2014 DO NOT EDIT -->
600
898
  <!-- Tailwind CSS scans this file for class name detection -->
601
899
  <div class="${classList}"><div class="${classList}">x</div><div class="${classList}">x</div></div>
602
900
  `;
603
901
  try {
604
- const existing = fs.existsSync(safelistPath) ? fs.readFileSync(safelistPath, "utf-8") : "";
902
+ const existing = fs2.existsSync(safelistPath) ? fs2.readFileSync(safelistPath, "utf-8") : "";
605
903
  if (existing !== content) {
606
- fs.writeFileSync(safelistPath, content);
904
+ fs2.writeFileSync(safelistPath, content);
607
905
  }
608
906
  } catch {
609
907
  }
@@ -614,19 +912,19 @@ function createCsszyxPlugins(options = {}) {
614
912
  function scanDir(dir) {
615
913
  let entries;
616
914
  try {
617
- entries = fs.readdirSync(dir, { withFileTypes: true });
915
+ entries = fs2.readdirSync(dir, { withFileTypes: true });
618
916
  } catch {
619
917
  return;
620
918
  }
621
919
  for (const entry of entries) {
622
920
  if (entry.isDirectory()) {
623
921
  if (!IGNORE_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
624
- scanDir(path.join(dir, entry.name));
922
+ scanDir(path2.join(dir, entry.name));
625
923
  }
626
- } else if (SOURCE_EXTENSIONS.has(path.extname(entry.name))) {
627
- 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);
628
926
  try {
629
- const content = fs.readFileSync(filePath, "utf-8");
927
+ const content = fs2.readFileSync(filePath, "utf-8");
630
928
  if (!content.includes("sz=") && !content.includes("sz:")) {
631
929
  continue;
632
930
  }
@@ -818,14 +1116,17 @@ function createCsszyxPlugins(options = {}) {
818
1116
  * @returns transformed code with source map, or null if no changes were made
819
1117
  */
820
1118
  transform(code, id) {
1119
+ if (/\.[tj]sx?(\?.*)?$/.test(id)) {
1120
+ assertNoRSCBoundaryViolation(code, id);
1121
+ }
821
1122
  if (/\.css(\?.*)?$/.test(id)) {
822
1123
  const hasTailwindImport = code.includes('@import "tailwindcss') || code.includes("@import 'tailwindcss");
823
1124
  if (hasTailwindImport && state.classes.size > 0) {
824
1125
  const candidates = Array.from(state.classes).filter((c) => c.length >= 2 && /^[a-z]/.test(c)).join(" ");
825
1126
  if (candidates) {
826
- const safelistPath = path.join(state.rootDir, SAFELIST_FILENAME).replace(/\\/g, "/");
827
- const cssDir = path.dirname(id).replace(/\\/g, "/");
828
- 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);
829
1130
  if (!relPath.startsWith(".")) {
830
1131
  relPath = "./" + relPath;
831
1132
  }
@@ -929,6 +1230,11 @@ ${sourceDirective}`
929
1230
  transformed = true;
930
1231
  }
931
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
+ }
932
1238
  if (transformed || transformedCode.includes("class=") || transformedCode.includes("className=")) {
933
1239
  if (szClasses !== void 0) {
934
1240
  for (const cls of szClasses) {
@@ -944,6 +1250,7 @@ ${sourceDirective}`
944
1250
  /** Finalizes the mangle map after all source modules have been processed. */
945
1251
  buildEnd() {
946
1252
  finalizeMangleMap();
1253
+ assertNoRSCGraphViolation(state.rscModules);
947
1254
  if (manglingEnabled && Object.keys(state.mangleMap).length > 0) {
948
1255
  globalThis.__csszyx_ssr_mangle_map = state.mangleMap;
949
1256
  }
@@ -966,8 +1273,8 @@ ${sourceDirective}`
966
1273
  compiler.hooks.thisCompilation.tap("csszyx:theme-deps", (compilation) => {
967
1274
  const root = compiler.context || process.cwd();
968
1275
  for (const pattern of patterns) {
969
- const resolved = path.isAbsolute(pattern) ? pattern : path.join(root, pattern);
970
- if (fs.existsSync(resolved)) {
1276
+ const resolved = path2.isAbsolute(pattern) ? pattern : path2.join(root, pattern);
1277
+ if (fs2.existsSync(resolved)) {
971
1278
  compilation.fileDependencies.add(resolved);
972
1279
  }
973
1280
  }
@@ -997,14 +1304,14 @@ ${sourceDirective}`
997
1304
  const patterns = Array.isArray(scanCss) ? scanCss : [scanCss];
998
1305
  const root = ctx.server.config.root || process.cwd();
999
1306
  const isWatched = patterns.some((p) => {
1000
- const resolved = path.isAbsolute(p) ? p : path.join(root, p);
1307
+ const resolved = path2.isAbsolute(p) ? p : path2.join(root, p);
1001
1308
  return ctx.file === resolved;
1002
1309
  });
1003
1310
  if (isWatched) {
1004
1311
  runThemeScan(root, scanCss);
1005
1312
  }
1006
1313
  }
1007
- if (!SOURCE_EXTENSIONS.has(path.extname(ctx.file))) {
1314
+ if (!SOURCE_EXTENSIONS.has(path2.extname(ctx.file))) {
1008
1315
  return;
1009
1316
  }
1010
1317
  if (ctx.file.includes("node_modules")) {
@@ -1012,7 +1319,7 @@ ${sourceDirective}`
1012
1319
  }
1013
1320
  let fileContent, result;
1014
1321
  try {
1015
- fileContent = fs.readFileSync(ctx.file, "utf-8");
1322
+ fileContent = fs2.readFileSync(ctx.file, "utf-8");
1016
1323
  } catch {
1017
1324
  return;
1018
1325
  }
@@ -1036,7 +1343,7 @@ ${sourceDirective}`
1036
1343
  }
1037
1344
  if (state.classes.size > sizeBefore) {
1038
1345
  writeSafelistFile(state.classes);
1039
- const safelistPath = path.join(state.rootDir, SAFELIST_FILENAME);
1346
+ const safelistPath = path2.join(state.rootDir, SAFELIST_FILENAME);
1040
1347
  ctx.server.watcher.emit("change", safelistPath);
1041
1348
  }
1042
1349
  },
@@ -1058,7 +1365,10 @@ ${sourceDirective}`
1058
1365
  const isProduction = process.env.NODE_ENV === "production";
1059
1366
  const { manifest, strippedDevOnlyPaths } = buildRecoveryManifest(
1060
1367
  state.recoveryTokens,
1061
- { production: isProduction }
1368
+ {
1369
+ production: isProduction,
1370
+ mangleChecksum: state.checksum
1371
+ }
1062
1372
  );
1063
1373
  if (strippedDevOnlyPaths.length > 0) {
1064
1374
  console.warn(
@@ -1272,6 +1582,14 @@ var esbuildPlugin = (options = {}) => {
1272
1582
  };
1273
1583
 
1274
1584
  export {
1585
+ hasUseServerDirective,
1586
+ hasUseClientDirective,
1587
+ isRSCServerModule,
1588
+ findRSCBoundaryViolation,
1589
+ createRSCModuleRecord,
1590
+ findRSCGraphViolation,
1591
+ assertNoRSCGraphViolation,
1592
+ assertNoRSCBoundaryViolation,
1275
1593
  parseThemeBlocks,
1276
1594
  mergeThemes,
1277
1595
  hasTokens,