@fluixi/compiler 1.0.0-alpha.91 → 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 +21 -1
- package/dist/analyze/intrinsics.d.ts.map +1 -1
- package/dist/analyze/intrinsics.js +20 -0
- package/dist/analyze/intrinsics.mjs +21 -1
- package/dist/analyze/reactive-bindings.cjs +21 -1
- package/dist/analyze/reactive-bindings.mjs +21 -1
- package/dist/analyze/static-graph.cjs +25 -5
- package/dist/analyze/static-graph.d.ts.map +1 -1
- package/dist/analyze/static-graph.js +6 -4
- package/dist/analyze/static-graph.mjs +25 -5
- package/dist/{babel-VBLQRHQ2.mjs → babel-RJHJQVEM.mjs} +4 -4
- package/dist/{chunk-D53J7ICY.mjs → chunk-56QSOVVL.mjs} +1 -1
- package/dist/{chunk-S4J4OCWK.mjs → chunk-OD53TMER.mjs} +22 -2
- package/dist/{chunk-TWDJUXWZ.mjs → chunk-R7PPFBCL.mjs} +1 -1
- package/dist/{chunk-QX6Y3OAR.mjs → chunk-TJIH7TLX.mjs} +1 -1
- package/dist/{chunk-3JWMCK4A.mjs → chunk-U7HCFLZ2.mjs} +153 -48
- package/dist/codegen/backends/imperative.cjs +27 -7
- package/dist/codegen/backends/imperative.d.ts.map +1 -1
- package/dist/codegen/backends/imperative.js +19 -4
- package/dist/codegen/backends/imperative.mjs +27 -7
- package/dist/frontend/babel/build-ir-lit.cjs +123 -44
- package/dist/frontend/babel/build-ir-lit.mjs +123 -44
- package/dist/frontend/babel/build-ir.cjs +123 -44
- package/dist/frontend/babel/build-ir.mjs +123 -44
- package/dist/frontend/babel/index.cjs +124 -45
- package/dist/frontend/babel/index.mjs +124 -45
- package/dist/frontend/babel/lower-template.cjs +123 -44
- package/dist/frontend/babel/lower-template.mjs +123 -44
- package/dist/frontend/babel/plugin.cjs +123 -44
- package/dist/frontend/babel/plugin.mjs +123 -44
- package/dist/index.cjs +86 -46
- package/dist/index.mjs +88 -48
- package/dist/integrations.cjs +246 -61
- package/dist/integrations.mjs +53 -19
- package/dist/lower/compile-template.cjs +44 -39
- package/dist/lower/compile-template.mjs +44 -39
- 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 +43 -38
- package/dist/lower/template.d.ts.map +1 -1
- package/dist/lower/template.js +22 -30
- package/dist/lower/template.mjs +43 -38
- package/dist/resolve/builtins.cjs +1 -1
- package/dist/resolve/builtins.mjs +1 -1
- package/dist/resolve/component-globals.cjs +33 -8
- package/dist/resolve/component-globals.d.cts +8 -0
- package/dist/resolve/component-globals.d.ts +8 -0
- package/dist/resolve/component-globals.d.ts.map +1 -1
- package/dist/resolve/component-globals.js +21 -12
- package/dist/resolve/component-globals.mjs +33 -8
- package/dist/resolve/write-globals.cjs +59 -8
- package/dist/resolve/write-globals.d.cts +6 -0
- package/dist/resolve/write-globals.d.ts +6 -0
- package/dist/resolve/write-globals.d.ts.map +1 -1
- package/dist/resolve/write-globals.js +35 -2
- package/dist/resolve/write-globals.mjs +61 -10
- package/dist/{server-fns-J56G3PFP.mjs → server-fns-ZFRDIQ2X.mjs} +4 -4
- package/dist/{server-functions-7PUFLRGF.mjs → server-functions-CTDXX67X.mjs} +3 -3
- package/dist/transform/index.cjs +199 -49
- package/dist/transform/index.mjs +199 -49
- package/dist/transform/intrinsics.cjs +47 -2
- package/dist/transform/intrinsics.d.cts +12 -0
- package/dist/transform/intrinsics.d.ts +12 -0
- package/dist/transform/intrinsics.d.ts.map +1 -1
- package/dist/transform/intrinsics.js +43 -1
- package/dist/transform/intrinsics.mjs +47 -2
- package/dist/transform/source-locations.cjs +67 -4
- 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 +67 -4
- package/dist/transform/templates.cjs +198 -48
- package/dist/transform/templates.d.ts.map +1 -1
- package/dist/transform/templates.js +5 -3
- package/dist/transform/templates.mjs +198 -48
- package/dist/{transform-D536WXGM.mjs → transform-QWWQDCXE.mjs} +33 -8
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +9 -3
|
@@ -1519,6 +1519,7 @@ var INTRINSICS = {
|
|
|
1519
1519
|
$effect: { export: "effect", module: REACTIVE_MODULE, returns: "effect" },
|
|
1520
1520
|
$store: { export: "store", module: "@fluixi/reactive/store", returns: "store-handle" },
|
|
1521
1521
|
$resource: { export: "resource", module: REACTIVE_MODULE, returns: "resource-handle" },
|
|
1522
|
+
$cachedResource: { export: "cachedResource", module: "@fluixi/reactive/cached-resource", returns: "resource-handle" },
|
|
1522
1523
|
// No short runtime form for these yet, so the intrinsic stands for the `create*`
|
|
1523
1524
|
// name. Still worth having: no import to write, and when a shorter form is
|
|
1524
1525
|
// designed, the change is this line rather than a compiler pass.
|
|
@@ -1528,7 +1529,22 @@ var INTRINSICS = {
|
|
|
1528
1529
|
// does. `untrack` suppresses dependency collection, which is exactly the kind of thing
|
|
1529
1530
|
// dependency analysis must not guess at.
|
|
1530
1531
|
$untrack: { export: "untrack", module: REACTIVE_MODULE, returns: "plain" },
|
|
1531
|
-
$untrackStore: { export: "untrackStore", module: "@fluixi/reactive/store", returns: "plain" }
|
|
1532
|
+
$untrackStore: { export: "untrackStore", module: "@fluixi/reactive/store", returns: "plain" },
|
|
1533
|
+
// Scopes, scheduling and lifecycle: no value to classify, but the same authoring promise,
|
|
1534
|
+
// no import to write. `$cleanup` registers a callback on the current owner (`onCleanup`).
|
|
1535
|
+
$batch: { export: "batch", module: REACTIVE_MODULE, returns: "plain" },
|
|
1536
|
+
$cleanup: { export: "onCleanup", module: REACTIVE_MODULE, returns: "plain" },
|
|
1537
|
+
$root: { export: "root", module: REACTIVE_MODULE, returns: "plain" },
|
|
1538
|
+
$context: { export: "context", module: REACTIVE_MODULE, returns: "plain" },
|
|
1539
|
+
$renderEffect: { export: "renderEffect", module: REACTIVE_MODULE, returns: "effect" },
|
|
1540
|
+
$computed: { export: "computed", module: REACTIVE_MODULE, returns: "effect" },
|
|
1541
|
+
// Storage for where the code runs, and a signal kept in it. `$persisted` is a signal
|
|
1542
|
+
// handle as far as reads go: the same accessor with `set` on it.
|
|
1543
|
+
$storage: { export: "useStorage", module: "@fluixi/core/storage", returns: "plain" },
|
|
1544
|
+
$asyncStorage: { export: "useAsyncStorage", module: "@fluixi/core/storage", returns: "plain" },
|
|
1545
|
+
$persisted: { export: "persisted", module: "@fluixi/core/storage", returns: "signal-handle" },
|
|
1546
|
+
// An environment variable, public or server-only; the browser build refuses a secret.
|
|
1547
|
+
$env: { export: "env", module: "@fluixi/start/env", returns: "plain" }
|
|
1532
1548
|
};
|
|
1533
1549
|
var RUNTIME_PRIMITIVES = {
|
|
1534
1550
|
signal: "signal-handle",
|
|
@@ -1539,8 +1555,11 @@ var RUNTIME_PRIMITIVES = {
|
|
|
1539
1555
|
createMemo: "memo-accessor",
|
|
1540
1556
|
createEffect: "effect",
|
|
1541
1557
|
createRenderEffect: "effect",
|
|
1558
|
+
renderEffect: "effect",
|
|
1559
|
+
computed: "effect",
|
|
1542
1560
|
createStore: "reactive-object",
|
|
1543
1561
|
resource: "resource-handle",
|
|
1562
|
+
cachedResource: "resource-handle",
|
|
1544
1563
|
createResource: "reactive-object",
|
|
1545
1564
|
createSelector: "memo-accessor",
|
|
1546
1565
|
createDeferred: "memo-accessor"
|
|
@@ -1549,6 +1568,7 @@ var PRIMITIVE_MODULES = [
|
|
|
1549
1568
|
"@fluixi/reactive",
|
|
1550
1569
|
"@fluixi/reactive/signal",
|
|
1551
1570
|
"@fluixi/reactive/store",
|
|
1571
|
+
"@fluixi/reactive/cached-resource",
|
|
1552
1572
|
"@fluixi/core"
|
|
1553
1573
|
];
|
|
1554
1574
|
var INTRINSIC_CALL = new RegExp(`\\$(?:${Object.keys(INTRINSICS).map((n2) => n2.slice(1)).join("|")})\\s*\\(`);
|
|
@@ -1684,6 +1704,7 @@ function resolveReactiveBindings(program) {
|
|
|
1684
1704
|
// src/transform/source-locations.ts
|
|
1685
1705
|
var SOURCE_MARKER = "__fx_source";
|
|
1686
1706
|
var COMPONENT_MARKER = "__fx_component";
|
|
1707
|
+
var CLASS_MARKER = "__fx_class";
|
|
1687
1708
|
var HOLE_MARKER = "__fx_hole";
|
|
1688
1709
|
var markHole = (accessor, line, column, name) => `(globalThis.${HOLE_MARKER} ?? ((f) => f))(${accessor},${line},${column}${name === void 0 ? "" : `,${JSON.stringify(name)}`})`;
|
|
1689
1710
|
var PROPS_MARKER = "__fx_props";
|
|
@@ -1701,11 +1722,12 @@ var RUNTIME_PRIMITIVES2 = /* @__PURE__ */ new Set([
|
|
|
1701
1722
|
"createStore",
|
|
1702
1723
|
"createResource"
|
|
1703
1724
|
]);
|
|
1704
|
-
function
|
|
1725
|
+
function mayHaveSourceMarks(code) {
|
|
1705
1726
|
for (const name of RUNTIME_PRIMITIVES2) {
|
|
1706
1727
|
if (code.includes(name)) return true;
|
|
1707
1728
|
}
|
|
1708
|
-
|
|
1729
|
+
if (code.includes("$signal") || code.includes("$memo") || code.includes("$effect") || code.includes("$store")) return true;
|
|
1730
|
+
return /\bclass\b[^{;]*\bextends\b/.test(code);
|
|
1709
1731
|
}
|
|
1710
1732
|
var SINGLE_STATEMENT_PARENTS = /* @__PURE__ */ new Set([
|
|
1711
1733
|
"IfStatement",
|
|
@@ -1724,6 +1746,7 @@ function isLoneBranch(statement, parent) {
|
|
|
1724
1746
|
function isExport(node) {
|
|
1725
1747
|
return node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration";
|
|
1726
1748
|
}
|
|
1749
|
+
var CLASS_FIELDS = /* @__PURE__ */ new Set(["PropertyDefinition", "ClassProperty", "ClassPrivateProperty", "AccessorProperty"]);
|
|
1727
1750
|
function isStatement(node) {
|
|
1728
1751
|
return node.type.endsWith("Statement") || node.type === "VariableDeclaration";
|
|
1729
1752
|
}
|
|
@@ -1744,6 +1767,14 @@ function walk3(node, visit, stack = []) {
|
|
|
1744
1767
|
}
|
|
1745
1768
|
function nameFor(stack) {
|
|
1746
1769
|
const declarator = stack[stack.length - 1];
|
|
1770
|
+
if (declarator && CLASS_FIELDS.has(declarator.type)) {
|
|
1771
|
+
const key = declarator.key;
|
|
1772
|
+
if (key?.type === "Identifier" || key?.type === "PrivateIdentifier" || key?.type === "PrivateName") {
|
|
1773
|
+
const name = key.name ?? key.id?.name;
|
|
1774
|
+
return name;
|
|
1775
|
+
}
|
|
1776
|
+
return void 0;
|
|
1777
|
+
}
|
|
1747
1778
|
if (declarator?.type !== "VariableDeclarator") return void 0;
|
|
1748
1779
|
const id = declarator.id;
|
|
1749
1780
|
if (id?.type === "Identifier") return id.name;
|
|
@@ -1792,6 +1823,17 @@ function collectSourceEdits(program, filename) {
|
|
|
1792
1823
|
});
|
|
1793
1824
|
}
|
|
1794
1825
|
}
|
|
1826
|
+
if ((node.type === "ClassDeclaration" || node.type === "ClassExpression") && node.superClass && !node.declare) {
|
|
1827
|
+
const at = node.loc?.start;
|
|
1828
|
+
const body = node.body;
|
|
1829
|
+
if (at && body) {
|
|
1830
|
+
edits.push({
|
|
1831
|
+
start: body.start + 1,
|
|
1832
|
+
end: body.start + 1,
|
|
1833
|
+
code: `static{globalThis.${CLASS_MARKER}?.(this,${JSON.stringify(filename)},${at.line},${at.column});}`
|
|
1834
|
+
});
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1795
1837
|
if (node.type !== "CallExpression") return;
|
|
1796
1838
|
const callee = node.callee;
|
|
1797
1839
|
if (callee?.type !== "Identifier") return;
|
|
@@ -1801,6 +1843,26 @@ function collectSourceEdits(program, filename) {
|
|
|
1801
1843
|
if (!intrinsic && !imported) return;
|
|
1802
1844
|
const position = node.loc?.start;
|
|
1803
1845
|
if (!position) return;
|
|
1846
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
1847
|
+
const up = stack[i];
|
|
1848
|
+
if (isStatement(up)) break;
|
|
1849
|
+
if (CLASS_FIELDS.has(up.type)) {
|
|
1850
|
+
if (claimed.has(node.start)) return;
|
|
1851
|
+
claimed.add(node.start);
|
|
1852
|
+
const label2 = nameFor(stack);
|
|
1853
|
+
const own = !up.static;
|
|
1854
|
+
const args2 = [
|
|
1855
|
+
JSON.stringify(filename),
|
|
1856
|
+
String(position.line),
|
|
1857
|
+
String(position.column),
|
|
1858
|
+
label2 ? JSON.stringify(label2) : own ? "undefined" : void 0,
|
|
1859
|
+
own ? "this" : void 0
|
|
1860
|
+
].filter((a) => a !== void 0).join(",");
|
|
1861
|
+
edits.push({ start: node.start, end: node.start, code: `(globalThis.${SOURCE_MARKER}?.(${args2}),` });
|
|
1862
|
+
edits.push({ start: node.end, end: node.end, code: ")" });
|
|
1863
|
+
return;
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1804
1866
|
let statement;
|
|
1805
1867
|
let parent;
|
|
1806
1868
|
let index = -1;
|
|
@@ -2006,13 +2068,16 @@ function emitComponent(name, props, children, used, templates, at) {
|
|
|
2006
2068
|
used.add("createComponent");
|
|
2007
2069
|
const spreads = props.filter((p) => p.kind === "spread");
|
|
2008
2070
|
const normal = props.filter((p) => p.kind !== "spread");
|
|
2009
|
-
const
|
|
2010
|
-
(p) => `get ${propKey(p.name)}() { return ${componentPropValue(p)}; }`
|
|
2011
|
-
);
|
|
2071
|
+
const bodies = normal.map((p) => [p.name, componentPropValue(p)]);
|
|
2012
2072
|
if (children.length > 0) {
|
|
2013
|
-
|
|
2073
|
+
bodies.push(["children", emitChildren(children, used, templates)]);
|
|
2074
|
+
}
|
|
2075
|
+
let obj = `{ ${bodies.map(([name2, body]) => `get ${propKey(name2)}() { return ${body}; }`).join(", ")} }`;
|
|
2076
|
+
if (bodies.some(([, body]) => /\bthis\b/.test(body))) {
|
|
2077
|
+
const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => ${body}`);
|
|
2078
|
+
const getters = bodies.map(([name2]) => `get ${propKey(name2)}() { return _$t[${JSON.stringify(name2)}](); }`);
|
|
2079
|
+
obj = `((_$t) => ({ ${getters.join(", ")} }))({ ${thunks.join(", ")} })`;
|
|
2014
2080
|
}
|
|
2015
|
-
let obj = `{ ${entries.join(", ")} }`;
|
|
2016
2081
|
if (spreads.length > 0) {
|
|
2017
2082
|
used.add("mergeProps");
|
|
2018
2083
|
obj = `mergeProps(${spreads.map((s) => s.expr).join(", ")}, ${obj})`;
|
|
@@ -2094,7 +2159,8 @@ function emitNode(node, used, templates) {
|
|
|
2094
2159
|
} else {
|
|
2095
2160
|
used.add("spread");
|
|
2096
2161
|
const svgFlag = node.svg ? ", isSVG: true" : "";
|
|
2097
|
-
const
|
|
2162
|
+
const accessors = node.props.filter((p) => p.kind !== "spread" && p.expr !== void 0 && p.reactive && p.name !== "ref").map((p) => p.name);
|
|
2163
|
+
const customFlag = node.tag.includes("-") ? `, isCustomElement: true, accessors: ${JSON.stringify(accessors)}` : "";
|
|
2098
2164
|
parts.push(
|
|
2099
2165
|
`spread({ element: ${el}, props: ${emitProps(node.props, null, used)}${svgFlag}${customFlag} });`
|
|
2100
2166
|
);
|
|
@@ -2227,6 +2293,7 @@ var DELEGATED = /* @__PURE__ */ new Set([
|
|
|
2227
2293
|
function escapeTemplate(s) {
|
|
2228
2294
|
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
2229
2295
|
}
|
|
2296
|
+
var CONTAINER = "container";
|
|
2230
2297
|
function capitalize(s) {
|
|
2231
2298
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
2232
2299
|
}
|
|
@@ -2281,10 +2348,6 @@ var Lowerer = class {
|
|
|
2281
2348
|
if (hasElse) i = elseIdx;
|
|
2282
2349
|
continue;
|
|
2283
2350
|
}
|
|
2284
|
-
if (child.attributes.some((a) => a.kind === "EachDirective")) {
|
|
2285
|
-
out.push(this.lowerEach(child));
|
|
2286
|
-
continue;
|
|
2287
|
-
}
|
|
2288
2351
|
}
|
|
2289
2352
|
const node = this.lowerNode(child);
|
|
2290
2353
|
if (node) out.push(node);
|
|
@@ -2326,13 +2389,16 @@ var Lowerer = class {
|
|
|
2326
2389
|
node.props.unshift({ name: "component", kind: "attr", expr: `() => ${paren(this.hole(isAttr.value.hole).code, "arrowBody")}` });
|
|
2327
2390
|
return node;
|
|
2328
2391
|
}
|
|
2392
|
+
const each = this.lowerEach(el);
|
|
2393
|
+
const children = each ? [each] : this.lowerChildren(el.children);
|
|
2394
|
+
if (el.tag === CONTAINER) return children.length === 1 ? children[0] : { kind: "fragment", children };
|
|
2329
2395
|
const at = this.tagAt(el);
|
|
2330
2396
|
return {
|
|
2331
2397
|
kind: "element",
|
|
2332
2398
|
tag: el.tag,
|
|
2333
2399
|
svg: el.namespace === "svg",
|
|
2334
2400
|
props: this.lowerAttributes(el.attributes),
|
|
2335
|
-
children
|
|
2401
|
+
children,
|
|
2336
2402
|
static: false,
|
|
2337
2403
|
...at ? { at } : {}
|
|
2338
2404
|
};
|
|
@@ -2404,10 +2470,14 @@ var Lowerer = class {
|
|
|
2404
2470
|
const at = this.tagAt(el);
|
|
2405
2471
|
return { kind: "component", name: "Show", props, children: [child], ...at ? { at } : {}, ...cond.at ? { bindAt: cond.at } : {} };
|
|
2406
2472
|
}
|
|
2407
|
-
/**
|
|
2473
|
+
/**
|
|
2474
|
+
* `<el each=${items} key?>${item => …}</el>` → `<el><For each>{item => …}</For></el>`: the
|
|
2475
|
+
* content is repeated per item. Content that is not a `${item => …}` arrow is repeated as
|
|
2476
|
+
* it is. Null when the element has no `each`.
|
|
2477
|
+
*/
|
|
2408
2478
|
lowerEach(el) {
|
|
2409
2479
|
const eachDir = el.attributes.find((a) => a.kind === "EachDirective");
|
|
2410
|
-
if (!eachDir || eachDir.kind !== "EachDirective") return
|
|
2480
|
+
if (!eachDir || eachDir.kind !== "EachDirective") return null;
|
|
2411
2481
|
const each = this.hole(eachDir.hole);
|
|
2412
2482
|
const props = [{ name: "each", kind: "attr", expr: each.code, reactive: each.reactive, ...each.at ? { at: each.at } : {} }];
|
|
2413
2483
|
if (eachDir.key) {
|
|
@@ -2417,12 +2487,12 @@ var Lowerer = class {
|
|
|
2417
2487
|
const arrow = this.itemArrow(el);
|
|
2418
2488
|
let childrenCode;
|
|
2419
2489
|
if (arrow) {
|
|
2420
|
-
const
|
|
2421
|
-
|
|
2422
|
-
childrenCode = `(${arrow.params.join(", ")}) => ${paren(this.emit(repeated), "arrowBody")}`;
|
|
2490
|
+
const body = arrow.bodyReactive ? `() => ${paren(arrow.body, "arrowBody")}` : paren(arrow.body, "arrowBody");
|
|
2491
|
+
childrenCode = `(${arrow.params.join(", ")}) => ${body}`;
|
|
2423
2492
|
} else {
|
|
2424
|
-
const
|
|
2425
|
-
|
|
2493
|
+
const content = this.lowerChildren(el.children);
|
|
2494
|
+
const ir = content.length === 1 ? content[0] : { kind: "fragment", children: content };
|
|
2495
|
+
childrenCode = `() => ${paren(this.emit(ir), "arrowBody")}`;
|
|
2426
2496
|
}
|
|
2427
2497
|
const children = [{ kind: "expr", code: childrenCode, reactive: false }];
|
|
2428
2498
|
const at = this.tagAt(el);
|
|
@@ -2439,25 +2509,6 @@ var Lowerer = class {
|
|
|
2439
2509
|
const clone = { ...el, attributes: el.attributes.filter((a) => !drop(a)) };
|
|
2440
2510
|
return clone.kind === "Element" ? this.lowerElement(clone) : this.lowerComponent(clone);
|
|
2441
2511
|
}
|
|
2442
|
-
/** Same element (minus each/key) but with explicit IR children. */
|
|
2443
|
-
rebuildWithChildren(el, children) {
|
|
2444
|
-
const props = this.lowerAttributes(
|
|
2445
|
-
el.attributes.filter((a) => a.kind !== "EachDirective")
|
|
2446
|
-
);
|
|
2447
|
-
if (el.kind === "Element") {
|
|
2448
|
-
const at = this.tagAt(el);
|
|
2449
|
-
return {
|
|
2450
|
-
kind: "element",
|
|
2451
|
-
tag: el.tag,
|
|
2452
|
-
svg: el.namespace === "svg",
|
|
2453
|
-
props,
|
|
2454
|
-
children,
|
|
2455
|
-
static: false,
|
|
2456
|
-
...at ? { at } : {}
|
|
2457
|
-
};
|
|
2458
|
-
}
|
|
2459
|
-
return { kind: "component", name: el.tag, props, children };
|
|
2460
|
-
}
|
|
2461
2512
|
// --- attributes ---------------------------------------------------------
|
|
2462
2513
|
lowerAttributes(attrs) {
|
|
2463
2514
|
const props = [];
|
|
@@ -2776,6 +2827,22 @@ var DELEGATED2 = /* @__PURE__ */ new Set([
|
|
|
2776
2827
|
"mouseup"
|
|
2777
2828
|
]);
|
|
2778
2829
|
var isReactive = (node) => isReactiveShape(shapeOf(node));
|
|
2830
|
+
var CONTAINER2 = "container";
|
|
2831
|
+
function directive(node, name) {
|
|
2832
|
+
if (node.type !== "JSXElement") return void 0;
|
|
2833
|
+
const opening = node.openingElement;
|
|
2834
|
+
if (opening.name.type !== "JSXIdentifier" || opening.name.name[0] !== opening.name.name[0].toLowerCase()) return void 0;
|
|
2835
|
+
return opening.attributes.find((a) => a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" && a.name.name === name);
|
|
2836
|
+
}
|
|
2837
|
+
function directiveExpr(attr) {
|
|
2838
|
+
const v = attr.value;
|
|
2839
|
+
return v?.type === "JSXExpressionContainer" && v.expression?.type !== "JSXEmptyExpression" ? v.expression : void 0;
|
|
2840
|
+
}
|
|
2841
|
+
function emitIR(ir, ctx) {
|
|
2842
|
+
const { code, imports, templates } = imperativeBackend.emit(ir, {});
|
|
2843
|
+
for (const s of imports) ctx.used.add(s);
|
|
2844
|
+
return inlineTemplates(code, templates);
|
|
2845
|
+
}
|
|
2779
2846
|
var posOf = (node, ctx) => {
|
|
2780
2847
|
if (!ctx.sourceFile) return void 0;
|
|
2781
2848
|
const at = node.loc?.start;
|
|
@@ -2884,7 +2951,16 @@ function buildProps(attrs, ctx) {
|
|
|
2884
2951
|
}
|
|
2885
2952
|
function buildChildren(children, ctx) {
|
|
2886
2953
|
const out = [];
|
|
2887
|
-
for (
|
|
2954
|
+
for (let i = 0; i < children.length; i++) {
|
|
2955
|
+
const child = children[i];
|
|
2956
|
+
if (directive(child, "if")) {
|
|
2957
|
+
let next = i + 1;
|
|
2958
|
+
while (next < children.length && children[next].type === "JSXText" && !cleanTemplateText(children[next].value)) next++;
|
|
2959
|
+
const fallback = directive(children[next], "else") ? children[next] : null;
|
|
2960
|
+
out.push(buildIf(child, fallback, ctx));
|
|
2961
|
+
if (fallback) i = next;
|
|
2962
|
+
continue;
|
|
2963
|
+
}
|
|
2888
2964
|
if (child.type === "JSXText") {
|
|
2889
2965
|
const text = cleanTemplateText(child.value);
|
|
2890
2966
|
if (text) out.push({ kind: "text", value: text });
|
|
@@ -2921,19 +2997,68 @@ function readLoad(attrs) {
|
|
|
2921
2997
|
}
|
|
2922
2998
|
return void 0;
|
|
2923
2999
|
}
|
|
3000
|
+
function buildIf(node, fallback, ctx) {
|
|
3001
|
+
const cond = directiveExpr(directive(node, "if"));
|
|
3002
|
+
const props = [
|
|
3003
|
+
cond ? { name: "when", kind: "attr", expr: ctx.code(cond), reactive: isReactive(cond), at: posOf(cond, ctx) } : { name: "when", kind: "attr", literal: true }
|
|
3004
|
+
];
|
|
3005
|
+
if (fallback) {
|
|
3006
|
+
props.push({ name: "fallback", kind: "attr", expr: emitIR(buildElement(fallback, ctx, ["else"]), ctx), jsxElement: true });
|
|
3007
|
+
}
|
|
3008
|
+
return { kind: "component", name: "Show", props, children: [buildElement(node, ctx, ["if"])] };
|
|
3009
|
+
}
|
|
3010
|
+
function buildEach(node, ctx) {
|
|
3011
|
+
const attr = directive(node, "each");
|
|
3012
|
+
if (!attr) return null;
|
|
3013
|
+
const list = directiveExpr(attr);
|
|
3014
|
+
const props = [
|
|
3015
|
+
list ? { name: "each", kind: "attr", expr: ctx.code(list), reactive: isReactive(list), at: posOf(list, ctx) } : { name: "each", kind: "attr", expr: "[]" }
|
|
3016
|
+
];
|
|
3017
|
+
const key = directive(node, "key");
|
|
3018
|
+
if (key) {
|
|
3019
|
+
const keyExpr = directiveExpr(key);
|
|
3020
|
+
const by = isString(key.value) ? `(item) => item[${JSON.stringify(literalOf(key.value))}]` : keyExpr ? ctx.code(keyExpr) : void 0;
|
|
3021
|
+
if (by) props.push({ name: "by", kind: "attr", expr: by });
|
|
3022
|
+
}
|
|
3023
|
+
const content = node.children.filter((c) => !(c.type === "JSXText" && !cleanTemplateText(c.value)));
|
|
3024
|
+
const only = content.length === 1 && content[0].type === "JSXExpressionContainer" ? content[0].expression : null;
|
|
3025
|
+
let render;
|
|
3026
|
+
if (only && (only.type === "ArrowFunctionExpression" || only.type === "FunctionExpression")) {
|
|
3027
|
+
const fn = ctx.code(only);
|
|
3028
|
+
const live = only.type === "ArrowFunctionExpression" && only.body.type !== "BlockStatement" && isReactive(only.body);
|
|
3029
|
+
render = live ? `(...args) => () => (${fn})(...args)` : fn;
|
|
3030
|
+
} else {
|
|
3031
|
+
const built = buildChildren(node.children, ctx);
|
|
3032
|
+
const ir = built.length === 1 ? built[0] : { kind: "fragment", children: built };
|
|
3033
|
+
render = `() => ${paren(emitIR(ir, ctx), "arrowBody")}`;
|
|
3034
|
+
}
|
|
3035
|
+
return { kind: "component", name: "For", props, children: [{ kind: "expr", code: render, reactive: false }] };
|
|
3036
|
+
}
|
|
3037
|
+
function buildElement(node, ctx, handled) {
|
|
3038
|
+
const skip = new Set(handled);
|
|
3039
|
+
const directives = /* @__PURE__ */ new Set(["if", "else", "each", ...directive(node, "each") ? ["key"] : []]);
|
|
3040
|
+
const attributes = node.openingElement.attributes.filter(
|
|
3041
|
+
(a) => !(a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" && (skip.has(a.name.name) || directives.has(a.name.name)))
|
|
3042
|
+
);
|
|
3043
|
+
const { tag } = tagInfo(node.openingElement.name, ctx);
|
|
3044
|
+
const each = buildEach(node, ctx);
|
|
3045
|
+
const children = each ? [each] : buildChildren(node.children, ctx);
|
|
3046
|
+
if (tag === CONTAINER2) return children.length === 1 ? children[0] : { kind: "fragment", children };
|
|
3047
|
+
const at = ctx.sourceFile && node.loc?.start ? { file: ctx.sourceFile, line: node.loc.start.line, column: node.loc.start.column } : void 0;
|
|
3048
|
+
return { kind: "element", tag, svg: SVG_TAGS.has(tag), props: buildProps(attributes, ctx), children, static: false, ...at ? { at } : {} };
|
|
3049
|
+
}
|
|
2924
3050
|
function buildNode(node, ctx) {
|
|
2925
3051
|
if (node.type === "JSXFragment") {
|
|
2926
3052
|
return { kind: "fragment", children: buildChildren(node.children, ctx) };
|
|
2927
3053
|
}
|
|
3054
|
+
if (directive(node, "if")) return buildIf(node, null, ctx);
|
|
2928
3055
|
const { tag, component } = tagInfo(node.openingElement.name, ctx);
|
|
3056
|
+
if (!component) return buildElement(node, ctx, []);
|
|
2929
3057
|
const props = buildProps(node.openingElement.attributes, ctx);
|
|
2930
3058
|
const children = buildChildren(node.children, ctx);
|
|
2931
3059
|
const at = ctx.sourceFile && node.loc?.start ? { file: ctx.sourceFile, line: node.loc.start.line, column: node.loc.start.column } : void 0;
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
return { kind: "component", name: tag, props, children, ...load ? { load } : {}, ...at ? { at } : {} };
|
|
2935
|
-
}
|
|
2936
|
-
return { kind: "element", tag, svg: SVG_TAGS.has(tag), props, children, static: false, ...at ? { at } : {} };
|
|
3060
|
+
const load = readLoad(node.openingElement.attributes);
|
|
3061
|
+
return { kind: "component", name: tag, props, children, ...load ? { load } : {}, ...at ? { at } : {} };
|
|
2937
3062
|
}
|
|
2938
3063
|
function buildJsxIR(node, ctx) {
|
|
2939
3064
|
const ir = buildNode(node, ctx);
|
|
@@ -3366,10 +3491,34 @@ function collectIntrinsicEdits(program) {
|
|
|
3366
3491
|
});
|
|
3367
3492
|
return { edits, diagnostics, imports };
|
|
3368
3493
|
}
|
|
3494
|
+
function avoidBindingClashes(program, result, bound) {
|
|
3495
|
+
const importedAsIs = /* @__PURE__ */ new Set();
|
|
3496
|
+
for (const stmt of program.body ?? []) {
|
|
3497
|
+
if (stmt.type !== "ImportDeclaration") continue;
|
|
3498
|
+
const module = stmt.source.value;
|
|
3499
|
+
for (const spec of stmt.specifiers ?? []) {
|
|
3500
|
+
if (spec.type !== "ImportSpecifier") continue;
|
|
3501
|
+
const imported = spec.imported.name ?? spec.imported.value;
|
|
3502
|
+
if (imported === spec.local.name && result.imports.get(module)?.has(imported)) {
|
|
3503
|
+
importedAsIs.add(imported);
|
|
3504
|
+
}
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
3508
|
+
for (const names of result.imports.values()) {
|
|
3509
|
+
for (const name of names) if (bound.has(name) && !importedAsIs.has(name)) aliases.set(name, `__fx_${name}`);
|
|
3510
|
+
}
|
|
3511
|
+
if (!aliases.size) return;
|
|
3512
|
+
for (const edit of result.edits) {
|
|
3513
|
+
const alias = aliases.get(edit.code);
|
|
3514
|
+
if (alias) edit.code = alias;
|
|
3515
|
+
}
|
|
3516
|
+
result.aliases = aliases;
|
|
3517
|
+
}
|
|
3369
3518
|
function intrinsicImports(result, bound) {
|
|
3370
3519
|
const lines = [];
|
|
3371
3520
|
for (const [module, names] of [...result.imports].sort(([a], [b]) => a.localeCompare(b))) {
|
|
3372
|
-
const wanted = [...names].filter((name) => !bound.has(name)).sort();
|
|
3521
|
+
const wanted = [...names].filter((name) => result.aliases?.has(name) || !bound.has(name)).sort().map((name) => result.aliases?.has(name) ? `${name} as ${result.aliases.get(name)}` : name);
|
|
3373
3522
|
if (wanted.length) lines.push(`import { ${wanted.join(", ")} } from ${JSON.stringify(module)};`);
|
|
3374
3523
|
}
|
|
3375
3524
|
return lines.length ? `${lines.join("\n")}
|
|
@@ -3554,7 +3703,7 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3554
3703
|
const wantsJsx = format !== "lit";
|
|
3555
3704
|
const mayHaveTemplate = wantsLit && (code.includes(`${litTag}\``) || code.includes("svg`"));
|
|
3556
3705
|
const wantsIntrinsics = options.intrinsics !== false && mayHaveIntrinsic(code);
|
|
3557
|
-
const wantsSources = options.sourceLocations === true &&
|
|
3706
|
+
const wantsSources = options.sourceLocations === true && mayHaveSourceMarks(code);
|
|
3558
3707
|
const sourceName = relativeToRoot(id, options.sourceRoot);
|
|
3559
3708
|
if (!mayHaveTemplate && !(wantsJsx && code.includes("<")) && !wantsIntrinsics && !wantsSources) return null;
|
|
3560
3709
|
const ast = parse2(code, {
|
|
@@ -3569,6 +3718,7 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3569
3718
|
});
|
|
3570
3719
|
const props = options.propsDestructure === false ? { edits: [], diagnostics: [], used: /* @__PURE__ */ new Set() } : collectPropsEdits(ast.program, code, { runtimeModule: options.runtimeModule });
|
|
3571
3720
|
const intrinsics = options.intrinsics === false ? { edits: [], diagnostics: [], imports: /* @__PURE__ */ new Map() } : collectIntrinsicEdits(ast.program);
|
|
3721
|
+
if (intrinsics.edits.length) avoidBindingClashes(ast.program, intrinsics, moduleBindings(ast.program));
|
|
3572
3722
|
const sources = options.sourceLocations === true ? collectSourceEdits(ast.program, sourceName) : { edits: [], marked: 0 };
|
|
3573
3723
|
const silent = found.length === 0 && props.edits.length === 0 && sources.edits.length === 0 && intrinsics.edits.length === 0 && intrinsics.diagnostics.length === 0 && props.diagnostics.length === 0;
|
|
3574
3724
|
if (silent) return null;
|
|
@@ -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
|
import {
|
|
3
3
|
analyzeStatic,
|
|
4
4
|
buildJsxIR,
|
|
@@ -10,11 +10,11 @@ import {
|
|
|
10
10
|
isDeferred,
|
|
11
11
|
isReactiveShape,
|
|
12
12
|
lowerTemplate,
|
|
13
|
-
|
|
13
|
+
mayHaveSourceMarks,
|
|
14
14
|
resolveComponentSources,
|
|
15
15
|
resolveReactiveBindings,
|
|
16
16
|
shapeOf
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-U7HCFLZ2.mjs";
|
|
18
18
|
import {
|
|
19
19
|
CORE_CONTROL_FLOW,
|
|
20
20
|
DOM_CONTROL_FLOW,
|
|
@@ -23,11 +23,11 @@ import {
|
|
|
23
23
|
createComponentResolver,
|
|
24
24
|
isIntrinsicName,
|
|
25
25
|
mayHaveIntrinsic
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-OD53TMER.mjs";
|
|
27
27
|
import {
|
|
28
28
|
MagicString
|
|
29
|
-
} from "./chunk-
|
|
30
|
-
import "./chunk-
|
|
29
|
+
} from "./chunk-R7PPFBCL.mjs";
|
|
30
|
+
import "./chunk-TJIH7TLX.mjs";
|
|
31
31
|
|
|
32
32
|
// src/transform/templates.ts
|
|
33
33
|
import { parse as parse2 } from "@babel/parser";
|
|
@@ -508,10 +508,34 @@ function collectIntrinsicEdits(program) {
|
|
|
508
508
|
});
|
|
509
509
|
return { edits, diagnostics, imports };
|
|
510
510
|
}
|
|
511
|
+
function avoidBindingClashes(program, result, bound) {
|
|
512
|
+
const importedAsIs = /* @__PURE__ */ new Set();
|
|
513
|
+
for (const stmt of program.body ?? []) {
|
|
514
|
+
if (stmt.type !== "ImportDeclaration") continue;
|
|
515
|
+
const module = stmt.source.value;
|
|
516
|
+
for (const spec of stmt.specifiers ?? []) {
|
|
517
|
+
if (spec.type !== "ImportSpecifier") continue;
|
|
518
|
+
const imported = spec.imported.name ?? spec.imported.value;
|
|
519
|
+
if (imported === spec.local.name && result.imports.get(module)?.has(imported)) {
|
|
520
|
+
importedAsIs.add(imported);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
525
|
+
for (const names of result.imports.values()) {
|
|
526
|
+
for (const name of names) if (bound.has(name) && !importedAsIs.has(name)) aliases.set(name, `__fx_${name}`);
|
|
527
|
+
}
|
|
528
|
+
if (!aliases.size) return;
|
|
529
|
+
for (const edit of result.edits) {
|
|
530
|
+
const alias = aliases.get(edit.code);
|
|
531
|
+
if (alias) edit.code = alias;
|
|
532
|
+
}
|
|
533
|
+
result.aliases = aliases;
|
|
534
|
+
}
|
|
511
535
|
function intrinsicImports(result, bound) {
|
|
512
536
|
const lines = [];
|
|
513
537
|
for (const [module, names] of [...result.imports].sort(([a], [b]) => a.localeCompare(b))) {
|
|
514
|
-
const wanted = [...names].filter((name) => !bound.has(name)).sort();
|
|
538
|
+
const wanted = [...names].filter((name) => result.aliases?.has(name) || !bound.has(name)).sort().map((name) => result.aliases?.has(name) ? `${name} as ${result.aliases.get(name)}` : name);
|
|
515
539
|
if (wanted.length) lines.push(`import { ${wanted.join(", ")} } from ${JSON.stringify(module)};`);
|
|
516
540
|
}
|
|
517
541
|
return lines.length ? `${lines.join("\n")}
|
|
@@ -696,7 +720,7 @@ function transformTemplates(code, id, options = {}) {
|
|
|
696
720
|
const wantsJsx = format !== "lit";
|
|
697
721
|
const mayHaveTemplate = wantsLit && (code.includes(`${litTag}\``) || code.includes("svg`"));
|
|
698
722
|
const wantsIntrinsics = options.intrinsics !== false && mayHaveIntrinsic(code);
|
|
699
|
-
const wantsSources = options.sourceLocations === true &&
|
|
723
|
+
const wantsSources = options.sourceLocations === true && mayHaveSourceMarks(code);
|
|
700
724
|
const sourceName = relativeToRoot(id, options.sourceRoot);
|
|
701
725
|
if (!mayHaveTemplate && !(wantsJsx && code.includes("<")) && !wantsIntrinsics && !wantsSources) return null;
|
|
702
726
|
const ast = parse2(code, {
|
|
@@ -711,6 +735,7 @@ function transformTemplates(code, id, options = {}) {
|
|
|
711
735
|
});
|
|
712
736
|
const props = options.propsDestructure === false ? { edits: [], diagnostics: [], used: /* @__PURE__ */ new Set() } : collectPropsEdits(ast.program, code, { runtimeModule: options.runtimeModule });
|
|
713
737
|
const intrinsics = options.intrinsics === false ? { edits: [], diagnostics: [], imports: /* @__PURE__ */ new Map() } : collectIntrinsicEdits(ast.program);
|
|
738
|
+
if (intrinsics.edits.length) avoidBindingClashes(ast.program, intrinsics, moduleBindings(ast.program));
|
|
714
739
|
const sources = options.sourceLocations === true ? collectSourceEdits(ast.program, sourceName) : { edits: [], marked: 0 };
|
|
715
740
|
const silent = found.length === 0 && props.edits.length === 0 && sources.edits.length === 0 && intrinsics.edits.length === 0 && intrinsics.diagnostics.length === 0 && props.diagnostics.length === 0;
|
|
716
741
|
if (silent) return null;
|