@homebound/truss 2.29.7 → 2.29.8

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.
@@ -56,6 +56,7 @@ function removeCssImport(ast, cssBinding) {
56
56
  ast.program.body.splice(i, 1);
57
57
  } else {
58
58
  node.specifiers.splice(cssSpecIndex, 1);
59
+ hoistTypeOnlyImportKind(node);
59
60
  }
60
61
  return;
61
62
  }
@@ -76,10 +77,10 @@ function insertAfterLeadingImports(ast, statements) {
76
77
  }
77
78
  function findNamedImportBinding(ast, importedName, source) {
78
79
  for (const node of ast.program.body) {
79
- if (!t.isImportDeclaration(node)) continue;
80
+ if (!t.isImportDeclaration(node) || node.importKind === "type") continue;
80
81
  if (source !== void 0 && node.source.value !== source) continue;
81
82
  for (const spec of node.specifiers) {
82
- if (t.isImportSpecifier(spec) && t.isIdentifier(spec.imported, { name: importedName })) {
83
+ if (t.isImportSpecifier(spec) && spec.importKind !== "type" && t.isIdentifier(spec.imported, { name: importedName })) {
83
84
  return spec.local.name;
84
85
  }
85
86
  }
@@ -109,7 +110,9 @@ function replaceCssImportWithNamedImports(ast, cssBinding, source, imports) {
109
110
  }
110
111
  function upsertNamedImports(ast, source, imports) {
111
112
  if (imports.length === 0) return;
112
- const existing = findImportDeclaration(ast, source);
113
+ const existing = ast.program.body.find(
114
+ (node) => t.isImportDeclaration(node) && node.source.value === source && node.importKind !== "type" && !node.specifiers.some((spec) => t.isImportNamespaceSpecifier(spec))
115
+ );
113
116
  if (!existing) {
114
117
  const importDecl = t.importDeclaration(imports.map(toImportSpecifier), t.stringLiteral(source));
115
118
  ast.program.body.splice(findLastImportIndex(ast) + 1, 0, importDecl);
@@ -117,7 +120,7 @@ function upsertNamedImports(ast, source, imports) {
117
120
  }
118
121
  for (const entry of imports) {
119
122
  const exists = existing.specifiers.some((spec) => {
120
- return t.isImportSpecifier(spec) && t.isIdentifier(spec.imported, { name: entry.importedName });
123
+ return t.isImportSpecifier(spec) && spec.importKind !== "type" && t.isIdentifier(spec.imported, { name: entry.importedName });
121
124
  });
122
125
  if (!exists) existing.specifiers.push(toImportSpecifier(entry));
123
126
  }
@@ -183,6 +186,15 @@ function memberPropertyName(node) {
183
186
  if (node.computed && t.isStringLiteral(node.property)) return node.property.value;
184
187
  return null;
185
188
  }
189
+ function hoistTypeOnlyImportKind(node) {
190
+ if (node.importKind === "type") return;
191
+ const typeOnly = node.specifiers.every((spec) => t.isImportSpecifier(spec) && spec.importKind === "type");
192
+ if (!typeOnly) return;
193
+ node.importKind = "type";
194
+ for (const spec of node.specifiers) {
195
+ if (t.isImportSpecifier(spec)) spec.importKind = null;
196
+ }
197
+ }
186
198
  function toImportSpecifier(entry) {
187
199
  return t.importSpecifier(t.identifier(entry.localName), t.identifier(entry.importedName));
188
200
  }
@@ -2486,6 +2498,84 @@ function sortRulesByPriority(rules) {
2486
2498
  return decorated.map((d) => ({ rule: d.rule, priority: d.priority }));
2487
2499
  }
2488
2500
 
2501
+ // src/plugin/truss-css.ts
2502
+ var RULE_ANNOTATION_RE = /^\/\* @truss p:([\d.]+) c:(\S+) \*\/$/;
2503
+ var PROPERTY_ANNOTATION_RE = /^\/\* @truss @property \*\/$/;
2504
+ var ARBITRARY_START_RE = /^\/\* @truss arbitrary:start \*\/$/;
2505
+ var ARBITRARY_END_RE = /^\/\* @truss arbitrary:end \*\/$/;
2506
+ var PROPERTY_VAR_RE = /^@property\s+(--\S+)/;
2507
+ function parseTrussCss(cssText) {
2508
+ const lines = cssText.split("\n");
2509
+ const rules = [];
2510
+ const properties = [];
2511
+ const arbitraryCssBlocks = [];
2512
+ let i = 0;
2513
+ function takeAnnotatedLine() {
2514
+ i++;
2515
+ while (i < lines.length && lines[i].trim() === "") i++;
2516
+ return i < lines.length ? lines[i].trim() : null;
2517
+ }
2518
+ while (i < lines.length) {
2519
+ const line = lines[i].trim();
2520
+ const ruleMatch = RULE_ANNOTATION_RE.exec(line);
2521
+ if (ruleMatch) {
2522
+ const cssText2 = takeAnnotatedLine();
2523
+ if (cssText2 !== null) {
2524
+ rules.push({ priority: parseFloat(ruleMatch[1]), className: ruleMatch[2], cssText: cssText2 });
2525
+ }
2526
+ i++;
2527
+ continue;
2528
+ }
2529
+ if (PROPERTY_ANNOTATION_RE.test(line)) {
2530
+ const propLine = takeAnnotatedLine();
2531
+ const varMatch = propLine === null ? null : PROPERTY_VAR_RE.exec(propLine);
2532
+ if (propLine !== null && varMatch) {
2533
+ properties.push({ cssText: propLine, varName: varMatch[1] });
2534
+ }
2535
+ i++;
2536
+ continue;
2537
+ }
2538
+ if (ARBITRARY_START_RE.test(line)) {
2539
+ i++;
2540
+ const blockLines = [];
2541
+ while (i < lines.length && !ARBITRARY_END_RE.test(lines[i].trim())) {
2542
+ blockLines.push(lines[i]);
2543
+ i++;
2544
+ }
2545
+ const blockText = blockLines.join("\n").trim();
2546
+ if (blockText.length > 0) {
2547
+ arbitraryCssBlocks.push({ cssText: blockText });
2548
+ }
2549
+ if (i < lines.length && ARBITRARY_END_RE.test(lines[i].trim())) {
2550
+ i++;
2551
+ }
2552
+ continue;
2553
+ }
2554
+ i++;
2555
+ }
2556
+ return { rules, properties, arbitraryCssBlocks };
2557
+ }
2558
+ function serializeTrussCss(css) {
2559
+ const lines = [];
2560
+ for (const rule of css.rules) {
2561
+ lines.push(`/* @truss p:${rule.priority} c:${rule.className} */`, rule.cssText);
2562
+ }
2563
+ for (const prop of css.properties) {
2564
+ lines.push(`/* @truss @property */`, prop.cssText);
2565
+ }
2566
+ for (const block of css.arbitraryCssBlocks) {
2567
+ lines.push(annotateArbitraryCssBlock(block.cssText));
2568
+ }
2569
+ return lines.join("\n");
2570
+ }
2571
+ function annotateArbitraryCssBlock(cssText) {
2572
+ const trimmed = cssText.trim();
2573
+ if (trimmed.length === 0) {
2574
+ return "";
2575
+ }
2576
+ return ["/* @truss arbitrary:start */", trimmed, "/* @truss arbitrary:end */"].join("\n");
2577
+ }
2578
+
2489
2579
  // src/plugin/emit-css.ts
2490
2580
  function collectAtomicRules(chains, mapping) {
2491
2581
  const rules = /* @__PURE__ */ new Map();
@@ -2545,22 +2635,28 @@ function whenSelectorFor(whenPseudo) {
2545
2635
  pseudo: whenPseudo.pseudo
2546
2636
  };
2547
2637
  }
2548
- function generateCssText(rules) {
2638
+ function generateCssData(rules) {
2549
2639
  const sorted = sortRulesByPriority(rules.values());
2550
- const lines = [];
2551
- for (const { rule, priority } of sorted) {
2552
- lines.push(`/* @truss p:${priority} c:${rule.className} */`);
2553
- lines.push(formatRule(rule));
2554
- }
2640
+ const css = {
2641
+ rules: sorted.map((entry) => ({
2642
+ priority: entry.priority,
2643
+ className: entry.rule.className,
2644
+ cssText: formatRule(entry.rule)
2645
+ })),
2646
+ properties: [],
2647
+ arbitraryCssBlocks: []
2648
+ };
2555
2649
  for (const { rule } of sorted) {
2556
2650
  for (const declaration of rule.declarations) {
2557
2651
  if (declaration.cssVarName) {
2558
- lines.push(`/* @truss @property */`);
2559
- lines.push(`@property ${declaration.cssVarName} { syntax: "*"; inherits: false; }`);
2652
+ css.properties.push({
2653
+ varName: declaration.cssVarName,
2654
+ cssText: `@property ${declaration.cssVarName} { syntax: "*"; inherits: false; }`
2655
+ });
2560
2656
  }
2561
2657
  }
2562
2658
  }
2563
- return lines.join("\n");
2659
+ return css;
2564
2660
  }
2565
2661
  function formatRule(rule) {
2566
2662
  const duplicateClassName = !!rule.mediaQuery;
@@ -2805,6 +2901,38 @@ ${body}
2805
2901
  import * as t15 from "@babel/types";
2806
2902
  import { basename } from "path";
2807
2903
 
2904
+ // src/plugin/test-css.ts
2905
+ import { parse as parse2 } from "css-tree";
2906
+ function createTestCssPayload(css) {
2907
+ const payload = {};
2908
+ if (css.rules.length > 0) {
2909
+ payload.rules = css.rules.map((rule) => {
2910
+ const atRule = atRulePrelude(rule.cssText);
2911
+ return { ...rule, ...atRule === void 0 ? {} : { atRule } };
2912
+ });
2913
+ }
2914
+ if (css.properties.length > 0) payload.properties = css.properties;
2915
+ const arbitraryRules = css.arbitraryCssBlocks.flatMap((block) => splitArbitraryCss(block.cssText));
2916
+ if (arbitraryRules.length > 0) payload.arbitraryRules = arbitraryRules;
2917
+ return payload;
2918
+ }
2919
+ function splitArbitraryCss(cssText) {
2920
+ const root = parse2(cssText, {
2921
+ context: "stylesheet",
2922
+ positions: true,
2923
+ parseRulePrelude: false,
2924
+ parseAtrulePrelude: false,
2925
+ parseValue: false
2926
+ });
2927
+ const rules = [];
2928
+ root.children.forEach((node) => {
2929
+ if (node.type === "Rule" || node.type === "Atrule") {
2930
+ rules.push(cssText.slice(node.loc.start.offset, node.loc.end.offset));
2931
+ }
2932
+ });
2933
+ return rules;
2934
+ }
2935
+
2808
2936
  // src/plugin/emit-style-hash.ts
2809
2937
  import * as t13 from "@babel/types";
2810
2938
  function buildStyleHashProperties(segments, mapping, maybeIncHelperName, maybeCssVarHelperName) {
@@ -3271,7 +3399,8 @@ function transformTruss(code, filename, mapping, options = {}) {
3271
3399
  if (sites.length === 0 && !hasCssPropsCall && !hasBuildtimeJsxCssAttribute) return null;
3272
3400
  const chains = sites.map((s) => s.resolvedChain);
3273
3401
  const { rules, needsMaybeInc, needsMaybeCssVar } = collectAtomicRules(chains, mapping);
3274
- const cssText = generateCssText(rules);
3402
+ const cssData = generateCssData(rules);
3403
+ const cssText = serializeTrussCss(cssData);
3275
3404
  const runtime = createRuntimeHelpers(ast, usedTopLevelNames);
3276
3405
  const maybeIncHelperName = needsMaybeInc ? reservePreferredName(usedTopLevelNames, "__maybeInc") : null;
3277
3406
  const maybeCssVarHelperName = needsMaybeCssVar ? runtime.use("maybeCssVar") : null;
@@ -3317,7 +3446,9 @@ function transformTruss(code, filename, mapping, options = {}) {
3317
3446
  }
3318
3447
  if (options.injectCss && cssText.length > 0) {
3319
3448
  declarationsToInsert.push(
3320
- t15.expressionStatement(t15.callExpression(t15.identifier("__injectTrussCSS"), [t15.stringLiteral(cssText)]))
3449
+ t15.expressionStatement(
3450
+ t15.callExpression(t15.identifier("__injectTrussCSS"), [t15.valueToNode(createTestCssPayload(cssData))])
3451
+ )
3321
3452
  );
3322
3453
  }
3323
3454
  for (const { message, line } of errorMessages) {
@@ -3436,78 +3567,11 @@ function findLastImportLine(lines) {
3436
3567
 
3437
3568
  // src/plugin/merge-css.ts
3438
3569
  import { readFileSync as readFileSync2 } from "fs";
3439
-
3440
- // src/truss-css.ts
3441
- var RULE_ANNOTATION_RE = /^\/\* @truss p:([\d.]+) c:(\S+) \*\/$/;
3442
- var PROPERTY_ANNOTATION_RE = /^\/\* @truss @property \*\/$/;
3443
- var ARBITRARY_START_RE = /^\/\* @truss arbitrary:start \*\/$/;
3444
- var ARBITRARY_END_RE = /^\/\* @truss arbitrary:end \*\/$/;
3445
- var PROPERTY_VAR_RE = /^@property\s+(--\S+)/;
3446
- function parseTrussCss(cssText) {
3447
- const lines = cssText.split("\n");
3448
- const rules = [];
3449
- const properties = [];
3450
- const arbitraryCssBlocks = [];
3451
- let i = 0;
3452
- function takeAnnotatedLine() {
3453
- i++;
3454
- while (i < lines.length && lines[i].trim() === "") i++;
3455
- return i < lines.length ? lines[i].trim() : null;
3456
- }
3457
- while (i < lines.length) {
3458
- const line = lines[i].trim();
3459
- const ruleMatch = RULE_ANNOTATION_RE.exec(line);
3460
- if (ruleMatch) {
3461
- const cssText2 = takeAnnotatedLine();
3462
- if (cssText2 !== null) {
3463
- rules.push({ priority: parseFloat(ruleMatch[1]), className: ruleMatch[2], cssText: cssText2 });
3464
- }
3465
- i++;
3466
- continue;
3467
- }
3468
- if (PROPERTY_ANNOTATION_RE.test(line)) {
3469
- const propLine = takeAnnotatedLine();
3470
- const varMatch = propLine === null ? null : PROPERTY_VAR_RE.exec(propLine);
3471
- if (propLine !== null && varMatch) {
3472
- properties.push({ cssText: propLine, varName: varMatch[1] });
3473
- }
3474
- i++;
3475
- continue;
3476
- }
3477
- if (ARBITRARY_START_RE.test(line)) {
3478
- i++;
3479
- const blockLines = [];
3480
- while (i < lines.length && !ARBITRARY_END_RE.test(lines[i].trim())) {
3481
- blockLines.push(lines[i]);
3482
- i++;
3483
- }
3484
- const blockText = blockLines.join("\n").trim();
3485
- if (blockText.length > 0) {
3486
- arbitraryCssBlocks.push({ cssText: blockText });
3487
- }
3488
- if (i < lines.length && ARBITRARY_END_RE.test(lines[i].trim())) {
3489
- i++;
3490
- }
3491
- continue;
3492
- }
3493
- i++;
3494
- }
3495
- return { rules, properties, arbitraryCssBlocks };
3496
- }
3497
- function annotateArbitraryCssBlock(cssText) {
3498
- const trimmed = cssText.trim();
3499
- if (trimmed.length === 0) {
3500
- return "";
3501
- }
3502
- return ["/* @truss arbitrary:start */", trimmed, "/* @truss arbitrary:end */"].join("\n");
3503
- }
3504
-
3505
- // src/plugin/merge-css.ts
3506
3570
  function readTrussCss(filePath) {
3507
3571
  const content = readFileSync2(filePath, "utf8");
3508
3572
  return parseTrussCss(content);
3509
3573
  }
3510
- function mergeTrussCss(sources) {
3574
+ function mergeTrussCssData(sources) {
3511
3575
  const seenClasses = /* @__PURE__ */ new Set();
3512
3576
  const allRules = [];
3513
3577
  const seenProperties = /* @__PURE__ */ new Set();
@@ -3532,19 +3596,11 @@ function mergeTrussCss(sources) {
3532
3596
  return { rule, key: ruleSortKey(rule.priority, rule.className, atRulePrelude(rule.cssText)) };
3533
3597
  });
3534
3598
  decorated.sort((a, b) => compareRuleSortKeys(a.key, b.key));
3535
- const lines = [];
3536
- for (const entry of decorated) {
3537
- lines.push(`/* @truss p:${entry.rule.priority} c:${entry.rule.className} */`);
3538
- lines.push(entry.rule.cssText);
3539
- }
3540
- for (const prop of allProperties) {
3541
- lines.push(`/* @truss @property */`);
3542
- lines.push(prop.cssText);
3543
- }
3544
- for (const block of allArbitraryCssBlocks) {
3545
- lines.push(annotateArbitraryCssBlock(block.cssText));
3546
- }
3547
- return lines.join("\n");
3599
+ return {
3600
+ rules: decorated.map((entry) => entry.rule),
3601
+ properties: allProperties,
3602
+ arbitraryCssBlocks: allArbitraryCssBlocks
3603
+ };
3548
3604
  }
3549
3605
 
3550
3606
  // src/plugin/transform-session.ts
@@ -3604,12 +3660,11 @@ function createTrussTransformSession(options) {
3604
3660
  }
3605
3661
  function collectCss() {
3606
3662
  const mapping2 = ensureMapping();
3607
- const appCssParts = [generateCssText(cssRegistry)];
3663
+ const appCss = generateCssData(cssRegistry);
3608
3664
  const allArbitrary = Array.from(arbitraryCssRegistry.entries()).sort((a, b) => compareClassNames(a[0], b[0])).map((entry) => entry[1]).join("\n\n");
3609
- appCssParts.push(annotateArbitraryCssBlock(allArbitrary));
3610
- const appCss = appCssParts.filter((part) => part.length > 0).join("\n");
3665
+ if (allArbitrary.length > 0) appCss.arbitraryCssBlocks.push({ cssText: allArbitrary });
3611
3666
  const libs = loadLibraries();
3612
- const body = libs.length === 0 ? appCss : mergeTrussCss([...libs, parseTrussCss(appCss)]);
3667
+ const body = serializeTrussCss(libs.length === 0 ? appCss : mergeTrussCssData([...libs, appCss]));
3613
3668
  if (body.length === 0) return "";
3614
3669
  return `${rootSpacingPreludeCss(mapping2.increment)}
3615
3670
  ${body}`;
@@ -3618,7 +3673,7 @@ ${body}`;
3618
3673
  return cssRegistry.size > 0 || arbitraryCssRegistry.size > 0 || libraryPaths.length > 0;
3619
3674
  }
3620
3675
  function collectTestCss() {
3621
- return mergeTrussCss(loadLibraries());
3676
+ return createTestCssPayload(mergeTrussCssData(loadLibraries()));
3622
3677
  }
3623
3678
  function getArbitraryCss(sourcePath) {
3624
3679
  return arbitraryCssRegistry.get(resolve2(sourcePath).replace(/\\/g, "/")) ?? "";
@@ -3687,6 +3742,8 @@ function loaderForPath(filePath) {
3687
3742
  var VIRTUAL_CSS_PREFIX = "\0truss-css:";
3688
3743
  var VIRTUAL_TEST_CSS_PREFIX = "\0truss-test-css:";
3689
3744
  var CSS_TS_QUERY = "?truss-css";
3745
+ var RUNTIME_MODULE2 = "@homebound/truss/runtime";
3746
+ var INJECT_CSS_HELPER = "__injectTrussCSS";
3690
3747
  var TRUSS_CSS_PLACEHOLDER = "__TRUSS_CSS_HASH__";
3691
3748
  var VIRTUAL_CSS_ENDPOINT = "/virtual:truss.css";
3692
3749
  var VIRTUAL_RUNTIME_ID = "virtual:truss:runtime";
@@ -3809,8 +3866,8 @@ function trussPlugin(opts) {
3809
3866
  `;
3810
3867
  }
3811
3868
  if (id === RESOLVED_VIRTUAL_TEST_CSS_ID) {
3812
- const css = session.collectTestCss();
3813
- const options = {
3869
+ const payload = {
3870
+ ...session.collectTestCss(),
3814
3871
  source: "libraries",
3815
3872
  order: 0,
3816
3873
  prelude: rootSpacingPreludeCss(session.ensureMapping().increment)
@@ -3818,18 +3875,21 @@ function trussPlugin(opts) {
3818
3875
  return `
3819
3876
  import { __injectTrussCSS } from "@homebound/truss/runtime";
3820
3877
 
3821
- __injectTrussCSS(${JSON.stringify(css)}, ${JSON.stringify(options)});
3878
+ __injectTrussCSS(${JSON.stringify(payload)});
3822
3879
  `;
3823
3880
  }
3824
3881
  if (id.startsWith(VIRTUAL_TEST_CSS_PREFIX)) {
3825
- const sourcePath2 = resolve4(id.slice(VIRTUAL_TEST_CSS_PREFIX.length)).replace(/\\/g, "/");
3882
+ const sourcePath2 = canonicalSourcePath(id.slice(VIRTUAL_TEST_CSS_PREFIX.length));
3826
3883
  session.updateArbitraryCssRegistry(sourcePath2, readFileSync4(sourcePath2, "utf8"));
3827
- const css = annotateArbitraryCssBlock(session.getArbitraryCss(sourcePath2));
3884
+ const payload = {
3885
+ arbitraryRules: splitArbitraryCss(session.getArbitraryCss(sourcePath2)),
3886
+ source: sourcePath2
3887
+ };
3828
3888
  return `
3829
3889
  import "${VIRTUAL_TEST_CSS_ID}";
3830
3890
  import { __injectTrussCSS } from "@homebound/truss/runtime";
3831
3891
 
3832
- __injectTrussCSS(${JSON.stringify(css)}, ${JSON.stringify({ source: sourcePath2 })});
3892
+ __injectTrussCSS(${JSON.stringify(payload)});
3833
3893
  `;
3834
3894
  }
3835
3895
  if (!id.startsWith(VIRTUAL_CSS_PREFIX)) return null;
@@ -3851,32 +3911,8 @@ import "${VIRTUAL_TEST_CSS_ID}";` : rewrittenImports.code;
3851
3911
  if (fileId.endsWith(".css.ts")) {
3852
3912
  session.updateArbitraryCssRegistry(fileId, code);
3853
3913
  if (isTest) {
3854
- const css = annotateArbitraryCssBlock(session.getArbitraryCss(fileId));
3855
- const ast = parseModule(transformedCode, fileId);
3856
- traverse(ast, {
3857
- Program(path) {
3858
- const inject = path.scope.generateUidIdentifier("injectTrussCSS");
3859
- path.unshiftContainer(
3860
- "body",
3861
- t16.importDeclaration(
3862
- [t16.importSpecifier(inject, t16.identifier("__injectTrussCSS"))],
3863
- t16.stringLiteral("@homebound/truss/runtime")
3864
- )
3865
- );
3866
- path.pushContainer(
3867
- "body",
3868
- t16.expressionStatement(
3869
- t16.callExpression(inject, [
3870
- t16.stringLiteral(css),
3871
- t16.objectExpression([
3872
- t16.objectProperty(t16.identifier("source"), t16.stringLiteral(resolve4(fileId).replace(/\\/g, "/")))
3873
- ])
3874
- ])
3875
- )
3876
- );
3877
- }
3878
- });
3879
- return { code: generate(ast, { sourceFileName: fileId }).code, map: null };
3914
+ const css = session.getArbitraryCss(fileId);
3915
+ return { code: appendTestCssInjection(transformedCode, fileId, css), map: null };
3880
3916
  }
3881
3917
  return importsOnlyResult;
3882
3918
  }
@@ -3938,6 +3974,30 @@ function stripQueryAndHash(id) {
3938
3974
  function isNodeModulesFile(filePath) {
3939
3975
  return filePath.replace(/\\/g, "/").includes("/node_modules/");
3940
3976
  }
3977
+ function canonicalSourcePath(filePath) {
3978
+ return resolve4(filePath).replace(/\\/g, "/");
3979
+ }
3980
+ function appendTestCssInjection(code, fileId, css) {
3981
+ const ast = parseModule(code, fileId);
3982
+ let usedTopLevelNames = /* @__PURE__ */ new Set();
3983
+ traverse(ast, {
3984
+ Program(path) {
3985
+ usedTopLevelNames = new Set(Object.keys(path.scope.bindings));
3986
+ path.stop();
3987
+ }
3988
+ });
3989
+ const existing = findNamedImportBinding(ast, INJECT_CSS_HELPER, RUNTIME_MODULE2);
3990
+ const localName = existing ?? reservePreferredName(usedTopLevelNames, INJECT_CSS_HELPER);
3991
+ if (!existing) upsertNamedImports(ast, RUNTIME_MODULE2, [{ importedName: INJECT_CSS_HELPER, localName }]);
3992
+ ast.program.body.push(
3993
+ t16.expressionStatement(
3994
+ t16.callExpression(t16.identifier(localName), [
3995
+ t16.valueToNode({ arbitraryRules: splitArbitraryCss(css), source: canonicalSourcePath(fileId) })
3996
+ ])
3997
+ )
3998
+ );
3999
+ return generate(ast, { sourceFileName: fileId }).code;
4000
+ }
3941
4001
  export {
3942
4002
  loadMapping,
3943
4003
  trussEsbuildPlugin,