@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
|
@@ -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.
|
|
@@ -1529,6 +1530,19 @@ var INTRINSICS = {
|
|
|
1529
1530
|
// dependency analysis must not guess at.
|
|
1530
1531
|
$untrack: { export: "untrack", module: REACTIVE_MODULE, returns: "plain" },
|
|
1531
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" },
|
|
1532
1546
|
// An environment variable, public or server-only; the browser build refuses a secret.
|
|
1533
1547
|
$env: { export: "env", module: "@fluixi/start/env", returns: "plain" }
|
|
1534
1548
|
};
|
|
@@ -1541,8 +1555,11 @@ var RUNTIME_PRIMITIVES = {
|
|
|
1541
1555
|
createMemo: "memo-accessor",
|
|
1542
1556
|
createEffect: "effect",
|
|
1543
1557
|
createRenderEffect: "effect",
|
|
1558
|
+
renderEffect: "effect",
|
|
1559
|
+
computed: "effect",
|
|
1544
1560
|
createStore: "reactive-object",
|
|
1545
1561
|
resource: "resource-handle",
|
|
1562
|
+
cachedResource: "resource-handle",
|
|
1546
1563
|
createResource: "reactive-object",
|
|
1547
1564
|
createSelector: "memo-accessor",
|
|
1548
1565
|
createDeferred: "memo-accessor"
|
|
@@ -1551,6 +1568,7 @@ var PRIMITIVE_MODULES = [
|
|
|
1551
1568
|
"@fluixi/reactive",
|
|
1552
1569
|
"@fluixi/reactive/signal",
|
|
1553
1570
|
"@fluixi/reactive/store",
|
|
1571
|
+
"@fluixi/reactive/cached-resource",
|
|
1554
1572
|
"@fluixi/core"
|
|
1555
1573
|
];
|
|
1556
1574
|
var INTRINSIC_CALL = new RegExp(`\\$(?:${Object.keys(INTRINSICS).map((n2) => n2.slice(1)).join("|")})\\s*\\(`);
|
|
@@ -1686,6 +1704,7 @@ function resolveReactiveBindings(program) {
|
|
|
1686
1704
|
// src/transform/source-locations.ts
|
|
1687
1705
|
var SOURCE_MARKER = "__fx_source";
|
|
1688
1706
|
var COMPONENT_MARKER = "__fx_component";
|
|
1707
|
+
var CLASS_MARKER = "__fx_class";
|
|
1689
1708
|
var HOLE_MARKER = "__fx_hole";
|
|
1690
1709
|
var markHole = (accessor, line, column, name) => `(globalThis.${HOLE_MARKER} ?? ((f) => f))(${accessor},${line},${column}${name === void 0 ? "" : `,${JSON.stringify(name)}`})`;
|
|
1691
1710
|
var PROPS_MARKER = "__fx_props";
|
|
@@ -1703,11 +1722,12 @@ var RUNTIME_PRIMITIVES2 = /* @__PURE__ */ new Set([
|
|
|
1703
1722
|
"createStore",
|
|
1704
1723
|
"createResource"
|
|
1705
1724
|
]);
|
|
1706
|
-
function
|
|
1725
|
+
function mayHaveSourceMarks(code) {
|
|
1707
1726
|
for (const name of RUNTIME_PRIMITIVES2) {
|
|
1708
1727
|
if (code.includes(name)) return true;
|
|
1709
1728
|
}
|
|
1710
|
-
|
|
1729
|
+
if (code.includes("$signal") || code.includes("$memo") || code.includes("$effect") || code.includes("$store")) return true;
|
|
1730
|
+
return /\bclass\b[^{;]*\bextends\b/.test(code);
|
|
1711
1731
|
}
|
|
1712
1732
|
var SINGLE_STATEMENT_PARENTS = /* @__PURE__ */ new Set([
|
|
1713
1733
|
"IfStatement",
|
|
@@ -1726,6 +1746,7 @@ function isLoneBranch(statement, parent) {
|
|
|
1726
1746
|
function isExport(node) {
|
|
1727
1747
|
return node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration";
|
|
1728
1748
|
}
|
|
1749
|
+
var CLASS_FIELDS = /* @__PURE__ */ new Set(["PropertyDefinition", "ClassProperty", "ClassPrivateProperty", "AccessorProperty"]);
|
|
1729
1750
|
function isStatement(node) {
|
|
1730
1751
|
return node.type.endsWith("Statement") || node.type === "VariableDeclaration";
|
|
1731
1752
|
}
|
|
@@ -1746,6 +1767,14 @@ function walk3(node, visit, stack = []) {
|
|
|
1746
1767
|
}
|
|
1747
1768
|
function nameFor(stack) {
|
|
1748
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
|
+
}
|
|
1749
1778
|
if (declarator?.type !== "VariableDeclarator") return void 0;
|
|
1750
1779
|
const id = declarator.id;
|
|
1751
1780
|
if (id?.type === "Identifier") return id.name;
|
|
@@ -1794,6 +1823,17 @@ function collectSourceEdits(program, filename) {
|
|
|
1794
1823
|
});
|
|
1795
1824
|
}
|
|
1796
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
|
+
}
|
|
1797
1837
|
if (node.type !== "CallExpression") return;
|
|
1798
1838
|
const callee = node.callee;
|
|
1799
1839
|
if (callee?.type !== "Identifier") return;
|
|
@@ -1803,6 +1843,26 @@ function collectSourceEdits(program, filename) {
|
|
|
1803
1843
|
if (!intrinsic && !imported) return;
|
|
1804
1844
|
const position = node.loc?.start;
|
|
1805
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
|
+
}
|
|
1806
1866
|
let statement;
|
|
1807
1867
|
let parent;
|
|
1808
1868
|
let index = -1;
|
|
@@ -2008,13 +2068,16 @@ function emitComponent(name, props, children, used, templates, at) {
|
|
|
2008
2068
|
used.add("createComponent");
|
|
2009
2069
|
const spreads = props.filter((p) => p.kind === "spread");
|
|
2010
2070
|
const normal = props.filter((p) => p.kind !== "spread");
|
|
2011
|
-
const
|
|
2012
|
-
(p) => `get ${propKey(p.name)}() { return ${componentPropValue(p)}; }`
|
|
2013
|
-
);
|
|
2071
|
+
const bodies = normal.map((p) => [p.name, componentPropValue(p)]);
|
|
2014
2072
|
if (children.length > 0) {
|
|
2015
|
-
|
|
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(", ")} })`;
|
|
2016
2080
|
}
|
|
2017
|
-
let obj = `{ ${entries.join(", ")} }`;
|
|
2018
2081
|
if (spreads.length > 0) {
|
|
2019
2082
|
used.add("mergeProps");
|
|
2020
2083
|
obj = `mergeProps(${spreads.map((s) => s.expr).join(", ")}, ${obj})`;
|
|
@@ -2096,7 +2159,8 @@ function emitNode(node, used, templates) {
|
|
|
2096
2159
|
} else {
|
|
2097
2160
|
used.add("spread");
|
|
2098
2161
|
const svgFlag = node.svg ? ", isSVG: true" : "";
|
|
2099
|
-
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)}` : "";
|
|
2100
2164
|
parts.push(
|
|
2101
2165
|
`spread({ element: ${el}, props: ${emitProps(node.props, null, used)}${svgFlag}${customFlag} });`
|
|
2102
2166
|
);
|
|
@@ -2229,6 +2293,7 @@ var DELEGATED = /* @__PURE__ */ new Set([
|
|
|
2229
2293
|
function escapeTemplate(s) {
|
|
2230
2294
|
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
2231
2295
|
}
|
|
2296
|
+
var CONTAINER = "container";
|
|
2232
2297
|
function capitalize(s) {
|
|
2233
2298
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
2234
2299
|
}
|
|
@@ -2283,10 +2348,6 @@ var Lowerer = class {
|
|
|
2283
2348
|
if (hasElse) i = elseIdx;
|
|
2284
2349
|
continue;
|
|
2285
2350
|
}
|
|
2286
|
-
if (child.attributes.some((a) => a.kind === "EachDirective")) {
|
|
2287
|
-
out.push(this.lowerEach(child));
|
|
2288
|
-
continue;
|
|
2289
|
-
}
|
|
2290
2351
|
}
|
|
2291
2352
|
const node = this.lowerNode(child);
|
|
2292
2353
|
if (node) out.push(node);
|
|
@@ -2328,13 +2389,16 @@ var Lowerer = class {
|
|
|
2328
2389
|
node.props.unshift({ name: "component", kind: "attr", expr: `() => ${paren(this.hole(isAttr.value.hole).code, "arrowBody")}` });
|
|
2329
2390
|
return node;
|
|
2330
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 };
|
|
2331
2395
|
const at = this.tagAt(el);
|
|
2332
2396
|
return {
|
|
2333
2397
|
kind: "element",
|
|
2334
2398
|
tag: el.tag,
|
|
2335
2399
|
svg: el.namespace === "svg",
|
|
2336
2400
|
props: this.lowerAttributes(el.attributes),
|
|
2337
|
-
children
|
|
2401
|
+
children,
|
|
2338
2402
|
static: false,
|
|
2339
2403
|
...at ? { at } : {}
|
|
2340
2404
|
};
|
|
@@ -2406,10 +2470,14 @@ var Lowerer = class {
|
|
|
2406
2470
|
const at = this.tagAt(el);
|
|
2407
2471
|
return { kind: "component", name: "Show", props, children: [child], ...at ? { at } : {}, ...cond.at ? { bindAt: cond.at } : {} };
|
|
2408
2472
|
}
|
|
2409
|
-
/**
|
|
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
|
+
*/
|
|
2410
2478
|
lowerEach(el) {
|
|
2411
2479
|
const eachDir = el.attributes.find((a) => a.kind === "EachDirective");
|
|
2412
|
-
if (!eachDir || eachDir.kind !== "EachDirective") return
|
|
2480
|
+
if (!eachDir || eachDir.kind !== "EachDirective") return null;
|
|
2413
2481
|
const each = this.hole(eachDir.hole);
|
|
2414
2482
|
const props = [{ name: "each", kind: "attr", expr: each.code, reactive: each.reactive, ...each.at ? { at: each.at } : {} }];
|
|
2415
2483
|
if (eachDir.key) {
|
|
@@ -2419,12 +2487,12 @@ var Lowerer = class {
|
|
|
2419
2487
|
const arrow = this.itemArrow(el);
|
|
2420
2488
|
let childrenCode;
|
|
2421
2489
|
if (arrow) {
|
|
2422
|
-
const
|
|
2423
|
-
|
|
2424
|
-
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}`;
|
|
2425
2492
|
} else {
|
|
2426
|
-
const
|
|
2427
|
-
|
|
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")}`;
|
|
2428
2496
|
}
|
|
2429
2497
|
const children = [{ kind: "expr", code: childrenCode, reactive: false }];
|
|
2430
2498
|
const at = this.tagAt(el);
|
|
@@ -2441,25 +2509,6 @@ var Lowerer = class {
|
|
|
2441
2509
|
const clone = { ...el, attributes: el.attributes.filter((a) => !drop(a)) };
|
|
2442
2510
|
return clone.kind === "Element" ? this.lowerElement(clone) : this.lowerComponent(clone);
|
|
2443
2511
|
}
|
|
2444
|
-
/** Same element (minus each/key) but with explicit IR children. */
|
|
2445
|
-
rebuildWithChildren(el, children) {
|
|
2446
|
-
const props = this.lowerAttributes(
|
|
2447
|
-
el.attributes.filter((a) => a.kind !== "EachDirective")
|
|
2448
|
-
);
|
|
2449
|
-
if (el.kind === "Element") {
|
|
2450
|
-
const at = this.tagAt(el);
|
|
2451
|
-
return {
|
|
2452
|
-
kind: "element",
|
|
2453
|
-
tag: el.tag,
|
|
2454
|
-
svg: el.namespace === "svg",
|
|
2455
|
-
props,
|
|
2456
|
-
children,
|
|
2457
|
-
static: false,
|
|
2458
|
-
...at ? { at } : {}
|
|
2459
|
-
};
|
|
2460
|
-
}
|
|
2461
|
-
return { kind: "component", name: el.tag, props, children };
|
|
2462
|
-
}
|
|
2463
2512
|
// --- attributes ---------------------------------------------------------
|
|
2464
2513
|
lowerAttributes(attrs) {
|
|
2465
2514
|
const props = [];
|
|
@@ -2778,6 +2827,22 @@ var DELEGATED2 = /* @__PURE__ */ new Set([
|
|
|
2778
2827
|
"mouseup"
|
|
2779
2828
|
]);
|
|
2780
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
|
+
}
|
|
2781
2846
|
var posOf = (node, ctx) => {
|
|
2782
2847
|
if (!ctx.sourceFile) return void 0;
|
|
2783
2848
|
const at = node.loc?.start;
|
|
@@ -2886,7 +2951,16 @@ function buildProps(attrs, ctx) {
|
|
|
2886
2951
|
}
|
|
2887
2952
|
function buildChildren(children, ctx) {
|
|
2888
2953
|
const out = [];
|
|
2889
|
-
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
|
+
}
|
|
2890
2964
|
if (child.type === "JSXText") {
|
|
2891
2965
|
const text = cleanTemplateText(child.value);
|
|
2892
2966
|
if (text) out.push({ kind: "text", value: text });
|
|
@@ -2923,19 +2997,68 @@ function readLoad(attrs) {
|
|
|
2923
2997
|
}
|
|
2924
2998
|
return void 0;
|
|
2925
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
|
+
}
|
|
2926
3050
|
function buildNode(node, ctx) {
|
|
2927
3051
|
if (node.type === "JSXFragment") {
|
|
2928
3052
|
return { kind: "fragment", children: buildChildren(node.children, ctx) };
|
|
2929
3053
|
}
|
|
3054
|
+
if (directive(node, "if")) return buildIf(node, null, ctx);
|
|
2930
3055
|
const { tag, component } = tagInfo(node.openingElement.name, ctx);
|
|
3056
|
+
if (!component) return buildElement(node, ctx, []);
|
|
2931
3057
|
const props = buildProps(node.openingElement.attributes, ctx);
|
|
2932
3058
|
const children = buildChildren(node.children, ctx);
|
|
2933
3059
|
const at = ctx.sourceFile && node.loc?.start ? { file: ctx.sourceFile, line: node.loc.start.line, column: node.loc.start.column } : void 0;
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
return { kind: "component", name: tag, props, children, ...load ? { load } : {}, ...at ? { at } : {} };
|
|
2937
|
-
}
|
|
2938
|
-
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 } : {} };
|
|
2939
3062
|
}
|
|
2940
3063
|
function buildJsxIR(node, ctx) {
|
|
2941
3064
|
const ir = buildNode(node, ctx);
|
|
@@ -3580,7 +3703,7 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3580
3703
|
const wantsJsx = format !== "lit";
|
|
3581
3704
|
const mayHaveTemplate = wantsLit && (code.includes(`${litTag}\``) || code.includes("svg`"));
|
|
3582
3705
|
const wantsIntrinsics = options.intrinsics !== false && mayHaveIntrinsic(code);
|
|
3583
|
-
const wantsSources = options.sourceLocations === true &&
|
|
3706
|
+
const wantsSources = options.sourceLocations === true && mayHaveSourceMarks(code);
|
|
3584
3707
|
const sourceName = relativeToRoot(id, options.sourceRoot);
|
|
3585
3708
|
if (!mayHaveTemplate && !(wantsJsx && code.includes("<")) && !wantsIntrinsics && !wantsSources) return null;
|
|
3586
3709
|
const ast = parse2(code, {
|
|
@@ -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";
|
|
@@ -720,7 +720,7 @@ function transformTemplates(code, id, options = {}) {
|
|
|
720
720
|
const wantsJsx = format !== "lit";
|
|
721
721
|
const mayHaveTemplate = wantsLit && (code.includes(`${litTag}\``) || code.includes("svg`"));
|
|
722
722
|
const wantsIntrinsics = options.intrinsics !== false && mayHaveIntrinsic(code);
|
|
723
|
-
const wantsSources = options.sourceLocations === true &&
|
|
723
|
+
const wantsSources = options.sourceLocations === true && mayHaveSourceMarks(code);
|
|
724
724
|
const sourceName = relativeToRoot(id, options.sourceRoot);
|
|
725
725
|
if (!mayHaveTemplate && !(wantsJsx && code.includes("<")) && !wantsIntrinsics && !wantsSources) return null;
|
|
726
726
|
const ast = parse2(code, {
|