@homebound/truss 2.3.4 → 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.
- package/build/plugin/index.d.ts +2 -2
- package/build/plugin/index.js +119 -23
- package/build/plugin/index.js.map +1 -1
- package/package.json +1 -1
package/build/plugin/index.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
41
|
-
|
|
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;
|
package/build/plugin/index.js
CHANGED
|
@@ -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
|
|
@@ -565,18 +565,22 @@ function computeRulePriority(rule) {
|
|
|
565
565
|
}
|
|
566
566
|
function isVariableRule(rule) {
|
|
567
567
|
if (rule.declarations) {
|
|
568
|
-
return rule.declarations.some(
|
|
569
|
-
return d.cssVarName !== void 0;
|
|
570
|
-
});
|
|
568
|
+
return rule.declarations.some((d) => d.cssVarName !== void 0);
|
|
571
569
|
}
|
|
572
570
|
return rule.cssVarName !== void 0;
|
|
573
571
|
}
|
|
574
572
|
function sortRulesByPriority(rules) {
|
|
575
|
-
rules.
|
|
576
|
-
|
|
573
|
+
const decorated = rules.map((rule, i) => {
|
|
574
|
+
return { rule, priority: computeRulePriority(rule), index: i };
|
|
575
|
+
});
|
|
576
|
+
decorated.sort((a, b) => {
|
|
577
|
+
const diff = a.priority - b.priority;
|
|
577
578
|
if (diff !== 0) return diff;
|
|
578
|
-
return a.className < b.className ? -1 : a.className > b.className ? 1 : 0;
|
|
579
|
+
return a.rule.className < b.rule.className ? -1 : a.rule.className > b.rule.className ? 1 : 0;
|
|
579
580
|
});
|
|
581
|
+
for (let i = 0; i < decorated.length; i++) {
|
|
582
|
+
rules[i] = decorated[i].rule;
|
|
583
|
+
}
|
|
580
584
|
}
|
|
581
585
|
|
|
582
586
|
// src/plugin/emit-truss.ts
|
|
@@ -834,13 +838,18 @@ function collectVariableRules(rules, seg, mapping) {
|
|
|
834
838
|
function generateCssText(rules) {
|
|
835
839
|
const allRules = Array.from(rules.values());
|
|
836
840
|
sortRulesByPriority(allRules);
|
|
841
|
+
const priorities = allRules.map(computeRulePriority);
|
|
837
842
|
const lines = [];
|
|
838
|
-
for (
|
|
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} */`);
|
|
839
847
|
lines.push(formatRule(rule));
|
|
840
848
|
}
|
|
841
849
|
for (const rule of allRules) {
|
|
842
850
|
for (const declaration of getRuleDeclarations(rule)) {
|
|
843
851
|
if (declaration.cssVarName) {
|
|
852
|
+
lines.push(`/* @truss @property */`);
|
|
844
853
|
lines.push(`@property ${declaration.cssVarName} { syntax: "*"; inherits: false; }`);
|
|
845
854
|
}
|
|
846
855
|
}
|
|
@@ -2787,6 +2796,87 @@ function toVirtualCssSpecifier(source) {
|
|
|
2787
2796
|
return `${source}?truss-css`;
|
|
2788
2797
|
}
|
|
2789
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
|
+
|
|
2790
2880
|
// src/plugin/index.ts
|
|
2791
2881
|
var VIRTUAL_CSS_PREFIX = "\0truss-css:";
|
|
2792
2882
|
var CSS_TS_QUERY = "?truss-css";
|
|
@@ -2799,7 +2889,7 @@ function trussPlugin(opts) {
|
|
|
2799
2889
|
let debug = false;
|
|
2800
2890
|
let isTest = false;
|
|
2801
2891
|
let isBuild = false;
|
|
2802
|
-
const
|
|
2892
|
+
const libraryPaths = opts.libraries ?? [];
|
|
2803
2893
|
const cssRegistry = /* @__PURE__ */ new Map();
|
|
2804
2894
|
let cssVersion = 0;
|
|
2805
2895
|
let lastSentVersion = 0;
|
|
@@ -2812,8 +2902,22 @@ function trussPlugin(opts) {
|
|
|
2812
2902
|
}
|
|
2813
2903
|
return mapping;
|
|
2814
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
|
+
}
|
|
2815
2915
|
function collectCss() {
|
|
2816
|
-
|
|
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]);
|
|
2817
2921
|
}
|
|
2818
2922
|
return {
|
|
2819
2923
|
name: "truss",
|
|
@@ -2827,6 +2931,7 @@ function trussPlugin(opts) {
|
|
|
2827
2931
|
buildStart() {
|
|
2828
2932
|
ensureMapping();
|
|
2829
2933
|
cssRegistry.clear();
|
|
2934
|
+
libraryCache = null;
|
|
2830
2935
|
cssVersion = 0;
|
|
2831
2936
|
lastSentVersion = 0;
|
|
2832
2937
|
},
|
|
@@ -2903,7 +3008,7 @@ function trussPlugin(opts) {
|
|
|
2903
3008
|
}
|
|
2904
3009
|
if (!id.startsWith(VIRTUAL_CSS_PREFIX)) return null;
|
|
2905
3010
|
const sourcePath = id.slice(VIRTUAL_CSS_PREFIX.length) + ".ts";
|
|
2906
|
-
const sourceCode =
|
|
3011
|
+
const sourceCode = readFileSync2(sourcePath, "utf8");
|
|
2907
3012
|
return transformCssTs(sourceCode, sourcePath, ensureMapping());
|
|
2908
3013
|
},
|
|
2909
3014
|
transform(code, id) {
|
|
@@ -2913,7 +3018,7 @@ function trussPlugin(opts) {
|
|
|
2913
3018
|
const hasCssDsl = rewrittenCode.includes("Css");
|
|
2914
3019
|
if (!hasCssDsl && !rewrittenImports.changed) return null;
|
|
2915
3020
|
const fileId = stripQueryAndHash(id);
|
|
2916
|
-
if (isNodeModulesFile(fileId)
|
|
3021
|
+
if (isNodeModulesFile(fileId)) {
|
|
2917
3022
|
return null;
|
|
2918
3023
|
}
|
|
2919
3024
|
if (fileId.endsWith(".css.ts")) {
|
|
@@ -3003,19 +3108,10 @@ function stripQueryAndHash(id) {
|
|
|
3003
3108
|
return cleanId;
|
|
3004
3109
|
}
|
|
3005
3110
|
function isNodeModulesFile(filePath) {
|
|
3006
|
-
return
|
|
3007
|
-
}
|
|
3008
|
-
function isWhitelistedExternalPackageFile(filePath, externalPackages) {
|
|
3009
|
-
const normalizedPath = normalizePath(filePath);
|
|
3010
|
-
return externalPackages.some(function(pkg) {
|
|
3011
|
-
return normalizedPath.includes(`/node_modules/${pkg}/`);
|
|
3012
|
-
});
|
|
3013
|
-
}
|
|
3014
|
-
function normalizePath(path) {
|
|
3015
|
-
return path.replace(/\\/g, "/");
|
|
3111
|
+
return filePath.replace(/\\/g, "/").includes("/node_modules/");
|
|
3016
3112
|
}
|
|
3017
3113
|
function loadMapping(path) {
|
|
3018
|
-
const raw =
|
|
3114
|
+
const raw = readFileSync2(path, "utf8");
|
|
3019
3115
|
return JSON.parse(raw);
|
|
3020
3116
|
}
|
|
3021
3117
|
export {
|