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

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 (90) hide show
  1. package/dist/analyze/intrinsics.cjs +13 -1
  2. package/dist/analyze/intrinsics.d.cts +14 -0
  3. package/dist/analyze/intrinsics.d.ts +14 -0
  4. package/dist/analyze/intrinsics.d.ts.map +1 -1
  5. package/dist/analyze/intrinsics.js +17 -0
  6. package/dist/analyze/intrinsics.mjs +13 -1
  7. package/dist/analyze/static-graph.cjs +1 -1
  8. package/dist/analyze/static-graph.mjs +1 -1
  9. package/dist/{babel-RJHJQVEM.mjs → babel-RJFQVFJW.mjs} +4 -4
  10. package/dist/{chunk-56QSOVVL.mjs → chunk-DP2QDWWH.mjs} +1 -1
  11. package/dist/{chunk-R7PPFBCL.mjs → chunk-E2RWTIYE.mjs} +21 -15
  12. package/dist/{chunk-OD53TMER.mjs → chunk-HCCBEJEZ.mjs} +13 -1
  13. package/dist/{chunk-TJIH7TLX.mjs → chunk-HIZU7WI2.mjs} +1 -1
  14. package/dist/{chunk-U7HCFLZ2.mjs → chunk-ZR2QHTEX.mjs} +356 -24
  15. package/dist/codegen/backends/imperative.cjs +1 -1
  16. package/dist/codegen/backends/imperative.d.ts.map +1 -1
  17. package/dist/codegen/backends/imperative.js +2 -1
  18. package/dist/codegen/backends/imperative.mjs +1 -1
  19. package/dist/frontend/babel/build-ir-lit.cjs +352 -22
  20. package/dist/frontend/babel/build-ir-lit.mjs +352 -22
  21. package/dist/frontend/babel/build-ir.cjs +352 -22
  22. package/dist/frontend/babel/build-ir.mjs +352 -22
  23. package/dist/frontend/babel/index.cjs +353 -23
  24. package/dist/frontend/babel/index.mjs +353 -23
  25. package/dist/frontend/babel/lower-template.cjs +352 -22
  26. package/dist/frontend/babel/lower-template.mjs +352 -22
  27. package/dist/frontend/babel/plugin.cjs +352 -22
  28. package/dist/frontend/babel/plugin.mjs +352 -22
  29. package/dist/index.cjs +321 -22
  30. package/dist/index.mjs +333 -22
  31. package/dist/integrations.cjs +1174 -49
  32. package/dist/integrations.d.ts.map +1 -1
  33. package/dist/integrations.js +44 -2
  34. package/dist/integrations.mjs +205 -19
  35. package/dist/lower/compile-template.cjs +315 -21
  36. package/dist/lower/compile-template.d.cts +13 -0
  37. package/dist/lower/compile-template.d.ts +13 -0
  38. package/dist/lower/compile-template.d.ts.map +1 -1
  39. package/dist/lower/compile-template.js +3 -0
  40. package/dist/lower/compile-template.mjs +327 -21
  41. package/dist/lower/entities.cjs +288 -0
  42. package/dist/lower/entities.d.cts +1 -0
  43. package/dist/lower/entities.d.ts +2 -0
  44. package/dist/lower/entities.d.ts.map +1 -0
  45. package/dist/lower/entities.js +54 -0
  46. package/dist/lower/entities.mjs +267 -0
  47. package/dist/lower/jsx.cjs +104 -47
  48. package/dist/lower/jsx.d.cts +8 -0
  49. package/dist/lower/jsx.d.ts +8 -0
  50. package/dist/lower/jsx.d.ts.map +1 -1
  51. package/dist/lower/jsx.js +92 -2
  52. package/dist/lower/jsx.mjs +104 -47
  53. package/dist/lower/template.cjs +293 -20
  54. package/dist/lower/template.d.ts.map +1 -1
  55. package/dist/lower/template.js +35 -19
  56. package/dist/lower/template.mjs +293 -20
  57. package/dist/resolve/builtins.cjs +1 -1
  58. package/dist/resolve/builtins.mjs +1 -1
  59. package/dist/resolve/component-globals.cjs +6 -1
  60. package/dist/resolve/component-globals.js +2 -2
  61. package/dist/resolve/component-globals.mjs +6 -1
  62. package/dist/resolve/write-globals.cjs +6 -1
  63. package/dist/resolve/write-globals.mjs +6 -1
  64. package/dist/{server-fns-ZFRDIQ2X.mjs → server-fns-JLSTKWPS.mjs} +4 -4
  65. package/dist/{server-functions-CTDXX67X.mjs → server-functions-BGY3RD4R.mjs} +3 -3
  66. package/dist/transform/index.cjs +956 -33
  67. package/dist/transform/index.mjs +974 -47
  68. package/dist/transform/props.mjs +19 -14
  69. package/dist/transform/server-fns.mjs +19 -14
  70. package/dist/transform/styles.cjs +588 -0
  71. package/dist/transform/styles.d.cts +211 -0
  72. package/dist/transform/styles.d.ts +212 -0
  73. package/dist/transform/styles.d.ts.map +1 -0
  74. package/dist/transform/styles.js +714 -0
  75. package/dist/transform/styles.mjs +653 -0
  76. package/dist/transform/templates.cjs +955 -32
  77. package/dist/transform/templates.d.cts +13 -0
  78. package/dist/transform/templates.d.ts +13 -0
  79. package/dist/transform/templates.d.ts.map +1 -1
  80. package/dist/transform/templates.js +49 -12
  81. package/dist/transform/templates.mjs +973 -46
  82. package/dist/{transform-QWWQDCXE.mjs → transform-GBP6Y4UI.mjs} +601 -17
  83. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  84. package/dist/vite-styles.cjs +180 -0
  85. package/dist/vite-styles.d.cts +59 -0
  86. package/dist/vite-styles.d.ts +60 -0
  87. package/dist/vite-styles.d.ts.map +1 -0
  88. package/dist/vite-styles.js +198 -0
  89. package/dist/vite-styles.mjs +159 -0
  90. package/package.json +4 -3
@@ -1 +1 @@
1
- {"version":3,"file":"integrations.d.ts","sourceRoot":"","sources":["../src/integrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC3C;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACzB,6FAA6F;IAC7F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAEhC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAE5C;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAMD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,eAAoB;;;;;;;;;;;;;;;;;GAwCpE;AAMD;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,eAAoB,aAIpD,GAAG,MAAM,YAAY,GAAG,SAkB5C;AAqCD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAE,eAAoB,GAAG,CAAC,CAsHpE;AAoID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,eAAoB,IACxC,MAAM,GAAG,EAAE,QAAQ,MAAM,mBAUjD;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,eAAoB;;oBAItC,MAAM,MAAM,MAAM;;;;;;;;;;;;EAK3C;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,eAAoB;;iBAIhD,GAAG;EAwBnB;AAWD,YAAY,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAoD7E;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,GAAG,GAAG,EAAE,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,CAAC,CAqCvF;;;;;;;;;AAED,wBAOE"}
1
+ {"version":3,"file":"integrations.d.ts","sourceRoot":"","sources":["../src/integrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC3C;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACzB,6FAA6F;IAC7F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAEhC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAE5C;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAMD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,eAAoB;;;;;;;;;;;;;;;;;GAwCpE;AAMD;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,eAAoB,aAIpD,GAAG,MAAM,YAAY,GAAG,SAkB5C;AAqCD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAE,eAAoB,GAAG,CAAC,CA0JpE;AAsID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,eAAoB,IACxC,MAAM,GAAG,EAAE,QAAQ,MAAM,mBAUjD;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,eAAoB;;oBAItC,MAAM,MAAM,MAAM;;;;;;;;;;;;EAK3C;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,eAAoB;;iBAIhD,GAAG;EAwBnB;AAWD,YAAY,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAqD7E;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,GAAG,GAAG,EAAE,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,CAAC,CAqCvF;;;;;;;;;AAED,wBAOE"}
@@ -120,6 +120,16 @@ const RETIRED_SUBPATHS = {
120
120
  * Create a Vite plugin for JSX transformation
121
121
  */
122
122
  export function createVitePlugin(options = {}) {
123
+ // Component `<style>` blocks, when @fluixi-css/vite is in the build to process them.
124
+ let transformTemplates;
125
+ let projectRoot = process.cwd();
126
+ const componentStyles = createComponentStyles((code, id, styles) => {
127
+ // Scope ids hash the path from the project root, marks or not: the same on every machine
128
+ // and for every id a module is reached by.
129
+ // Reported by `transform`, from the module's last pass: a first pass, or a compile of
130
+ // another module whose values this one uses, would report what the next pass resolves.
131
+ return transformTemplates(code, id, { ...transformOptions(options, id), sourceRoot: projectRoot, styles });
132
+ });
123
133
  return {
124
134
  name: 'vite-fluixi-jsx',
125
135
  enforce: 'pre',
@@ -133,15 +143,39 @@ export function createVitePlugin(options = {}) {
133
143
  },
134
144
  // Written once per build, and on dev-server start, rather than per transform: the
135
145
  // set of resolvable names comes from config, so nothing a file does can change it.
136
- configResolved(config) {
146
+ async configResolved(config) {
137
147
  const outcome = writeComponentGlobals(options, config?.root ?? process.cwd());
138
148
  if (outcome.warning)
139
149
  console.warn(outcome.warning);
150
+ if (options.babel)
151
+ return;
152
+ projectRoot = config?.root ?? projectRoot;
153
+ componentStyles.connect(config?.plugins, config?.root);
154
+ const entry = config?.command === 'build' && config.build?.lib ? config.build.lib.entry : undefined;
155
+ const first = typeof entry === 'string' ? entry : Array.isArray(entry) ? entry[0] : entry && typeof entry === 'object' ? Object.values(entry)[0] : undefined;
156
+ if (typeof first === 'string')
157
+ componentStyles.setLibrary(dirname(resolvePath(config.root ?? process.cwd(), first)));
158
+ if (componentStyles.active)
159
+ ({ transformTemplates } = await import('./transform/index.js'));
160
+ },
161
+ generateBundle() {
162
+ for (const [fileName, source] of componentStyles.libraryFiles())
163
+ this.emitFile({ type: 'asset', fileName, source });
164
+ },
165
+ configureServer(server) {
166
+ componentStyles.setServer(server);
167
+ },
168
+ load(id) {
169
+ return componentStyles.isStyle(id) ? componentStyles.load(id, this) : null;
140
170
  },
141
171
  // A subpath we retired resolves to nothing, and the bundler reports that as
142
172
  // `Missing "./x" specifier`, which names neither the replacement nor the file
143
173
  // that asked. Answer it here, where the rename is known.
144
174
  resolveId(id, importer) {
175
+ if (componentStyles.isStyle(id))
176
+ return componentStyles.resolveId(id);
177
+ if (componentStyles.isLibraryImport(id, importer))
178
+ return { id, external: true };
145
179
  const moved = RETIRED_SUBPATHS[id];
146
180
  if (!moved)
147
181
  return null;
@@ -152,6 +186,11 @@ export function createVitePlugin(options = {}) {
152
186
  if (!/\.(jsx|tsx|ts)$/i.test(id)) {
153
187
  return null;
154
188
  }
189
+ if (!options.babel && componentStyles.active) {
190
+ const result = await componentStyles.compile(code, id, this);
191
+ reportDiagnostics(result, id);
192
+ return result;
193
+ }
155
194
  if (!options.babel)
156
195
  return compileModule(code, id, options);
157
196
  const babelPlugin = await createBabelPlugin(options);
@@ -306,6 +345,8 @@ function reportDiagnostics(result, id) {
306
345
  say(d.message);
307
346
  for (const d of r?.intrinsicDiagnostics ?? [])
308
347
  say(d.message);
348
+ for (const d of r?.styleDiagnostics ?? [])
349
+ say(`${d.line}:${d.column + 1} ${d.message}`);
309
350
  for (const d of r?.propsDiagnostics ?? []) {
310
351
  say(`\`${d.name}\` was left destructured: ${d.message}. It reads once instead of tracking.`);
311
352
  }
@@ -403,8 +444,9 @@ export function createESBuildPlugin(options = {}) {
403
444
  };
404
445
  }
405
446
  import { writeComponentGlobals } from './resolve/write-globals.js';
447
+ import { createComponentStyles } from './vite-styles.js';
406
448
  import { readdirSync, readFileSync } from 'node:fs';
407
- import { join as _join } from 'node:path';
449
+ import { dirname, join as _join, resolve as resolvePath } from 'node:path';
408
450
  const SERVER_FNS_VMOD = 'virtual:fluixi-server-fns';
409
451
  /** Recursively find source files containing the `"use server"` directive under `dir`. */
410
452
  /**
@@ -1,12 +1,13 @@
1
- /*! @fluixi/compiler v1.0.0-alpha.93 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/compiler v1.0.0-alpha.94 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
  import {
3
3
  INTRINSICS,
4
+ TAG_INTRINSICS,
4
5
  builtinComponentMap,
5
6
  createComponentResolver
6
- } from "./chunk-OD53TMER.mjs";
7
+ } from "./chunk-HCCBEJEZ.mjs";
7
8
  import {
8
9
  __require
9
- } from "./chunk-TJIH7TLX.mjs";
10
+ } from "./chunk-HIZU7WI2.mjs";
10
11
 
11
12
  // src/resolve/write-globals.ts
12
13
  import { mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
@@ -75,7 +76,7 @@ function componentGlobals(rules, options = {}) {
75
76
  resolved.set(name, target);
76
77
  }
77
78
  }
78
- const usableIntrinsics = intrinsics ? Object.entries(INTRINSICS).filter(([, i]) => {
79
+ const usableIntrinsics = intrinsics ? Object.entries({ ...INTRINSICS, ...TAG_INTRINSICS }).filter(([, i]) => {
79
80
  const pkg = packageOf(i.module);
80
81
  return !available || !pkg || available.has(pkg);
81
82
  }) : [];
@@ -138,11 +139,11 @@ function coveredByInclude(root, target) {
138
139
  }
139
140
  if (config.extends !== void 0) return void 0;
140
141
  if (!Array.isArray(config.include)) return true;
141
- const relative2 = relativePosix(root, target);
142
+ const relative3 = relativePosix(root, target);
142
143
  return config.include.some((entry) => {
143
144
  if (typeof entry !== "string") return false;
144
145
  const pattern = entry.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*\//g, "(?:.*/)?").replace(/\*/g, "[^/]*");
145
- return new RegExp(`^${pattern}(?:/.*)?$`).test(relative2);
146
+ return new RegExp(`^${pattern}(?:/.*)?$`).test(relative3);
146
147
  });
147
148
  }
148
149
  function relativePosix(from, to) {
@@ -228,17 +229,173 @@ function writeComponentGlobals(options, root) {
228
229
  }
229
230
  function warnIfUnreachable(root, target) {
230
231
  if (coveredByInclude(root, target) !== false) return void 0;
231
- const relative2 = relativePosix(root, target);
232
- return `[fluixi] ${relative2} is not covered by "include" in tsconfig.json, so TypeScript will ignore it and every resolved component stays "Cannot find name". Add "${relative2}" to "include".`;
232
+ const relative3 = relativePosix(root, target);
233
+ return `[fluixi] ${relative3} is not covered by "include" in tsconfig.json, so TypeScript will ignore it and every resolved component stays "Cannot find name". Add "${relative3}" to "include".`;
234
+ }
235
+
236
+ // src/vite-styles.ts
237
+ import { existsSync, readFileSync as readFileSync2 } from "node:fs";
238
+ import { basename as basename2, dirname as dirname2, extname, join, relative as relative2 } from "node:path";
239
+ var STYLE_ID = /\?fx-style&index=(\d+)(?:&inline)?&lang\.css$/;
240
+ var LITERAL_ID = /\?fx-literal=([\w$]+)&inline&lang\.css$/;
241
+ var styleId = (file, index) => `${file}?fx-style&index=${index}&lang.css`;
242
+ var loader = (name) => `const href = new URL(${JSON.stringify(`./${name}`)}, import.meta.url).href;
243
+ if (typeof document !== 'undefined' && !document.querySelector(\`link[data-fx-css="\${href}"]\`)) {
244
+ const link = document.createElement('link');
245
+ link.rel = 'stylesheet';
246
+ link.href = href;
247
+ link.dataset.fxCss = href;
248
+ document.head.appendChild(link);
249
+ }
250
+ `;
251
+ function createComponentStyles(compile) {
252
+ let api;
253
+ let server;
254
+ let root = process.cwd();
255
+ let library;
256
+ const emitted = /* @__PURE__ */ new Map();
257
+ const fileOf = (id) => existsSync(id) ? id : join(root, id);
258
+ const cache = /* @__PURE__ */ new Map();
259
+ const resolveReference = async (ref, importer, ctx, seen) => {
260
+ const resolved = await ctx.resolve?.(ref.source, importer);
261
+ if (!resolved) return null;
262
+ const file = resolved.id.split("?")[0];
263
+ if (seen.has(file)) return null;
264
+ let code;
265
+ try {
266
+ code = readFileSync2(fileOf(file), "utf8");
267
+ } catch {
268
+ return null;
269
+ }
270
+ const styles = api.styles(file);
271
+ let result = compile(code, file, styles);
272
+ if (result?.styleReferences?.length) {
273
+ const imported = await resolveAll(result.styleReferences, file, ctx, /* @__PURE__ */ new Set([...seen, file]));
274
+ result = compile(code, file, { ...styles, imported });
275
+ }
276
+ const literal = result?.styleLiterals?.find((l) => l.name === ref.name);
277
+ return literal ? styles.process(literal.css, file) : null;
278
+ };
279
+ const resolveAll = async (refs, importer, ctx, seen) => {
280
+ const imported = /* @__PURE__ */ new Map();
281
+ for (const ref of refs) {
282
+ const nodes = await resolveReference(ref, importer, ctx, seen);
283
+ if (nodes) imported.set(`${ref.source}#${ref.name}`, nodes);
284
+ }
285
+ return imported;
286
+ };
287
+ const run = async (code, id, ctx) => {
288
+ const file = fileOf(id);
289
+ const styles = api.styles(file);
290
+ let result = compile(code, file, styles);
291
+ if (result?.styleReferences?.length) {
292
+ const imported = await resolveAll(result.styleReferences, id, ctx, /* @__PURE__ */ new Set([file]));
293
+ result = compile(code, file, { ...styles, imported });
294
+ }
295
+ const css = (result?.styles ?? []).map((s) => s.css);
296
+ const maps = (result?.styles ?? []).map((s) => s.map ?? null);
297
+ const literals = new Map((result?.styleLiterals ?? []).map((l) => [l.name, l.css]));
298
+ const before = cache.get(file);
299
+ cache.set(file, { source: code, css, maps, literals });
300
+ if (server && before) {
301
+ for (let i = 0; i < css.length; i++) {
302
+ if (before.css[i] === css[i]) continue;
303
+ const mod = server.moduleGraph.getModuleById(styleId(id, i));
304
+ if (mod) void server.reloadModule(mod);
305
+ }
306
+ }
307
+ const page = (result?.styles ?? []).flatMap((s, i) => s.shadow ? [] : [i]);
308
+ if (!result || page.length === 0) return result;
309
+ if (library) {
310
+ const name = `${basename2(file, extname(file))}.css`;
311
+ if (existsSync(join(dirname2(file), name))) {
312
+ throw new Error(`[fluixi] ${file} has <style> blocks, and ${name} next to it would be overwritten by their CSS. Rename one of them.`);
313
+ }
314
+ const out = join(relative2(library, dirname2(file)), name);
315
+ emitted.set(out, page.map((i) => css[i]).join("\n"));
316
+ emitted.set(`${out}.js`, loader(name));
317
+ return { ...result, code: `${result.code}
318
+ import ${JSON.stringify(`./${name}`)};` };
319
+ }
320
+ const imports = page.map((i) => `
321
+ import ${JSON.stringify(styleId(id, i))};`).join("");
322
+ return { ...result, code: result.code + imports };
323
+ };
324
+ return {
325
+ /** Looks for @fluixi-css/vite among the plugins; without it component styles stay off. */
326
+ connect(plugins, projectRoot) {
327
+ if (projectRoot) root = projectRoot;
328
+ api = (plugins ?? []).map((p) => p?.api?.fluixiCss).find((a) => Boolean(a));
329
+ api?.useComponentStyles();
330
+ },
331
+ /** Turns on library output, from the directory of a `build.lib` entry. */
332
+ setLibrary(entryDir) {
333
+ library = entryDir;
334
+ },
335
+ /** A library build's style import: left for the package's consumer to bundle. */
336
+ isLibraryImport(id, importer) {
337
+ if (library === void 0 || !importer || !id.startsWith("./") || !id.endsWith(".css")) return false;
338
+ return emitted.has(join(relative2(library, dirname2(fileOf(importer))), id));
339
+ },
340
+ /** The style files a library build writes, by path under the output directory. */
341
+ libraryFiles() {
342
+ return emitted;
343
+ },
344
+ get active() {
345
+ return api !== void 0;
346
+ },
347
+ setServer(dev) {
348
+ server = dev;
349
+ },
350
+ isStyle(id) {
351
+ return STYLE_ID.test(id) || LITERAL_ID.test(id);
352
+ },
353
+ /**
354
+ * A style request as the module id Vite should keep: the file's absolute path and the
355
+ * query. Vite invalidates a module when the file its id names changes, so a root-relative id
356
+ * (`/src/card.tsx?fx-style…`, which is how a request arrives before the component's imports
357
+ * were analysed) was never invalidated, and an edited block kept its old CSS until restart.
358
+ */
359
+ resolveId(id) {
360
+ const at = id.indexOf("?");
361
+ return fileOf(id.slice(0, at)) + id.slice(at);
362
+ },
363
+ compile: run,
364
+ /**
365
+ * A block's CSS and its map back to the module, compiling the module again when the cache
366
+ * does not match the file.
367
+ */
368
+ async load(id, ctx) {
369
+ const match = STYLE_ID.exec(id);
370
+ const literal = LITERAL_ID.exec(id);
371
+ if (!match && !literal || !api) return null;
372
+ const file = id.slice(0, id.indexOf("?"));
373
+ let source;
374
+ try {
375
+ source = readFileSync2(fileOf(file), "utf8");
376
+ } catch {
377
+ return null;
378
+ }
379
+ if (cache.get(fileOf(file))?.source !== source) await run(source, file, ctx);
380
+ const entry = cache.get(fileOf(file));
381
+ if (literal) {
382
+ const css = entry?.literals.get(literal[1]);
383
+ if (css === void 0) throw new Error(`[fluixi] ${literal[1]} in ${file} is not a css\`\` value, so it cannot be a shadow root's styles.`);
384
+ return { code: css, map: null };
385
+ }
386
+ const index = Number(match[1]);
387
+ return { code: entry?.css[index] ?? "", map: entry?.maps[index] ?? null };
388
+ }
389
+ };
233
390
  }
234
391
 
235
392
  // src/integrations.ts
236
- import { readdirSync as readdirSync2, readFileSync as readFileSync2 } from "node:fs";
237
- import { join as _join } from "node:path";
393
+ import { readdirSync as readdirSync2, readFileSync as readFileSync3 } from "node:fs";
394
+ import { dirname as dirname3, join as _join, resolve as resolvePath2 } from "node:path";
238
395
  async function createBabelPlugin(options = {}) {
239
396
  let pluginModule = null;
240
397
  try {
241
- pluginModule = await import("./babel-RJHJQVEM.mjs");
398
+ pluginModule = await import("./babel-RJFQVFJW.mjs");
242
399
  } catch (e) {
243
400
  console.warn("Could not load the babel front-end:", e);
244
401
  }
@@ -299,6 +456,11 @@ var RETIRED_SUBPATHS = {
299
456
  "@fluixi/core/rx": "is gone — import signals and effects from @fluixi/reactive, or the server primitives it resolved to under node from @fluixi/core/server"
300
457
  };
301
458
  function createVitePlugin(options = {}) {
459
+ let transformTemplates;
460
+ let projectRoot = process.cwd();
461
+ const componentStyles = createComponentStyles((code, id, styles) => {
462
+ return transformTemplates(code, id, { ...transformOptions(options, id), sourceRoot: projectRoot, styles });
463
+ });
302
464
  return {
303
465
  name: "vite-fluixi-jsx",
304
466
  enforce: "pre",
@@ -312,14 +474,32 @@ function createVitePlugin(options = {}) {
312
474
  },
313
475
  // Written once per build, and on dev-server start, rather than per transform: the
314
476
  // set of resolvable names comes from config, so nothing a file does can change it.
315
- configResolved(config) {
477
+ async configResolved(config) {
316
478
  const outcome = writeComponentGlobals(options, config?.root ?? process.cwd());
317
479
  if (outcome.warning) console.warn(outcome.warning);
480
+ if (options.babel) return;
481
+ projectRoot = config?.root ?? projectRoot;
482
+ componentStyles.connect(config?.plugins, config?.root);
483
+ const entry = config?.command === "build" && config.build?.lib ? config.build.lib.entry : void 0;
484
+ const first = typeof entry === "string" ? entry : Array.isArray(entry) ? entry[0] : entry && typeof entry === "object" ? Object.values(entry)[0] : void 0;
485
+ if (typeof first === "string") componentStyles.setLibrary(dirname3(resolvePath2(config.root ?? process.cwd(), first)));
486
+ if (componentStyles.active) ({ transformTemplates } = await import("./transform-GBP6Y4UI.mjs"));
487
+ },
488
+ generateBundle() {
489
+ for (const [fileName, source] of componentStyles.libraryFiles()) this.emitFile({ type: "asset", fileName, source });
490
+ },
491
+ configureServer(server) {
492
+ componentStyles.setServer(server);
493
+ },
494
+ load(id) {
495
+ return componentStyles.isStyle(id) ? componentStyles.load(id, this) : null;
318
496
  },
319
497
  // A subpath we retired resolves to nothing, and the bundler reports that as
320
498
  // `Missing "./x" specifier`, which names neither the replacement nor the file
321
499
  // that asked. Answer it here, where the rename is known.
322
500
  resolveId(id, importer) {
501
+ if (componentStyles.isStyle(id)) return componentStyles.resolveId(id);
502
+ if (componentStyles.isLibraryImport(id, importer)) return { id, external: true };
323
503
  const moved = RETIRED_SUBPATHS[id];
324
504
  if (!moved) return null;
325
505
  throw new Error(
@@ -331,6 +511,11 @@ function createVitePlugin(options = {}) {
331
511
  if (!/\.(jsx|tsx|ts)$/i.test(id)) {
332
512
  return null;
333
513
  }
514
+ if (!options.babel && componentStyles.active) {
515
+ const result = await componentStyles.compile(code, id, this);
516
+ reportDiagnostics(result, id);
517
+ return result;
518
+ }
334
519
  if (!options.babel) return compileModule(code, id, options);
335
520
  const babelPlugin = await createBabelPlugin(options);
336
521
  try {
@@ -409,7 +594,7 @@ function transformOptions(options, id) {
409
594
  }
410
595
  async function rewriteProps(code, id, options) {
411
596
  if (options.propsDestructure === false) return code;
412
- const { transformProps } = await import("./transform-QWWQDCXE.mjs");
597
+ const { transformProps } = await import("./transform-GBP6Y4UI.mjs");
413
598
  const result = transformProps(code, id);
414
599
  reportDiagnostics({ propsDiagnostics: result.diagnostics }, id);
415
600
  return result.rewritten > 0 ? result.code : code;
@@ -426,13 +611,14 @@ function reportDiagnostics(result, id) {
426
611
  for (const d of r?.unresolvedDiagnostics ?? []) say(d.message);
427
612
  for (const d of r?.loadDiagnostics ?? []) say(d.message);
428
613
  for (const d of r?.intrinsicDiagnostics ?? []) say(d.message);
614
+ for (const d of r?.styleDiagnostics ?? []) say(`${d.line}:${d.column + 1} ${d.message}`);
429
615
  for (const d of r?.propsDiagnostics ?? []) {
430
616
  say(`\`${d.name}\` was left destructured: ${d.message}. It reads once instead of tracking.`);
431
617
  }
432
618
  }
433
619
  async function compileModule(code, id, options) {
434
620
  if (!options.babel) {
435
- const { transformTemplates } = await import("./transform-QWWQDCXE.mjs");
621
+ const { transformTemplates } = await import("./transform-GBP6Y4UI.mjs");
436
622
  const result2 = transformTemplates(code, id, transformOptions(options, id));
437
623
  reportDiagnostics(result2, id);
438
624
  return result2;
@@ -478,8 +664,8 @@ function createESBuildPlugin(options = {}) {
478
664
  name: "esbuild-fluixi-jsx",
479
665
  setup(build) {
480
666
  build.onLoad({ filter: /\.[jt]sx?$/ }, async (args) => {
481
- const { readFileSync: readFileSync3 } = await import("node:fs");
482
- const source = readFileSync3(args.path, "utf8");
667
+ const { readFileSync: readFileSync4 } = await import("node:fs");
668
+ const source = readFileSync4(args.path, "utf8");
483
669
  try {
484
670
  const result = await compileModule(source, args.path, options);
485
671
  return {
@@ -517,7 +703,7 @@ function findServerFnModules(dir, out = []) {
517
703
  if (e.isDirectory()) findServerFnModules(full, out);
518
704
  else if (/\.[jt]sx?$/.test(e.name)) {
519
705
  try {
520
- if (hasServerDirective(readFileSync2(full, "utf8"))) out.push(full);
706
+ if (hasServerDirective(readFileSync3(full, "utf8"))) out.push(full);
521
707
  } catch {
522
708
  }
523
709
  }
@@ -551,10 +737,10 @@ export { isServerFnRequest, handleServerFn } from '@fluixi/start/server-fn';
551
737
  if (!code.includes("use server")) return null;
552
738
  const args = { ssr: !!opts?.ssr, filename: id, root };
553
739
  if (options.babel) {
554
- const { transformServerFunctions } = await import("./server-functions-CTDXX67X.mjs");
740
+ const { transformServerFunctions } = await import("./server-functions-BGY3RD4R.mjs");
555
741
  return transformServerFunctions(code, args);
556
742
  }
557
- const { transformServerFns } = await import("./server-fns-ZFRDIQ2X.mjs");
743
+ const { transformServerFns } = await import("./server-fns-JLSTKWPS.mjs");
558
744
  return transformServerFns(code, args);
559
745
  }
560
746
  };