@fluixi/compiler 1.0.0-alpha.94 → 1.0.0-alpha.96

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.
Files changed (60) hide show
  1. package/LICENSE +1 -1
  2. package/dist/analyze/static-graph.cjs +1 -1
  3. package/dist/analyze/static-graph.mjs +1 -1
  4. package/dist/{babel-RJFQVFJW.mjs → babel-YG5PQAMX.mjs} +4 -4
  5. package/dist/{chunk-ZR2QHTEX.mjs → chunk-JHBI26FW.mjs} +6 -4
  6. package/dist/{chunk-DP2QDWWH.mjs → chunk-JJ4ZAZKY.mjs} +1 -1
  7. package/dist/{chunk-HCCBEJEZ.mjs → chunk-L6WBOEIO.mjs} +1 -1
  8. package/dist/{chunk-HIZU7WI2.mjs → chunk-UVH2BMMY.mjs} +1 -1
  9. package/dist/chunk-VX2OBUMB.mjs +92 -0
  10. package/dist/{chunk-E2RWTIYE.mjs → chunk-X735CULF.mjs} +4 -89
  11. package/dist/chunk-ZPEHDBCH.mjs +584 -0
  12. package/dist/codegen/backends/imperative.cjs +4 -2
  13. package/dist/codegen/backends/imperative.d.ts.map +1 -1
  14. package/dist/codegen/backends/imperative.js +9 -2
  15. package/dist/codegen/backends/imperative.mjs +4 -2
  16. package/dist/frontend/babel/build-ir-lit.cjs +4 -2
  17. package/dist/frontend/babel/build-ir-lit.mjs +4 -2
  18. package/dist/frontend/babel/build-ir.cjs +4 -2
  19. package/dist/frontend/babel/build-ir.mjs +4 -2
  20. package/dist/frontend/babel/index.cjs +5 -3
  21. package/dist/frontend/babel/index.mjs +5 -3
  22. package/dist/frontend/babel/lower-template.cjs +4 -2
  23. package/dist/frontend/babel/lower-template.mjs +4 -2
  24. package/dist/frontend/babel/plugin.cjs +4 -2
  25. package/dist/frontend/babel/plugin.mjs +4 -2
  26. package/dist/index.cjs +5 -3
  27. package/dist/index.mjs +5 -3
  28. package/dist/integrations.cjs +3330 -3269
  29. package/dist/integrations.d.ts.map +1 -1
  30. package/dist/integrations.js +19 -8
  31. package/dist/integrations.mjs +85 -40
  32. package/dist/lower/compile-template.cjs +5 -3
  33. package/dist/lower/compile-template.mjs +5 -3
  34. package/dist/lower/jsx.cjs +4 -2
  35. package/dist/lower/jsx.mjs +4 -2
  36. package/dist/lower/template.cjs +4 -2
  37. package/dist/lower/template.mjs +4 -2
  38. package/dist/resolve/builtins.cjs +1 -1
  39. package/dist/resolve/builtins.mjs +1 -1
  40. package/dist/{server-fns-JLSTKWPS.mjs → server-fns-PZEOON2D.mjs} +5 -4
  41. package/dist/{server-functions-BGY3RD4R.mjs → server-functions-JNSQMA63.mjs} +3 -3
  42. package/dist/transform/index.cjs +35 -16
  43. package/dist/transform/index.mjs +35 -16
  44. package/dist/transform/styles.cjs +31 -13
  45. package/dist/transform/styles.d.cts +27 -1
  46. package/dist/transform/styles.d.ts +27 -1
  47. package/dist/transform/styles.d.ts.map +1 -1
  48. package/dist/transform/styles.js +45 -16
  49. package/dist/transform/styles.mjs +31 -13
  50. package/dist/transform/templates.cjs +34 -15
  51. package/dist/transform/templates.mjs +34 -15
  52. package/dist/{transform-GBP6Y4UI.mjs → transform-UODP37VJ.mjs} +12 -563
  53. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  54. package/dist/vite-styles.cjs +66 -23
  55. package/dist/vite-styles.d.cts +16 -7
  56. package/dist/vite-styles.d.ts +16 -7
  57. package/dist/vite-styles.d.ts.map +1 -1
  58. package/dist/vite-styles.js +68 -25
  59. package/dist/vite-styles.mjs +78 -23
  60. package/package.json +4 -4
@@ -1,4 +1,9 @@
1
- /*! @fluixi/compiler v1.0.0-alpha.94 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/compiler v1.0.0-alpha.96 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
+ import {
3
+ applyTemplateStyles,
4
+ collectStyles,
5
+ finishShadowStyles
6
+ } from "./chunk-ZPEHDBCH.mjs";
2
7
  import {
3
8
  analyzeStatic,
4
9
  buildJsxIR,
@@ -14,7 +19,7 @@ import {
14
19
  resolveComponentSources,
15
20
  resolveReactiveBindings,
16
21
  shapeOf
17
- } from "./chunk-ZR2QHTEX.mjs";
22
+ } from "./chunk-JHBI26FW.mjs";
18
23
  import {
19
24
  CORE_CONTROL_FLOW,
20
25
  DOM_CONTROL_FLOW,
@@ -24,572 +29,16 @@ import {
24
29
  isIntrinsicName,
25
30
  mayHaveIntrinsic,
26
31
  tagIntrinsics
27
- } from "./chunk-HCCBEJEZ.mjs";
32
+ } from "./chunk-L6WBOEIO.mjs";
28
33
  import {
29
- MagicString,
30
- encode
31
- } from "./chunk-E2RWTIYE.mjs";
32
- import "./chunk-HIZU7WI2.mjs";
34
+ MagicString
35
+ } from "./chunk-X735CULF.mjs";
36
+ import "./chunk-VX2OBUMB.mjs";
37
+ import "./chunk-UVH2BMMY.mjs";
33
38
 
34
39
  // src/transform/templates.ts
35
40
  import { parse as parse2 } from "@babel/parser";
36
41
 
37
- // src/transform/styles.ts
38
- var SCOPE_ATTR = "data-fx-s";
39
- var FUNCTIONS = /* @__PURE__ */ new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression", "ObjectMethod", "ClassMethod"]);
40
- function collectStyles(program, sourceName, options, tags = { html: /* @__PURE__ */ new Map([["html", "html"]]) }, module) {
41
- const plan = {
42
- scopes: [],
43
- templateOwners: /* @__PURE__ */ new Map(),
44
- drop: /* @__PURE__ */ new Set(),
45
- styles: [],
46
- diagnostics: [],
47
- edits: [],
48
- literals: [],
49
- references: [],
50
- shadowClasses: /* @__PURE__ */ new Map()
51
- };
52
- if (!options) return plan;
53
- const literalsOf = findLiterals(program, options.cssModules ?? ["@fluixi/core", "@fluixi/dom"], plan, tags.css ?? []);
54
- plan.names = literalsOf;
55
- const classOf = /* @__PURE__ */ new Map();
56
- const shadowOf = (owner) => {
57
- const cls = classOf.get(owner);
58
- return cls ? plan.shadowClasses.get(cls) : void 0;
59
- };
60
- const resolved = /* @__PURE__ */ new Map();
61
- const piecesToNodes = (quasis, expressions, at, stack) => {
62
- const out = [];
63
- for (let i = 0; i < quasis.length; i++) {
64
- const text = quasis[i].value.cooked ?? quasis[i].value.raw;
65
- if (text.trim()) {
66
- try {
67
- const start = quasis[i].loc?.start;
68
- out.push(...options.process(text, sourceName).map((n) => start ? shiftLoc(n, sourceName, start) : n));
69
- } catch (error) {
70
- plan.diagnostics.push({ ...at, message: `CSS could not be processed: ${error.message}` });
71
- return null;
72
- }
73
- }
74
- const expr = expressions[i];
75
- if (!expr) continue;
76
- const value = expr.type === "Identifier" ? resolveLiteral(expr.name, at, stack) : void 0;
77
- if (value === void 0) {
78
- plan.diagnostics.push({
79
- ...at,
80
- message: "Only css`` values can be interpolated into styles, and only by name: ${base}. Dynamic values go through custom properties (style:--x={...} and var(--x))."
81
- });
82
- return null;
83
- }
84
- if (value === null) return null;
85
- out.push(...value);
86
- }
87
- return out;
88
- };
89
- function resolveLiteral(name, at, stack) {
90
- const imported = literalsOf.imports.get(name);
91
- if (imported) {
92
- const nodes = options?.imported?.get(`${imported.source}#${imported.name}`);
93
- if (nodes) return nodes.map(dropLoc);
94
- plan.references.push({ name: imported.name, source: imported.source, ...at });
95
- plan.diagnostics.push({
96
- ...at,
97
- message: options?.imported ? `${name} from ${imported.source} is not a css\`\` value the build could find.` : `${name} comes from ${imported.source}: style values from another module are resolved by the build.`
98
- });
99
- return null;
100
- }
101
- const literal = literalsOf.literals.get(name);
102
- if (!literal) return void 0;
103
- if (stack.includes(name)) {
104
- plan.diagnostics.push({ ...at, message: `css\`\` values include each other: ${[...stack, name].join(" → ")}.` });
105
- return null;
106
- }
107
- if (!resolved.has(name)) {
108
- resolved.set(name, piecesToNodes(literal.quasi.quasis, literal.quasi.expressions, at, [...stack, name]));
109
- }
110
- return resolved.get(name);
111
- }
112
- for (const [name, literal] of literalsOf.literals) {
113
- const at = { line: literal.loc?.start.line ?? 0, column: literal.loc?.start.column ?? 0 };
114
- const nodes = resolveLiteral(name, at, []);
115
- const id = hash(`${sourceName}:css:${name}`);
116
- plan.edits.push({ start: literal.start, end: literal.end, code: `({ $fxStyle: ${JSON.stringify(id)} })` });
117
- if (nodes) plan.literals.push({ id, name, css: printStyle(nodes, options.minify) });
118
- }
119
- const scopeOf = /* @__PURE__ */ new Map();
120
- const names = /* @__PURE__ */ new Map();
121
- const named = /* @__PURE__ */ new Map();
122
- const visit = (node, owners) => {
123
- if (!node || typeof node !== "object") return;
124
- if (node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.init && FUNCTIONS.has(node.init.type)) {
125
- named.set(node.init, node.id.name);
126
- }
127
- if ((node.type === "ClassDeclaration" || node.type === "ClassExpression") && node.id) {
128
- for (const member of node.body.body) if (member.type === "ClassMethod") named.set(member, node.id.name);
129
- }
130
- if (node.type === "ClassDeclaration" || node.type === "ClassExpression") {
131
- for (const member of node.body.body) if (member.type === "ClassMethod") classOf.set(member, node);
132
- const shadow = staticMember(node, "shadow");
133
- if (shadow?.value && !(shadow.value.type === "BooleanLiteral" && shadow.value.value === false)) {
134
- plan.shadowClasses.set(node, { node, styles: staticMember(node, "styles"), indexes: [] });
135
- }
136
- }
137
- if (node.type === "TaggedTemplateExpression" && node.tag.type === "Identifier" && tags.html.get(node.tag.name) === "html") {
138
- const text = node.quasi.quasis.map((q) => q.value.raw).join("");
139
- if (/<style[\s>]/.test(text)) {
140
- const at = { line: node.loc?.start.line ?? 0, column: node.loc?.start.column ?? 0 };
141
- const owner = owners[0];
142
- if (!owner) plan.diagnostics.push({ ...at, message: "<style> has to be written inside a component." });
143
- else {
144
- const id = idFor(owner);
145
- const shadow = shadowOf(owner);
146
- plan.templateOwners.set(node.start, { id, component: functionName(owner, named) });
147
- for (const block of templateBlocks(node.quasi)) compileBlock(block, block.scoped, owner, at);
148
- }
149
- }
150
- }
151
- const inner = FUNCTIONS.has(node.type) ? [...owners, node] : owners;
152
- if (node.type === "JSXElement" && isStyle(node)) {
153
- handle(node, owners);
154
- return;
155
- }
156
- for (const key of Object.keys(node)) {
157
- if (key === "loc" || key === "leadingComments" || key === "trailingComments" || key === "innerComments") continue;
158
- const value = node[key];
159
- if (Array.isArray(value)) for (const v of value) visit(v, inner);
160
- else if (value && typeof value === "object" && "type" in value) visit(value, inner);
161
- }
162
- };
163
- const handle = (node, owners) => {
164
- const at = { line: node.loc?.start.line ?? 0, column: node.loc?.start.column ?? 0 };
165
- const pieces = blockPieces(node);
166
- if (pieces === null) {
167
- plan.diagnostics.push({
168
- ...at,
169
- message: "<style> needs its CSS as one template literal, <style>{`...`}</style>: JSX reads a bare `{` as an expression."
170
- });
171
- return;
172
- }
173
- const owner = owners[0];
174
- if (!owner) {
175
- plan.diagnostics.push({ ...at, message: "<style> has to be written inside a component." });
176
- return;
177
- }
178
- compileBlock(pieces, isScoped(node), owner, at);
179
- plan.drop.add(node.start);
180
- };
181
- const compileBlock = (pieces, scoped, owner, at) => {
182
- const component = functionName(owner, named);
183
- const id = idFor(owner);
184
- const processed = piecesToNodes(pieces.quasis, pieces.expressions, at, []);
185
- if (!processed) return;
186
- let nodes = processed;
187
- const shadow = shadowOf(owner);
188
- if (scoped && !shadow) {
189
- if (!plan.scopes.some((s) => s.value === id)) plan.scopes.push({ start: owner.start, end: owner.end, value: id });
190
- nodes = scopeNodes(nodes, id, (message) => plan.diagnostics.push({ ...at, message }));
191
- }
192
- const printed = module ? printStyleWithMap(nodes, options.minify, sourceName, module) : { css: printStyle(nodes, options.minify) };
193
- plan.styles.push({ id, scoped: scoped && !shadow, component, ...printed, ...shadow ? { shadow: true } : {}, ...at });
194
- if (shadow) shadow.indexes.push(plan.styles.length - 1);
195
- };
196
- function idFor(owner) {
197
- let id = scopeOf.get(owner);
198
- if (!id) {
199
- const component = functionName(owner, named);
200
- const seen = names.get(component) ?? 0;
201
- names.set(component, seen + 1);
202
- id = hash(`${sourceName}:${component}${seen ? ":" + seen : ""}`);
203
- scopeOf.set(owner, id);
204
- }
205
- return id;
206
- }
207
- visit(program, []);
208
- return plan;
209
- }
210
- function applyTemplateStyles(ir, t) {
211
- const walk5 = (node) => {
212
- const children = node.children;
213
- if (children) {
214
- for (let i = children.length - 1; i >= 0; i--) {
215
- const child = children[i];
216
- if (child.kind === "element" && child.tag === "style" && t.owner) children.splice(i, 1);
217
- else walk5(child);
218
- }
219
- }
220
- if (t.scope && node.kind === "element" && node.tag !== "style" && node.props && !node.props.some((p) => p.name === SCOPE_ATTR)) {
221
- node.props.unshift({ name: SCOPE_ATTR, kind: "attr", literal: t.scope });
222
- }
223
- };
224
- walk5(ir);
225
- }
226
- function staticMember(cls, name) {
227
- return cls.body.body.find(
228
- (m) => m.type === "ClassProperty" && m.static && (m.key.type === "Identifier" && m.key.name === name || m.key.type === "StringLiteral" && m.key.value === name)
229
- );
230
- }
231
- function finishShadowStyles(plan, code, moduleId) {
232
- const edits = [];
233
- const imports = [];
234
- let next = 0;
235
- const importOf = (specifier) => {
236
- const local = `__fxShadow${next++}`;
237
- imports.push(`import ${local} from ${JSON.stringify(specifier)};
238
- `);
239
- return local;
240
- };
241
- for (const shadow of plan.shadowClasses.values()) {
242
- const blocks = shadow.indexes.map((i) => importOf(`${moduleId}?fx-style&index=${i}&inline&lang.css`));
243
- let value;
244
- const prop = shadow.styles;
245
- if (prop?.value) {
246
- const start = prop.value.start;
247
- let text = code.slice(start, prop.value.end);
248
- const replacements = [];
249
- walkIdentifiers(prop.value, (id) => {
250
- const local = plan.names?.literals.has(id.name) ? importOf(`${moduleId}?fx-literal=${id.name}&inline&lang.css`) : plan.names?.imports.has(id.name) && !/\.css(\?|$)/.test(plan.names.imports.get(id.name).source) ? importOf(`${plan.names.imports.get(id.name).source}?fx-literal=${plan.names.imports.get(id.name).name}&inline&lang.css`) : void 0;
251
- if (local) replacements.push({ at: id.start - start, length: id.name.length, with: local });
252
- });
253
- for (const r of replacements.sort((a, b) => b.at - a.at)) text = text.slice(0, r.at) + r.with + text.slice(r.at + r.length);
254
- value = text;
255
- }
256
- if (!blocks.length && value === void 0) continue;
257
- if (prop?.value) {
258
- const merged = blocks.length ? `[${value}, ${blocks.join(", ")}]` : value;
259
- edits.push({ start: prop.value.start, end: prop.value.end, code: merged });
260
- } else if (blocks.length) {
261
- const open = shadow.node.body.start + 1;
262
- edits.push({ start: open, end: open, code: ` static styles = [${blocks.join(", ")}];` });
263
- }
264
- }
265
- if (imports.length) edits.push({ start: 0, end: 0, code: imports.join("") });
266
- return edits;
267
- }
268
- function walkIdentifiers(node, visit) {
269
- if (!node || typeof node !== "object") return;
270
- if (node.type === "Identifier") return visit(node);
271
- if (node.type === "MemberExpression") return walkIdentifiers(node.object, visit);
272
- if (node.type === "ObjectProperty") return walkIdentifiers(node.value, visit);
273
- for (const key of Object.keys(node)) {
274
- if (key === "loc") continue;
275
- const value = node[key];
276
- if (Array.isArray(value)) for (const v of value) walkIdentifiers(v, visit);
277
- else if (value && typeof value === "object" && "type" in value) walkIdentifiers(value, visit);
278
- }
279
- }
280
- function isStyle(node) {
281
- const name = node.openingElement.name;
282
- return name.type === "JSXIdentifier" && name.name === "style";
283
- }
284
- function isScoped(node) {
285
- return node.openingElement.attributes.some((a) => a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" && a.name.name === "scoped");
286
- }
287
- function templateBlocks(quasi) {
288
- const blocks = [];
289
- let open = null;
290
- quasi.quasis.forEach((q, i) => {
291
- const raw = q.value.raw;
292
- let from = 0;
293
- while (from <= raw.length) {
294
- if (!open) {
295
- const tag = /<style\b([^>]*)>/g;
296
- tag.lastIndex = from;
297
- const m = tag.exec(raw);
298
- if (!m) break;
299
- open = { quasis: [], expressions: [], scoped: /\bscoped\b/.test(m[1]) };
300
- from = m.index + m[0].length;
301
- }
302
- const close = raw.indexOf("</style", from);
303
- open.quasis.push(slicePiece(q, raw, from, close === -1 ? raw.length : close));
304
- if (close === -1) break;
305
- blocks.push(open);
306
- open = null;
307
- from = close;
308
- }
309
- const expr = quasi.expressions[i];
310
- if (open && expr) open.expressions.push(expr);
311
- });
312
- return blocks;
313
- }
314
- function slicePiece(q, raw, from, to) {
315
- const text = raw.slice(from, to);
316
- const start = q.loc?.start;
317
- if (!start) return { type: "TemplateElement", value: { raw: text, cooked: text } };
318
- const before = raw.slice(0, from).split("\n");
319
- const line = start.line + before.length - 1;
320
- const column = before.length > 1 ? before[before.length - 1].length : start.column + from;
321
- return { type: "TemplateElement", value: { raw: text, cooked: text }, loc: { start: { line, column } } };
322
- }
323
- function blockPieces(node) {
324
- const meaningful = node.children.filter((c) => !(c.type === "JSXText" && !c.value.trim()));
325
- if (meaningful.length === 0) return { quasis: [], expressions: [] };
326
- if (meaningful.length !== 1) return null;
327
- const only = meaningful[0];
328
- if (only.type !== "JSXExpressionContainer") return null;
329
- const expr = only.expression;
330
- if (expr.type === "StringLiteral") return { quasis: [{ type: "TemplateElement", value: { raw: expr.value, cooked: expr.value } }], expressions: [] };
331
- if (expr.type === "TemplateLiteral") return { quasis: expr.quasis, expressions: expr.expressions };
332
- return null;
333
- }
334
- function findLiterals(program, modules, plan, intrinsic) {
335
- const literals = /* @__PURE__ */ new Map();
336
- const imports = /* @__PURE__ */ new Map();
337
- const tags = new Set(intrinsic);
338
- for (const statement of program.body ?? []) {
339
- if (statement.type !== "ImportDeclaration") continue;
340
- const source = statement.source.value;
341
- const specifiers = statement.specifiers;
342
- for (const sp of specifiers) {
343
- if (sp.type === "ImportSpecifier") imports.set(sp.local.name, { source, name: sp.imported.name ?? sp.imported.value });
344
- }
345
- if (!modules.includes(source)) continue;
346
- const css = specifiers.find((sp) => sp.type === "ImportSpecifier" && (sp.imported.name ?? sp.imported.value) === "css");
347
- if (!css) continue;
348
- const local = css.local.name;
349
- tags.add(local);
350
- imports.delete(local);
351
- plan.edits.push({ start: statement.start, end: statement.end, code: importWithout(statement, css) });
352
- }
353
- if (tags.size === 0) return { literals, imports };
354
- const visit = (node) => {
355
- if (!node || typeof node !== "object") return;
356
- if (node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.init?.type === "TaggedTemplateExpression" && node.init.tag.type === "Identifier" && tags.has(node.init.tag.name)) {
357
- literals.set(node.id.name, node.init);
358
- }
359
- for (const key of Object.keys(node)) {
360
- if (key === "loc") continue;
361
- const value = node[key];
362
- if (Array.isArray(value)) for (const v of value) visit(v);
363
- else if (value && typeof value === "object" && "type" in value) visit(value);
364
- }
365
- };
366
- visit(program);
367
- return { literals, imports };
368
- }
369
- function importWithout(statement, removed) {
370
- const rest = statement.specifiers.filter((sp) => sp !== removed);
371
- const source = JSON.stringify(statement.source.value);
372
- if (rest.length === 0) return "";
373
- const def = rest.find((sp) => sp.type === "ImportDefaultSpecifier");
374
- const ns = rest.find((sp) => sp.type === "ImportNamespaceSpecifier");
375
- const named = rest.filter((sp) => sp.type === "ImportSpecifier").map((sp) => {
376
- const imported = sp.imported.name ?? JSON.stringify(sp.imported.value);
377
- return imported === sp.local.name ? imported : `${imported} as ${sp.local.name}`;
378
- });
379
- const parts = [def?.local.name, ns ? `* as ${ns.local.name}` : void 0, named.length ? `{ ${named.join(", ")} }` : void 0].filter(Boolean);
380
- return `import ${parts.join(", ")} from ${source};`;
381
- }
382
- function functionName(fn, named) {
383
- if ((fn.type === "FunctionDeclaration" || fn.type === "FunctionExpression") && fn.id) return fn.id.name;
384
- return named.get(fn) ?? "anonymous";
385
- }
386
- function hash(text) {
387
- let h = 2166136261;
388
- for (let i = 0; i < text.length; i++) {
389
- h ^= text.charCodeAt(i);
390
- h = Math.imul(h, 16777619);
391
- }
392
- return (h >>> 0).toString(36);
393
- }
394
- var OPAQUE = /(^|-)keyframes$|^font-face$|^property$|^counter-style$|^page$|^font-feature-values$/;
395
- function scopeNodes(nodes, id, warn = () => {
396
- }) {
397
- return nodes.map((node) => {
398
- if (node.kind === "rule") return { ...node, selector: scopeSelector(node.selector, id, warn) };
399
- if (node.kind === "at-rule" && !OPAQUE.test(node.name)) return { ...node, nodes: scopeNodes(node.nodes, id, warn) };
400
- return node;
401
- });
402
- }
403
- function scopeSelector(selector, id, warn = () => {
404
- }) {
405
- return splitTop(selector, ",").map((complex) => scopeComplex(complex.trim(), `[${SCOPE_ATTR}="${id}"]`, warn)).join(", ");
406
- }
407
- function scopeComplex(selector, attr, warn) {
408
- if (/:host\b|::slotted\(/.test(selector)) {
409
- warn(`\`${selector}\` only means something in a shadow root; in a light-DOM component it is left as written.`);
410
- return selector;
411
- }
412
- const parts = compounds(selector);
413
- const deep = parts.findIndex((p) => p.text.startsWith(":deep("));
414
- if (deep !== -1) {
415
- const inner = unwrap(parts[deep].text, ":deep(");
416
- const before = parts.slice(0, deep);
417
- if (before.length === 0) return `${attr} ${inner}`;
418
- const scopedBefore = scopeAt(before, before.length - 1, attr);
419
- return `${join(scopedBefore)} ${inner}`;
420
- }
421
- let target = -1;
422
- for (let i = parts.length - 1; i >= 0; i--) {
423
- if (!parts[i].text.startsWith(":global(")) {
424
- target = i;
425
- break;
426
- }
427
- }
428
- const out = target === -1 ? parts : scopeAt(parts, target, attr);
429
- return join(out.map((p) => p.text.startsWith(":global(") ? { ...p, text: unwrap(p.text, ":global(") } : p));
430
- }
431
- function scopeAt(parts, index, attr) {
432
- return parts.map((p, i) => i === index ? { ...p, text: insertAttr(p.text, attr) } : p);
433
- }
434
- function insertAttr(compound, attr) {
435
- let depth = 0;
436
- let quote = "";
437
- for (let i = 0; i < compound.length; i++) {
438
- const c = compound[i];
439
- if (quote) {
440
- if (c === "\\") i++;
441
- else if (c === quote) quote = "";
442
- continue;
443
- }
444
- if (c === "\\") {
445
- i++;
446
- continue;
447
- }
448
- if (c === '"' || c === "'") quote = c;
449
- else if (c === "(" || c === "[") depth++;
450
- else if (c === ")" || c === "]") depth--;
451
- else if (c === ":" && depth === 0 && i > 0) return compound.slice(0, i) + attr + compound.slice(i);
452
- }
453
- return compound + attr;
454
- }
455
- function compounds(selector) {
456
- const out = [];
457
- let depth = 0;
458
- let quote = "";
459
- let current = "";
460
- let combinator = "";
461
- const push = () => {
462
- if (current.trim()) out.push({ combinator: out.length ? combinator || " " : "", text: current.trim() });
463
- current = "";
464
- combinator = "";
465
- };
466
- for (let i = 0; i < selector.length; i++) {
467
- const c = selector[i];
468
- if (quote) {
469
- current += c;
470
- if (c === "\\") current += selector[++i] ?? "";
471
- else if (c === quote) quote = "";
472
- continue;
473
- }
474
- if (c === "\\") {
475
- current += c + (selector[++i] ?? "");
476
- continue;
477
- }
478
- if (c === '"' || c === "'") quote = c;
479
- if (c === "(" || c === "[") depth++;
480
- if (c === ")" || c === "]") depth--;
481
- if (depth === 0 && (c === ">" || c === "+" || c === "~")) {
482
- push();
483
- combinator = c;
484
- continue;
485
- }
486
- if (depth === 0 && /\s/.test(c)) {
487
- if (current.trim()) {
488
- const keep = combinator;
489
- push();
490
- combinator = keep;
491
- }
492
- continue;
493
- }
494
- current += c;
495
- }
496
- push();
497
- return out;
498
- }
499
- function join(parts) {
500
- return parts.map((p, i) => i === 0 ? p.text : p.combinator === " " ? ` ${p.text}` : ` ${p.combinator} ${p.text}`).join("");
501
- }
502
- function unwrap(text, prefix) {
503
- return text.slice(prefix.length, text.lastIndexOf(")")).trim() + text.slice(text.lastIndexOf(")") + 1);
504
- }
505
- function splitTop(selector, separator) {
506
- const parts = [];
507
- let depth = 0;
508
- let quote = "";
509
- let start = 0;
510
- for (let i = 0; i < selector.length; i++) {
511
- const c = selector[i];
512
- if (quote) {
513
- if (c === "\\") i++;
514
- else if (c === quote) quote = "";
515
- } else if (c === '"' || c === "'") quote = c;
516
- else if (c === "\\") i++;
517
- else if (c === "(" || c === "[") depth++;
518
- else if (c === ")" || c === "]") depth--;
519
- else if (c === separator && depth === 0) {
520
- parts.push(selector.slice(start, i));
521
- start = i + 1;
522
- }
523
- }
524
- parts.push(selector.slice(start));
525
- return parts.filter((p) => p.trim());
526
- }
527
- function shiftLoc(node, source, start) {
528
- const loc = node.loc && node.loc.source === source ? { source, line: start.line + node.loc.line - 1, column: node.loc.line === 1 ? start.column + node.loc.column : node.loc.column } : node.loc;
529
- if (node.kind === "rule" || node.kind === "at-rule") return { ...node, loc, nodes: node.nodes.map((n) => shiftLoc(n, source, start)) };
530
- return { ...node, loc };
531
- }
532
- function dropLoc(node) {
533
- const { loc: _loc, ...rest } = node;
534
- if (rest.kind === "rule" || rest.kind === "at-rule") return { ...rest, nodes: rest.nodes.map(dropLoc) };
535
- return rest;
536
- }
537
- function printStyleWithMap(nodes, minify, sourceName, module) {
538
- const lines = [[]];
539
- let css = "";
540
- let column = 0;
541
- const emit = (text) => {
542
- for (const ch of text) {
543
- css += ch;
544
- if (ch === "\n") {
545
- lines.push([]);
546
- column = 0;
547
- } else column++;
548
- }
549
- };
550
- const mark = (loc) => {
551
- if (loc && loc.source === sourceName) lines[lines.length - 1].push([column, 0, loc.line - 1, loc.column]);
552
- };
553
- const write = (node, depth) => {
554
- const pad = minify ? "" : " ".repeat(depth);
555
- const nl = minify ? "" : "\n";
556
- const sp = minify ? "" : " ";
557
- emit(pad);
558
- mark(node.loc);
559
- if (node.kind === "declaration") {
560
- emit(`${node.property}:${sp}${node.value}${node.important ? `${sp}!important` : ""};${nl}`);
561
- } else if (node.kind === "raw") {
562
- emit(`${node.text}${nl}`);
563
- } else {
564
- emit(`${node.kind === "rule" ? node.selector : `@${node.name}${node.params ? " " + node.params : ""}`}${sp}{${nl}`);
565
- for (const child of node.nodes) write(child, depth + 1);
566
- emit(`${pad}}${nl}`);
567
- }
568
- };
569
- for (const node of nodes) write(node, 0);
570
- return { css, map: { version: 3, sources: [module.id], sourcesContent: [module.code], names: [], mappings: encode(lines) } };
571
- }
572
- function printStyle(nodes, minify = false) {
573
- const out = [];
574
- const write = (node, depth) => {
575
- const pad = minify ? "" : " ".repeat(depth);
576
- const nl = minify ? "" : "\n";
577
- const sp = minify ? "" : " ";
578
- if (node.kind === "declaration") {
579
- out.push(`${pad}${node.property}:${sp}${node.value}${node.important ? `${sp}!important` : ""};${nl}`);
580
- } else if (node.kind === "raw") {
581
- out.push(`${pad}${node.text}${nl}`);
582
- } else {
583
- const header = node.kind === "rule" ? node.selector : `@${node.name}${node.params ? " " + node.params : ""}`;
584
- out.push(`${pad}${header}${sp}{${nl}`);
585
- for (const child of node.nodes) write(child, depth + 1);
586
- out.push(`${pad}}${nl}`);
587
- }
588
- };
589
- for (const node of nodes) write(node, 0);
590
- return out.join("");
591
- }
592
-
593
42
  // src/lower/compile-template.ts
594
43
  function compilePieces(pieces, holes, options = {}) {
595
44
  const used = /* @__PURE__ */ new Set();