@fluixi/compiler 1.0.0-alpha.92 → 1.0.0-alpha.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyze/intrinsics.cjs +18 -0
- package/dist/analyze/intrinsics.d.ts.map +1 -1
- package/dist/analyze/intrinsics.js +18 -0
- package/dist/analyze/intrinsics.mjs +18 -0
- package/dist/analyze/reactive-bindings.cjs +18 -0
- package/dist/analyze/reactive-bindings.mjs +18 -0
- package/dist/analyze/static-graph.cjs +22 -4
- package/dist/analyze/static-graph.d.ts.map +1 -1
- package/dist/analyze/static-graph.js +6 -4
- package/dist/analyze/static-graph.mjs +22 -4
- package/dist/{babel-GI375YZ2.mjs → babel-RJHJQVEM.mjs} +4 -4
- package/dist/{chunk-QZ4CJPYP.mjs → chunk-56QSOVVL.mjs} +1 -1
- package/dist/{chunk-XJ5H2MXY.mjs → chunk-OD53TMER.mjs} +19 -1
- package/dist/{chunk-DWNWN5RH.mjs → chunk-R7PPFBCL.mjs} +1 -1
- package/dist/{chunk-VOUI6XPV.mjs → chunk-TJIH7TLX.mjs} +1 -1
- package/dist/{chunk-VC6X44FS.mjs → chunk-U7HCFLZ2.mjs} +153 -48
- package/dist/codegen/backends/imperative.cjs +24 -6
- package/dist/codegen/backends/imperative.d.ts.map +1 -1
- package/dist/codegen/backends/imperative.js +19 -4
- package/dist/codegen/backends/imperative.mjs +24 -6
- package/dist/frontend/babel/build-ir-lit.cjs +120 -43
- package/dist/frontend/babel/build-ir-lit.mjs +120 -43
- package/dist/frontend/babel/build-ir.cjs +120 -43
- package/dist/frontend/babel/build-ir.mjs +120 -43
- package/dist/frontend/babel/index.cjs +121 -44
- package/dist/frontend/babel/index.mjs +121 -44
- package/dist/frontend/babel/lower-template.cjs +120 -43
- package/dist/frontend/babel/lower-template.mjs +120 -43
- package/dist/frontend/babel/plugin.cjs +120 -43
- package/dist/frontend/babel/plugin.mjs +120 -43
- package/dist/index.cjs +41 -38
- package/dist/index.mjs +41 -38
- package/dist/integrations.cjs +176 -52
- package/dist/integrations.mjs +8 -8
- package/dist/lower/compile-template.cjs +41 -38
- package/dist/lower/compile-template.mjs +41 -38
- package/dist/lower/jsx.cjs +509 -6
- package/dist/lower/jsx.d.ts.map +1 -1
- package/dist/lower/jsx.js +114 -6
- package/dist/lower/jsx.mjs +509 -6
- package/dist/lower/template.cjs +40 -37
- package/dist/lower/template.d.ts.map +1 -1
- package/dist/lower/template.js +22 -30
- package/dist/lower/template.mjs +40 -37
- package/dist/resolve/builtins.cjs +1 -1
- package/dist/resolve/builtins.mjs +1 -1
- package/dist/resolve/component-globals.cjs +14 -0
- package/dist/resolve/component-globals.mjs +14 -0
- package/dist/resolve/write-globals.cjs +14 -0
- package/dist/resolve/write-globals.mjs +14 -0
- package/dist/{server-fns-BBZRZUPP.mjs → server-fns-ZFRDIQ2X.mjs} +4 -4
- package/dist/{server-functions-VEGLIFCE.mjs → server-functions-CTDXX67X.mjs} +3 -3
- package/dist/transform/index.cjs +170 -47
- package/dist/transform/index.mjs +170 -47
- package/dist/transform/intrinsics.cjs +18 -0
- package/dist/transform/intrinsics.mjs +18 -0
- package/dist/transform/source-locations.cjs +64 -3
- package/dist/transform/source-locations.d.cts +7 -2
- package/dist/transform/source-locations.d.ts +7 -2
- package/dist/transform/source-locations.d.ts.map +1 -1
- package/dist/transform/source-locations.js +68 -3
- package/dist/transform/source-locations.mjs +64 -3
- package/dist/transform/templates.cjs +169 -46
- package/dist/transform/templates.js +2 -2
- package/dist/transform/templates.mjs +169 -46
- package/dist/{transform-UWZ7ZGJ2.mjs → transform-QWWQDCXE.mjs} +7 -7
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +9 -3
package/dist/integrations.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.93 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __create = Object.create;
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -156,6 +156,7 @@ var init_intrinsics = __esm({
|
|
|
156
156
|
$effect: { export: "effect", module: REACTIVE_MODULE, returns: "effect" },
|
|
157
157
|
$store: { export: "store", module: "@fluixi/reactive/store", returns: "store-handle" },
|
|
158
158
|
$resource: { export: "resource", module: REACTIVE_MODULE, returns: "resource-handle" },
|
|
159
|
+
$cachedResource: { export: "cachedResource", module: "@fluixi/reactive/cached-resource", returns: "resource-handle" },
|
|
159
160
|
// No short runtime form for these yet, so the intrinsic stands for the `create*`
|
|
160
161
|
// name. Still worth having: no import to write, and when a shorter form is
|
|
161
162
|
// designed, the change is this line rather than a compiler pass.
|
|
@@ -166,6 +167,19 @@ var init_intrinsics = __esm({
|
|
|
166
167
|
// dependency analysis must not guess at.
|
|
167
168
|
$untrack: { export: "untrack", module: REACTIVE_MODULE, returns: "plain" },
|
|
168
169
|
$untrackStore: { export: "untrackStore", module: "@fluixi/reactive/store", returns: "plain" },
|
|
170
|
+
// Scopes, scheduling and lifecycle: no value to classify, but the same authoring promise,
|
|
171
|
+
// no import to write. `$cleanup` registers a callback on the current owner (`onCleanup`).
|
|
172
|
+
$batch: { export: "batch", module: REACTIVE_MODULE, returns: "plain" },
|
|
173
|
+
$cleanup: { export: "onCleanup", module: REACTIVE_MODULE, returns: "plain" },
|
|
174
|
+
$root: { export: "root", module: REACTIVE_MODULE, returns: "plain" },
|
|
175
|
+
$context: { export: "context", module: REACTIVE_MODULE, returns: "plain" },
|
|
176
|
+
$renderEffect: { export: "renderEffect", module: REACTIVE_MODULE, returns: "effect" },
|
|
177
|
+
$computed: { export: "computed", module: REACTIVE_MODULE, returns: "effect" },
|
|
178
|
+
// Storage for where the code runs, and a signal kept in it. `$persisted` is a signal
|
|
179
|
+
// handle as far as reads go: the same accessor with `set` on it.
|
|
180
|
+
$storage: { export: "useStorage", module: "@fluixi/core/storage", returns: "plain" },
|
|
181
|
+
$asyncStorage: { export: "useAsyncStorage", module: "@fluixi/core/storage", returns: "plain" },
|
|
182
|
+
$persisted: { export: "persisted", module: "@fluixi/core/storage", returns: "signal-handle" },
|
|
169
183
|
// An environment variable, public or server-only; the browser build refuses a secret.
|
|
170
184
|
$env: { export: "env", module: "@fluixi/start/env", returns: "plain" }
|
|
171
185
|
};
|
|
@@ -178,8 +192,11 @@ var init_intrinsics = __esm({
|
|
|
178
192
|
createMemo: "memo-accessor",
|
|
179
193
|
createEffect: "effect",
|
|
180
194
|
createRenderEffect: "effect",
|
|
195
|
+
renderEffect: "effect",
|
|
196
|
+
computed: "effect",
|
|
181
197
|
createStore: "reactive-object",
|
|
182
198
|
resource: "resource-handle",
|
|
199
|
+
cachedResource: "resource-handle",
|
|
183
200
|
createResource: "reactive-object",
|
|
184
201
|
createSelector: "memo-accessor",
|
|
185
202
|
createDeferred: "memo-accessor"
|
|
@@ -188,6 +205,7 @@ var init_intrinsics = __esm({
|
|
|
188
205
|
"@fluixi/reactive",
|
|
189
206
|
"@fluixi/reactive/signal",
|
|
190
207
|
"@fluixi/reactive/store",
|
|
208
|
+
"@fluixi/reactive/cached-resource",
|
|
191
209
|
"@fluixi/core"
|
|
192
210
|
];
|
|
193
211
|
INTRINSIC_CALL = new RegExp(`\\$(?:${Object.keys(INTRINSICS).map((n) => n.slice(1)).join("|")})\\s*\\(`);
|
|
@@ -686,11 +704,12 @@ var init_reactive_bindings = __esm({
|
|
|
686
704
|
});
|
|
687
705
|
|
|
688
706
|
// src/transform/source-locations.ts
|
|
689
|
-
function
|
|
707
|
+
function mayHaveSourceMarks(code) {
|
|
690
708
|
for (const name of RUNTIME_PRIMITIVES2) {
|
|
691
709
|
if (code.includes(name)) return true;
|
|
692
710
|
}
|
|
693
|
-
|
|
711
|
+
if (code.includes("$signal") || code.includes("$memo") || code.includes("$effect") || code.includes("$store")) return true;
|
|
712
|
+
return /\bclass\b[^{;]*\bextends\b/.test(code);
|
|
694
713
|
}
|
|
695
714
|
function isLoneBranch(statement, parent) {
|
|
696
715
|
if (!parent || statement.type === "BlockStatement") return false;
|
|
@@ -719,6 +738,14 @@ function walk3(node, visit, stack = []) {
|
|
|
719
738
|
}
|
|
720
739
|
function nameFor(stack) {
|
|
721
740
|
const declarator = stack[stack.length - 1];
|
|
741
|
+
if (declarator && CLASS_FIELDS.has(declarator.type)) {
|
|
742
|
+
const key = declarator.key;
|
|
743
|
+
if (key?.type === "Identifier" || key?.type === "PrivateIdentifier" || key?.type === "PrivateName") {
|
|
744
|
+
const name = key.name ?? key.id?.name;
|
|
745
|
+
return name;
|
|
746
|
+
}
|
|
747
|
+
return void 0;
|
|
748
|
+
}
|
|
722
749
|
if (declarator?.type !== "VariableDeclarator") return void 0;
|
|
723
750
|
const id = declarator.id;
|
|
724
751
|
if (id?.type === "Identifier") return id.name;
|
|
@@ -767,6 +794,17 @@ function collectSourceEdits(program, filename) {
|
|
|
767
794
|
});
|
|
768
795
|
}
|
|
769
796
|
}
|
|
797
|
+
if ((node.type === "ClassDeclaration" || node.type === "ClassExpression") && node.superClass && !node.declare) {
|
|
798
|
+
const at = node.loc?.start;
|
|
799
|
+
const body = node.body;
|
|
800
|
+
if (at && body) {
|
|
801
|
+
edits.push({
|
|
802
|
+
start: body.start + 1,
|
|
803
|
+
end: body.start + 1,
|
|
804
|
+
code: `static{globalThis.${CLASS_MARKER}?.(this,${JSON.stringify(filename)},${at.line},${at.column});}`
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
}
|
|
770
808
|
if (node.type !== "CallExpression") return;
|
|
771
809
|
const callee = node.callee;
|
|
772
810
|
if (callee?.type !== "Identifier") return;
|
|
@@ -776,6 +814,26 @@ function collectSourceEdits(program, filename) {
|
|
|
776
814
|
if (!intrinsic && !imported) return;
|
|
777
815
|
const position = node.loc?.start;
|
|
778
816
|
if (!position) return;
|
|
817
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
818
|
+
const up = stack[i];
|
|
819
|
+
if (isStatement(up)) break;
|
|
820
|
+
if (CLASS_FIELDS.has(up.type)) {
|
|
821
|
+
if (claimed.has(node.start)) return;
|
|
822
|
+
claimed.add(node.start);
|
|
823
|
+
const label2 = nameFor(stack);
|
|
824
|
+
const own = !up.static;
|
|
825
|
+
const args2 = [
|
|
826
|
+
JSON.stringify(filename),
|
|
827
|
+
String(position.line),
|
|
828
|
+
String(position.column),
|
|
829
|
+
label2 ? JSON.stringify(label2) : own ? "undefined" : void 0,
|
|
830
|
+
own ? "this" : void 0
|
|
831
|
+
].filter((a) => a !== void 0).join(",");
|
|
832
|
+
edits.push({ start: node.start, end: node.start, code: `(globalThis.${SOURCE_MARKER}?.(${args2}),` });
|
|
833
|
+
edits.push({ start: node.end, end: node.end, code: ")" });
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
779
837
|
let statement;
|
|
780
838
|
let parent;
|
|
781
839
|
let index = -1;
|
|
@@ -815,7 +873,7 @@ function collectSourceEdits(program, filename) {
|
|
|
815
873
|
});
|
|
816
874
|
return { edits, marked: edits.length };
|
|
817
875
|
}
|
|
818
|
-
var SOURCE_MARKER, COMPONENT_MARKER, HOLE_MARKER, markHole, PROPS_MARKER, markProps, RUNTIME_PRIMITIVES2, SINGLE_STATEMENT_PARENTS;
|
|
876
|
+
var SOURCE_MARKER, COMPONENT_MARKER, CLASS_MARKER, HOLE_MARKER, markHole, PROPS_MARKER, markProps, RUNTIME_PRIMITIVES2, SINGLE_STATEMENT_PARENTS, CLASS_FIELDS;
|
|
819
877
|
var init_source_locations = __esm({
|
|
820
878
|
"src/transform/source-locations.ts"() {
|
|
821
879
|
"use strict";
|
|
@@ -823,6 +881,7 @@ var init_source_locations = __esm({
|
|
|
823
881
|
init_reactive_bindings();
|
|
824
882
|
SOURCE_MARKER = "__fx_source";
|
|
825
883
|
COMPONENT_MARKER = "__fx_component";
|
|
884
|
+
CLASS_MARKER = "__fx_class";
|
|
826
885
|
HOLE_MARKER = "__fx_hole";
|
|
827
886
|
markHole = (accessor, line, column, name) => `(globalThis.${HOLE_MARKER} ?? ((f) => f))(${accessor},${line},${column}${name === void 0 ? "" : `,${JSON.stringify(name)}`})`;
|
|
828
887
|
PROPS_MARKER = "__fx_props";
|
|
@@ -850,6 +909,7 @@ var init_source_locations = __esm({
|
|
|
850
909
|
"LabeledStatement",
|
|
851
910
|
"WithStatement"
|
|
852
911
|
]);
|
|
912
|
+
CLASS_FIELDS = /* @__PURE__ */ new Set(["PropertyDefinition", "ClassProperty", "ClassPrivateProperty", "AccessorProperty"]);
|
|
853
913
|
}
|
|
854
914
|
});
|
|
855
915
|
|
|
@@ -1013,13 +1073,16 @@ function emitComponent(name, props, children, used, templates, at) {
|
|
|
1013
1073
|
used.add("createComponent");
|
|
1014
1074
|
const spreads = props.filter((p) => p.kind === "spread");
|
|
1015
1075
|
const normal = props.filter((p) => p.kind !== "spread");
|
|
1016
|
-
const
|
|
1017
|
-
(p) => `get ${propKey(p.name)}() { return ${componentPropValue(p)}; }`
|
|
1018
|
-
);
|
|
1076
|
+
const bodies = normal.map((p) => [p.name, componentPropValue(p)]);
|
|
1019
1077
|
if (children.length > 0) {
|
|
1020
|
-
|
|
1078
|
+
bodies.push(["children", emitChildren(children, used, templates)]);
|
|
1079
|
+
}
|
|
1080
|
+
let obj = `{ ${bodies.map(([name2, body]) => `get ${propKey(name2)}() { return ${body}; }`).join(", ")} }`;
|
|
1081
|
+
if (bodies.some(([, body]) => /\bthis\b/.test(body))) {
|
|
1082
|
+
const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => ${body}`);
|
|
1083
|
+
const getters = bodies.map(([name2]) => `get ${propKey(name2)}() { return _$t[${JSON.stringify(name2)}](); }`);
|
|
1084
|
+
obj = `((_$t) => ({ ${getters.join(", ")} }))({ ${thunks.join(", ")} })`;
|
|
1021
1085
|
}
|
|
1022
|
-
let obj = `{ ${entries.join(", ")} }`;
|
|
1023
1086
|
if (spreads.length > 0) {
|
|
1024
1087
|
used.add("mergeProps");
|
|
1025
1088
|
obj = `mergeProps(${spreads.map((s) => s.expr).join(", ")}, ${obj})`;
|
|
@@ -1100,7 +1163,8 @@ function emitNode(node, used, templates) {
|
|
|
1100
1163
|
} else {
|
|
1101
1164
|
used.add("spread");
|
|
1102
1165
|
const svgFlag = node.svg ? ", isSVG: true" : "";
|
|
1103
|
-
const
|
|
1166
|
+
const accessors = node.props.filter((p) => p.kind !== "spread" && p.expr !== void 0 && p.reactive && p.name !== "ref").map((p) => p.name);
|
|
1167
|
+
const customFlag = node.tag.includes("-") ? `, isCustomElement: true, accessors: ${JSON.stringify(accessors)}` : "";
|
|
1104
1168
|
parts.push(
|
|
1105
1169
|
`spread({ element: ${el}, props: ${emitProps(node.props, null, used)}${svgFlag}${customFlag} });`
|
|
1106
1170
|
);
|
|
@@ -1191,7 +1255,7 @@ function lowerTemplate(pieces, holes, used, opts = {}) {
|
|
|
1191
1255
|
const { root } = (0, import_template_parser.parseTemplate)(pieces, { svg: opts.svg });
|
|
1192
1256
|
return new Lowerer(holes, used, opts.sourceFile, opts.positionAt).lowerRoot(root.children);
|
|
1193
1257
|
}
|
|
1194
|
-
var import_template_parser, DELEGATED, Lowerer;
|
|
1258
|
+
var import_template_parser, DELEGATED, CONTAINER, Lowerer;
|
|
1195
1259
|
var init_template = __esm({
|
|
1196
1260
|
"src/lower/template.ts"() {
|
|
1197
1261
|
"use strict";
|
|
@@ -1214,6 +1278,7 @@ var init_template = __esm({
|
|
|
1214
1278
|
"mousedown",
|
|
1215
1279
|
"mouseup"
|
|
1216
1280
|
]);
|
|
1281
|
+
CONTAINER = "container";
|
|
1217
1282
|
Lowerer = class {
|
|
1218
1283
|
constructor(holes, used, sourceFile, positionAt) {
|
|
1219
1284
|
this.holes = holes;
|
|
@@ -1265,10 +1330,6 @@ var init_template = __esm({
|
|
|
1265
1330
|
if (hasElse) i = elseIdx;
|
|
1266
1331
|
continue;
|
|
1267
1332
|
}
|
|
1268
|
-
if (child.attributes.some((a) => a.kind === "EachDirective")) {
|
|
1269
|
-
out.push(this.lowerEach(child));
|
|
1270
|
-
continue;
|
|
1271
|
-
}
|
|
1272
1333
|
}
|
|
1273
1334
|
const node = this.lowerNode(child);
|
|
1274
1335
|
if (node) out.push(node);
|
|
@@ -1310,13 +1371,16 @@ var init_template = __esm({
|
|
|
1310
1371
|
node.props.unshift({ name: "component", kind: "attr", expr: `() => ${paren(this.hole(isAttr.value.hole).code, "arrowBody")}` });
|
|
1311
1372
|
return node;
|
|
1312
1373
|
}
|
|
1374
|
+
const each = this.lowerEach(el);
|
|
1375
|
+
const children = each ? [each] : this.lowerChildren(el.children);
|
|
1376
|
+
if (el.tag === CONTAINER) return children.length === 1 ? children[0] : { kind: "fragment", children };
|
|
1313
1377
|
const at = this.tagAt(el);
|
|
1314
1378
|
return {
|
|
1315
1379
|
kind: "element",
|
|
1316
1380
|
tag: el.tag,
|
|
1317
1381
|
svg: el.namespace === "svg",
|
|
1318
1382
|
props: this.lowerAttributes(el.attributes),
|
|
1319
|
-
children
|
|
1383
|
+
children,
|
|
1320
1384
|
static: false,
|
|
1321
1385
|
...at ? { at } : {}
|
|
1322
1386
|
};
|
|
@@ -1388,10 +1452,14 @@ var init_template = __esm({
|
|
|
1388
1452
|
const at = this.tagAt(el);
|
|
1389
1453
|
return { kind: "component", name: "Show", props, children: [child], ...at ? { at } : {}, ...cond.at ? { bindAt: cond.at } : {} };
|
|
1390
1454
|
}
|
|
1391
|
-
/**
|
|
1455
|
+
/**
|
|
1456
|
+
* `<el each=${items} key?>${item => …}</el>` → `<el><For each>{item => …}</For></el>`: the
|
|
1457
|
+
* content is repeated per item. Content that is not a `${item => …}` arrow is repeated as
|
|
1458
|
+
* it is. Null when the element has no `each`.
|
|
1459
|
+
*/
|
|
1392
1460
|
lowerEach(el) {
|
|
1393
1461
|
const eachDir = el.attributes.find((a) => a.kind === "EachDirective");
|
|
1394
|
-
if (!eachDir || eachDir.kind !== "EachDirective") return
|
|
1462
|
+
if (!eachDir || eachDir.kind !== "EachDirective") return null;
|
|
1395
1463
|
const each = this.hole(eachDir.hole);
|
|
1396
1464
|
const props = [{ name: "each", kind: "attr", expr: each.code, reactive: each.reactive, ...each.at ? { at: each.at } : {} }];
|
|
1397
1465
|
if (eachDir.key) {
|
|
@@ -1401,12 +1469,12 @@ var init_template = __esm({
|
|
|
1401
1469
|
const arrow = this.itemArrow(el);
|
|
1402
1470
|
let childrenCode;
|
|
1403
1471
|
if (arrow) {
|
|
1404
|
-
const
|
|
1405
|
-
|
|
1406
|
-
childrenCode = `(${arrow.params.join(", ")}) => ${paren(this.emit(repeated), "arrowBody")}`;
|
|
1472
|
+
const body = arrow.bodyReactive ? `() => ${paren(arrow.body, "arrowBody")}` : paren(arrow.body, "arrowBody");
|
|
1473
|
+
childrenCode = `(${arrow.params.join(", ")}) => ${body}`;
|
|
1407
1474
|
} else {
|
|
1408
|
-
const
|
|
1409
|
-
|
|
1475
|
+
const content = this.lowerChildren(el.children);
|
|
1476
|
+
const ir = content.length === 1 ? content[0] : { kind: "fragment", children: content };
|
|
1477
|
+
childrenCode = `() => ${paren(this.emit(ir), "arrowBody")}`;
|
|
1410
1478
|
}
|
|
1411
1479
|
const children = [{ kind: "expr", code: childrenCode, reactive: false }];
|
|
1412
1480
|
const at = this.tagAt(el);
|
|
@@ -1423,25 +1491,6 @@ var init_template = __esm({
|
|
|
1423
1491
|
const clone = { ...el, attributes: el.attributes.filter((a) => !drop(a)) };
|
|
1424
1492
|
return clone.kind === "Element" ? this.lowerElement(clone) : this.lowerComponent(clone);
|
|
1425
1493
|
}
|
|
1426
|
-
/** Same element (minus each/key) but with explicit IR children. */
|
|
1427
|
-
rebuildWithChildren(el, children) {
|
|
1428
|
-
const props = this.lowerAttributes(
|
|
1429
|
-
el.attributes.filter((a) => a.kind !== "EachDirective")
|
|
1430
|
-
);
|
|
1431
|
-
if (el.kind === "Element") {
|
|
1432
|
-
const at = this.tagAt(el);
|
|
1433
|
-
return {
|
|
1434
|
-
kind: "element",
|
|
1435
|
-
tag: el.tag,
|
|
1436
|
-
svg: el.namespace === "svg",
|
|
1437
|
-
props,
|
|
1438
|
-
children,
|
|
1439
|
-
static: false,
|
|
1440
|
-
...at ? { at } : {}
|
|
1441
|
-
};
|
|
1442
|
-
}
|
|
1443
|
-
return { kind: "component", name: el.tag, props, children };
|
|
1444
|
-
}
|
|
1445
1494
|
// --- attributes ---------------------------------------------------------
|
|
1446
1495
|
lowerAttributes(attrs) {
|
|
1447
1496
|
const props = [];
|
|
@@ -1855,6 +1904,21 @@ var init_expr_shape = __esm({
|
|
|
1855
1904
|
});
|
|
1856
1905
|
|
|
1857
1906
|
// src/lower/jsx.ts
|
|
1907
|
+
function directive(node, name) {
|
|
1908
|
+
if (node.type !== "JSXElement") return void 0;
|
|
1909
|
+
const opening = node.openingElement;
|
|
1910
|
+
if (opening.name.type !== "JSXIdentifier" || opening.name.name[0] !== opening.name.name[0].toLowerCase()) return void 0;
|
|
1911
|
+
return opening.attributes.find((a) => a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" && a.name.name === name);
|
|
1912
|
+
}
|
|
1913
|
+
function directiveExpr(attr) {
|
|
1914
|
+
const v = attr.value;
|
|
1915
|
+
return v?.type === "JSXExpressionContainer" && v.expression?.type !== "JSXEmptyExpression" ? v.expression : void 0;
|
|
1916
|
+
}
|
|
1917
|
+
function emitIR(ir, ctx) {
|
|
1918
|
+
const { code, imports, templates } = imperativeBackend.emit(ir, {});
|
|
1919
|
+
for (const s of imports) ctx.used.add(s);
|
|
1920
|
+
return inlineTemplates(code, templates);
|
|
1921
|
+
}
|
|
1858
1922
|
function literalOf(node) {
|
|
1859
1923
|
if (node.type === "StringLiteral" || node.type === "NumericLiteral" || node.type === "BooleanLiteral") {
|
|
1860
1924
|
return node.value;
|
|
@@ -1957,7 +2021,16 @@ function buildProps(attrs, ctx) {
|
|
|
1957
2021
|
}
|
|
1958
2022
|
function buildChildren(children, ctx) {
|
|
1959
2023
|
const out = [];
|
|
1960
|
-
for (
|
|
2024
|
+
for (let i = 0; i < children.length; i++) {
|
|
2025
|
+
const child = children[i];
|
|
2026
|
+
if (directive(child, "if")) {
|
|
2027
|
+
let next = i + 1;
|
|
2028
|
+
while (next < children.length && children[next].type === "JSXText" && !cleanTemplateText(children[next].value)) next++;
|
|
2029
|
+
const fallback = directive(children[next], "else") ? children[next] : null;
|
|
2030
|
+
out.push(buildIf(child, fallback, ctx));
|
|
2031
|
+
if (fallback) i = next;
|
|
2032
|
+
continue;
|
|
2033
|
+
}
|
|
1961
2034
|
if (child.type === "JSXText") {
|
|
1962
2035
|
const text = cleanTemplateText(child.value);
|
|
1963
2036
|
if (text) out.push({ kind: "text", value: text });
|
|
@@ -1994,26 +2067,75 @@ function readLoad(attrs) {
|
|
|
1994
2067
|
}
|
|
1995
2068
|
return void 0;
|
|
1996
2069
|
}
|
|
2070
|
+
function buildIf(node, fallback, ctx) {
|
|
2071
|
+
const cond = directiveExpr(directive(node, "if"));
|
|
2072
|
+
const props = [
|
|
2073
|
+
cond ? { name: "when", kind: "attr", expr: ctx.code(cond), reactive: isReactive(cond), at: posOf(cond, ctx) } : { name: "when", kind: "attr", literal: true }
|
|
2074
|
+
];
|
|
2075
|
+
if (fallback) {
|
|
2076
|
+
props.push({ name: "fallback", kind: "attr", expr: emitIR(buildElement(fallback, ctx, ["else"]), ctx), jsxElement: true });
|
|
2077
|
+
}
|
|
2078
|
+
return { kind: "component", name: "Show", props, children: [buildElement(node, ctx, ["if"])] };
|
|
2079
|
+
}
|
|
2080
|
+
function buildEach(node, ctx) {
|
|
2081
|
+
const attr = directive(node, "each");
|
|
2082
|
+
if (!attr) return null;
|
|
2083
|
+
const list = directiveExpr(attr);
|
|
2084
|
+
const props = [
|
|
2085
|
+
list ? { name: "each", kind: "attr", expr: ctx.code(list), reactive: isReactive(list), at: posOf(list, ctx) } : { name: "each", kind: "attr", expr: "[]" }
|
|
2086
|
+
];
|
|
2087
|
+
const key = directive(node, "key");
|
|
2088
|
+
if (key) {
|
|
2089
|
+
const keyExpr = directiveExpr(key);
|
|
2090
|
+
const by = isString(key.value) ? `(item) => item[${JSON.stringify(literalOf(key.value))}]` : keyExpr ? ctx.code(keyExpr) : void 0;
|
|
2091
|
+
if (by) props.push({ name: "by", kind: "attr", expr: by });
|
|
2092
|
+
}
|
|
2093
|
+
const content = node.children.filter((c) => !(c.type === "JSXText" && !cleanTemplateText(c.value)));
|
|
2094
|
+
const only = content.length === 1 && content[0].type === "JSXExpressionContainer" ? content[0].expression : null;
|
|
2095
|
+
let render;
|
|
2096
|
+
if (only && (only.type === "ArrowFunctionExpression" || only.type === "FunctionExpression")) {
|
|
2097
|
+
const fn = ctx.code(only);
|
|
2098
|
+
const live = only.type === "ArrowFunctionExpression" && only.body.type !== "BlockStatement" && isReactive(only.body);
|
|
2099
|
+
render = live ? `(...args) => () => (${fn})(...args)` : fn;
|
|
2100
|
+
} else {
|
|
2101
|
+
const built = buildChildren(node.children, ctx);
|
|
2102
|
+
const ir = built.length === 1 ? built[0] : { kind: "fragment", children: built };
|
|
2103
|
+
render = `() => ${paren(emitIR(ir, ctx), "arrowBody")}`;
|
|
2104
|
+
}
|
|
2105
|
+
return { kind: "component", name: "For", props, children: [{ kind: "expr", code: render, reactive: false }] };
|
|
2106
|
+
}
|
|
2107
|
+
function buildElement(node, ctx, handled) {
|
|
2108
|
+
const skip = new Set(handled);
|
|
2109
|
+
const directives = /* @__PURE__ */ new Set(["if", "else", "each", ...directive(node, "each") ? ["key"] : []]);
|
|
2110
|
+
const attributes = node.openingElement.attributes.filter(
|
|
2111
|
+
(a) => !(a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" && (skip.has(a.name.name) || directives.has(a.name.name)))
|
|
2112
|
+
);
|
|
2113
|
+
const { tag } = tagInfo(node.openingElement.name, ctx);
|
|
2114
|
+
const each = buildEach(node, ctx);
|
|
2115
|
+
const children = each ? [each] : buildChildren(node.children, ctx);
|
|
2116
|
+
if (tag === CONTAINER2) return children.length === 1 ? children[0] : { kind: "fragment", children };
|
|
2117
|
+
const at = ctx.sourceFile && node.loc?.start ? { file: ctx.sourceFile, line: node.loc.start.line, column: node.loc.start.column } : void 0;
|
|
2118
|
+
return { kind: "element", tag, svg: SVG_TAGS.has(tag), props: buildProps(attributes, ctx), children, static: false, ...at ? { at } : {} };
|
|
2119
|
+
}
|
|
1997
2120
|
function buildNode(node, ctx) {
|
|
1998
2121
|
if (node.type === "JSXFragment") {
|
|
1999
2122
|
return { kind: "fragment", children: buildChildren(node.children, ctx) };
|
|
2000
2123
|
}
|
|
2124
|
+
if (directive(node, "if")) return buildIf(node, null, ctx);
|
|
2001
2125
|
const { tag, component } = tagInfo(node.openingElement.name, ctx);
|
|
2126
|
+
if (!component) return buildElement(node, ctx, []);
|
|
2002
2127
|
const props = buildProps(node.openingElement.attributes, ctx);
|
|
2003
2128
|
const children = buildChildren(node.children, ctx);
|
|
2004
2129
|
const at = ctx.sourceFile && node.loc?.start ? { file: ctx.sourceFile, line: node.loc.start.line, column: node.loc.start.column } : void 0;
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
return { kind: "component", name: tag, props, children, ...load ? { load } : {}, ...at ? { at } : {} };
|
|
2008
|
-
}
|
|
2009
|
-
return { kind: "element", tag, svg: SVG_TAGS.has(tag), props, children, static: false, ...at ? { at } : {} };
|
|
2130
|
+
const load = readLoad(node.openingElement.attributes);
|
|
2131
|
+
return { kind: "component", name: tag, props, children, ...load ? { load } : {}, ...at ? { at } : {} };
|
|
2010
2132
|
}
|
|
2011
2133
|
function buildJsxIR(node, ctx) {
|
|
2012
2134
|
const ir = buildNode(node, ctx);
|
|
2013
2135
|
analyzeStatic(ir);
|
|
2014
2136
|
return ir;
|
|
2015
2137
|
}
|
|
2016
|
-
var SVG_TAGS, EVENT_RE, DELEGATED2, isReactive, posOf, isString;
|
|
2138
|
+
var SVG_TAGS, EVENT_RE, DELEGATED2, isReactive, CONTAINER2, posOf, isString;
|
|
2017
2139
|
var init_jsx = __esm({
|
|
2018
2140
|
"src/lower/jsx.ts"() {
|
|
2019
2141
|
"use strict";
|
|
@@ -2023,6 +2145,7 @@ var init_jsx = __esm({
|
|
|
2023
2145
|
init_analyze_static();
|
|
2024
2146
|
init_text();
|
|
2025
2147
|
init_paren();
|
|
2148
|
+
init_imperative();
|
|
2026
2149
|
SVG_TAGS = /* @__PURE__ */ new Set([
|
|
2027
2150
|
"svg",
|
|
2028
2151
|
"path",
|
|
@@ -2053,6 +2176,7 @@ var init_jsx = __esm({
|
|
|
2053
2176
|
"mouseup"
|
|
2054
2177
|
]);
|
|
2055
2178
|
isReactive = (node) => isReactiveShape(shapeOf(node));
|
|
2179
|
+
CONTAINER2 = "container";
|
|
2056
2180
|
posOf = (node, ctx) => {
|
|
2057
2181
|
if (!ctx.sourceFile) return void 0;
|
|
2058
2182
|
const at = node.loc?.start;
|
|
@@ -3378,7 +3502,7 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3378
3502
|
const wantsJsx = format !== "lit";
|
|
3379
3503
|
const mayHaveTemplate = wantsLit && (code.includes(`${litTag}\``) || code.includes("svg`"));
|
|
3380
3504
|
const wantsIntrinsics = options.intrinsics !== false && mayHaveIntrinsic(code);
|
|
3381
|
-
const wantsSources = options.sourceLocations === true &&
|
|
3505
|
+
const wantsSources = options.sourceLocations === true && mayHaveSourceMarks(code);
|
|
3382
3506
|
const sourceName = relativeToRoot(id, options.sourceRoot);
|
|
3383
3507
|
if (!mayHaveTemplate && !(wantsJsx && code.includes("<")) && !wantsIntrinsics && !wantsSources) return null;
|
|
3384
3508
|
const ast = (0, import_parser2.parse)(code, {
|
|
@@ -3733,7 +3857,7 @@ var server_fns_exports = {};
|
|
|
3733
3857
|
__export(server_fns_exports, {
|
|
3734
3858
|
transformServerFns: () => transformServerFns
|
|
3735
3859
|
});
|
|
3736
|
-
function
|
|
3860
|
+
function directive2(node) {
|
|
3737
3861
|
if (!FUNCTION_TYPES.has(node.type)) return null;
|
|
3738
3862
|
const body = node.body;
|
|
3739
3863
|
if (!body || body.type !== "BlockStatement") return null;
|
|
@@ -3749,7 +3873,7 @@ function findServerFns(node, out) {
|
|
|
3749
3873
|
return;
|
|
3750
3874
|
}
|
|
3751
3875
|
if (typeof node.type === "string") {
|
|
3752
|
-
const found =
|
|
3876
|
+
const found = directive2(node);
|
|
3753
3877
|
if (found) {
|
|
3754
3878
|
out.push({ fn: node, directive: found });
|
|
3755
3879
|
return;
|
package/dist/integrations.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.93 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
import {
|
|
3
3
|
INTRINSICS,
|
|
4
4
|
builtinComponentMap,
|
|
5
5
|
createComponentResolver
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-OD53TMER.mjs";
|
|
7
7
|
import {
|
|
8
8
|
__require
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-TJIH7TLX.mjs";
|
|
10
10
|
|
|
11
11
|
// src/resolve/write-globals.ts
|
|
12
12
|
import { mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
@@ -238,7 +238,7 @@ import { join as _join } from "node:path";
|
|
|
238
238
|
async function createBabelPlugin(options = {}) {
|
|
239
239
|
let pluginModule = null;
|
|
240
240
|
try {
|
|
241
|
-
pluginModule = await import("./babel-
|
|
241
|
+
pluginModule = await import("./babel-RJHJQVEM.mjs");
|
|
242
242
|
} catch (e) {
|
|
243
243
|
console.warn("Could not load the babel front-end:", e);
|
|
244
244
|
}
|
|
@@ -409,7 +409,7 @@ function transformOptions(options, id) {
|
|
|
409
409
|
}
|
|
410
410
|
async function rewriteProps(code, id, options) {
|
|
411
411
|
if (options.propsDestructure === false) return code;
|
|
412
|
-
const { transformProps } = await import("./transform-
|
|
412
|
+
const { transformProps } = await import("./transform-QWWQDCXE.mjs");
|
|
413
413
|
const result = transformProps(code, id);
|
|
414
414
|
reportDiagnostics({ propsDiagnostics: result.diagnostics }, id);
|
|
415
415
|
return result.rewritten > 0 ? result.code : code;
|
|
@@ -432,7 +432,7 @@ function reportDiagnostics(result, id) {
|
|
|
432
432
|
}
|
|
433
433
|
async function compileModule(code, id, options) {
|
|
434
434
|
if (!options.babel) {
|
|
435
|
-
const { transformTemplates } = await import("./transform-
|
|
435
|
+
const { transformTemplates } = await import("./transform-QWWQDCXE.mjs");
|
|
436
436
|
const result2 = transformTemplates(code, id, transformOptions(options, id));
|
|
437
437
|
reportDiagnostics(result2, id);
|
|
438
438
|
return result2;
|
|
@@ -551,10 +551,10 @@ export { isServerFnRequest, handleServerFn } from '@fluixi/start/server-fn';
|
|
|
551
551
|
if (!code.includes("use server")) return null;
|
|
552
552
|
const args = { ssr: !!opts?.ssr, filename: id, root };
|
|
553
553
|
if (options.babel) {
|
|
554
|
-
const { transformServerFunctions } = await import("./server-functions-
|
|
554
|
+
const { transformServerFunctions } = await import("./server-functions-CTDXX67X.mjs");
|
|
555
555
|
return transformServerFunctions(code, args);
|
|
556
556
|
}
|
|
557
|
-
const { transformServerFns } = await import("./server-fns-
|
|
557
|
+
const { transformServerFns } = await import("./server-fns-ZFRDIQ2X.mjs");
|
|
558
558
|
return transformServerFns(code, args);
|
|
559
559
|
}
|
|
560
560
|
};
|