@homebound/truss 2.3.5 → 2.4.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.
@@ -37,8 +37,8 @@ type TrussMappingEntry =
37
37
  interface TrussPluginOptions {
38
38
  /** Path to the Css.json mapping file used for transforming files (relative to project root or absolute). */
39
39
  mapping: string;
40
- /** Packages in `node_modules` that should also be transformed, all other `node_modules` files are skipped. */
41
- externalPackages?: string[];
40
+ /** Paths to pre-compiled truss.css files from libraries to merge into the app's CSS. */
41
+ libraries?: string[];
42
42
  }
43
43
  interface TrussVitePlugin {
44
44
  name: string;
@@ -1,5 +1,5 @@
1
1
  // src/plugin/index.ts
2
- import { readFileSync, writeFileSync, existsSync } from "fs";
2
+ import { readFileSync as readFileSync2, writeFileSync, existsSync } from "fs";
3
3
  import { resolve, dirname, isAbsolute, join } from "path";
4
4
 
5
5
  // src/plugin/emit-truss.ts
@@ -838,13 +838,18 @@ function collectVariableRules(rules, seg, mapping) {
838
838
  function generateCssText(rules) {
839
839
  const allRules = Array.from(rules.values());
840
840
  sortRulesByPriority(allRules);
841
+ const priorities = allRules.map(computeRulePriority);
841
842
  const lines = [];
842
- for (const rule of allRules) {
843
+ for (let i = 0; i < allRules.length; i++) {
844
+ const rule = allRules[i];
845
+ const priority = priorities[i];
846
+ lines.push(`/* @truss p:${priority} c:${rule.className} */`);
843
847
  lines.push(formatRule(rule));
844
848
  }
845
849
  for (const rule of allRules) {
846
850
  for (const declaration of getRuleDeclarations(rule)) {
847
851
  if (declaration.cssVarName) {
852
+ lines.push(`/* @truss @property */`);
848
853
  lines.push(`@property ${declaration.cssVarName} { syntax: "*"; inherits: false; }`);
849
854
  }
850
855
  }
@@ -2791,6 +2796,87 @@ function toVirtualCssSpecifier(source) {
2791
2796
  return `${source}?truss-css`;
2792
2797
  }
2793
2798
 
2799
+ // src/plugin/merge-css.ts
2800
+ import { readFileSync } from "fs";
2801
+ var RULE_ANNOTATION_RE = /^\/\* @truss p:([\d.]+) c:(\S+) \*\/$/;
2802
+ var PROPERTY_ANNOTATION_RE = /^\/\* @truss @property \*\/$/;
2803
+ var PROPERTY_VAR_RE = /^@property\s+(--\S+)/;
2804
+ function parseTrussCss(cssText) {
2805
+ const lines = cssText.split("\n");
2806
+ const rules = [];
2807
+ const properties = [];
2808
+ let i = 0;
2809
+ while (i < lines.length) {
2810
+ const line = lines[i].trim();
2811
+ const ruleMatch = RULE_ANNOTATION_RE.exec(line);
2812
+ if (ruleMatch) {
2813
+ const priority = parseFloat(ruleMatch[1]);
2814
+ const className = ruleMatch[2];
2815
+ i++;
2816
+ while (i < lines.length && lines[i].trim() === "") i++;
2817
+ if (i < lines.length) {
2818
+ rules.push({ priority, className, cssText: lines[i].trim() });
2819
+ }
2820
+ i++;
2821
+ continue;
2822
+ }
2823
+ if (PROPERTY_ANNOTATION_RE.test(line)) {
2824
+ i++;
2825
+ while (i < lines.length && lines[i].trim() === "") i++;
2826
+ if (i < lines.length) {
2827
+ const propLine = lines[i].trim();
2828
+ const varMatch = PROPERTY_VAR_RE.exec(propLine);
2829
+ if (varMatch) {
2830
+ properties.push({ cssText: propLine, varName: varMatch[1] });
2831
+ }
2832
+ }
2833
+ i++;
2834
+ continue;
2835
+ }
2836
+ i++;
2837
+ }
2838
+ return { rules, properties };
2839
+ }
2840
+ function readTrussCss(filePath) {
2841
+ const content = readFileSync(filePath, "utf8");
2842
+ return parseTrussCss(content);
2843
+ }
2844
+ function mergeTrussCss(sources) {
2845
+ const seenClasses = /* @__PURE__ */ new Set();
2846
+ const allRules = [];
2847
+ const seenProperties = /* @__PURE__ */ new Set();
2848
+ const allProperties = [];
2849
+ for (const source of sources) {
2850
+ for (const rule of source.rules) {
2851
+ if (!seenClasses.has(rule.className)) {
2852
+ seenClasses.add(rule.className);
2853
+ allRules.push(rule);
2854
+ }
2855
+ }
2856
+ for (const prop of source.properties) {
2857
+ if (!seenProperties.has(prop.varName)) {
2858
+ seenProperties.add(prop.varName);
2859
+ allProperties.push(prop);
2860
+ }
2861
+ }
2862
+ }
2863
+ allRules.sort(function(a, b) {
2864
+ const diff = a.priority - b.priority;
2865
+ if (diff !== 0) return diff;
2866
+ return a.className < b.className ? -1 : a.className > b.className ? 1 : 0;
2867
+ });
2868
+ const lines = [];
2869
+ for (const rule of allRules) {
2870
+ lines.push(`/* @truss p:${rule.priority} c:${rule.className} */`);
2871
+ lines.push(rule.cssText);
2872
+ }
2873
+ for (const prop of allProperties) {
2874
+ lines.push(`/* @truss @property */`);
2875
+ lines.push(prop.cssText);
2876
+ }
2877
+ return lines.join("\n");
2878
+ }
2879
+
2794
2880
  // src/plugin/index.ts
2795
2881
  var VIRTUAL_CSS_PREFIX = "\0truss-css:";
2796
2882
  var CSS_TS_QUERY = "?truss-css";
@@ -2803,7 +2889,7 @@ function trussPlugin(opts) {
2803
2889
  let debug = false;
2804
2890
  let isTest = false;
2805
2891
  let isBuild = false;
2806
- const externalPackages = opts.externalPackages ?? [];
2892
+ const libraryPaths = opts.libraries ?? [];
2807
2893
  const cssRegistry = /* @__PURE__ */ new Map();
2808
2894
  let cssVersion = 0;
2809
2895
  let lastSentVersion = 0;
@@ -2816,8 +2902,22 @@ function trussPlugin(opts) {
2816
2902
  }
2817
2903
  return mapping;
2818
2904
  }
2905
+ let libraryCache = null;
2906
+ function loadLibraries() {
2907
+ if (!libraryCache) {
2908
+ libraryCache = libraryPaths.map(function(libPath) {
2909
+ const resolved = resolve(projectRoot || process.cwd(), libPath);
2910
+ return readTrussCss(resolved);
2911
+ });
2912
+ }
2913
+ return libraryCache;
2914
+ }
2819
2915
  function collectCss() {
2820
- return generateCssText(cssRegistry);
2916
+ const appCss = generateCssText(cssRegistry);
2917
+ const libs = loadLibraries();
2918
+ if (libs.length === 0) return appCss;
2919
+ const appParsed = parseTrussCss(appCss);
2920
+ return mergeTrussCss([...libs, appParsed]);
2821
2921
  }
2822
2922
  return {
2823
2923
  name: "truss",
@@ -2831,6 +2931,7 @@ function trussPlugin(opts) {
2831
2931
  buildStart() {
2832
2932
  ensureMapping();
2833
2933
  cssRegistry.clear();
2934
+ libraryCache = null;
2834
2935
  cssVersion = 0;
2835
2936
  lastSentVersion = 0;
2836
2937
  },
@@ -2907,7 +3008,7 @@ function trussPlugin(opts) {
2907
3008
  }
2908
3009
  if (!id.startsWith(VIRTUAL_CSS_PREFIX)) return null;
2909
3010
  const sourcePath = id.slice(VIRTUAL_CSS_PREFIX.length) + ".ts";
2910
- const sourceCode = readFileSync(sourcePath, "utf8");
3011
+ const sourceCode = readFileSync2(sourcePath, "utf8");
2911
3012
  return transformCssTs(sourceCode, sourcePath, ensureMapping());
2912
3013
  },
2913
3014
  transform(code, id) {
@@ -2917,7 +3018,7 @@ function trussPlugin(opts) {
2917
3018
  const hasCssDsl = rewrittenCode.includes("Css");
2918
3019
  if (!hasCssDsl && !rewrittenImports.changed) return null;
2919
3020
  const fileId = stripQueryAndHash(id);
2920
- if (isNodeModulesFile(fileId) && !isWhitelistedExternalPackageFile(fileId, externalPackages)) {
3021
+ if (isNodeModulesFile(fileId)) {
2921
3022
  return null;
2922
3023
  }
2923
3024
  if (fileId.endsWith(".css.ts")) {
@@ -3007,19 +3108,10 @@ function stripQueryAndHash(id) {
3007
3108
  return cleanId;
3008
3109
  }
3009
3110
  function isNodeModulesFile(filePath) {
3010
- return normalizePath(filePath).includes("/node_modules/");
3011
- }
3012
- function isWhitelistedExternalPackageFile(filePath, externalPackages) {
3013
- const normalizedPath = normalizePath(filePath);
3014
- return externalPackages.some(function(pkg) {
3015
- return normalizedPath.includes(`/node_modules/${pkg}/`);
3016
- });
3017
- }
3018
- function normalizePath(path) {
3019
- return path.replace(/\\/g, "/");
3111
+ return filePath.replace(/\\/g, "/").includes("/node_modules/");
3020
3112
  }
3021
3113
  function loadMapping(path) {
3022
- const raw = readFileSync(path, "utf8");
3114
+ const raw = readFileSync2(path, "utf8");
3023
3115
  return JSON.parse(raw);
3024
3116
  }
3025
3117
  export {