@plumeria/utils 19.6.0 → 19.6.2
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/dist/compile.js +10 -3
- package/dist/dynamicKey.d.ts +11 -1
- package/dist/dynamicKey.js +200 -33
- package/dist/parser.d.ts +2 -0
- package/dist/parser.js +30 -17
- package/dist/transform.js +31 -9
- package/package.json +1 -1
package/dist/compile.js
CHANGED
|
@@ -41,6 +41,7 @@ const path = __importStar(require("path"));
|
|
|
41
41
|
const rs = __importStar(require("@rust-gear/glob"));
|
|
42
42
|
const index_1 = require("./index");
|
|
43
43
|
const index_2 = require("./index");
|
|
44
|
+
const dynamicKey_1 = require("./dynamicKey");
|
|
44
45
|
const unwrapExport = (node) => {
|
|
45
46
|
if (node?.type === 'ExportDeclaration')
|
|
46
47
|
return node.declaration;
|
|
@@ -626,6 +627,7 @@ function compileCSS(options) {
|
|
|
626
627
|
const tempStaticTable = { ...ctx.mergedStaticTable };
|
|
627
628
|
const providedParams = new Set();
|
|
628
629
|
const runtime = [];
|
|
630
|
+
const definite = new Set();
|
|
629
631
|
const resolveObjectArg = (argExpr) => (0, index_1.objectExpressionToObject)({
|
|
630
632
|
...argExpr,
|
|
631
633
|
properties: argExpr.properties.filter((prop) => prop.type === 'Identifier' ||
|
|
@@ -662,8 +664,11 @@ function compileCSS(options) {
|
|
|
662
664
|
tempStaticTable[local] = argObj[key];
|
|
663
665
|
providedParams.add(local);
|
|
664
666
|
}
|
|
665
|
-
else
|
|
667
|
+
else {
|
|
666
668
|
runtime.push(local);
|
|
669
|
+
if ((0, dynamicKey_1.isDefinedArgument)(source))
|
|
670
|
+
definite.add(local);
|
|
671
|
+
}
|
|
667
672
|
});
|
|
668
673
|
}
|
|
669
674
|
else if (callArgs.length === 1 &&
|
|
@@ -677,14 +682,16 @@ function compileCSS(options) {
|
|
|
677
682
|
});
|
|
678
683
|
}
|
|
679
684
|
else {
|
|
680
|
-
callArgs.forEach((
|
|
685
|
+
callArgs.forEach((callArg, i) => {
|
|
681
686
|
const p = func.params[i];
|
|
682
687
|
if (!p)
|
|
683
688
|
return;
|
|
684
689
|
runtime.push(p);
|
|
690
|
+
if ((0, dynamicKey_1.isDefinedArgument)(callArg.expression))
|
|
691
|
+
definite.add(p);
|
|
685
692
|
});
|
|
686
693
|
}
|
|
687
|
-
const resolved = (0, index_1.resolveDynamicStyle)(func, runtime, tempStaticTable, dynamicTablesOf(ctx), providedParams);
|
|
694
|
+
const resolved = (0, index_1.resolveDynamicStyle)(func, runtime, tempStaticTable, dynamicTablesOf(ctx), providedParams, definite);
|
|
688
695
|
const { style } = resolved;
|
|
689
696
|
return style;
|
|
690
697
|
};
|
package/dist/dynamicKey.d.ts
CHANGED
|
@@ -35,6 +35,14 @@ export type DynamicStyleTables = {
|
|
|
35
35
|
createStaticHashTable: CreateStaticHashTable;
|
|
36
36
|
createStaticObjectTable: CreateStaticObjectTable;
|
|
37
37
|
};
|
|
38
|
+
export type DerivedPiece = string | {
|
|
39
|
+
param: string;
|
|
40
|
+
fallback?: string;
|
|
41
|
+
};
|
|
42
|
+
export type DerivedVar = {
|
|
43
|
+
name: string;
|
|
44
|
+
pieces: DerivedPiece[];
|
|
45
|
+
};
|
|
38
46
|
export type DynamicStyleResult = {
|
|
39
47
|
style: CSSObject;
|
|
40
48
|
varGroups: Map<string, Array<{
|
|
@@ -43,6 +51,8 @@ export type DynamicStyleResult = {
|
|
|
43
51
|
unit: string;
|
|
44
52
|
written: boolean;
|
|
45
53
|
}>>;
|
|
54
|
+
derived: DerivedVar[];
|
|
46
55
|
};
|
|
47
|
-
export declare const
|
|
56
|
+
export declare const isDefinedArgument: (expression: Expression) => boolean;
|
|
57
|
+
export declare const resolveDynamicStyle: (func: StyleFunction, runtimeParams: string[], staticTable: StaticTable, tables: DynamicStyleTables, providedParams?: ReadonlySet<string>, definiteParams?: ReadonlySet<string>) => DynamicStyleResult;
|
|
48
58
|
export {};
|
package/dist/dynamicKey.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveDynamicStyle = exports.applyVarFallback = exports.splitVarByUnit = exports.isUnitlessProp = exports.styleFunctionsOf = void 0;
|
|
3
|
+
exports.resolveDynamicStyle = exports.isDefinedArgument = exports.applyVarFallback = exports.splitVarByUnit = exports.isUnitlessProp = exports.styleFunctionsOf = void 0;
|
|
4
4
|
const zss_engine_1 = require("zss-engine");
|
|
5
5
|
const zss_engine_2 = require("zss-engine");
|
|
6
6
|
const parser_1 = require("./parser");
|
|
@@ -229,55 +229,222 @@ const applyVarFallback = (style, cssVar, literal, unit) => {
|
|
|
229
229
|
}
|
|
230
230
|
};
|
|
231
231
|
exports.applyVarFallback = applyVarFallback;
|
|
232
|
-
const
|
|
232
|
+
const ARITHMETIC = new Set(['+', '-', '*', '/', '%', '**']);
|
|
233
|
+
const isSign = (node) => parser_1.t.isUnaryExpression(node) && (node.operator === '-' || node.operator === '+');
|
|
234
|
+
const isDefinedArgument = (expression) => {
|
|
235
|
+
const node = (0, parser_1.unwrapExpression)(expression);
|
|
236
|
+
if (parser_1.t.isStringLiteral(node) ||
|
|
237
|
+
parser_1.t.isNumericLiteral(node) ||
|
|
238
|
+
parser_1.t.isBooleanLiteral(node) ||
|
|
239
|
+
parser_1.t.isNullLiteral(node) ||
|
|
240
|
+
parser_1.t.isTemplateLiteral(node))
|
|
241
|
+
return true;
|
|
242
|
+
return isSign(node) && parser_1.t.isNumericLiteral((0, parser_1.unwrapExpression)(node.argument));
|
|
243
|
+
};
|
|
244
|
+
exports.isDefinedArgument = isDefinedArgument;
|
|
245
|
+
const defaultError = (param, node, literal) => {
|
|
246
|
+
const kind = literal === null || parser_1.t.isNullLiteral(node)
|
|
247
|
+
? 'null'
|
|
248
|
+
: typeof literal === 'boolean'
|
|
249
|
+
? 'a boolean'
|
|
250
|
+
: literal !== undefined
|
|
251
|
+
? 'an object'
|
|
252
|
+
: undefined;
|
|
253
|
+
return new Error(kind
|
|
254
|
+
? `[plumeria] The default of "${param}" is ${kind}, which a dynamic style function cannot fall back on. Use a string or a number, or pass the value from the call.`
|
|
255
|
+
: `[plumeria] Cannot resolve the default of "${param}" at build time (${(0, parser_1.expressionLabel)(node)}). A dynamic style function falls back on it when the argument is undefined, so it has to be a string or a number plumeria can read. Pass the value from the call instead.`);
|
|
256
|
+
};
|
|
257
|
+
const replaceNodes = (node, replacements) => {
|
|
258
|
+
if (!node || typeof node !== 'object')
|
|
259
|
+
return node;
|
|
260
|
+
const replacement = replacements.get(node);
|
|
261
|
+
if (replacement)
|
|
262
|
+
return replacement;
|
|
263
|
+
if (Array.isArray(node))
|
|
264
|
+
return node.map((item) => replaceNodes(item, replacements));
|
|
265
|
+
const copy = {};
|
|
266
|
+
for (const key of Object.keys(node))
|
|
267
|
+
copy[key] =
|
|
268
|
+
key === 'span' ? node[key] : replaceNodes(node[key], replacements);
|
|
269
|
+
return copy;
|
|
270
|
+
};
|
|
271
|
+
const literalSource = (value) => {
|
|
272
|
+
if (typeof value === 'string')
|
|
273
|
+
return JSON.stringify(value);
|
|
274
|
+
const text = String(value);
|
|
275
|
+
return text.startsWith('-') ? `(${text})` : text;
|
|
276
|
+
};
|
|
277
|
+
const deriveArithmetic = (body, runtimeParams, varParams, defaults, evaluate) => {
|
|
278
|
+
const derived = [];
|
|
279
|
+
const names = new Map();
|
|
280
|
+
const replacements = new Map();
|
|
281
|
+
const render = (expression) => {
|
|
282
|
+
const node = (0, parser_1.unwrapExpression)(expression);
|
|
283
|
+
if (parser_1.t.isIdentifier(node) && runtimeParams.has(node.value)) {
|
|
284
|
+
const fallback = defaults.get(node.value);
|
|
285
|
+
return [
|
|
286
|
+
fallback === undefined
|
|
287
|
+
? { param: node.value }
|
|
288
|
+
: { param: node.value, fallback: literalSource(fallback) },
|
|
289
|
+
];
|
|
290
|
+
}
|
|
291
|
+
if (parser_1.t.isBinaryExpression(node) && ARITHMETIC.has(node.operator)) {
|
|
292
|
+
const left = render(node.left);
|
|
293
|
+
const right = render(node.right);
|
|
294
|
+
if (!left || !right)
|
|
295
|
+
return null;
|
|
296
|
+
return ['(', ...left, ` ${node.operator} `, ...right, ')'];
|
|
297
|
+
}
|
|
298
|
+
if (isSign(node)) {
|
|
299
|
+
const argument = render(node.argument);
|
|
300
|
+
return argument && ['(', node.operator, '(', ...argument, ')', ')'];
|
|
301
|
+
}
|
|
302
|
+
if ((0, parser_1.readsParams)(node, runtimeParams))
|
|
303
|
+
return null;
|
|
304
|
+
const value = evaluate(node);
|
|
305
|
+
return typeof value === 'number' ? [literalSource(value)] : null;
|
|
306
|
+
};
|
|
307
|
+
const register = (node, pieces) => {
|
|
308
|
+
const first = pieces.find((piece) => typeof piece !== 'string');
|
|
309
|
+
if (!first) {
|
|
310
|
+
replacements.set(node, {
|
|
311
|
+
type: 'NumericLiteral',
|
|
312
|
+
span: node.span,
|
|
313
|
+
value: evaluate(node),
|
|
314
|
+
});
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const key = JSON.stringify(pieces);
|
|
318
|
+
let name = names.get(key);
|
|
319
|
+
if (!name) {
|
|
320
|
+
name = `${first.param}-${derived.length + 1}`;
|
|
321
|
+
names.set(key, name);
|
|
322
|
+
derived.push({ name, pieces });
|
|
323
|
+
}
|
|
324
|
+
replacements.set(node, {
|
|
325
|
+
type: 'Identifier',
|
|
326
|
+
span: node.span,
|
|
327
|
+
value: name,
|
|
328
|
+
optional: false,
|
|
329
|
+
});
|
|
330
|
+
};
|
|
331
|
+
const visit = (expression) => {
|
|
332
|
+
const node = (0, parser_1.unwrapExpression)(expression);
|
|
333
|
+
if (parser_1.t.isObjectExpression(node)) {
|
|
334
|
+
node.properties.forEach((prop) => {
|
|
335
|
+
if (prop.type === 'KeyValueProperty')
|
|
336
|
+
visit(prop.value);
|
|
337
|
+
});
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
if (parser_1.t.isTemplateLiteral(node)) {
|
|
341
|
+
node.expressions.forEach(visit);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
const arithmetic = parser_1.t.isBinaryExpression(node) && ARITHMETIC.has(node.operator);
|
|
345
|
+
if (!arithmetic && !isSign(node))
|
|
346
|
+
return;
|
|
347
|
+
if (!(0, parser_1.readsParams)(node, varParams))
|
|
348
|
+
return;
|
|
349
|
+
const pieces = render(node);
|
|
350
|
+
if (pieces) {
|
|
351
|
+
register(node, pieces.slice(1, -1));
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (arithmetic && node.operator === '+') {
|
|
355
|
+
visit(node.left);
|
|
356
|
+
visit(node.right);
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
visit(body);
|
|
360
|
+
return {
|
|
361
|
+
body: replacements.size > 0 ? replaceNodes(body, replacements) : body,
|
|
362
|
+
derived,
|
|
363
|
+
};
|
|
364
|
+
};
|
|
365
|
+
const resolveDynamicStyle = (func, runtimeParams, staticTable, tables, providedParams, definiteParams) => {
|
|
233
366
|
if (func.unsupportedParams)
|
|
234
367
|
throw new Error('[plumeria] Dynamic styles require named parameters or object destructuring; array and rest parameters are not supported.');
|
|
235
368
|
const tempStaticTable = Object.create(staticTable);
|
|
236
|
-
const
|
|
369
|
+
const evaluate = (expr, table) => (0, parser_1.objectExpressionToObject)({
|
|
370
|
+
type: 'ObjectExpression',
|
|
371
|
+
span: func.body.span,
|
|
372
|
+
properties: [
|
|
373
|
+
{
|
|
374
|
+
type: 'KeyValueProperty',
|
|
375
|
+
key: {
|
|
376
|
+
type: 'Identifier',
|
|
377
|
+
span: func.body.span,
|
|
378
|
+
value: 'value',
|
|
379
|
+
optional: false,
|
|
380
|
+
},
|
|
381
|
+
value: expr,
|
|
382
|
+
},
|
|
383
|
+
],
|
|
384
|
+
}, table, tables.keyframesHashTable, tables.viewTransitionHashTable, tables.createThemeHashTable, tables.createThemeObjectTable, tables.createHashTable, tables.createStaticHashTable, tables.createStaticObjectTable).value;
|
|
237
385
|
const withDefault = Object.entries(func.defaults ?? {}).filter(([param]) => providedParams
|
|
238
386
|
? !providedParams.has(param)
|
|
239
387
|
: tempStaticTable[param] === undefined);
|
|
388
|
+
const defaultLiterals = new Map();
|
|
389
|
+
withDefault.forEach(([param, expr]) => {
|
|
390
|
+
const node = (0, parser_1.unwrapExpression)(expr);
|
|
391
|
+
if (parser_1.t.isIdentifier(node) && node.value === 'undefined')
|
|
392
|
+
return;
|
|
393
|
+
const definite = definiteParams?.has(param) || !(0, parser_1.readsParams)(func.body, new Set([param]));
|
|
394
|
+
let literal;
|
|
395
|
+
try {
|
|
396
|
+
literal = evaluate(expr, staticTable);
|
|
397
|
+
}
|
|
398
|
+
catch (error) {
|
|
399
|
+
if (definite)
|
|
400
|
+
return;
|
|
401
|
+
throw error;
|
|
402
|
+
}
|
|
403
|
+
if (typeof literal === 'string' || typeof literal === 'number') {
|
|
404
|
+
defaultLiterals.set(param, literal);
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
if (!definite)
|
|
408
|
+
throw defaultError(param, node, literal);
|
|
409
|
+
});
|
|
410
|
+
const holeDefaults = new Map([...defaultLiterals].filter(([param]) => !definiteParams?.has(param)));
|
|
240
411
|
const cssVars = {};
|
|
241
412
|
const varParams = Array.from(new Set([...runtimeParams, ...withDefault.map(([param]) => param)]));
|
|
242
|
-
|
|
243
|
-
|
|
413
|
+
const runtimeSet = new Set(runtimeParams);
|
|
414
|
+
const constantTable = Object.create(staticTable);
|
|
415
|
+
defaultLiterals.forEach((literal, param) => {
|
|
416
|
+
if (!runtimeSet.has(param))
|
|
417
|
+
constantTable[param] = literal;
|
|
418
|
+
});
|
|
419
|
+
const { body, derived } = deriveArithmetic(func.body, runtimeSet, new Set(varParams), holeDefaults, (node) => {
|
|
420
|
+
try {
|
|
421
|
+
return evaluate(node, constantTable);
|
|
422
|
+
}
|
|
423
|
+
catch {
|
|
424
|
+
return undefined;
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
const resolveBody = () => (0, parser_1.objectExpressionToObject)(body, tempStaticTable, tables.keyframesHashTable, tables.viewTransitionHashTable, tables.createThemeHashTable, tables.createThemeObjectTable, tables.createHashTable, tables.createStaticHashTable, tables.createStaticObjectTable);
|
|
428
|
+
const varNames = [...varParams, ...derived.map(({ name }) => name)];
|
|
429
|
+
if (varNames.length > 0) {
|
|
430
|
+
varNames.forEach((name) => (tempStaticTable[name] = name));
|
|
244
431
|
const hash = (0, zss_engine_2.genBase36Hash)(resolveBody(), 1, 8);
|
|
245
|
-
|
|
246
|
-
const cssVar = `--${hash}-${
|
|
247
|
-
tempStaticTable[
|
|
248
|
-
cssVars[
|
|
432
|
+
varNames.forEach((name) => {
|
|
433
|
+
const cssVar = `--${hash}-${name}`;
|
|
434
|
+
tempStaticTable[name] = `var(${cssVar})`;
|
|
435
|
+
cssVars[name] = cssVar;
|
|
249
436
|
});
|
|
250
437
|
}
|
|
251
438
|
const style = resolveBody();
|
|
252
439
|
const varGroups = new Map();
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
varGroups.set(param, (0, exports.splitVarByUnit)(style, cssVar));
|
|
440
|
+
varNames.forEach((name) => {
|
|
441
|
+
varGroups.set(name, (0, exports.splitVarByUnit)(style, cssVars[name]));
|
|
256
442
|
});
|
|
257
|
-
|
|
258
|
-
const resolved = (0, parser_1.objectExpressionToObject)({
|
|
259
|
-
type: 'ObjectExpression',
|
|
260
|
-
span: func.body.span,
|
|
261
|
-
properties: [
|
|
262
|
-
{
|
|
263
|
-
type: 'KeyValueProperty',
|
|
264
|
-
key: {
|
|
265
|
-
type: 'Identifier',
|
|
266
|
-
span: func.body.span,
|
|
267
|
-
value: 'value',
|
|
268
|
-
optional: false,
|
|
269
|
-
},
|
|
270
|
-
value: expr,
|
|
271
|
-
},
|
|
272
|
-
],
|
|
273
|
-
}, staticTable, tables.keyframesHashTable, tables.viewTransitionHashTable, tables.createThemeHashTable, tables.createThemeObjectTable, tables.createHashTable, tables.createStaticHashTable, tables.createStaticObjectTable);
|
|
274
|
-
const literal = resolved.value;
|
|
275
|
-
if (typeof literal !== 'string' && typeof literal !== 'number')
|
|
276
|
-
return;
|
|
443
|
+
defaultLiterals.forEach((literal, param) => {
|
|
277
444
|
varGroups
|
|
278
445
|
.get(param)
|
|
279
446
|
.forEach(({ cssVar, unit, written }) => (0, exports.applyVarFallback)(style, cssVar, literal, { unit, written }));
|
|
280
447
|
});
|
|
281
|
-
return { style, varGroups };
|
|
448
|
+
return { style, varGroups, derived };
|
|
282
449
|
};
|
|
283
450
|
exports.resolveDynamicStyle = resolveDynamicStyle;
|
package/dist/parser.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { CSSObject, Tables, StaticTable, KeyframesHashTable, ViewTransition
|
|
|
2
2
|
import type { Module, Expression, CallExpression, Identifier, KeyValueProperty, StringLiteral, NumericLiteral, BooleanLiteral, ObjectExpression, MemberExpression, TemplateLiteral, BinaryExpression, UnaryExpression, ParenthesisExpression, VariableDeclaration, VariableDeclarator, ExportDeclaration, ConditionalExpression, JSXExpression, ArrowFunctionExpression, FunctionExpression } from '@swc/core';
|
|
3
3
|
export declare function unwrapExpression(node: any): any;
|
|
4
4
|
export declare const getRootIdentifier: (node: Expression) => string | null;
|
|
5
|
+
export declare const expressionLabel: (node: Expression) => string;
|
|
5
6
|
export declare function resolveOriginError(node: Expression, rootName: string | null, localImports: Record<string, {
|
|
6
7
|
actualPath: string;
|
|
7
8
|
importedName: string;
|
|
@@ -45,6 +46,7 @@ export declare function traverse(node: Module | JSXExpression, visitor: {
|
|
|
45
46
|
export declare function objectExpressionToObject(node: ObjectExpression, staticTable: StaticTable, keyframesHashTable: KeyframesHashTable, viewTransitionHashTable: ViewTransitionHashTable, createThemeHashTable: CreateThemeHashTable, createThemeObjectTable: CreateThemeObjectTable, createHashTable: CreateHashTable, createStaticHashTable: CreateStaticHashTable, createStaticObjectTable: CreateStaticObjectTable, resolveVariable?: (name: string) => any): CSSObject;
|
|
46
47
|
export declare function collectLocalConstNodes(ast: Module): Map<string, any>;
|
|
47
48
|
export declare function collectLocalConsts(ast: Module): Record<string, any>;
|
|
49
|
+
export declare function readsParams(node: any, params: Set<string>): boolean;
|
|
48
50
|
export declare function resolveThemeSelector(node: Expression, staticTable: StaticTable, createStaticHashTable: CreateStaticHashTable, createStaticObjectTable: CreateStaticObjectTable): string;
|
|
49
51
|
export declare function resolveFileError(actualPath: string, importedName: string): {
|
|
50
52
|
filePath: string;
|
package/dist/parser.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.appendSheet = exports.t = exports.getRootIdentifier = void 0;
|
|
36
|
+
exports.appendSheet = exports.t = exports.expressionLabel = exports.getRootIdentifier = void 0;
|
|
37
37
|
exports.unwrapExpression = unwrapExpression;
|
|
38
38
|
exports.resolveOriginError = resolveOriginError;
|
|
39
39
|
exports.resolveComponentKey = resolveComponentKey;
|
|
@@ -41,6 +41,7 @@ exports.traverse = traverse;
|
|
|
41
41
|
exports.objectExpressionToObject = objectExpressionToObject;
|
|
42
42
|
exports.collectLocalConstNodes = collectLocalConstNodes;
|
|
43
43
|
exports.collectLocalConsts = collectLocalConsts;
|
|
44
|
+
exports.readsParams = readsParams;
|
|
44
45
|
exports.resolveThemeSelector = resolveThemeSelector;
|
|
45
46
|
exports.resolveFileError = resolveFileError;
|
|
46
47
|
exports.fileTableKeys = fileTableKeys;
|
|
@@ -127,12 +128,13 @@ const expressionLabel = (node) => {
|
|
|
127
128
|
if (exports.t.isMemberExpression(node)) {
|
|
128
129
|
const property = node.property;
|
|
129
130
|
if (property.type === 'Identifier')
|
|
130
|
-
return `${expressionLabel(node.object)}.${property.value}`;
|
|
131
|
+
return `${(0, exports.expressionLabel)(node.object)}.${property.value}`;
|
|
131
132
|
if (property.type === 'Computed')
|
|
132
|
-
return `${expressionLabel(node.object)}[${expressionLabel(property.expression)}]`;
|
|
133
|
+
return `${(0, exports.expressionLabel)(node.object)}[${(0, exports.expressionLabel)(property.expression)}]`;
|
|
133
134
|
}
|
|
134
135
|
return EXPRESSION_KINDS[node.type] ?? 'an expression';
|
|
135
136
|
};
|
|
137
|
+
exports.expressionLabel = expressionLabel;
|
|
136
138
|
const getNamespaceMember = (node, rootName) => {
|
|
137
139
|
node = unwrapExpression(node);
|
|
138
140
|
if (exports.t.isCallExpression(node)) {
|
|
@@ -309,7 +311,7 @@ function objectExpressionToObject(node, staticTable, keyframesHashTable, viewTra
|
|
|
309
311
|
[root]: resolved,
|
|
310
312
|
}));
|
|
311
313
|
if (member === undefined)
|
|
312
|
-
throw new Error(`[plumeria] Unknown style member: ${expressionLabel(val)} does not exist.`);
|
|
314
|
+
throw new Error(`[plumeria] Unknown style member: ${(0, exports.expressionLabel)(val)} does not exist.`);
|
|
313
315
|
obj[key] = member;
|
|
314
316
|
return;
|
|
315
317
|
}
|
|
@@ -715,7 +717,7 @@ function evaluateTemplateLiteral(node, staticTable, keyframesHashTable, viewTran
|
|
|
715
717
|
const expr = node.expressions[i];
|
|
716
718
|
const evaluatedExpr = evaluateExpression(expr, staticTable, keyframesHashTable, viewTransitionHashTable, createThemeHashTable, createThemeObjectTable, createStaticHashTable, createStaticObjectTable);
|
|
717
719
|
if (evaluatedExpr === null || typeof evaluatedExpr === 'object')
|
|
718
|
-
throw new Error(`[plumeria] Template value cannot be resolved to a primitive: ${expressionLabel(expr)} inside \${} must resolve to a string or number at build time.`);
|
|
720
|
+
throw new Error(`[plumeria] Template value cannot be resolved to a primitive: ${(0, exports.expressionLabel)(expr)} inside \${} must resolve to a string or number at build time.`);
|
|
719
721
|
result += String(evaluatedExpr);
|
|
720
722
|
}
|
|
721
723
|
}
|
|
@@ -872,7 +874,7 @@ function evaluateExpression(node, staticTable, keyframesHashTable, viewTransitio
|
|
|
872
874
|
if (resolvedStatic !== undefined) {
|
|
873
875
|
return resolvedStatic;
|
|
874
876
|
}
|
|
875
|
-
throw new Error(`[plumeria] Cannot resolve static member expression: ${expressionLabel(node)}. Its object must be a const or a value created by css.createStatic or css.createTheme.`);
|
|
877
|
+
throw new Error(`[plumeria] Cannot resolve static member expression: ${(0, exports.expressionLabel)(node)}. Its object must be a const or a value created by css.createStatic or css.createTheme.`);
|
|
876
878
|
}
|
|
877
879
|
if (exports.t.isBinaryExpression(node)) {
|
|
878
880
|
return evaluateBinaryExpression(node, staticTable, keyframesHashTable, viewTransitionHashTable, createThemeHashTable, createThemeObjectTable, createStaticHashTable, createStaticObjectTable);
|
|
@@ -892,12 +894,12 @@ function evaluateExpression(node, staticTable, keyframesHashTable, viewTransitio
|
|
|
892
894
|
if (node.operator === '~')
|
|
893
895
|
return ~value;
|
|
894
896
|
}
|
|
895
|
-
throw new Error(`[plumeria] Unsupported unary operand for ${node.operator}: ${expressionLabel(node.argument)} must resolve to a number at build time.`);
|
|
897
|
+
throw new Error(`[plumeria] Unsupported unary operand for ${node.operator}: ${(0, exports.expressionLabel)(node.argument)} must resolve to a number at build time.`);
|
|
896
898
|
}
|
|
897
899
|
if (exports.t.isParenthesisExpression(node)) {
|
|
898
900
|
return evaluateExpression(node.expression, staticTable, keyframesHashTable, viewTransitionHashTable, createThemeHashTable, createThemeObjectTable, createStaticHashTable, createStaticObjectTable);
|
|
899
901
|
}
|
|
900
|
-
throw new Error(`[plumeria] Unsupported expression type: ${expressionLabel(node)}. Style values must be literals, consts, or arithmetic and template expressions of them.`);
|
|
902
|
+
throw new Error(`[plumeria] Unsupported expression type: ${(0, exports.expressionLabel)(node)}. Style values must be literals, consts, or arithmetic and template expressions of them.`);
|
|
901
903
|
}
|
|
902
904
|
function resolveKeyframesTableMemberExpression(node, keyframesHashTable) {
|
|
903
905
|
if (exports.t.isIdentifier(node)) {
|
|
@@ -1858,22 +1860,27 @@ function runScan(scanCwd, styleProp) {
|
|
|
1858
1860
|
if (callArgs.some((a) => a.spread))
|
|
1859
1861
|
return null;
|
|
1860
1862
|
const runtime = [];
|
|
1863
|
+
const definite = new Set();
|
|
1861
1864
|
if (func.named) {
|
|
1862
1865
|
const argExpr = callArgs[0]?.expression;
|
|
1863
1866
|
if (callArgs.length > 1 ||
|
|
1864
1867
|
(argExpr && argExpr.type !== 'ObjectExpression'))
|
|
1865
1868
|
return null;
|
|
1866
|
-
const given = new
|
|
1869
|
+
const given = new Map();
|
|
1867
1870
|
(argExpr?.properties ?? []).forEach((prop) => {
|
|
1868
1871
|
if (prop.type === 'Identifier')
|
|
1869
|
-
given.
|
|
1872
|
+
given.set(prop.value, prop);
|
|
1870
1873
|
else if (prop.type === 'KeyValueProperty' &&
|
|
1871
1874
|
(exports.t.isIdentifier(prop.key) || exports.t.isStringLiteral(prop.key)))
|
|
1872
|
-
given.
|
|
1875
|
+
given.set(String(prop.key.value), prop.value);
|
|
1873
1876
|
});
|
|
1874
1877
|
for (const { key, local } of func.named) {
|
|
1875
|
-
|
|
1878
|
+
const source = given.get(key);
|
|
1879
|
+
if (source) {
|
|
1876
1880
|
runtime.push(local);
|
|
1881
|
+
if ((0, dynamicKey_1.isDefinedArgument)(source))
|
|
1882
|
+
definite.add(local);
|
|
1883
|
+
}
|
|
1877
1884
|
else if (!func.defaults?.[local])
|
|
1878
1885
|
return null;
|
|
1879
1886
|
}
|
|
@@ -1883,14 +1890,20 @@ function runScan(scanCwd, styleProp) {
|
|
|
1883
1890
|
return null;
|
|
1884
1891
|
}
|
|
1885
1892
|
else {
|
|
1886
|
-
callArgs.forEach((
|
|
1893
|
+
callArgs.forEach((callArg, i) => {
|
|
1887
1894
|
const param = func.params[i];
|
|
1888
|
-
if (param)
|
|
1889
|
-
|
|
1895
|
+
if (!param)
|
|
1896
|
+
return;
|
|
1897
|
+
runtime.push(param);
|
|
1898
|
+
if ((0, dynamicKey_1.isDefinedArgument)(callArg.expression))
|
|
1899
|
+
definite.add(param);
|
|
1890
1900
|
});
|
|
1891
1901
|
}
|
|
1892
|
-
const resolved = (0, dynamicKey_1.resolveDynamicStyle)(func, runtime, dynamicStaticTable, dynamicStyleTables, new Set());
|
|
1893
|
-
const hasVars =
|
|
1902
|
+
const resolved = (0, dynamicKey_1.resolveDynamicStyle)(func, runtime, dynamicStaticTable, dynamicStyleTables, new Set(), definite);
|
|
1903
|
+
const hasVars = [
|
|
1904
|
+
...runtime,
|
|
1905
|
+
...resolved.derived.map(({ name }) => name),
|
|
1906
|
+
].some((param) => (resolved.varGroups.get(param) ?? []).length > 0);
|
|
1894
1907
|
return { style: resolved.style, hasVars };
|
|
1895
1908
|
};
|
|
1896
1909
|
const resolveCallStylePropInScan = (expr) => {
|
package/dist/transform.js
CHANGED
|
@@ -1200,18 +1200,40 @@ const transformSource = async (env) => {
|
|
|
1200
1200
|
runtime.push({ param: p, source: callArg.expression });
|
|
1201
1201
|
});
|
|
1202
1202
|
}
|
|
1203
|
-
const resolved = (0, dynamicKey_1.resolveDynamicStyle)(func, runtime.map(({ param }) => param), tempStaticTable, dynamicStyleTables, providedParams
|
|
1204
|
-
|
|
1205
|
-
|
|
1203
|
+
const resolved = (0, dynamicKey_1.resolveDynamicStyle)(func, runtime.map(({ param }) => param), tempStaticTable, dynamicStyleTables, providedParams, new Set(runtime
|
|
1204
|
+
.filter(({ source }) => (0, dynamicKey_1.isDefinedArgument)(source))
|
|
1205
|
+
.map(({ param }) => param)));
|
|
1206
|
+
const { style, varGroups, derived } = resolved;
|
|
1207
|
+
const argSources = new Map();
|
|
1206
1208
|
runtime.forEach(({ param, source }) => {
|
|
1207
|
-
const groups = varGroups.get(param);
|
|
1208
|
-
if (!groups?.length)
|
|
1209
|
-
return;
|
|
1210
1209
|
const argStart = source.span.start - baseByteOffset;
|
|
1211
1210
|
const argEnd = source.span.end - baseByteOffset;
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1211
|
+
argSources.set(param, sourceBuffer.subarray(argStart, argEnd).toString('utf-8'));
|
|
1212
|
+
});
|
|
1213
|
+
const runtimeSources = runtime.map(({ param }) => ({
|
|
1214
|
+
name: param,
|
|
1215
|
+
argSource: argSources.get(param),
|
|
1216
|
+
}));
|
|
1217
|
+
derived.forEach(({ name, pieces }) => {
|
|
1218
|
+
runtimeSources.push({
|
|
1219
|
+
name,
|
|
1220
|
+
argSource: pieces
|
|
1221
|
+
.map((piece) => {
|
|
1222
|
+
if (typeof piece === 'string')
|
|
1223
|
+
return piece;
|
|
1224
|
+
const argument = `(${argSources.get(piece.param)})`;
|
|
1225
|
+
return piece.fallback === undefined
|
|
1226
|
+
? argument
|
|
1227
|
+
: `(${argument} === undefined ? ${piece.fallback} : ${argument})`;
|
|
1228
|
+
})
|
|
1229
|
+
.join(''),
|
|
1230
|
+
});
|
|
1231
|
+
});
|
|
1232
|
+
const vars = [];
|
|
1233
|
+
runtimeSources.forEach(({ name, argSource }) => {
|
|
1234
|
+
const groups = varGroups.get(name);
|
|
1235
|
+
if (!groups?.length)
|
|
1236
|
+
return;
|
|
1215
1237
|
const maybeNumber = Number(argSource);
|
|
1216
1238
|
groups.forEach(({ cssVar, prop, unit, written }) => {
|
|
1217
1239
|
let valueExpr;
|