@plumeria/utils 19.1.0 → 19.1.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.
@@ -0,0 +1,2286 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.transformSource = void 0;
37
+ const core_1 = require("@swc/core");
38
+ const path = __importStar(require("path"));
39
+ const zss_engine_1 = require("zss-engine");
40
+ const parser_1 = require("./parser");
41
+ const create_1 = require("./create");
42
+ const dynamicKey_1 = require("./dynamicKey");
43
+ const escalation_1 = require("./escalation");
44
+ const createTheme_1 = require("./createTheme");
45
+ const resolver_1 = require("./resolver");
46
+ const ast_1 = require("./ast");
47
+ const references_1 = require("./references");
48
+ const propertyPolicy_1 = require("./propertyPolicy");
49
+ const unwrapExport = (node) => {
50
+ if (node?.type === 'ExportDeclaration')
51
+ return node.declaration;
52
+ if (node?.type === 'ExportDefaultDeclaration')
53
+ return node.decl;
54
+ if (node?.type === 'ExportDefaultExpression')
55
+ return node.expression;
56
+ return node;
57
+ };
58
+ const isFunctionNode = (node) => node?.type === 'FunctionDeclaration' ||
59
+ node?.type === 'FunctionExpression' ||
60
+ node?.type === 'ArrowFunctionExpression';
61
+ const componentFunctionOf = (node) => {
62
+ if (isFunctionNode(node))
63
+ return node;
64
+ if (node?.type === 'CallExpression') {
65
+ for (const arg of node.arguments ?? []) {
66
+ const fn = componentFunctionOf(arg.expression);
67
+ if (fn)
68
+ return fn;
69
+ }
70
+ }
71
+ return undefined;
72
+ };
73
+ const unwrapPatternDefault = (pattern) => pattern?.type === 'AssignmentPattern' ? pattern.left : pattern;
74
+ const destructuredPropAliases = (fn) => {
75
+ const aliases = new Map();
76
+ const first = fn.params[0];
77
+ const pattern = unwrapPatternDefault(first?.pat ?? first);
78
+ if (pattern?.type !== 'ObjectPattern')
79
+ return aliases;
80
+ for (const item of pattern.properties ?? []) {
81
+ if (item.type !== 'KeyValuePatternProperty')
82
+ continue;
83
+ const local = unwrapPatternDefault(item.value);
84
+ const key = item.key;
85
+ if (!parser_1.t.isIdentifier(local))
86
+ continue;
87
+ if (!parser_1.t.isIdentifier(key) && !parser_1.t.isStringLiteral(key))
88
+ continue;
89
+ const name = String(key.value);
90
+ if (name !== local.value)
91
+ aliases.set(local.value, name);
92
+ }
93
+ return aliases;
94
+ };
95
+ const propDefaultMessage = (source) => `Plumeria: A style prop default must be a defined style: "${source}". ` +
96
+ `Apply a conditional or dynamic style where the element is styled.`;
97
+ const spreadStyleMessage = (source) => `Plumeria: Spread elements in a style array are not supported: "...${source}". ` +
98
+ `List each style explicitly.`;
99
+ const resolveLocalStyleAlias = (aliases, expression) => {
100
+ let current = expression;
101
+ const seen = new Set();
102
+ while (parser_1.t.isIdentifier(current)) {
103
+ const name = current.value;
104
+ if (seen.has(name))
105
+ break;
106
+ seen.add(name);
107
+ const candidates = aliases[name];
108
+ if (!candidates || candidates.length === 0)
109
+ break;
110
+ const candidate = candidates.find((candidate) => candidate.context === current.ctxt);
111
+ if (!candidate)
112
+ break;
113
+ current = candidate.expression;
114
+ }
115
+ return current;
116
+ };
117
+ const isStaticArgValue = (node) => node.type === 'StringLiteral' ||
118
+ node.type === 'NumericLiteral' ||
119
+ node.type === 'BooleanLiteral' ||
120
+ (node.type === 'TemplateLiteral' && node.expressions.length === 0) ||
121
+ parser_1.t.isIdentifier(node) ||
122
+ parser_1.t.isMemberExpression(node);
123
+ const isNoOpStyle = (node) => parser_1.t.isNullLiteral(node) ||
124
+ (parser_1.t.isBooleanLiteral(node) && node.value === false) ||
125
+ (parser_1.t.isIdentifier(node) && node.value === 'undefined');
126
+ const foldDynamicVars = (vars) => {
127
+ const grouped = new Map();
128
+ [...vars]
129
+ .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
130
+ .forEach((entry) => {
131
+ const list = grouped.get(entry.cssVar);
132
+ if (list)
133
+ list.push(entry);
134
+ else
135
+ grouped.set(entry.cssVar, [entry]);
136
+ });
137
+ return [...grouped].map(([cssVar, entries]) => {
138
+ let value = 'undefined';
139
+ entries.forEach((entry) => {
140
+ value = entry.test
141
+ ? `((${entry.test}) ? ${entry.valueExpr} : ${value})`
142
+ : entry.valueExpr;
143
+ });
144
+ return `"${cssVar}": ${value}`;
145
+ });
146
+ };
147
+ const transformSource = async (env) => {
148
+ const { source, root, styleProp, propertyPolicy, isDev, collectOndemandSheets, addDependency, } = env;
149
+ const id = env.moduleId;
150
+ const resourcePath = env.moduleId;
151
+ const baseId = env.filePath;
152
+ const ast = (0, core_1.parseSync)(source, {
153
+ syntax: 'typescript',
154
+ tsx: true,
155
+ target: 'es2022',
156
+ });
157
+ (0, propertyPolicy_1.assertPropertyPolicy)(ast, propertyPolicy, id);
158
+ const leadingLen = (0, ast_1.getLeadingCommentLength)(source);
159
+ const sourceBuffer = Buffer.from(source, 'utf-8');
160
+ const leadingBytes = Buffer.byteLength(source.slice(0, leadingLen), 'utf-8');
161
+ const baseByteOffset = ast.span.start - leadingBytes;
162
+ const throwCompilationError = (message, node) => {
163
+ let suffix = '';
164
+ if (node) {
165
+ const offset = node.span.start - baseByteOffset;
166
+ let line = 1;
167
+ let colStart = 0;
168
+ for (let i = 0; i < offset && i < sourceBuffer.length; i++) {
169
+ if (sourceBuffer[i] === 10) {
170
+ line++;
171
+ colStart = i + 1;
172
+ }
173
+ }
174
+ const col = offset - colStart + 1;
175
+ suffix = ` (${path.basename(resourcePath)}:${line}:${col})`;
176
+ }
177
+ const err = new Error(`${message}${suffix}`);
178
+ err.stack = err.message;
179
+ throw err;
180
+ };
181
+ const assertResolvable = (node) => {
182
+ if (parser_1.t.isIdentifier(node) && node.value === 'undefined')
183
+ return;
184
+ if (parser_1.t.isMemberExpression(node) ||
185
+ parser_1.t.isIdentifier(node) ||
186
+ parser_1.t.isCallExpression(node) ||
187
+ parser_1.t.isArrowFunctionExpression(node) ||
188
+ parser_1.t.isFunctionExpression(node)) {
189
+ const rootId = (0, parser_1.getRootIdentifier)(node);
190
+ const isPlumeriaStyle = rootId &&
191
+ isVisibleReference(node) &&
192
+ ((localCreateStyles[rootId] !== undefined &&
193
+ localCreateStyles[rootId].type !== 'constant') ||
194
+ mergedCreateTable[rootId] !== undefined);
195
+ if (!isPlumeriaStyle) {
196
+ const origin = rootId ? localImports[rootId] : undefined;
197
+ const failure = origin
198
+ ? (0, parser_1.resolveFileError)(origin.actualPath, origin.importedName)
199
+ : undefined;
200
+ if (failure) {
201
+ throwCompilationError(`Plumeria: ${failure.message} (${path.basename(failure.filePath)})`);
202
+ }
203
+ throwCompilationError(`Plumeria: Dynamic or unresolvable style object "${getSource(node)}" is not supported.`, node);
204
+ }
205
+ }
206
+ };
207
+ const scannedTables = (0, parser_1.scanAll)();
208
+ const ownFailure = (0, parser_1.resolveFileError)(baseId, '');
209
+ if (ownFailure)
210
+ throwCompilationError(`Plumeria: ${ownFailure.message}`);
211
+ for (const node of ast.body) {
212
+ if (node.type === 'ImportDeclaration') {
213
+ const sourcePath = node.source.value;
214
+ const actualPath = (0, resolver_1.resolveImportPath)(sourcePath, id);
215
+ if (actualPath) {
216
+ addDependency(actualPath);
217
+ const transDeps = (0, parser_1.getFileDependencies)(actualPath);
218
+ for (const dep of transDeps) {
219
+ addDependency(dep);
220
+ }
221
+ }
222
+ }
223
+ }
224
+ if (scannedTables.componentPropsTable) {
225
+ const parentFiles = new Set();
226
+ for (const compKey of Object.keys(scannedTables.componentPropsTable)) {
227
+ if (!compKey.startsWith(`${id}-`))
228
+ continue;
229
+ const props = scannedTables.componentPropsTable[compKey];
230
+ for (const propName of Object.keys(props)) {
231
+ for (const entry of props[propName]) {
232
+ if (entry.filePath !== id) {
233
+ parentFiles.add(entry.filePath);
234
+ }
235
+ }
236
+ }
237
+ }
238
+ for (const parentFile of parentFiles) {
239
+ addDependency(parentFile);
240
+ }
241
+ }
242
+ const components = [];
243
+ const propAliases = new Map();
244
+ const propDefaults = new Map();
245
+ const declaredProps = new Map();
246
+ const addComponent = (name, fn) => {
247
+ components.push({ name, node: fn });
248
+ const first = fn.params[0];
249
+ const pattern = unwrapPatternDefault(first?.pat ?? first);
250
+ const defaults = new Map();
251
+ for (const item of pattern?.properties ?? []) {
252
+ if (item.type === 'AssignmentPatternProperty' && item.value)
253
+ defaults.set(item.key.value, item.value);
254
+ if (item.type === 'KeyValuePatternProperty' &&
255
+ item.value?.type === 'AssignmentPattern')
256
+ defaults.set(item.key.value, item.value.right);
257
+ }
258
+ propDefaults.set(name, defaults);
259
+ const aliases = destructuredPropAliases(fn);
260
+ if (aliases.size > 0)
261
+ propAliases.set(name, aliases);
262
+ const declared = new Set();
263
+ for (const item of pattern?.properties ?? []) {
264
+ const key = item.key;
265
+ if (parser_1.t.isIdentifier(key) || parser_1.t.isStringLiteral(key))
266
+ declared.add(String(key.value));
267
+ }
268
+ if (declared.size > 0)
269
+ declaredProps.set(name, declared);
270
+ };
271
+ for (const node of ast.body) {
272
+ const statement = unwrapExport(node);
273
+ if (isFunctionNode(statement)) {
274
+ addComponent(statement.identifier?.value ?? 'default', statement);
275
+ }
276
+ else if (statement?.type === 'CallExpression') {
277
+ const fn = componentFunctionOf(statement);
278
+ if (fn)
279
+ addComponent('default', fn);
280
+ }
281
+ else if (parser_1.t.isVariableDeclaration(statement)) {
282
+ for (const decl of statement.declarations) {
283
+ if (!parser_1.t.isIdentifier(decl.id))
284
+ continue;
285
+ const fn = componentFunctionOf(decl.init);
286
+ if (fn)
287
+ addComponent(decl.id.value, fn);
288
+ }
289
+ }
290
+ }
291
+ const appliedStyleProps = new Set();
292
+ const ownerComponentOf = (at) => components.find((c) => at.span.start >= c.node.span.start && at.span.start <= c.node.span.end)?.name;
293
+ const markStylePropApplied = (name, at) => {
294
+ const owner = ownerComponentOf(at);
295
+ if (owner) {
296
+ appliedStyleProps.add(`${owner}:${name}`);
297
+ }
298
+ };
299
+ const extractedSheets = [];
300
+ const addSheet = (sheet) => {
301
+ if (!extractedSheets.includes(sheet)) {
302
+ extractedSheets.push(sheet);
303
+ }
304
+ };
305
+ const processStyleRecords = (style, weights) => {
306
+ const records = (0, create_1.getStyleRecords)(style, weights);
307
+ if (collectOndemandSheets) {
308
+ (0, parser_1.extractOndemandStyles)(style, extractedSheets, scannedTables);
309
+ records.forEach((r) => {
310
+ addSheet(r.sheet);
311
+ });
312
+ }
313
+ return records;
314
+ };
315
+ const localConsts = (0, parser_1.collectLocalConsts)(ast);
316
+ const importMap = {};
317
+ const keyframesImportMap = {};
318
+ const viewTransitionImportMap = {};
319
+ const createImportMap = {};
320
+ const createFunctionImportMap = {};
321
+ const createThemeImportMap = {};
322
+ const createStaticImportMap = {};
323
+ const plumeriaAliases = {};
324
+ const localImports = {};
325
+ (0, parser_1.traverse)(ast, {
326
+ ImportDeclaration({ node }) {
327
+ const sourcePath = node.source.value;
328
+ if (sourcePath === '@plumeria/core') {
329
+ node.specifiers.forEach((specifier) => {
330
+ if (specifier.type === 'ImportNamespaceSpecifier') {
331
+ plumeriaAliases[specifier.local.value] = 'NAMESPACE';
332
+ }
333
+ else if (specifier.type === 'ImportDefaultSpecifier') {
334
+ plumeriaAliases[specifier.local.value] = 'NAMESPACE';
335
+ }
336
+ else if (specifier.type === 'ImportSpecifier') {
337
+ const importedName = specifier.imported
338
+ ? specifier.imported.value
339
+ : specifier.local.value;
340
+ plumeriaAliases[specifier.local.value] = importedName;
341
+ }
342
+ });
343
+ }
344
+ const actualPath = (0, resolver_1.resolveImportPath)(sourcePath, resourcePath);
345
+ if (actualPath) {
346
+ node.specifiers.forEach((specifier) => {
347
+ if (specifier.type === 'ImportNamespaceSpecifier') {
348
+ localImports[specifier.local.value] = {
349
+ actualPath,
350
+ importedName: '*',
351
+ };
352
+ return;
353
+ }
354
+ if (specifier.type === 'ImportSpecifier' ||
355
+ specifier.type === 'ImportDefaultSpecifier') {
356
+ const importedName = specifier.type === 'ImportDefaultSpecifier'
357
+ ? 'default'
358
+ : specifier.imported
359
+ ? specifier.imported.value
360
+ : specifier.local.value;
361
+ const localName = specifier.local.value;
362
+ let resolvedKey = `${actualPath}-${importedName}`;
363
+ const resolved = (0, parser_1.resolveExport)(actualPath, importedName);
364
+ if (resolved) {
365
+ resolvedKey = `${resolved.filePath}-${resolved.localName}`;
366
+ }
367
+ const uniqueKey = resolvedKey;
368
+ localImports[localName] = { actualPath, importedName };
369
+ if (scannedTables.staticTable[uniqueKey]) {
370
+ importMap[localName] = scannedTables.staticTable[uniqueKey];
371
+ }
372
+ if (scannedTables.keyframesHashTable[uniqueKey]) {
373
+ keyframesImportMap[localName] =
374
+ scannedTables.keyframesHashTable[uniqueKey];
375
+ }
376
+ if (scannedTables.viewTransitionHashTable[uniqueKey]) {
377
+ viewTransitionImportMap[localName] =
378
+ scannedTables.viewTransitionHashTable[uniqueKey];
379
+ }
380
+ if (scannedTables.createHashTable[uniqueKey]) {
381
+ createImportMap[localName] =
382
+ scannedTables.createHashTable[uniqueKey];
383
+ }
384
+ if (scannedTables.createFunctionTable[uniqueKey]) {
385
+ createFunctionImportMap[localName] = (0, dynamicKey_1.styleFunctionsOf)(scannedTables.createFunctionTable[uniqueKey]);
386
+ }
387
+ if (scannedTables.createThemeHashTable[uniqueKey]) {
388
+ createThemeImportMap[localName] =
389
+ scannedTables.createThemeHashTable[uniqueKey];
390
+ }
391
+ if (scannedTables.createStaticHashTable[uniqueKey]) {
392
+ createStaticImportMap[localName] =
393
+ scannedTables.createStaticHashTable[uniqueKey];
394
+ }
395
+ }
396
+ });
397
+ }
398
+ },
399
+ });
400
+ const mergedStaticTable = {};
401
+ for (const key of Object.keys(scannedTables.staticTable)) {
402
+ mergedStaticTable[key] = scannedTables.staticTable[key];
403
+ }
404
+ for (const key of Object.keys(localConsts)) {
405
+ mergedStaticTable[key] = localConsts[key];
406
+ }
407
+ for (const key of Object.keys(importMap)) {
408
+ mergedStaticTable[key] = importMap[key];
409
+ }
410
+ const mergedKeyframesTable = {};
411
+ for (const key of Object.keys(scannedTables.keyframesHashTable)) {
412
+ mergedKeyframesTable[key] = scannedTables.keyframesHashTable[key];
413
+ if (key.startsWith(`${resourcePath}-`)) {
414
+ const varName = key.slice(resourcePath.length + 1);
415
+ mergedKeyframesTable[varName] = scannedTables.keyframesHashTable[key];
416
+ }
417
+ }
418
+ for (const key of Object.keys(keyframesImportMap)) {
419
+ mergedKeyframesTable[key] = keyframesImportMap[key];
420
+ }
421
+ const mergedViewTransitionTable = {};
422
+ for (const key of Object.keys(scannedTables.viewTransitionHashTable)) {
423
+ mergedViewTransitionTable[key] = scannedTables.viewTransitionHashTable[key];
424
+ if (key.startsWith(`${resourcePath}-`)) {
425
+ const varName = key.slice(resourcePath.length + 1);
426
+ mergedViewTransitionTable[varName] =
427
+ scannedTables.viewTransitionHashTable[key];
428
+ }
429
+ }
430
+ for (const key of Object.keys(viewTransitionImportMap)) {
431
+ mergedViewTransitionTable[key] = viewTransitionImportMap[key];
432
+ }
433
+ const mergedCreateTable = {};
434
+ for (const key of Object.keys(scannedTables.createHashTable)) {
435
+ mergedCreateTable[key] = scannedTables.createHashTable[key];
436
+ if (key.startsWith(`${resourcePath}-`)) {
437
+ const varName = key.slice(resourcePath.length + 1);
438
+ mergedCreateTable[varName] = scannedTables.createHashTable[key];
439
+ }
440
+ }
441
+ for (const key of Object.keys(createImportMap)) {
442
+ mergedCreateTable[key] = createImportMap[key];
443
+ }
444
+ const mergedCreateThemeHashTable = {};
445
+ for (const key of Object.keys(scannedTables.createThemeHashTable)) {
446
+ mergedCreateThemeHashTable[key] = scannedTables.createThemeHashTable[key];
447
+ if (key.startsWith(`${resourcePath}-`)) {
448
+ const varName = key.slice(resourcePath.length + 1);
449
+ mergedCreateThemeHashTable[varName] =
450
+ scannedTables.createThemeHashTable[key];
451
+ }
452
+ }
453
+ for (const key of Object.keys(createThemeImportMap)) {
454
+ mergedCreateThemeHashTable[key] = createThemeImportMap[key];
455
+ }
456
+ const mergedCreateStaticHashTable = {};
457
+ for (const key of Object.keys(scannedTables.createStaticHashTable)) {
458
+ mergedCreateStaticHashTable[key] = scannedTables.createStaticHashTable[key];
459
+ if (key.startsWith(`${resourcePath}-`)) {
460
+ const varName = key.slice(resourcePath.length + 1);
461
+ mergedCreateStaticHashTable[varName] =
462
+ scannedTables.createStaticHashTable[key];
463
+ }
464
+ }
465
+ for (const key of Object.keys(createStaticImportMap)) {
466
+ mergedCreateStaticHashTable[key] = createStaticImportMap[key];
467
+ }
468
+ const dynamicStyleTables = {
469
+ keyframesHashTable: mergedKeyframesTable,
470
+ viewTransitionHashTable: mergedViewTransitionTable,
471
+ createThemeHashTable: mergedCreateThemeHashTable,
472
+ createThemeObjectTable: scannedTables.createThemeObjectTable,
473
+ createHashTable: mergedCreateTable,
474
+ createStaticHashTable: mergedCreateStaticHashTable,
475
+ createStaticObjectTable: scannedTables.createStaticObjectTable,
476
+ };
477
+ const localCreateStyles = {};
478
+ const localStyleAliases = {};
479
+ const checkStyleAliasAssignment = (decl) => {
480
+ if (!parser_1.t.isIdentifier(decl.id) || !decl.init)
481
+ return;
482
+ const init = (0, parser_1.unwrapExpression)(decl.init);
483
+ if (parser_1.t.isMemberExpression(init) && parser_1.t.isIdentifier(init.object)) {
484
+ const objName = init.object.value;
485
+ if (localCreateStyles[objName] !== undefined ||
486
+ mergedCreateTable[objName] !== undefined) {
487
+ (localStyleAliases[decl.id.value] ??= []).push({
488
+ expression: init,
489
+ context: decl.id.ctxt,
490
+ });
491
+ }
492
+ }
493
+ };
494
+ const replacements = [];
495
+ const deferredSources = [];
496
+ const deferRange = (start, end) => {
497
+ const token = `__plumeria_preserved_${deferredSources.length}__`;
498
+ deferredSources.push({ token, start, end });
499
+ return token;
500
+ };
501
+ const deferSource = (node) => deferRange(node.span.start - baseByteOffset, node.span.end - baseByteOffset);
502
+ const deferProperty = (property) => {
503
+ const node = property;
504
+ const range = node.spread && node.arguments
505
+ ? { start: node.spread.start, end: node.arguments.span.end }
506
+ : node.span
507
+ ? { start: node.span.start, end: node.span.end }
508
+ : node.key && node.value
509
+ ? { start: node.key.span.start, end: node.value.span.end }
510
+ : null;
511
+ return range
512
+ ? deferRange(range.start - baseByteOffset, range.end - baseByteOffset)
513
+ : null;
514
+ };
515
+ const dynamicFnCalls = [];
516
+ const processedDecls = new Set();
517
+ const separatelyExported = new Set();
518
+ for (const statement of ast.body) {
519
+ if (statement.type !== 'ExportNamedDeclaration' || statement.source)
520
+ continue;
521
+ for (const specifier of statement.specifiers) {
522
+ if (specifier.type === 'ExportSpecifier' &&
523
+ parser_1.t.isIdentifier(specifier.orig)) {
524
+ separatelyExported.add(specifier.orig.value);
525
+ }
526
+ }
527
+ }
528
+ const idSpans = new Set();
529
+ const excludedSpans = new Set();
530
+ const referenceIdents = (0, references_1.collectReferenceIdentifiers)(ast);
531
+ const topLevelDeclarators = new Set();
532
+ for (const statement of ast.body) {
533
+ const declaration = unwrapExport(statement);
534
+ if (parser_1.t.isVariableDeclaration(declaration)) {
535
+ declaration.declarations.forEach((decl) => topLevelDeclarators.add(decl));
536
+ }
537
+ }
538
+ const unwrapStyleExpression = (node) => {
539
+ while (node &&
540
+ [
541
+ 'ParenthesisExpression',
542
+ 'TsAsExpression',
543
+ 'TsSatisfiesExpression',
544
+ 'TsNonNullExpression',
545
+ 'TsConstAssertion',
546
+ 'TsTypeAssertion',
547
+ ].includes(node.type))
548
+ node = node.expression;
549
+ return node;
550
+ };
551
+ const literalObjectArgument = (node, seen = new Set()) => {
552
+ node = unwrapStyleExpression(node);
553
+ if (parser_1.t.isObjectExpression(node))
554
+ return node;
555
+ if (!parser_1.t.isIdentifier(node) || seen.has(node.value))
556
+ return null;
557
+ seen.add(node.value);
558
+ const declaration = [...topLevelDeclarators].find((decl) => parser_1.t.isIdentifier(decl.id) && decl.id.value === node.value);
559
+ return declaration?.init
560
+ ? literalObjectArgument(declaration.init, seen)
561
+ : null;
562
+ };
563
+ const registeredStyleCalls = new Set();
564
+ const registerStyle = (node, declSpan, isExported) => {
565
+ let propName;
566
+ const init = unwrapStyleExpression(node.init);
567
+ if (parser_1.t.isIdentifier(node.id) &&
568
+ init &&
569
+ parser_1.t.isCallExpression(init) &&
570
+ init.arguments.length >= 1) {
571
+ const callee = init.callee;
572
+ if (parser_1.t.isMemberExpression(callee) &&
573
+ parser_1.t.isIdentifier(callee.object) &&
574
+ parser_1.t.isIdentifier(callee.property)) {
575
+ const objectName = callee.object.value;
576
+ const propertyName = callee.property.value;
577
+ const alias = plumeriaAliases[objectName];
578
+ if (alias === 'NAMESPACE') {
579
+ propName = propertyName;
580
+ }
581
+ }
582
+ else if (parser_1.t.isIdentifier(callee)) {
583
+ const calleeName = callee.value;
584
+ const originalName = plumeriaAliases[calleeName];
585
+ if (originalName) {
586
+ propName = originalName;
587
+ }
588
+ }
589
+ }
590
+ if (propName && init && parser_1.t.isCallExpression(init)) {
591
+ if (['create', 'createTheme', 'createStatic'].includes(propName) &&
592
+ !topLevelDeclarators.has(node)) {
593
+ throwCompilationError(`Plumeria: css.${propName} must be assigned to a top-level variable so its styles can be resolved across files. Move this declaration outside the function or block.`, node);
594
+ }
595
+ if (['create', 'createTheme', 'createStatic'].includes(propName)) {
596
+ const argumentIndex = propName === 'createTheme' ? 1 : 0;
597
+ const argument = init.arguments[argumentIndex];
598
+ const object = argument && literalObjectArgument(argument.expression);
599
+ if (!object)
600
+ throwCompilationError(`Plumeria: css.${propName} needs a style object it can read at build time. Pass an object literal or a top-level constant containing one.`, init);
601
+ argument.expression = object;
602
+ registeredStyleCalls.add(init.span.start);
603
+ }
604
+ if (propName === 'create' &&
605
+ parser_1.t.isObjectExpression(init.arguments[0].expression)) {
606
+ const obj = (0, parser_1.objectExpressionToObject)(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
607
+ if (obj) {
608
+ const hashMap = {};
609
+ Object.entries(obj).forEach(([key, style]) => {
610
+ if (typeof style !== 'object' || style === null)
611
+ return;
612
+ const records = (0, create_1.getStyleRecords)(style);
613
+ const atomMap = {};
614
+ records.forEach((r) => (atomMap[r.key] = r.hash));
615
+ hashMap[key] = atomMap;
616
+ });
617
+ const styleFunctions = (0, dynamicKey_1.styleFunctionsOf)(init.arguments[0].expression);
618
+ if (parser_1.t.isIdentifier(node.id)) {
619
+ idSpans.add(node.id.span.start);
620
+ }
621
+ if (parser_1.t.isIdentifier(node.id)) {
622
+ localCreateStyles[node.id.value] = {
623
+ name: node.id.value,
624
+ type: 'create',
625
+ obj,
626
+ hashMap,
627
+ isExported,
628
+ initSpan: {
629
+ start: init.span.start - baseByteOffset,
630
+ end: init.span.end - baseByteOffset,
631
+ },
632
+ declSpan: {
633
+ start: declSpan.start - baseByteOffset,
634
+ end: declSpan.end - baseByteOffset,
635
+ },
636
+ functions: styleFunctions,
637
+ };
638
+ }
639
+ }
640
+ }
641
+ else if (propName === 'createTheme' &&
642
+ init.arguments.length >= 2 &&
643
+ parser_1.t.isObjectExpression(init.arguments[1].expression)) {
644
+ if (parser_1.t.isIdentifier(node.id)) {
645
+ idSpans.add(node.id.span.start);
646
+ }
647
+ const selectorExpr = init.arguments[0].expression;
648
+ const selector = (0, parser_1.resolveThemeSelector)(selectorExpr, mergedStaticTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
649
+ if (!selector) {
650
+ throwCompilationError(`Plumeria: createTheme needs a selector it can read at build time. ` +
651
+ `Pass a string literal such as ".dark", or a name this file declares as one.`, selectorExpr);
652
+ }
653
+ if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
654
+ throwCompilationError(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`, selectorExpr);
655
+ }
656
+ const obj = (0, parser_1.objectExpressionToObject)(init.arguments[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
657
+ const hash = (0, createTheme_1.themeHashOf)(selector, obj);
658
+ if (parser_1.t.isIdentifier(node.id)) {
659
+ const uniqueKey = `${resourcePath}-${node.id.value}`;
660
+ scannedTables.createThemeHashTable[uniqueKey] = hash;
661
+ scannedTables.createThemeObjectTable[hash] = obj;
662
+ if (scannedTables.createThemeSelectorTable) {
663
+ scannedTables.createThemeSelectorTable[hash] = selector;
664
+ }
665
+ mergedCreateThemeHashTable[node.id.value] = hash;
666
+ const themeHashMap = {};
667
+ for (const [key, value] of Object.entries(obj)) {
668
+ const cssVarName = (0, zss_engine_1.camelToKebabCase)(key);
669
+ const atomicHash = (0, zss_engine_1.genBase36Hash)({ _theme: hash, [key]: value }, 1, 8);
670
+ themeHashMap[key] = `var(--${atomicHash}-${cssVarName})`;
671
+ }
672
+ localCreateStyles[node.id.value] = {
673
+ name: node.id.value,
674
+ type: 'constant',
675
+ obj,
676
+ hashMap: themeHashMap,
677
+ isExported,
678
+ initSpan: {
679
+ start: init.span.start - baseByteOffset,
680
+ end: init.span.end - baseByteOffset,
681
+ },
682
+ declSpan: {
683
+ start: declSpan.start - baseByteOffset,
684
+ end: declSpan.end - baseByteOffset,
685
+ },
686
+ };
687
+ }
688
+ }
689
+ else if (propName === 'createStatic' &&
690
+ parser_1.t.isObjectExpression(init.arguments[0].expression)) {
691
+ if (parser_1.t.isIdentifier(node.id)) {
692
+ idSpans.add(node.id.span.start);
693
+ }
694
+ const obj = (0, parser_1.objectExpressionToObject)(init.arguments[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
695
+ const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
696
+ if (parser_1.t.isIdentifier(node.id)) {
697
+ const uniqueKey = `${resourcePath}-${node.id.value}`;
698
+ scannedTables.createStaticHashTable[uniqueKey] = hash;
699
+ scannedTables.createStaticObjectTable[hash] = obj;
700
+ mergedCreateStaticHashTable[node.id.value] = hash;
701
+ localCreateStyles[node.id.value] = {
702
+ name: node.id.value,
703
+ type: 'constant',
704
+ obj,
705
+ hashMap: obj,
706
+ isExported,
707
+ initSpan: {
708
+ start: init.span.start - baseByteOffset,
709
+ end: init.span.end - baseByteOffset,
710
+ },
711
+ declSpan: {
712
+ start: declSpan.start - baseByteOffset,
713
+ end: declSpan.end - baseByteOffset,
714
+ },
715
+ };
716
+ }
717
+ }
718
+ }
719
+ };
720
+ (0, parser_1.traverse)(ast, {
721
+ ImportDeclaration({ node }) {
722
+ if (node.source.value === '@plumeria/core') {
723
+ if (node.typeOnly)
724
+ return;
725
+ const typeOnlySpecs = node.specifiers.filter((s) => s.type === 'ImportSpecifier' && s.isTypeOnly);
726
+ if (typeOnlySpecs.length > 0) {
727
+ const names = typeOnlySpecs
728
+ .map((s) => {
729
+ if (s.type !== 'ImportSpecifier')
730
+ return;
731
+ const imported = s.imported ? s.imported.value : s.local.value;
732
+ const local = s.local.value;
733
+ return imported === local ? imported : `${imported} as ${local}`;
734
+ })
735
+ .join(', ');
736
+ replacements.push({
737
+ start: node.span.start - baseByteOffset,
738
+ end: node.span.end - baseByteOffset,
739
+ content: `import type { ${names} } from '@plumeria/core'`,
740
+ });
741
+ }
742
+ else {
743
+ replacements.push({
744
+ start: node.span.start - baseByteOffset,
745
+ end: node.span.end - baseByteOffset,
746
+ content: '',
747
+ });
748
+ }
749
+ }
750
+ node.specifiers.forEach((specifier) => {
751
+ if (specifier.local) {
752
+ excludedSpans.add(specifier.local.span.start);
753
+ }
754
+ if (specifier.type === 'ImportSpecifier' && specifier.imported) {
755
+ excludedSpans.add(specifier.imported.span.start);
756
+ }
757
+ });
758
+ },
759
+ ExportDeclaration({ node }) {
760
+ if (parser_1.t.isVariableDeclaration(node.declaration)) {
761
+ processedDecls.add(node.declaration);
762
+ node.declaration.declarations.forEach((decl) => {
763
+ registerStyle(decl, node.span, true);
764
+ checkStyleAliasAssignment(decl);
765
+ });
766
+ }
767
+ },
768
+ VariableDeclaration({ node }) {
769
+ if (processedDecls.has(node))
770
+ return;
771
+ node.declarations.forEach((decl) => {
772
+ registerStyle(decl, node.span, node.declarations.length > 1 ||
773
+ (parser_1.t.isIdentifier(decl.id) && separatelyExported.has(decl.id.value)));
774
+ checkStyleAliasAssignment(decl);
775
+ });
776
+ },
777
+ CallExpression({ node }) {
778
+ const callee = node.callee;
779
+ let propName;
780
+ if (parser_1.t.isMemberExpression(callee) &&
781
+ parser_1.t.isIdentifier(callee.object) &&
782
+ parser_1.t.isIdentifier(callee.property)) {
783
+ const objectName = callee.object.value;
784
+ const propertyName = callee.property.value;
785
+ const alias = plumeriaAliases[objectName];
786
+ if (alias === 'NAMESPACE') {
787
+ propName = propertyName;
788
+ }
789
+ }
790
+ else if (parser_1.t.isIdentifier(callee)) {
791
+ const calleeName = callee.value;
792
+ const originalName = plumeriaAliases[calleeName];
793
+ if (originalName) {
794
+ propName = originalName;
795
+ }
796
+ }
797
+ if (propName) {
798
+ if (['create', 'createTheme', 'createStatic'].includes(propName) &&
799
+ !registeredStyleCalls.has(node.span.start)) {
800
+ throwCompilationError(`Plumeria: css.${propName} must be assigned to a named top-level variable. Destructuring, assignment statements, and default-exported calls cannot be compiled.`, node);
801
+ }
802
+ const args = node.arguments;
803
+ if (propName === 'keyframes' && args.length > 0) {
804
+ const expr = args[0].expression;
805
+ if (parser_1.t.isObjectExpression(expr)) {
806
+ const obj = (0, parser_1.objectExpressionToObject)(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
807
+ const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
808
+ scannedTables.keyframesObjectTable[hash] = obj;
809
+ replacements.push({
810
+ start: node.span.start - baseByteOffset,
811
+ end: node.span.end - baseByteOffset,
812
+ content: JSON.stringify(`kf-${hash}`),
813
+ });
814
+ }
815
+ }
816
+ else if (propName === 'viewTransition' &&
817
+ args.length > 0 &&
818
+ parser_1.t.isObjectExpression(args[0].expression)) {
819
+ const obj = (0, parser_1.objectExpressionToObject)(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
820
+ const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
821
+ scannedTables.viewTransitionObjectTable[hash] = obj;
822
+ replacements.push({
823
+ start: node.span.start - baseByteOffset,
824
+ end: node.span.end - baseByteOffset,
825
+ content: JSON.stringify(`vt-${hash}`),
826
+ });
827
+ }
828
+ else if (propName === 'createTheme' &&
829
+ args.length >= 2 &&
830
+ parser_1.t.isObjectExpression(args[1].expression)) {
831
+ const selectorExpr = args[0].expression;
832
+ const selector = (0, parser_1.resolveThemeSelector)(selectorExpr, mergedStaticTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
833
+ if (!selector) {
834
+ throwCompilationError(`Plumeria: createTheme needs a selector it can read at build time. ` +
835
+ `Pass a string literal such as ".dark", or a name this file declares as one.`, selectorExpr);
836
+ }
837
+ if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
838
+ throwCompilationError(`Plumeria: Unsupported at-rule: "${selector}". createTheme only supports nesting at-rules such as @media, @container, @supports, @layer, and @scope.`, selectorExpr);
839
+ }
840
+ const obj = (0, parser_1.objectExpressionToObject)(args[1].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
841
+ const hash = (0, createTheme_1.themeHashOf)(selector, obj);
842
+ scannedTables.createThemeObjectTable[hash] = obj;
843
+ if (scannedTables.createThemeSelectorTable) {
844
+ scannedTables.createThemeSelectorTable[hash] = selector;
845
+ }
846
+ }
847
+ else if (propName === 'createStatic' &&
848
+ args.length > 0 &&
849
+ parser_1.t.isObjectExpression(args[0].expression)) {
850
+ const obj = (0, parser_1.objectExpressionToObject)(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
851
+ const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
852
+ scannedTables.createStaticObjectTable[hash] = obj;
853
+ }
854
+ else if (propName === 'create' &&
855
+ args.length > 0 &&
856
+ parser_1.t.isObjectExpression(args[0].expression)) {
857
+ const obj = (0, parser_1.objectExpressionToObject)(args[0].expression, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
858
+ const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
859
+ scannedTables.createObjectTable[hash] = obj;
860
+ }
861
+ }
862
+ },
863
+ });
864
+ const jsxOpeningElementMap = new Map();
865
+ const componentParamNames = new Set();
866
+ const addFirstParamName = (fn) => {
867
+ const first = fn.params[0];
868
+ const p = unwrapPatternDefault(first?.pat ?? first);
869
+ if (parser_1.t.isIdentifier(p)) {
870
+ componentParamNames.add(p.value);
871
+ }
872
+ else if (p?.type === 'ObjectPattern') {
873
+ for (const item of p.properties) {
874
+ if (item.type === 'RestElement' && parser_1.t.isIdentifier(item.argument)) {
875
+ componentParamNames.add(item.argument.value);
876
+ }
877
+ }
878
+ }
879
+ };
880
+ for (const node of ast.body) {
881
+ const statement = unwrapExport(node);
882
+ if (isFunctionNode(statement)) {
883
+ addFirstParamName(statement);
884
+ }
885
+ else if (statement?.type === 'CallExpression') {
886
+ const fn = componentFunctionOf(statement);
887
+ if (fn)
888
+ addFirstParamName(fn);
889
+ }
890
+ else if (parser_1.t.isVariableDeclaration(statement)) {
891
+ for (const decl of statement.declarations) {
892
+ if (!parser_1.t.isIdentifier(decl.id) || !decl.init)
893
+ continue;
894
+ const fn = componentFunctionOf(decl.init);
895
+ if (fn)
896
+ addFirstParamName(fn);
897
+ }
898
+ }
899
+ }
900
+ const excludeSubtreeSpans = (n) => {
901
+ if (!n || typeof n !== 'object')
902
+ return;
903
+ if (n.span) {
904
+ excludedSpans.add(n.span.start);
905
+ }
906
+ Object.values(n).forEach((val) => excludeSubtreeSpans(val));
907
+ };
908
+ const getSource = (node) => {
909
+ const start = node.span.start - baseByteOffset;
910
+ const end = node.span.end - baseByteOffset;
911
+ return sourceBuffer.subarray(start, end).toString('utf-8');
912
+ };
913
+ const isVisibleReference = (expr) => {
914
+ if (parser_1.t.isIdentifier(expr))
915
+ return referenceIdents.references.has(expr.span.start);
916
+ if (parser_1.t.isMemberExpression(expr))
917
+ return isVisibleReference(expr.object);
918
+ if (parser_1.t.isCallExpression(expr) &&
919
+ expr.callee.type !== 'Super' &&
920
+ expr.callee.type !== 'Import')
921
+ return isVisibleReference(expr.callee);
922
+ return true;
923
+ };
924
+ const resolveStyleObject = (expr) => {
925
+ expr = (0, parser_1.unwrapExpression)(expr);
926
+ expr = resolveLocalStyleAlias(localStyleAliases, expr);
927
+ if (!isVisibleReference(expr))
928
+ return null;
929
+ if (expr.type === 'ArrayExpression') {
930
+ let merged = {};
931
+ for (const element of expr.elements ?? []) {
932
+ if (!element)
933
+ continue;
934
+ if (element.spread)
935
+ throwCompilationError(spreadStyleMessage(getSource(element.expression)), element.expression);
936
+ const style = resolveStyleObject(element.expression);
937
+ if (!style)
938
+ return null;
939
+ merged = (0, parser_1.deepMerge)(merged, style);
940
+ }
941
+ return merged;
942
+ }
943
+ if (parser_1.t.isObjectExpression(expr)) {
944
+ return (0, parser_1.objectExpressionToObject)(expr, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
945
+ }
946
+ else if (parser_1.t.isMemberExpression(expr) &&
947
+ parser_1.t.isIdentifier(expr.object) &&
948
+ (parser_1.t.isIdentifier(expr.property) || expr.property.type === 'Computed')) {
949
+ const varName = expr.object.value;
950
+ let propName;
951
+ if (expr.property.type === 'Computed') {
952
+ const keyExpr = expr.property.expression;
953
+ if (!parser_1.t.isStringLiteral(keyExpr))
954
+ return null;
955
+ propName = keyExpr.value;
956
+ }
957
+ else {
958
+ propName = expr.property.value;
959
+ }
960
+ const styleInfo = localCreateStyles[varName];
961
+ if (styleInfo?.obj[propName]) {
962
+ const style = styleInfo.obj[propName];
963
+ if (typeof style === 'object' && style !== null)
964
+ return style;
965
+ }
966
+ const hash = mergedCreateTable[varName];
967
+ if (hash) {
968
+ const obj = scannedTables.createObjectTable[hash];
969
+ if (obj?.[propName] && typeof obj[propName] === 'object')
970
+ return obj[propName];
971
+ }
972
+ }
973
+ else if (parser_1.t.isIdentifier(expr)) {
974
+ const varName = expr.value;
975
+ const uniqueKey = `${resourcePath}-${varName}`;
976
+ let hash = scannedTables.createHashTable[uniqueKey];
977
+ if (!hash)
978
+ hash = mergedCreateTable[varName];
979
+ if (hash) {
980
+ const obj = scannedTables.createObjectTable[hash];
981
+ if (obj && typeof obj === 'object')
982
+ return obj;
983
+ }
984
+ const styleInfo = localCreateStyles[varName];
985
+ if (styleInfo?.obj)
986
+ return styleInfo.obj;
987
+ }
988
+ return null;
989
+ };
990
+ const isStyleFunctionCall = (expr) => {
991
+ if (!parser_1.t.isCallExpression(expr) || !parser_1.t.isMemberExpression(expr.callee))
992
+ return false;
993
+ const callee = expr.callee;
994
+ if (!parser_1.t.isIdentifier(callee.object) || !parser_1.t.isIdentifier(callee.property))
995
+ return false;
996
+ return Boolean(localCreateStyles[callee.object.value]?.functions?.[callee.property.value] ??
997
+ createFunctionImportMap[callee.object.value]?.[callee.property.value]);
998
+ };
999
+ const carriesStyleReference = (expression) => {
1000
+ const node = (0, parser_1.unwrapExpression)(expression);
1001
+ if (node.type === 'ArrayExpression')
1002
+ return node.elements.some((element) => !!element && carriesStyleReference(element.expression));
1003
+ if (isStyleFunctionCall(node))
1004
+ return true;
1005
+ if (parser_1.t.isObjectExpression(node))
1006
+ return false;
1007
+ return resolveStyleObject(node) !== null;
1008
+ };
1009
+ const assertNoStyleArraySpread = (expression) => {
1010
+ const node = (0, parser_1.unwrapExpression)(expression);
1011
+ if (node.type !== 'ArrayExpression')
1012
+ return;
1013
+ const spread = node.elements.find((element) => element?.spread);
1014
+ if (!spread)
1015
+ return;
1016
+ if (carriesStyleReference(node))
1017
+ throwCompilationError(spreadStyleMessage(getSource(spread.expression)), spread.expression);
1018
+ };
1019
+ const resolveDynamicCall = (expr, forceRuntime = false) => {
1020
+ if (!parser_1.t.isCallExpression(expr) || !parser_1.t.isMemberExpression(expr.callee))
1021
+ return null;
1022
+ const callee = expr.callee;
1023
+ if (!parser_1.t.isIdentifier(callee.object) || !parser_1.t.isIdentifier(callee.property))
1024
+ return null;
1025
+ if (!isVisibleReference(callee.object))
1026
+ return null;
1027
+ const styleInfo = localCreateStyles[callee.object.value];
1028
+ const func = styleInfo?.functions?.[callee.property.value] ??
1029
+ createFunctionImportMap[callee.object.value]?.[callee.property.value];
1030
+ if (!func)
1031
+ return null;
1032
+ const callArgs = expr.arguments;
1033
+ if (callArgs.some((a) => a.spread))
1034
+ return null;
1035
+ const tempStaticTable = { ...mergedStaticTable };
1036
+ const providedParams = new Set();
1037
+ const runtime = [];
1038
+ const resolveObjectArg = (argExpr) => (0, parser_1.objectExpressionToObject)({
1039
+ ...argExpr,
1040
+ properties: argExpr.properties.filter((prop) => prop.type === 'Identifier' ||
1041
+ (prop.type === 'KeyValueProperty' &&
1042
+ isStaticArgValue(prop.value))),
1043
+ }, mergedStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable);
1044
+ if (func.named) {
1045
+ const argExpr = callArgs[0]?.expression;
1046
+ if (callArgs.length > 1 ||
1047
+ (argExpr && argExpr.type !== 'ObjectExpression')) {
1048
+ throwCompilationError(`Plumeria: ${getSource(expr)} takes one object argument, because ${callee.property.value} destructures its parameter.`, expr);
1049
+ }
1050
+ const given = new Map();
1051
+ (argExpr?.properties ?? []).forEach((prop) => {
1052
+ if (prop.type === 'Identifier') {
1053
+ given.set(prop.value, prop);
1054
+ }
1055
+ else if (prop.type === 'KeyValueProperty' &&
1056
+ (parser_1.t.isIdentifier(prop.key) || parser_1.t.isStringLiteral(prop.key))) {
1057
+ given.set(String(prop.key.value), prop.value);
1058
+ }
1059
+ });
1060
+ const argObj = argExpr
1061
+ ? (resolveObjectArg(argExpr) ?? {})
1062
+ : {};
1063
+ func.named.forEach(({ key, local }) => {
1064
+ const source = given.get(key);
1065
+ if (!source) {
1066
+ if (func.defaults?.[local])
1067
+ return;
1068
+ return throwCompilationError(`Plumeria: ${getSource(expr)} leaves "${key}" unset, and a dynamic style function has no value to fall back on.`, expr);
1069
+ }
1070
+ if (!forceRuntime &&
1071
+ isStaticArgValue(source) &&
1072
+ argObj[key] !== undefined) {
1073
+ tempStaticTable[local] = argObj[key];
1074
+ providedParams.add(local);
1075
+ }
1076
+ else
1077
+ runtime.push({ param: local, source });
1078
+ });
1079
+ }
1080
+ else if (callArgs.length === 1 &&
1081
+ callArgs[0].expression.type === 'ObjectExpression') {
1082
+ if (forceRuntime)
1083
+ return null;
1084
+ const argObj = resolveObjectArg(callArgs[0].expression) ?? {};
1085
+ func.params.forEach((p) => {
1086
+ if (argObj[p] !== undefined) {
1087
+ tempStaticTable[p] = argObj[p];
1088
+ providedParams.add(p);
1089
+ }
1090
+ });
1091
+ }
1092
+ else {
1093
+ callArgs.forEach((callArg, i) => {
1094
+ const p = func.params[i];
1095
+ if (!p)
1096
+ return;
1097
+ runtime.push({ param: p, source: callArg.expression });
1098
+ });
1099
+ }
1100
+ const resolved = (0, dynamicKey_1.resolveDynamicStyle)(func, runtime.map(({ param }) => param), tempStaticTable, dynamicStyleTables, providedParams);
1101
+ const { style, varGroups } = resolved;
1102
+ const vars = [];
1103
+ runtime.forEach(({ param, source }) => {
1104
+ const groups = varGroups.get(param);
1105
+ if (!groups?.length)
1106
+ return;
1107
+ const argStart = source.span.start - baseByteOffset;
1108
+ const argEnd = source.span.end - baseByteOffset;
1109
+ const argSource = sourceBuffer
1110
+ .subarray(argStart, argEnd)
1111
+ .toString('utf-8');
1112
+ const maybeNumber = Number(argSource);
1113
+ groups.forEach(({ cssVar, prop }) => {
1114
+ let valueExpr;
1115
+ const kebabProp = (0, zss_engine_1.camelToKebabCase)(prop);
1116
+ if (!isNaN(maybeNumber) && argSource.trim() === String(maybeNumber)) {
1117
+ valueExpr = JSON.stringify((0, zss_engine_1.applyCssValue)(maybeNumber, kebabProp));
1118
+ }
1119
+ else if ((argSource.startsWith('"') && argSource.endsWith('"')) ||
1120
+ (argSource.startsWith("'") && argSource.endsWith("'"))) {
1121
+ valueExpr = JSON.stringify((0, zss_engine_1.applyCssValue)(argSource.slice(1, -1), kebabProp));
1122
+ }
1123
+ else {
1124
+ valueExpr = (0, dynamicKey_1.isUnitlessProp)(prop)
1125
+ ? argSource
1126
+ : `(typeof (${argSource}) === 'number' ? (${argSource}) + 'px' : (${argSource}))`;
1127
+ }
1128
+ vars.push({ cssVar, valueExpr });
1129
+ });
1130
+ });
1131
+ return { style, vars };
1132
+ };
1133
+ const buildClassParts = (args, dynamicClassParts = [], existingClass = '', isStyleProp = false) => {
1134
+ args.forEach((arg) => {
1135
+ arg.expression = resolveLocalStyleAlias(localStyleAliases, arg.expression);
1136
+ });
1137
+ const conditionals = [];
1138
+ const dynamicVars = [];
1139
+ const propVarSpreads = [];
1140
+ let groupIdCounter = 0;
1141
+ let sourceOrder = 0;
1142
+ const baseChunks = [];
1143
+ let baseStyle = {};
1144
+ let isOptimizable = true;
1145
+ const resolveCreateObject = (varName) => {
1146
+ const localStyle = localCreateStyles[varName];
1147
+ if (localStyle?.type === 'create')
1148
+ return localStyle.obj;
1149
+ let hash = scannedTables.createHashTable[`${resourcePath}-${varName}`];
1150
+ if (!hash)
1151
+ hash = mergedCreateTable[varName];
1152
+ if (hash && scannedTables.createObjectTable[hash])
1153
+ return scannedTables.createObjectTable[hash];
1154
+ return null;
1155
+ };
1156
+ const resolveBracketGroup = (node) => {
1157
+ if (!parser_1.t.isMemberExpression(node) ||
1158
+ !parser_1.t.isIdentifier(node.object) ||
1159
+ node.property.type !== 'Computed' ||
1160
+ parser_1.t.isStringLiteral(node.property.expression)) {
1161
+ return null;
1162
+ }
1163
+ if (!isVisibleReference(node.object))
1164
+ return null;
1165
+ const varName = node.object.value;
1166
+ const obj = resolveCreateObject(varName);
1167
+ return obj ? { varName, keyExpr: node.property.expression, obj } : null;
1168
+ };
1169
+ const buildDecision = (node, prefix, off, counter, scoped) => {
1170
+ if (node.type === 'ParenthesisExpression') {
1171
+ return buildDecision(node.expression, prefix, off, counter, scoped);
1172
+ }
1173
+ if (node.type === 'ConditionalExpression') {
1174
+ const a = buildDecision(node.consequent, prefix, off, counter, scoped);
1175
+ if (!a)
1176
+ return null;
1177
+ const b = buildDecision(node.alternate, prefix, off, counter, scoped);
1178
+ if (!b)
1179
+ return null;
1180
+ return {
1181
+ keyExpr: `((${getSource(node.test)}) ? ${a.keyExpr} : ${b.keyExpr})`,
1182
+ options: [...a.options, ...b.options],
1183
+ leaves: a.leaves + b.leaves,
1184
+ hasGroup: a.hasGroup || b.hasGroup,
1185
+ };
1186
+ }
1187
+ if (node.type === 'BinaryExpression' && node.operator === '&&') {
1188
+ const right = buildDecision(node.right, prefix, off, counter, scoped);
1189
+ if (!right)
1190
+ return null;
1191
+ return {
1192
+ keyExpr: `((${getSource(node.left)}) ? ${right.keyExpr} : ${JSON.stringify(off)})`,
1193
+ options: right.options,
1194
+ leaves: right.leaves,
1195
+ hasGroup: right.hasGroup,
1196
+ };
1197
+ }
1198
+ const group = resolveBracketGroup(node);
1199
+ if (group) {
1200
+ const tag = scoped ? `${counter.n++}:` : '';
1201
+ const keySource = getSource(group.keyExpr);
1202
+ return {
1203
+ keyExpr: tag ? `(${JSON.stringify(tag)} + ${keySource})` : keySource,
1204
+ options: Object.entries(group.obj).map(([value, style]) => ({
1205
+ value: `${tag}${value}`,
1206
+ style: style,
1207
+ })),
1208
+ leaves: 1,
1209
+ hasGroup: true,
1210
+ };
1211
+ }
1212
+ const style = resolveStyleObject(node);
1213
+ if (!style)
1214
+ return null;
1215
+ const value = `${prefix}${counter.n++}`;
1216
+ return {
1217
+ keyExpr: JSON.stringify(value),
1218
+ options: [{ value, style }],
1219
+ leaves: 1,
1220
+ hasGroup: false,
1221
+ };
1222
+ };
1223
+ const collectGroupKeys = (node, acc) => {
1224
+ if (node.type === 'ParenthesisExpression') {
1225
+ collectGroupKeys(node.expression, acc);
1226
+ }
1227
+ else if (node.type === 'ConditionalExpression') {
1228
+ collectGroupKeys(node.consequent, acc);
1229
+ collectGroupKeys(node.alternate, acc);
1230
+ }
1231
+ else if (node.type === 'BinaryExpression' && node.operator === '&&') {
1232
+ collectGroupKeys(node.right, acc);
1233
+ }
1234
+ else {
1235
+ const group = resolveBracketGroup(node);
1236
+ if (group)
1237
+ Object.entries(group.obj).forEach(([key, style]) => {
1238
+ let styles = acc.get(key);
1239
+ if (!styles)
1240
+ acc.set(key, (styles = new Set()));
1241
+ styles.add(style);
1242
+ });
1243
+ }
1244
+ };
1245
+ const resolveDecision = (node) => {
1246
+ const groupKeys = new Map();
1247
+ collectGroupKeys(node, groupKeys);
1248
+ let prefix = '#';
1249
+ while ([...groupKeys.keys()].some((k) => k.startsWith(prefix)))
1250
+ prefix += '#';
1251
+ const scoped = [...groupKeys.values()].some((styles) => styles.size > 1);
1252
+ const off = !scoped && groupKeys.has('') ? `${prefix}off` : '';
1253
+ return buildDecision(node, prefix, off, { n: 0 }, scoped);
1254
+ };
1255
+ const collectConditions = (node, currentTestStrings = [], argOrder) => {
1256
+ node = (0, parser_1.unwrapExpression)(node);
1257
+ node = resolveLocalStyleAlias(localStyleAliases, node);
1258
+ if (isNoOpStyle(node))
1259
+ return true;
1260
+ if (node.type === 'ArrayExpression') {
1261
+ return node.elements.every((element) => {
1262
+ if (!element)
1263
+ return true;
1264
+ if (element.spread)
1265
+ throwCompilationError(spreadStyleMessage(getSource(element.expression)), element.expression);
1266
+ return collectConditions(element.expression, currentTestStrings, argOrder);
1267
+ });
1268
+ }
1269
+ let branchStyle = resolveStyleObject(node);
1270
+ if (!branchStyle) {
1271
+ const dynamic = resolveDynamicCall(node);
1272
+ if (dynamic) {
1273
+ if (!isStyleProp) {
1274
+ throwCompilationError(`Plumeria: css.use(${getSource(node)}) does not support dynamic function keys.`, node);
1275
+ }
1276
+ branchStyle = dynamic.style;
1277
+ dynamic.vars.forEach((v) => dynamicVars.push({
1278
+ ...v,
1279
+ test: currentTestStrings.length
1280
+ ? currentTestStrings.join(' && ')
1281
+ : undefined,
1282
+ order: argOrder,
1283
+ }));
1284
+ }
1285
+ }
1286
+ if (branchStyle) {
1287
+ const staticStyle = branchStyle;
1288
+ if (currentTestStrings.length === 0) {
1289
+ baseStyle = (0, parser_1.deepMerge)(baseStyle, staticStyle);
1290
+ baseChunks.push({ order: sourceOrder++, style: staticStyle });
1291
+ }
1292
+ else {
1293
+ conditionals.push({
1294
+ test: node,
1295
+ testString: currentTestStrings.join(' && '),
1296
+ truthy: staticStyle,
1297
+ falsy: {},
1298
+ varName: undefined,
1299
+ order: sourceOrder++,
1300
+ });
1301
+ }
1302
+ return true;
1303
+ }
1304
+ if (node.type === 'ConditionalExpression') {
1305
+ const testSource = getSource(node.test);
1306
+ if (currentTestStrings.length === 0) {
1307
+ const trueStyle = resolveStyleObject(node.consequent);
1308
+ const falseStyle = resolveStyleObject(node.alternate);
1309
+ if (trueStyle && falseStyle) {
1310
+ conditionals.push({
1311
+ test: node,
1312
+ testString: testSource,
1313
+ truthy: trueStyle,
1314
+ falsy: falseStyle,
1315
+ varName: undefined,
1316
+ order: sourceOrder++,
1317
+ });
1318
+ return true;
1319
+ }
1320
+ }
1321
+ const consequentHandled = collectConditions(node.consequent, [...currentTestStrings, `(${testSource})`], argOrder);
1322
+ const alternateHandled = collectConditions(node.alternate, [...currentTestStrings, `!(${testSource})`], argOrder);
1323
+ return consequentHandled && alternateHandled;
1324
+ }
1325
+ else if (node.type === 'BinaryExpression' && node.operator === '&&') {
1326
+ return collectConditions(node.right, [...currentTestStrings, `(${getSource(node.left)})`], argOrder);
1327
+ }
1328
+ else if (node.type === 'ParenthesisExpression') {
1329
+ return collectConditions(node.expression, currentTestStrings, argOrder);
1330
+ }
1331
+ if (pushPropPossibilities(node, currentTestStrings))
1332
+ return true;
1333
+ assertResolvable(node);
1334
+ return false;
1335
+ };
1336
+ const pushPropPossibilities = (expr, gates) => {
1337
+ const isParamMember = parser_1.t.isMemberExpression(expr) &&
1338
+ parser_1.t.isIdentifier(expr.object) &&
1339
+ componentParamNames.has(expr.object.value) &&
1340
+ parser_1.t.isIdentifier(expr.property);
1341
+ if (!parser_1.t.isIdentifier(expr) && !isParamMember)
1342
+ return false;
1343
+ const paramObject = isParamMember
1344
+ ? expr.object.value
1345
+ : undefined;
1346
+ const isPropsMember = Boolean(paramObject &&
1347
+ localCreateStyles[paramObject] === undefined &&
1348
+ mergedCreateTable[paramObject] === undefined);
1349
+ const varName = parser_1.t.isIdentifier(expr)
1350
+ ? expr.value
1351
+ : expr.property.value;
1352
+ const source = parser_1.t.isIdentifier(expr) ? varName : getSource(expr);
1353
+ const owner = ownerComponentOf(expr);
1354
+ const propName = (parser_1.t.isIdentifier(expr) && owner
1355
+ ? propAliases.get(owner)?.get(varName)
1356
+ : undefined) ?? varName;
1357
+ markStylePropApplied(propName, expr);
1358
+ let possibilities = owner
1359
+ ? scannedTables.componentPropsTable?.[`${resourcePath}-${owner}`]?.[propName]
1360
+ : undefined;
1361
+ if (!possibilities) {
1362
+ const candidates = [];
1363
+ for (const key of Object.keys(scannedTables.componentPropsTable || {})) {
1364
+ if (!key.startsWith(`${resourcePath}-`))
1365
+ continue;
1366
+ const entries = scannedTables.componentPropsTable?.[key]?.[propName];
1367
+ if (entries)
1368
+ candidates.push(...entries);
1369
+ }
1370
+ if (candidates.length > 0)
1371
+ possibilities = candidates;
1372
+ }
1373
+ const fallback = owner && propDefaults.get(owner)?.get(propName);
1374
+ if (fallback && !isNoOpStyle((0, parser_1.unwrapExpression)(fallback))) {
1375
+ const style = resolveStyleObject(fallback);
1376
+ if (!style)
1377
+ throwCompilationError(propDefaultMessage(getSource(fallback)), fallback);
1378
+ const atoms = {};
1379
+ (0, create_1.getStyleRecords)(style).forEach((record) => {
1380
+ atoms[record.key] = record.hash;
1381
+ });
1382
+ const key = (0, zss_engine_1.genBase36Hash)(Object.values(atoms).join(' '), 1, 8);
1383
+ possibilities = [...(possibilities ?? []), { key, styleObj: style }];
1384
+ const span = fallback.span;
1385
+ for (let index = replacements.length - 1; index >= 0; index--) {
1386
+ const replacement = replacements[index];
1387
+ if (replacement.start >= span.start - baseByteOffset &&
1388
+ replacement.end <= span.end - baseByteOffset)
1389
+ replacements.splice(index, 1);
1390
+ }
1391
+ excludeSubtreeSpans(fallback);
1392
+ replacements.push({
1393
+ start: span.start - baseByteOffset,
1394
+ end: span.end - baseByteOffset,
1395
+ content: JSON.stringify(key),
1396
+ });
1397
+ }
1398
+ if (!possibilities || possibilities.length === 0) {
1399
+ return Boolean(isPropsMember || (owner && declaredProps.get(owner)?.has(propName)));
1400
+ }
1401
+ const carriesVars = possibilities.some((entry) => entry.hasVars);
1402
+ if (carriesVars && !isStyleProp) {
1403
+ throwCompilationError(`Plumeria: "${varName}" carries a dynamic function key, and css.use() returns only a class name. ` +
1404
+ `Apply it to ${styleProp} on the element instead.`, expr);
1405
+ }
1406
+ const gate = gates.length ? `(${gates.join(' && ')}) && ` : '';
1407
+ if (carriesVars) {
1408
+ const spread = `...(${gate}${source} && ${source}.vars)`;
1409
+ if (!propVarSpreads.includes(spread))
1410
+ propVarSpreads.push(spread);
1411
+ }
1412
+ const token = carriesVars
1413
+ ? `((${source} && ${source}.key) || ${source})`
1414
+ : source;
1415
+ const testLHS = gates.length
1416
+ ? `((${gates.join(' && ')}) ? ${token} : "")`
1417
+ : token;
1418
+ const currentGroupId = ++groupIdCounter;
1419
+ const currentOrder = sourceOrder++;
1420
+ const seen = new Set();
1421
+ const pushOption = (valueName, style) => {
1422
+ conditionals.push({
1423
+ test: expr,
1424
+ testLHS,
1425
+ testString: `${testLHS} === ${JSON.stringify(valueName)}`,
1426
+ truthy: style,
1427
+ falsy: {},
1428
+ groupId: currentGroupId,
1429
+ order: currentOrder,
1430
+ groupName: undefined,
1431
+ valueName,
1432
+ varName,
1433
+ });
1434
+ };
1435
+ possibilities.forEach((entry) => {
1436
+ if (seen.has(entry.key))
1437
+ return;
1438
+ seen.add(entry.key);
1439
+ pushOption(entry.key, entry.styleObj);
1440
+ });
1441
+ if (gates.length)
1442
+ pushOption('', {});
1443
+ return true;
1444
+ };
1445
+ for (const arg of args) {
1446
+ const expr = arg.expression;
1447
+ if (isNoOpStyle(expr))
1448
+ continue;
1449
+ if (pushPropPossibilities(expr, []))
1450
+ continue;
1451
+ if (parser_1.t.isMemberExpression(expr) &&
1452
+ parser_1.t.isIdentifier(expr.object) &&
1453
+ expr.property.type === 'Computed') {
1454
+ const varName = expr.object.value;
1455
+ const styleObj = isVisibleReference(expr)
1456
+ ? resolveCreateObject(varName)
1457
+ : null;
1458
+ if (styleObj) {
1459
+ const dynExpr = expr.property.expression;
1460
+ const dynSource = getSource(dynExpr);
1461
+ const currentGroupId = ++groupIdCounter;
1462
+ const currentOrder = sourceOrder++;
1463
+ Object.entries(styleObj).forEach(([optionName, style]) => {
1464
+ conditionals.push({
1465
+ test: dynExpr,
1466
+ testLHS: dynSource,
1467
+ testString: `${dynSource} === '${optionName}'`,
1468
+ truthy: style,
1469
+ falsy: {},
1470
+ groupId: currentGroupId,
1471
+ order: currentOrder,
1472
+ groupName: undefined,
1473
+ valueName: optionName,
1474
+ varName,
1475
+ ownKeys: true,
1476
+ });
1477
+ });
1478
+ continue;
1479
+ }
1480
+ }
1481
+ const decision = resolveDecision(expr);
1482
+ if (decision && (decision.hasGroup || decision.leaves > 2)) {
1483
+ const groupId = ++groupIdCounter;
1484
+ const currentOrder = sourceOrder++;
1485
+ decision.options.forEach(({ value, style }) => conditionals.push({
1486
+ test: expr,
1487
+ testLHS: decision.keyExpr,
1488
+ testString: `${decision.keyExpr} === '${value}'`,
1489
+ truthy: style,
1490
+ falsy: {},
1491
+ groupId,
1492
+ order: currentOrder,
1493
+ groupName: undefined,
1494
+ valueName: value,
1495
+ varName: undefined,
1496
+ ownKeys: true,
1497
+ }));
1498
+ continue;
1499
+ }
1500
+ const handled = collectConditions(expr, [], arg.order);
1501
+ if (handled)
1502
+ continue;
1503
+ assertResolvable(expr);
1504
+ isOptimizable = false;
1505
+ break;
1506
+ }
1507
+ if (!isOptimizable ||
1508
+ (args.length === 0 && Object.keys(baseStyle).length === 0)) {
1509
+ return {
1510
+ classParts: [...dynamicClassParts],
1511
+ isOptimizable,
1512
+ baseStyle,
1513
+ dynamicVars,
1514
+ propVarSpreads,
1515
+ };
1516
+ }
1517
+ const stateSources = baseChunks.map(({ order, style }) => ({
1518
+ order,
1519
+ style: style,
1520
+ }));
1521
+ conditionals.forEach((c) => {
1522
+ const order = c.order ?? 0;
1523
+ stateSources.push({ order, style: c.truthy });
1524
+ stateSources.push({ order, style: c.falsy });
1525
+ });
1526
+ const stateWeights = (0, escalation_1.getStateWeights)(stateSources);
1527
+ const participation = {};
1528
+ const registerParticipation = (style, sourceId) => {
1529
+ Object.keys(style).forEach((key) => {
1530
+ if (!participation[key])
1531
+ participation[key] = new Set();
1532
+ participation[key].add(sourceId);
1533
+ });
1534
+ };
1535
+ registerParticipation(baseStyle, 'base');
1536
+ conditionals
1537
+ .filter((c) => c.groupId === undefined)
1538
+ .forEach((c, idx) => {
1539
+ registerParticipation(c.truthy, `std_${idx}`);
1540
+ registerParticipation(c.falsy, `std_${idx}`);
1541
+ });
1542
+ const variantGroups = {};
1543
+ conditionals.forEach((c) => {
1544
+ if (c.groupId !== undefined) {
1545
+ if (!variantGroups[c.groupId])
1546
+ variantGroups[c.groupId] = [];
1547
+ variantGroups[c.groupId].push(c);
1548
+ }
1549
+ });
1550
+ Object.entries(variantGroups).forEach(([groupId, opts]) => {
1551
+ opts.forEach((opt) => registerParticipation(opt.truthy, `var_${groupId}`));
1552
+ });
1553
+ const conflictingKeys = new Set();
1554
+ Object.entries(participation).forEach(([key, sources]) => {
1555
+ if (sources.size > 1)
1556
+ conflictingKeys.add(key);
1557
+ });
1558
+ const baseIndependent = {};
1559
+ const baseConflict = {};
1560
+ Object.entries(baseStyle).forEach(([key, val]) => {
1561
+ if (conflictingKeys.has(key))
1562
+ baseConflict[key] = val;
1563
+ else
1564
+ baseIndependent[key] = val;
1565
+ });
1566
+ const indepConditionals = [];
1567
+ const conflictConditionals = [];
1568
+ conditionals.forEach((c) => {
1569
+ const truthyIndep = {};
1570
+ const truthyConf = {};
1571
+ const falsyIndep = {};
1572
+ const falsyConf = {};
1573
+ let hasIndep = false;
1574
+ let hasConf = false;
1575
+ Object.entries(c.truthy).forEach(([k, v]) => {
1576
+ if (conflictingKeys.has(k)) {
1577
+ truthyConf[k] = v;
1578
+ hasConf = true;
1579
+ }
1580
+ else {
1581
+ truthyIndep[k] = v;
1582
+ hasIndep = true;
1583
+ }
1584
+ });
1585
+ Object.entries(c.falsy).forEach(([k, v]) => {
1586
+ if (conflictingKeys.has(k)) {
1587
+ falsyConf[k] = v;
1588
+ hasConf = true;
1589
+ }
1590
+ else {
1591
+ falsyIndep[k] = v;
1592
+ hasIndep = true;
1593
+ }
1594
+ });
1595
+ if (hasIndep)
1596
+ indepConditionals.push({
1597
+ ...c,
1598
+ truthy: truthyIndep,
1599
+ falsy: falsyIndep,
1600
+ });
1601
+ if (hasConf)
1602
+ conflictConditionals.push({
1603
+ ...c,
1604
+ truthy: truthyConf,
1605
+ falsy: falsyConf,
1606
+ });
1607
+ });
1608
+ const classParts = [];
1609
+ if (existingClass)
1610
+ classParts.push(existingClass);
1611
+ if (Object.keys(baseIndependent).length > 0) {
1612
+ const className = processStyleRecords(baseIndependent, stateWeights)
1613
+ .map((r) => r.hash)
1614
+ .join(' ');
1615
+ if (className)
1616
+ classParts.push(JSON.stringify(className));
1617
+ }
1618
+ indepConditionals
1619
+ .filter((c) => c.groupId === undefined)
1620
+ .forEach((c) => {
1621
+ const processBranch = (style) => {
1622
+ if (Object.keys(style).length === 0)
1623
+ return '""';
1624
+ return JSON.stringify(processStyleRecords(style, stateWeights)
1625
+ .map((r) => r.hash)
1626
+ .join(' '));
1627
+ };
1628
+ const testStr = c.testString ?? getSource(c.test);
1629
+ classParts.push(`(${testStr} ? ${processBranch(c.truthy)} : ${processBranch(c.falsy)})`);
1630
+ });
1631
+ const indepVarGroups = {};
1632
+ indepConditionals.forEach((c) => {
1633
+ if (c.groupId !== undefined) {
1634
+ if (!indepVarGroups[c.groupId])
1635
+ indepVarGroups[c.groupId] = [];
1636
+ indepVarGroups[c.groupId].push(c);
1637
+ }
1638
+ });
1639
+ Object.values(indepVarGroups).forEach((options) => {
1640
+ const commonTestExpr = options[0].testLHS ??
1641
+ options[0].testString ??
1642
+ getSource(options[0].test);
1643
+ const lookupMap = {};
1644
+ options.forEach((opt) => {
1645
+ if (opt.valueName !== undefined && opt.truthy) {
1646
+ const className = processStyleRecords(opt.truthy, stateWeights)
1647
+ .map((r) => r.hash)
1648
+ .join(' ');
1649
+ if (className)
1650
+ lookupMap[opt.valueName] = className;
1651
+ }
1652
+ });
1653
+ if (Object.keys(lookupMap).length > 0) {
1654
+ const entries = Object.entries(lookupMap)
1655
+ .map(([k, v]) => `${JSON.stringify(k)}:${JSON.stringify(v)}`)
1656
+ .join(',');
1657
+ classParts.push(`({${entries}}[${commonTestExpr}] || "")`);
1658
+ }
1659
+ });
1660
+ if (Object.keys(baseConflict).length > 0 ||
1661
+ conflictConditionals.length > 0) {
1662
+ const ordered = [];
1663
+ baseChunks.forEach(({ order, style }) => {
1664
+ const conflicting = {};
1665
+ Object.entries(style).forEach(([key, value]) => {
1666
+ if (conflictingKeys.has(key))
1667
+ conflicting[key] = value;
1668
+ });
1669
+ if (Object.keys(conflicting).length === 0)
1670
+ return;
1671
+ ordered.push({
1672
+ order,
1673
+ dimension: {
1674
+ type: 'const',
1675
+ options: [{ value: undefined, style: conflicting, label: 'base' }],
1676
+ },
1677
+ });
1678
+ });
1679
+ conflictConditionals
1680
+ .filter((c) => c.groupId === undefined)
1681
+ .forEach((c) => {
1682
+ ordered.push({
1683
+ order: c.order ?? 0,
1684
+ dimension: {
1685
+ type: 'std',
1686
+ testExpr: c.testString ?? getSource(c.test),
1687
+ options: [
1688
+ { value: 0, style: c.falsy, label: 'false' },
1689
+ { value: 1, style: c.truthy, label: 'true' },
1690
+ ],
1691
+ },
1692
+ });
1693
+ });
1694
+ const conflictVarGroups = {};
1695
+ conflictConditionals.forEach((c) => {
1696
+ if (c.groupId !== undefined) {
1697
+ if (!conflictVarGroups[c.groupId])
1698
+ conflictVarGroups[c.groupId] = [];
1699
+ conflictVarGroups[c.groupId].push(c);
1700
+ }
1701
+ });
1702
+ Object.keys(conflictVarGroups).forEach((id) => {
1703
+ const groupId = Number(id);
1704
+ const opts = conflictVarGroups[groupId];
1705
+ if (opts.some((c) => c.valueName === ''))
1706
+ return;
1707
+ const off = conditionals.find((c) => c.groupId === groupId && c.valueName === '');
1708
+ if (off)
1709
+ opts.push({ ...off, truthy: {}, falsy: {} });
1710
+ });
1711
+ Object.entries(conflictVarGroups).forEach(([, opts]) => {
1712
+ ordered.push({
1713
+ order: opts[0].order ?? 0,
1714
+ dimension: {
1715
+ type: 'var',
1716
+ testExpr: opts[0].testLHS ?? opts[0].testString ?? getSource(opts[0].test),
1717
+ options: opts.map((opt) => ({
1718
+ value: opt.valueName,
1719
+ style: opt.truthy,
1720
+ label: opt.valueName || 'default',
1721
+ })),
1722
+ ownKeys: opts[0].ownKeys,
1723
+ },
1724
+ });
1725
+ });
1726
+ ordered.sort((a, b) => a.order - b.order);
1727
+ const dimensions = ordered.map((o) => o.dimension);
1728
+ const joined = dimensions.filter((dim) => dim.type !== 'const').length > 1;
1729
+ dimensions.forEach((dim) => {
1730
+ if (!joined || dim.type !== 'var' || !dim.ownKeys)
1731
+ return;
1732
+ const numbers = {};
1733
+ dim.options.forEach((opt, index) => {
1734
+ numbers[String(opt.value)] = String(index);
1735
+ opt.value = String(index);
1736
+ });
1737
+ dim.testExpr = `(${JSON.stringify(numbers)}[${dim.testExpr}] || "")`;
1738
+ });
1739
+ const results = {};
1740
+ const recurse = (dimIndex, currentStyle, keyParts) => {
1741
+ if (dimIndex >= dimensions.length) {
1742
+ const className = processStyleRecords(currentStyle, stateWeights)
1743
+ .map((r) => r.hash)
1744
+ .join(' ');
1745
+ if (className)
1746
+ results[keyParts.join('__')] = className;
1747
+ return;
1748
+ }
1749
+ const dimension = dimensions[dimIndex];
1750
+ dimension.options.forEach((opt) => recurse(dimIndex + 1, (0, parser_1.deepMerge)(currentStyle, opt.style), dimension.type === 'const'
1751
+ ? keyParts
1752
+ : [...keyParts, String(opt.value)]));
1753
+ };
1754
+ recurse(0, {}, []);
1755
+ const baseConflictClass = Object.keys(baseConflict).length > 0
1756
+ ? processStyleRecords(baseConflict, stateWeights)
1757
+ .map((r) => r.hash)
1758
+ .join(' ')
1759
+ : '';
1760
+ const masterKeyExpr = dimensions
1761
+ .filter((dim) => dim.type !== 'const')
1762
+ .map((dim) => dim.type === 'std'
1763
+ ? `(${dim.testExpr} ? "1" : "0")`
1764
+ : dim.testExpr || '""')
1765
+ .join(' + "__" + ');
1766
+ classParts.push(`(${JSON.stringify(results)}[${masterKeyExpr || '""'}] || ${baseConflictClass ? JSON.stringify(baseConflictClass) : '""'})`);
1767
+ }
1768
+ classParts.push(...dynamicClassParts);
1769
+ return {
1770
+ classParts,
1771
+ isOptimizable,
1772
+ baseStyle,
1773
+ dynamicVars,
1774
+ propVarSpreads,
1775
+ };
1776
+ };
1777
+ (0, parser_1.traverse)(ast, {
1778
+ JSXOpeningElement({ node }) {
1779
+ jsxOpeningElementMap.set(node.span.start, {
1780
+ compKey: (0, parser_1.resolveComponentKey)(node.name, resourcePath, localImports),
1781
+ attributes: node.attributes,
1782
+ });
1783
+ },
1784
+ MemberExpression({ node }) {
1785
+ if (!isVisibleReference(node))
1786
+ return;
1787
+ if (parser_1.t.isIdentifier(node.object) &&
1788
+ (parser_1.t.isIdentifier(node.property) || node.property.type === 'Computed')) {
1789
+ const varName = node.object.value;
1790
+ const uniqueKey = `${resourcePath}-${varName}`;
1791
+ if (node.property.type === 'Computed') {
1792
+ const dynExpr = node.property.expression;
1793
+ const dynSource = getSource(dynExpr);
1794
+ const localStyle = localCreateStyles[varName];
1795
+ let hashMap;
1796
+ if (localStyle) {
1797
+ hashMap = localStyle.hashMap;
1798
+ }
1799
+ else {
1800
+ let hash = scannedTables.createHashTable[uniqueKey];
1801
+ if (!hash) {
1802
+ hash = mergedCreateTable[varName];
1803
+ }
1804
+ if (hash) {
1805
+ const obj = scannedTables.createObjectTable[hash];
1806
+ const atomicMap = scannedTables.createAtomicMapTable[hash];
1807
+ if (obj && atomicMap) {
1808
+ hashMap = {};
1809
+ Object.keys(obj).forEach((key) => {
1810
+ if (atomicMap[key]) {
1811
+ hashMap[key] = atomicMap[key];
1812
+ }
1813
+ });
1814
+ }
1815
+ }
1816
+ }
1817
+ if (hashMap) {
1818
+ replacements.push({
1819
+ start: node.span.start - baseByteOffset,
1820
+ end: node.span.end - baseByteOffset,
1821
+ content: `((${JSON.stringify(hashMap)})[${dynSource}] || {})`,
1822
+ });
1823
+ }
1824
+ return;
1825
+ }
1826
+ const propName = node.property.value;
1827
+ const localStyle = localCreateStyles[varName];
1828
+ if (localStyle && localStyle.type === 'create') {
1829
+ const atomMap = localStyle.hashMap[propName];
1830
+ if (atomMap) {
1831
+ replacements.push({
1832
+ start: node.span.start - baseByteOffset,
1833
+ end: node.span.end - baseByteOffset,
1834
+ content: `(${JSON.stringify(atomMap)})`,
1835
+ });
1836
+ return;
1837
+ }
1838
+ }
1839
+ let hash = scannedTables.createHashTable[uniqueKey];
1840
+ if (!hash) {
1841
+ hash = mergedCreateTable[varName];
1842
+ }
1843
+ if (hash) {
1844
+ let atomMap;
1845
+ if (scannedTables.createAtomicMapTable[hash]) {
1846
+ atomMap = scannedTables.createAtomicMapTable[hash][propName];
1847
+ }
1848
+ if (atomMap) {
1849
+ replacements.push({
1850
+ start: node.span.start - baseByteOffset,
1851
+ end: node.span.end - baseByteOffset,
1852
+ content: `(${JSON.stringify(atomMap)})`,
1853
+ });
1854
+ }
1855
+ }
1856
+ let themeHash = mergedCreateThemeHashTable[varName];
1857
+ if (!themeHash) {
1858
+ themeHash = scannedTables.createThemeHashTable[uniqueKey];
1859
+ }
1860
+ if (themeHash) {
1861
+ const atomicMap = scannedTables.createAtomicMapTable[themeHash];
1862
+ if (atomicMap && atomicMap[propName]) {
1863
+ replacements.push({
1864
+ start: node.span.start - baseByteOffset,
1865
+ end: node.span.end - baseByteOffset,
1866
+ content: `(${JSON.stringify(atomicMap[propName])})`,
1867
+ });
1868
+ }
1869
+ else {
1870
+ const cssVarName = (0, zss_engine_1.camelToKebabCase)(propName);
1871
+ replacements.push({
1872
+ start: node.span.start - baseByteOffset,
1873
+ end: node.span.end - baseByteOffset,
1874
+ content: `(${JSON.stringify(`var(--${themeHash}-${cssVarName})`)})`,
1875
+ });
1876
+ }
1877
+ }
1878
+ let staticHash = mergedCreateStaticHashTable[varName];
1879
+ if (!staticHash) {
1880
+ staticHash = scannedTables.createStaticHashTable[uniqueKey];
1881
+ }
1882
+ if (staticHash) {
1883
+ const staticObj = scannedTables.createStaticObjectTable[staticHash];
1884
+ if (staticObj && staticObj[propName] !== undefined) {
1885
+ replacements.push({
1886
+ start: node.span.start - baseByteOffset,
1887
+ end: node.span.end - baseByteOffset,
1888
+ content: `(${JSON.stringify(staticObj[propName])})`,
1889
+ });
1890
+ }
1891
+ }
1892
+ }
1893
+ },
1894
+ Identifier({ node }) {
1895
+ if (excludedSpans.has(node.span.start))
1896
+ return;
1897
+ if (idSpans.has(node.span.start))
1898
+ return;
1899
+ if (!referenceIdents.references.has(node.span.start))
1900
+ return;
1901
+ const prefix = referenceIdents.shorthands.has(node.span.start)
1902
+ ? `${node.value}: `
1903
+ : '';
1904
+ const pushReplacement = (content) => {
1905
+ replacements.push({
1906
+ start: node.span.start - baseByteOffset,
1907
+ end: node.span.end - baseByteOffset,
1908
+ content: `${prefix}${content}`,
1909
+ });
1910
+ };
1911
+ const styleInfo = localCreateStyles[node.value];
1912
+ if (styleInfo) {
1913
+ pushReplacement(`(${JSON.stringify(styleInfo.hashMap)})`);
1914
+ return;
1915
+ }
1916
+ const varName = node.value;
1917
+ const uniqueKey = `${resourcePath}-${varName}`;
1918
+ let hash = mergedCreateTable[varName];
1919
+ if (!hash) {
1920
+ hash = scannedTables.createHashTable[uniqueKey];
1921
+ }
1922
+ if (hash) {
1923
+ const obj = scannedTables.createObjectTable[hash];
1924
+ const atomicMap = scannedTables.createAtomicMapTable[hash];
1925
+ if (obj && atomicMap) {
1926
+ const hashMap = {};
1927
+ Object.keys(obj).forEach((key) => {
1928
+ if (atomicMap[key]) {
1929
+ hashMap[key] = atomicMap[key];
1930
+ }
1931
+ });
1932
+ pushReplacement(`(${JSON.stringify(hashMap)})`);
1933
+ }
1934
+ }
1935
+ let themeHash = mergedCreateThemeHashTable[varName];
1936
+ if (!themeHash) {
1937
+ themeHash = scannedTables.createThemeHashTable[uniqueKey];
1938
+ }
1939
+ if (themeHash) {
1940
+ const atomicMap = scannedTables.createAtomicMapTable[themeHash];
1941
+ if (atomicMap) {
1942
+ pushReplacement(`(${JSON.stringify(atomicMap)})`);
1943
+ return;
1944
+ }
1945
+ }
1946
+ let staticHash = mergedCreateStaticHashTable[varName];
1947
+ if (!staticHash) {
1948
+ staticHash = scannedTables.createStaticHashTable[uniqueKey];
1949
+ }
1950
+ if (staticHash) {
1951
+ const staticObj = scannedTables.createStaticObjectTable[staticHash];
1952
+ if (staticObj) {
1953
+ pushReplacement(`(${JSON.stringify(staticObj)})`);
1954
+ }
1955
+ }
1956
+ },
1957
+ JSXAttribute({ node }) {
1958
+ if (node.name.type !== 'Identifier')
1959
+ return;
1960
+ const attrName = node.name.value;
1961
+ if (attrName !== styleProp) {
1962
+ let compKey = null;
1963
+ for (const [, val] of jsxOpeningElementMap) {
1964
+ const found = val.attributes
1965
+ .filter((a) => a.type === 'JSXAttribute')
1966
+ .find((a) => a.span.start === node.span.start);
1967
+ if (found) {
1968
+ compKey = val.compKey;
1969
+ break;
1970
+ }
1971
+ }
1972
+ if (compKey) {
1973
+ if (node.value?.type === 'JSXExpressionContainer')
1974
+ assertNoStyleArraySpread(node.value.expression);
1975
+ const list = scannedTables.componentPropsTable?.[compKey]?.[attrName];
1976
+ if (list &&
1977
+ node.value &&
1978
+ node.value.type === 'JSXExpressionContainer') {
1979
+ const expr = node.value.expression;
1980
+ const carrierFor = (subNode, calls) => {
1981
+ const vars = [];
1982
+ let unresolved = false;
1983
+ for (const expression of calls ?? [subNode])
1984
+ (0, parser_1.traverse)(expression, {
1985
+ CallExpression({ node: call }) {
1986
+ if (!isStyleFunctionCall(call))
1987
+ return;
1988
+ const resolved = resolveDynamicCall(call, true);
1989
+ if (!resolved) {
1990
+ unresolved = true;
1991
+ return;
1992
+ }
1993
+ vars.push(...resolved.vars);
1994
+ },
1995
+ });
1996
+ if (unresolved)
1997
+ return null;
1998
+ return `{ ${foldDynamicVars(vars).join(', ')} }`;
1999
+ };
2000
+ const replaceWithKey = (subNode) => {
2001
+ const entries = list.filter((entry) => entry.spanStart === subNode.span.start &&
2002
+ entry.filePath === resourcePath);
2003
+ if (!entries.length)
2004
+ return false;
2005
+ let content = '""';
2006
+ for (const entry of [...entries].reverse()) {
2007
+ let value = JSON.stringify(entry.key);
2008
+ if (entry.hasVars) {
2009
+ const carrier = carrierFor(subNode, entry.dynamicCalls);
2010
+ if (!carrier)
2011
+ return false;
2012
+ value = `{ key: ${value}, vars: ${carrier} }`;
2013
+ }
2014
+ const condition = entry.conditions
2015
+ ?.map(({ test, truthy }) => `${truthy ? '' : '!'}(${getSource(test)})`)
2016
+ .join(' && ');
2017
+ content = condition
2018
+ ? `((${condition}) ? ${value} : ${content})`
2019
+ : value;
2020
+ processStyleRecords(entry.styleObj);
2021
+ }
2022
+ replacements.push({
2023
+ start: subNode.span.start - baseByteOffset,
2024
+ end: subNode.span.end - baseByteOffset,
2025
+ content,
2026
+ });
2027
+ return true;
2028
+ };
2029
+ (0, parser_1.traverse)(expr, {
2030
+ MemberExpression({ node: subNode }) {
2031
+ if (replaceWithKey(subNode)) {
2032
+ excludeSubtreeSpans(subNode);
2033
+ }
2034
+ },
2035
+ ArrayExpression({ node: subNode }) {
2036
+ if (replaceWithKey(subNode)) {
2037
+ excludeSubtreeSpans(subNode);
2038
+ }
2039
+ },
2040
+ CallExpression({ node: subNode }) {
2041
+ if (replaceWithKey(subNode)) {
2042
+ excludeSubtreeSpans(subNode);
2043
+ }
2044
+ },
2045
+ });
2046
+ }
2047
+ }
2048
+ return;
2049
+ }
2050
+ if (!node.value || node.value.type !== 'JSXExpressionContainer')
2051
+ return;
2052
+ const expr = node.value.expression;
2053
+ const args = expr.type === 'ArrayExpression'
2054
+ ? expr.elements
2055
+ .filter((el) => el != null)
2056
+ .map((el) => {
2057
+ if (el.spread)
2058
+ throwCompilationError(spreadStyleMessage(getSource(el.expression)), el.expression);
2059
+ return { expression: el.expression };
2060
+ })
2061
+ : [{ expression: expr }];
2062
+ const dynamicClassParts = [];
2063
+ const existingStyleParts = [];
2064
+ let attributes = [];
2065
+ for (const [, val] of jsxOpeningElementMap) {
2066
+ const found = val.attributes
2067
+ .filter((a) => a.type === 'JSXAttribute')
2068
+ .find((a) => a.span.start === node.span.start);
2069
+ if (found) {
2070
+ attributes = val.attributes;
2071
+ break;
2072
+ }
2073
+ }
2074
+ const classNameAttr = attributes.find((attr) => attr.type === 'JSXAttribute' &&
2075
+ attr.name.type === 'Identifier' &&
2076
+ attr.name.value === 'className');
2077
+ let existingClassExpr = '';
2078
+ if (classNameAttr) {
2079
+ replacements.push({
2080
+ start: classNameAttr.span.start - baseByteOffset,
2081
+ end: classNameAttr.span.end - baseByteOffset,
2082
+ content: '',
2083
+ });
2084
+ if (classNameAttr.value?.type === 'StringLiteral') {
2085
+ existingClassExpr = JSON.stringify(classNameAttr.value.value);
2086
+ }
2087
+ else if (classNameAttr.value?.type === 'JSXExpressionContainer') {
2088
+ existingClassExpr = `(${deferSource(classNameAttr.value.expression)})`;
2089
+ }
2090
+ }
2091
+ const styleAttrExisting = attributes.find((attr) => attr.type === 'JSXAttribute' &&
2092
+ attr.name.type === 'Identifier' &&
2093
+ attr.name.value === 'style');
2094
+ let existingStyleExpr = '';
2095
+ if (styleAttrExisting) {
2096
+ replacements.push({
2097
+ start: styleAttrExisting.span.start - baseByteOffset,
2098
+ end: styleAttrExisting.span.end - baseByteOffset,
2099
+ content: '',
2100
+ });
2101
+ if (styleAttrExisting.value?.type === 'JSXExpressionContainer') {
2102
+ const innerExpr = styleAttrExisting.value?.expression;
2103
+ if (innerExpr.type === 'ObjectExpression') {
2104
+ for (const property of innerExpr.properties) {
2105
+ const token = deferProperty(property);
2106
+ if (token)
2107
+ existingStyleParts.push(token);
2108
+ }
2109
+ }
2110
+ else {
2111
+ existingStyleExpr = `...(${deferSource(innerExpr)})`;
2112
+ }
2113
+ }
2114
+ }
2115
+ const { classParts, isOptimizable, baseStyle, dynamicVars, propVarSpreads, } = buildClassParts(args, dynamicClassParts, existingClassExpr, true);
2116
+ if (!isOptimizable) {
2117
+ throwCompilationError(`Plumeria: Dynamic or unresolvable style object "${getSource(expr)}" is not supported.`, expr);
2118
+ }
2119
+ const styleParts = [
2120
+ ...existingStyleParts,
2121
+ ...foldDynamicVars(dynamicVars),
2122
+ ...propVarSpreads,
2123
+ ];
2124
+ const styleAttr = styleParts.length > 0 || existingStyleExpr
2125
+ ? ` style={{ ${[existingStyleExpr, ...styleParts].filter(Boolean).join(', ')} }}`
2126
+ : '';
2127
+ if (isOptimizable &&
2128
+ (args.length > 0 ||
2129
+ Object.keys(baseStyle).length > 0 ||
2130
+ dynamicClassParts.length > 0)) {
2131
+ const replacement = classParts.length > 0 ? classParts.join(' + " " + ') : '""';
2132
+ replacements.push({
2133
+ start: node.span.start - baseByteOffset,
2134
+ end: node.span.end - baseByteOffset,
2135
+ content: `className={${replacement}}${styleAttr}`,
2136
+ });
2137
+ }
2138
+ else {
2139
+ const keptClass = existingClassExpr
2140
+ ? `className={${existingClassExpr}}`
2141
+ : '';
2142
+ replacements.push({
2143
+ start: node.span.start - baseByteOffset,
2144
+ end: node.span.end - baseByteOffset,
2145
+ content: `${keptClass}${styleAttr}`,
2146
+ });
2147
+ }
2148
+ },
2149
+ CallExpression({ node }) {
2150
+ const callee = node.callee;
2151
+ let isUseCall = false;
2152
+ if (parser_1.t.isMemberExpression(callee) &&
2153
+ parser_1.t.isIdentifier(callee.object) &&
2154
+ parser_1.t.isIdentifier(callee.property)) {
2155
+ const objectName = callee.object.value;
2156
+ const propertyName = callee.property.value;
2157
+ if (localCreateStyles[objectName]?.functions?.[propertyName] ||
2158
+ createFunctionImportMap[objectName]?.[propertyName]) {
2159
+ dynamicFnCalls.push(node);
2160
+ }
2161
+ const alias = plumeriaAliases[objectName];
2162
+ if (alias === 'NAMESPACE' && propertyName === 'use') {
2163
+ isUseCall = true;
2164
+ }
2165
+ }
2166
+ else if (parser_1.t.isIdentifier(callee)) {
2167
+ const calleeName = callee.value;
2168
+ const originalName = plumeriaAliases[calleeName];
2169
+ if (originalName === 'use') {
2170
+ isUseCall = true;
2171
+ }
2172
+ }
2173
+ if (!isUseCall)
2174
+ return;
2175
+ const args = node.arguments;
2176
+ for (const arg of args) {
2177
+ const expr = arg.expression;
2178
+ if (!parser_1.t.isCallExpression(expr) || !parser_1.t.isMemberExpression(expr.callee))
2179
+ continue;
2180
+ const callee = expr.callee;
2181
+ if (!parser_1.t.isIdentifier(callee.object) || !parser_1.t.isIdentifier(callee.property))
2182
+ continue;
2183
+ const varName = callee.object.value;
2184
+ const propKey = callee.property.value;
2185
+ const styleInfo = localCreateStyles[varName];
2186
+ if (styleInfo?.functions?.[propKey]) {
2187
+ throwCompilationError(`Plumeria: css.use(${getSource(expr)}) does not support dynamic function keys.`, expr);
2188
+ }
2189
+ }
2190
+ const { classParts, isOptimizable } = buildClassParts(args);
2191
+ if (isOptimizable) {
2192
+ const replacement = classParts.length > 0 ? classParts.join(' + " " + ') : '""';
2193
+ replacements.push({
2194
+ start: node.span.start - baseByteOffset,
2195
+ end: node.span.end - baseByteOffset,
2196
+ content: replacement,
2197
+ });
2198
+ }
2199
+ else {
2200
+ throwCompilationError(`Plumeria: Dynamic or unresolvable style object "${getSource(node)}" is not supported.`, node);
2201
+ }
2202
+ },
2203
+ });
2204
+ for (const { name, node } of components) {
2205
+ const props = scannedTables.componentPropsTable?.[`${resourcePath}-${name}`];
2206
+ for (const propName of Object.keys(props ?? {})) {
2207
+ if (appliedStyleProps.has(`${name}:${propName}`)) {
2208
+ continue;
2209
+ }
2210
+ throwCompilationError(`Plumeria: "${propName}" is a style received through a prop but is never applied ` +
2211
+ `to ${styleProp} or css.use() here. Apply it on an element this component renders; ` +
2212
+ `a style prop cannot be passed on to another component.`, node);
2213
+ }
2214
+ }
2215
+ const buildExportedInit = (info) => {
2216
+ const keys = Object.keys(info.obj);
2217
+ if (!isDev || keys.length === 0) {
2218
+ return JSON.stringify('');
2219
+ }
2220
+ const head = JSON.stringify(`Plumeria: "${info.name}.`);
2221
+ const tail = JSON.stringify(`" was read at runtime. The file that read it was not compiled ` +
2222
+ `because it does not reference "@plumeria/core" — add ` +
2223
+ `import '@plumeria/core'; to it (see the stack below). Defined in ` +
2224
+ `${path.relative(root, baseId)}.`);
2225
+ return (`(()=>{const k=new Set(${JSON.stringify(keys)});` +
2226
+ `return new Proxy({},{get(t,p){` +
2227
+ `if(typeof p==="string"&&k.has(p))throw new Error(${head}+p+${tail});` +
2228
+ `return t[p];}});})()`);
2229
+ };
2230
+ Object.values(localCreateStyles).forEach((info) => {
2231
+ if (info.isExported) {
2232
+ replacements.push({
2233
+ start: info.initSpan.start,
2234
+ end: info.initSpan.end,
2235
+ content: buildExportedInit(info),
2236
+ });
2237
+ }
2238
+ else {
2239
+ replacements.push({
2240
+ start: info.declSpan.start,
2241
+ end: info.declSpan.end,
2242
+ content: '',
2243
+ });
2244
+ }
2245
+ });
2246
+ dynamicFnCalls.forEach((call) => {
2247
+ const start = call.span.start - baseByteOffset;
2248
+ const end = call.span.end - baseByteOffset;
2249
+ const isResolved = replacements.some((r) => r.start <= start && r.end >= end);
2250
+ if (!isResolved) {
2251
+ throwCompilationError(`Plumeria: ${getSource(call)} is only supported in the ${styleProp} prop. ` +
2252
+ `A dynamic style function resolves to a class name and a CSS variable on the element itself, ` +
2253
+ `so it cannot be passed through another prop or read as a value.`, call);
2254
+ }
2255
+ });
2256
+ for (const deferred of deferredSources) {
2257
+ let cursor = deferred.start;
2258
+ const pieces = [];
2259
+ for (const replacement of [...replacements].sort((a, b) => a.start - b.start || b.end - a.end)) {
2260
+ if (replacement.start < cursor || replacement.end > deferred.end)
2261
+ continue;
2262
+ pieces.push(sourceBuffer.subarray(cursor, replacement.start).toString('utf-8'), replacement.content);
2263
+ cursor = replacement.end;
2264
+ }
2265
+ pieces.push(sourceBuffer.subarray(cursor, deferred.end).toString('utf-8'));
2266
+ const content = pieces.join('');
2267
+ for (const replacement of replacements)
2268
+ replacement.content = replacement.content.replaceAll(deferred.token, content);
2269
+ }
2270
+ const buffer = Buffer.from(source);
2271
+ let offset = 0;
2272
+ const parts = [];
2273
+ replacements
2274
+ .sort((a, b) => a.start - b.start || b.end - a.end)
2275
+ .forEach((r) => {
2276
+ if (r.start < offset)
2277
+ return;
2278
+ parts.push(buffer.subarray(offset, r.start));
2279
+ parts.push(Buffer.from(r.content));
2280
+ offset = r.end;
2281
+ });
2282
+ parts.push(buffer.subarray(offset));
2283
+ const transformedSource = Buffer.concat(parts).toString();
2284
+ return { code: transformedSource, sheets: extractedSheets };
2285
+ };
2286
+ exports.transformSource = transformSource;