@homebound/truss 2.19.3 → 2.20.1
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/index.js +30 -8
- package/build/index.js.map +1 -1
- package/build/plugin/index.js +126 -60
- package/build/plugin/index.js.map +1 -1
- package/build/runtime.js +4 -6
- package/build/runtime.js.map +1 -1
- package/package.json +1 -1
package/build/plugin/index.js
CHANGED
|
@@ -6,6 +6,23 @@ import { createHash } from "crypto";
|
|
|
6
6
|
// src/plugin/emit-truss.ts
|
|
7
7
|
import * as t from "@babel/types";
|
|
8
8
|
|
|
9
|
+
// src/plugin/types.ts
|
|
10
|
+
var _longhandCache = /* @__PURE__ */ new WeakMap();
|
|
11
|
+
function getLonghandLookup(mapping) {
|
|
12
|
+
let lookup = _longhandCache.get(mapping);
|
|
13
|
+
if (lookup) return lookup;
|
|
14
|
+
lookup = /* @__PURE__ */ new Map();
|
|
15
|
+
for (const [abbr, entry] of Object.entries(mapping.abbreviations)) {
|
|
16
|
+
if (entry.kind !== "static") continue;
|
|
17
|
+
const keys = Object.keys(entry.defs);
|
|
18
|
+
if (keys.length !== 1) continue;
|
|
19
|
+
const key = `${keys[0]}\0${entry.defs[keys[0]]}`;
|
|
20
|
+
if (!lookup.has(key)) lookup.set(key, abbr);
|
|
21
|
+
}
|
|
22
|
+
_longhandCache.set(mapping, lookup);
|
|
23
|
+
return lookup;
|
|
24
|
+
}
|
|
25
|
+
|
|
9
26
|
// src/plugin/property-priorities.ts
|
|
10
27
|
var longHandPhysical = /* @__PURE__ */ new Set();
|
|
11
28
|
var longHandLogical = /* @__PURE__ */ new Set();
|
|
@@ -1067,30 +1084,6 @@ function cleanValueForClassName(value) {
|
|
|
1067
1084
|
function getPropertyAbbreviation(cssProp) {
|
|
1068
1085
|
return cssPropertyAbbreviations[cssProp] ?? cssProp;
|
|
1069
1086
|
}
|
|
1070
|
-
function buildLonghandLookup(mapping) {
|
|
1071
|
-
const lookup = /* @__PURE__ */ new Map();
|
|
1072
|
-
for (const [abbrev, entry] of Object.entries(mapping.abbreviations)) {
|
|
1073
|
-
if (entry.kind !== "static") continue;
|
|
1074
|
-
const props = Object.keys(entry.defs);
|
|
1075
|
-
if (props.length !== 1) continue;
|
|
1076
|
-
const prop = props[0];
|
|
1077
|
-
const value = String(entry.defs[prop]);
|
|
1078
|
-
const key = `${prop}\0${value}`;
|
|
1079
|
-
if (!lookup.has(key)) {
|
|
1080
|
-
lookup.set(key, abbrev);
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
return lookup;
|
|
1084
|
-
}
|
|
1085
|
-
var cachedMapping = null;
|
|
1086
|
-
var cachedLookup = null;
|
|
1087
|
-
function getLonghandLookup(mapping) {
|
|
1088
|
-
if (cachedMapping !== mapping) {
|
|
1089
|
-
cachedMapping = mapping;
|
|
1090
|
-
cachedLookup = buildLonghandLookup(mapping);
|
|
1091
|
-
}
|
|
1092
|
-
return cachedLookup;
|
|
1093
|
-
}
|
|
1094
1087
|
function computeStaticBaseName(seg, cssProp, cssValue, isMultiProp, mapping) {
|
|
1095
1088
|
const abbr = seg.abbr;
|
|
1096
1089
|
if (seg.argResolved !== void 0) {
|
|
@@ -2036,10 +2029,9 @@ function resolveChain(ctx, chain) {
|
|
|
2036
2029
|
context.mediaQuery = containerSelectorFromCall(node);
|
|
2037
2030
|
continue;
|
|
2038
2031
|
}
|
|
2039
|
-
if (abbr === "
|
|
2040
|
-
const seg =
|
|
2032
|
+
if (abbr === "with") {
|
|
2033
|
+
const seg = resolveWithCall(
|
|
2041
2034
|
node,
|
|
2042
|
-
mapping,
|
|
2043
2035
|
context.mediaQuery,
|
|
2044
2036
|
context.pseudoClass,
|
|
2045
2037
|
context.pseudoElement,
|
|
@@ -2048,6 +2040,18 @@ function resolveChain(ctx, chain) {
|
|
|
2048
2040
|
segments.push(seg);
|
|
2049
2041
|
continue;
|
|
2050
2042
|
}
|
|
2043
|
+
if (abbr === "add") {
|
|
2044
|
+
const segs = resolveAddCall(
|
|
2045
|
+
node,
|
|
2046
|
+
mapping,
|
|
2047
|
+
context.mediaQuery,
|
|
2048
|
+
context.pseudoClass,
|
|
2049
|
+
context.pseudoElement,
|
|
2050
|
+
context.whenPseudo
|
|
2051
|
+
);
|
|
2052
|
+
segments.push(...segs);
|
|
2053
|
+
continue;
|
|
2054
|
+
}
|
|
2051
2055
|
if (abbr === "className") {
|
|
2052
2056
|
const seg = resolveClassNameCall(
|
|
2053
2057
|
node,
|
|
@@ -2364,18 +2368,15 @@ function resolveStyleCall(node, mediaQuery, pseudoClass, pseudoElement, whenPseu
|
|
|
2364
2368
|
styleArg: arg
|
|
2365
2369
|
};
|
|
2366
2370
|
}
|
|
2367
|
-
function
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
if (styleArg.type === "SpreadElement") {
|
|
2377
|
-
throw new UnsupportedPatternError(`addCss() does not support spread arguments`);
|
|
2378
|
-
}
|
|
2371
|
+
function resolveWithCall(node, mediaQuery, pseudoClass, pseudoElement, whenPseudo) {
|
|
2372
|
+
if (node.args.length !== 1) {
|
|
2373
|
+
throw new UnsupportedPatternError(`with() requires exactly 1 argument`);
|
|
2374
|
+
}
|
|
2375
|
+
const styleArg = node.args[0];
|
|
2376
|
+
if (styleArg.type === "SpreadElement") {
|
|
2377
|
+
throw new UnsupportedPatternError(`with() does not support spread arguments`);
|
|
2378
|
+
}
|
|
2379
|
+
if (styleArg.type === "ObjectExpression") {
|
|
2379
2380
|
return {
|
|
2380
2381
|
abbr: "__composed_css_prop",
|
|
2381
2382
|
defs: {},
|
|
@@ -2383,25 +2384,34 @@ function resolveAddCall(node, mapping, mediaQuery, pseudoClass, pseudoElement, w
|
|
|
2383
2384
|
isAddCss: true
|
|
2384
2385
|
};
|
|
2385
2386
|
}
|
|
2387
|
+
return {
|
|
2388
|
+
abbr: "__composed_css_prop",
|
|
2389
|
+
defs: {},
|
|
2390
|
+
styleArrayArg: styleArg
|
|
2391
|
+
};
|
|
2392
|
+
}
|
|
2393
|
+
function resolveAddCall(node, mapping, mediaQuery, pseudoClass, pseudoElement, whenPseudo) {
|
|
2394
|
+
const context = {
|
|
2395
|
+
mediaQuery,
|
|
2396
|
+
pseudoClass,
|
|
2397
|
+
pseudoElement,
|
|
2398
|
+
whenPseudo
|
|
2399
|
+
};
|
|
2386
2400
|
if (node.args.length === 1) {
|
|
2387
2401
|
const styleArg = node.args[0];
|
|
2388
2402
|
if (styleArg.type === "SpreadElement") {
|
|
2389
2403
|
throw new UnsupportedPatternError(`add() does not support spread arguments`);
|
|
2390
2404
|
}
|
|
2391
2405
|
if (styleArg.type === "ObjectExpression") {
|
|
2392
|
-
|
|
2393
|
-
`add(cssProp) does not accept object literals -- pass an existing CssProp expression instead`
|
|
2394
|
-
);
|
|
2406
|
+
return resolveAddObjectLiteral(styleArg, mapping, context);
|
|
2395
2407
|
}
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
styleArrayArg: styleArg
|
|
2400
|
-
};
|
|
2408
|
+
throw new UnsupportedPatternError(
|
|
2409
|
+
`add() requires 1 or 2 arguments (property name and value, or an object literal), got ${node.args.length}. Supported overloads are add({ prop: value }), add("propName", value), and with(cssProp)`
|
|
2410
|
+
);
|
|
2401
2411
|
}
|
|
2402
2412
|
if (node.args.length !== 2) {
|
|
2403
2413
|
throw new UnsupportedPatternError(
|
|
2404
|
-
`add() requires
|
|
2414
|
+
`add() requires 1 or 2 arguments (property name and value, or an object literal), got ${node.args.length}. Supported overloads are add({ prop: value }), add("propName", value), and with(cssProp)`
|
|
2405
2415
|
);
|
|
2406
2416
|
}
|
|
2407
2417
|
const propArg = node.args[0];
|
|
@@ -2411,19 +2421,13 @@ function resolveAddCall(node, mapping, mediaQuery, pseudoClass, pseudoElement, w
|
|
|
2411
2421
|
const propName = propArg.value;
|
|
2412
2422
|
const valueArg = node.args[1];
|
|
2413
2423
|
const literalValue = tryEvaluateAddLiteral(valueArg);
|
|
2414
|
-
const context = {
|
|
2415
|
-
mediaQuery,
|
|
2416
|
-
pseudoClass,
|
|
2417
|
-
pseudoElement,
|
|
2418
|
-
whenPseudo
|
|
2419
|
-
};
|
|
2420
2424
|
if (literalValue !== null) {
|
|
2421
|
-
return segmentWithConditionContext(
|
|
2425
|
+
return [segmentWithConditionContext(
|
|
2422
2426
|
{ abbr: propName, defs: { [propName]: literalValue }, argResolved: literalValue },
|
|
2423
2427
|
context
|
|
2424
|
-
);
|
|
2428
|
+
)];
|
|
2425
2429
|
}
|
|
2426
|
-
return segmentWithConditionContext(
|
|
2430
|
+
return [segmentWithConditionContext(
|
|
2427
2431
|
{
|
|
2428
2432
|
abbr: propName,
|
|
2429
2433
|
defs: {},
|
|
@@ -2432,7 +2436,52 @@ function resolveAddCall(node, mapping, mediaQuery, pseudoClass, pseudoElement, w
|
|
|
2432
2436
|
argNode: valueArg
|
|
2433
2437
|
},
|
|
2434
2438
|
context
|
|
2435
|
-
);
|
|
2439
|
+
)];
|
|
2440
|
+
}
|
|
2441
|
+
function resolveAddObjectLiteral(obj, mapping, context) {
|
|
2442
|
+
const segments = [];
|
|
2443
|
+
for (const property of obj.properties) {
|
|
2444
|
+
if (property.type === "SpreadElement") {
|
|
2445
|
+
throw new UnsupportedPatternError(`add({...}) does not support spread properties -- use with() instead`);
|
|
2446
|
+
}
|
|
2447
|
+
if (property.type !== "ObjectProperty" || property.computed) {
|
|
2448
|
+
throw new UnsupportedPatternError(`add({...}) only supports simple property keys`);
|
|
2449
|
+
}
|
|
2450
|
+
let propName;
|
|
2451
|
+
if (property.key.type === "Identifier") {
|
|
2452
|
+
propName = property.key.name;
|
|
2453
|
+
} else if (property.key.type === "StringLiteral") {
|
|
2454
|
+
propName = property.key.value;
|
|
2455
|
+
} else {
|
|
2456
|
+
throw new UnsupportedPatternError(`add({...}) property keys must be identifiers or string literals`);
|
|
2457
|
+
}
|
|
2458
|
+
const valueNode = property.value;
|
|
2459
|
+
const literalValue = tryEvaluateAddLiteral(valueNode);
|
|
2460
|
+
if (literalValue !== null) {
|
|
2461
|
+
const canonicalAbbr = findCanonicalAbbreviation(mapping, propName, literalValue);
|
|
2462
|
+
if (canonicalAbbr) {
|
|
2463
|
+
const entry = mapping.abbreviations[canonicalAbbr];
|
|
2464
|
+
segments.push(segmentWithConditionContext(
|
|
2465
|
+
{ abbr: canonicalAbbr, defs: entry.defs },
|
|
2466
|
+
context
|
|
2467
|
+
));
|
|
2468
|
+
} else {
|
|
2469
|
+
segments.push(segmentWithConditionContext(
|
|
2470
|
+
{ abbr: propName, defs: { [propName]: literalValue }, argResolved: literalValue },
|
|
2471
|
+
context
|
|
2472
|
+
));
|
|
2473
|
+
}
|
|
2474
|
+
} else {
|
|
2475
|
+
segments.push(segmentWithConditionContext(
|
|
2476
|
+
{ abbr: propName, defs: {}, variableProps: [propName], incremented: false, argNode: valueNode },
|
|
2477
|
+
context
|
|
2478
|
+
));
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
return segments;
|
|
2482
|
+
}
|
|
2483
|
+
function findCanonicalAbbreviation(mapping, prop, value) {
|
|
2484
|
+
return getLonghandLookup(mapping).get(`${prop}\0${value}`) ?? null;
|
|
2436
2485
|
}
|
|
2437
2486
|
function tryEvaluateAddLiteral(node) {
|
|
2438
2487
|
if (node.type === "StringLiteral") {
|
|
@@ -3822,6 +3871,7 @@ function trussPlugin(opts) {
|
|
|
3822
3871
|
const libraryPaths = opts.libraries ?? [];
|
|
3823
3872
|
let emittedCssFileName = null;
|
|
3824
3873
|
const cssRegistry = /* @__PURE__ */ new Map();
|
|
3874
|
+
const arbitraryCssRegistry = /* @__PURE__ */ new Map();
|
|
3825
3875
|
let cssVersion = 0;
|
|
3826
3876
|
let lastSentVersion = 0;
|
|
3827
3877
|
function mappingPath() {
|
|
@@ -3843,8 +3893,21 @@ function trussPlugin(opts) {
|
|
|
3843
3893
|
}
|
|
3844
3894
|
return libraryCache;
|
|
3845
3895
|
}
|
|
3896
|
+
function updateArbitraryCssRegistry(sourcePath, sourceCode) {
|
|
3897
|
+
const css = transformCssTs(sourceCode, sourcePath, ensureMapping()).trim();
|
|
3898
|
+
if (css.length > 0) {
|
|
3899
|
+
const prev = arbitraryCssRegistry.get(sourcePath);
|
|
3900
|
+
arbitraryCssRegistry.set(sourcePath, css);
|
|
3901
|
+
if (prev !== css) cssVersion++;
|
|
3902
|
+
} else {
|
|
3903
|
+
if (arbitraryCssRegistry.delete(sourcePath)) cssVersion++;
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3846
3906
|
function collectCss() {
|
|
3847
|
-
const
|
|
3907
|
+
const appCssParts = [generateCssText(cssRegistry)];
|
|
3908
|
+
const allArbitrary = Array.from(arbitraryCssRegistry.values()).join("\n\n");
|
|
3909
|
+
appCssParts.push(annotateArbitraryCssBlock(allArbitrary));
|
|
3910
|
+
const appCss = appCssParts.filter((p) => p.length > 0).join("\n");
|
|
3848
3911
|
const libs = loadLibraries();
|
|
3849
3912
|
if (libs.length === 0) return appCss;
|
|
3850
3913
|
const appParsed = parseTrussCss(appCss);
|
|
@@ -3862,6 +3925,7 @@ function trussPlugin(opts) {
|
|
|
3862
3925
|
buildStart() {
|
|
3863
3926
|
ensureMapping();
|
|
3864
3927
|
cssRegistry.clear();
|
|
3928
|
+
arbitraryCssRegistry.clear();
|
|
3865
3929
|
libraryCache = null;
|
|
3866
3930
|
cssVersion = 0;
|
|
3867
3931
|
lastSentVersion = 0;
|
|
@@ -3956,7 +4020,8 @@ __injectTrussCSS(${JSON.stringify(css)});
|
|
|
3956
4020
|
if (!id.startsWith(VIRTUAL_CSS_PREFIX)) return null;
|
|
3957
4021
|
const sourcePath = id.slice(VIRTUAL_CSS_PREFIX.length) + ".ts";
|
|
3958
4022
|
const sourceCode = readFileSync3(sourcePath, "utf8");
|
|
3959
|
-
|
|
4023
|
+
updateArbitraryCssRegistry(sourcePath, sourceCode);
|
|
4024
|
+
return `/* [truss] ${sourcePath} \u2014 included via truss.css */`;
|
|
3960
4025
|
},
|
|
3961
4026
|
transform(code, id) {
|
|
3962
4027
|
if (!/\.[cm]?[jt]sx?(\?|$)/.test(id)) return null;
|
|
@@ -3972,6 +4037,7 @@ __injectTrussCSS(${JSON.stringify(css)});
|
|
|
3972
4037
|
}
|
|
3973
4038
|
if (!hasCssDsl && !rewrittenImports.changed && !testCssBootstrap.changed) return null;
|
|
3974
4039
|
if (fileId.endsWith(".css.ts")) {
|
|
4040
|
+
updateArbitraryCssRegistry(fileId, code);
|
|
3975
4041
|
return rewrittenImports.changed || testCssBootstrap.changed ? { code: transformedCode, map: null } : null;
|
|
3976
4042
|
}
|
|
3977
4043
|
if (!hasCssDsl) {
|