@fluixi/compiler 1.0.0-alpha.84 → 1.0.0-alpha.85
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/expr-shape.d.cts +2 -2
- package/dist/analyze/expr-shape.d.ts +2 -2
- package/dist/analyze/expr-shape.js +1 -1
- package/dist/analyze/intrinsics.cjs +1 -1
- package/dist/analyze/intrinsics.d.cts +7 -7
- package/dist/analyze/intrinsics.d.ts +7 -7
- package/dist/analyze/intrinsics.d.ts.map +1 -1
- package/dist/analyze/intrinsics.js +3 -3
- package/dist/analyze/intrinsics.mjs +1 -1
- package/dist/analyze/props-destructure.d.cts +3 -3
- package/dist/analyze/props-destructure.d.ts +3 -3
- package/dist/analyze/props-destructure.d.ts.map +1 -1
- package/dist/analyze/props-destructure.js +4 -4
- package/dist/analyze/reactive-bindings.cjs +1 -1
- package/dist/analyze/reactive-bindings.d.cts +1 -1
- package/dist/analyze/reactive-bindings.d.ts +1 -1
- package/dist/analyze/reactive-bindings.js +2 -2
- package/dist/analyze/reactive-bindings.mjs +1 -1
- package/dist/analyze/reactive-expr.d.cts +4 -4
- package/dist/analyze/reactive-expr.d.ts +4 -4
- package/dist/analyze/reactive-expr.d.ts.map +1 -1
- package/dist/analyze/reactive-expr.js +2 -2
- package/dist/analyze/static-graph.cjs +2 -2
- package/dist/analyze/static-graph.d.cts +1 -1
- package/dist/analyze/static-graph.d.ts +1 -1
- package/dist/analyze/static-graph.d.ts.map +1 -1
- package/dist/analyze/static-graph.js +11 -11
- package/dist/analyze/static-graph.mjs +2 -2
- package/dist/{babel-NRW4EFTG.mjs → babel-TGY76XJ7.mjs} +6 -6
- package/dist/{chunk-MJV3UXIL.mjs → chunk-4PLHS2FP.mjs} +2 -2
- package/dist/{chunk-EZR7NZOY.mjs → chunk-6DB5FXS4.mjs} +3 -3
- package/dist/{chunk-FSSWUXUR.mjs → chunk-F74GFKSL.mjs} +1 -1
- package/dist/{chunk-3YKZ4GNH.mjs → chunk-G6QC2WRJ.mjs} +1 -1
- package/dist/{chunk-R2VHAZAX.mjs → chunk-RUDJDZAA.mjs} +1 -1
- package/dist/codegen/backends/imperative.cjs +1 -1
- package/dist/codegen/backends/imperative.d.cts +1 -1
- package/dist/codegen/backends/imperative.d.ts +1 -1
- package/dist/codegen/backends/imperative.js +12 -12
- package/dist/codegen/backends/imperative.mjs +1 -1
- package/dist/codegen/contract.d.cts +2 -2
- package/dist/codegen/contract.d.ts +2 -2
- package/dist/codegen/contract.js +2 -2
- package/dist/codegen/partial-template.d.cts +4 -4
- package/dist/codegen/partial-template.d.ts +4 -4
- package/dist/codegen/partial-template.js +0 -0
- package/dist/codegen/serialize-static.d.cts +3 -3
- package/dist/codegen/serialize-static.d.ts +3 -3
- package/dist/codegen/serialize-static.js +6 -6
- package/dist/frontend/babel/build-ir-lit.cjs +3 -3
- package/dist/frontend/babel/build-ir-lit.d.cts +2 -2
- package/dist/frontend/babel/build-ir-lit.d.ts +2 -2
- package/dist/frontend/babel/build-ir-lit.mjs +3 -3
- package/dist/frontend/babel/build-ir.cjs +3 -3
- package/dist/frontend/babel/build-ir.d.cts +2 -2
- package/dist/frontend/babel/build-ir.d.ts +2 -2
- package/dist/frontend/babel/build-ir.js +2 -2
- package/dist/frontend/babel/build-ir.mjs +3 -3
- package/dist/frontend/babel/index.cjs +5 -5
- package/dist/frontend/babel/index.d.cts +1 -1
- package/dist/frontend/babel/index.d.ts +1 -1
- package/dist/frontend/babel/index.js +1 -1
- package/dist/frontend/babel/index.mjs +5 -5
- package/dist/frontend/babel/lower-template.cjs +3 -3
- package/dist/frontend/babel/lower-template.d.cts +1 -1
- package/dist/frontend/babel/lower-template.d.ts +1 -1
- package/dist/frontend/babel/lower-template.js +2 -2
- package/dist/frontend/babel/lower-template.mjs +3 -3
- package/dist/frontend/babel/plugin.cjs +4 -4
- package/dist/frontend/babel/plugin.d.cts +5 -5
- package/dist/frontend/babel/plugin.d.ts +5 -5
- package/dist/frontend/babel/plugin.d.ts.map +1 -1
- package/dist/frontend/babel/plugin.js +14 -14
- package/dist/frontend/babel/plugin.mjs +4 -4
- package/dist/index.cjs +5 -5
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -4
- package/dist/index.mjs +5 -5
- package/dist/integrations.cjs +12 -8
- package/dist/integrations.d.cts +9 -9
- package/dist/integrations.d.ts +9 -9
- package/dist/integrations.d.ts.map +1 -1
- package/dist/integrations.js +29 -8
- package/dist/integrations.mjs +15 -11
- package/dist/ir/nodes.d.cts +6 -6
- package/dist/ir/nodes.d.ts +6 -6
- package/dist/lower/compile-template.cjs +3 -3
- package/dist/lower/compile-template.d.cts +3 -3
- package/dist/lower/compile-template.d.ts +3 -3
- package/dist/lower/compile-template.js +1 -1
- package/dist/lower/compile-template.mjs +3 -3
- package/dist/lower/jsx.d.cts +1 -1
- package/dist/lower/jsx.d.ts +1 -1
- package/dist/lower/jsx.js +4 -4
- package/dist/lower/template.cjs +2 -2
- package/dist/lower/template.d.cts +3 -3
- package/dist/lower/template.d.ts +3 -3
- package/dist/lower/template.d.ts.map +1 -1
- package/dist/lower/template.js +7 -7
- package/dist/lower/template.mjs +2 -2
- package/dist/lower/text.d.cts +2 -2
- package/dist/lower/text.d.ts +2 -2
- package/dist/lower/text.d.ts.map +1 -1
- package/dist/lower/text.js +2 -2
- package/dist/optimize/analyze-static.d.cts +2 -2
- package/dist/optimize/analyze-static.d.ts +2 -2
- package/dist/optimize/analyze-static.js +2 -2
- package/dist/optimize/collapse-strategies.d.cts +3 -3
- package/dist/optimize/collapse-strategies.d.ts +3 -3
- package/dist/options.d.cts +2 -2
- package/dist/options.d.ts +2 -2
- package/dist/resolve/builtins.cjs +1 -1
- package/dist/resolve/builtins.d.cts +8 -8
- package/dist/resolve/builtins.d.ts +8 -8
- package/dist/resolve/builtins.d.ts.map +1 -1
- package/dist/resolve/builtins.js +4 -4
- package/dist/resolve/builtins.mjs +1 -1
- package/dist/resolve/component-globals.cjs +3 -3
- package/dist/resolve/component-globals.d.cts +5 -5
- package/dist/resolve/component-globals.d.ts +5 -5
- package/dist/resolve/component-globals.js +10 -10
- package/dist/resolve/component-globals.mjs +3 -3
- package/dist/resolve/component-resolver.d.cts +3 -3
- package/dist/resolve/component-resolver.d.ts +3 -3
- package/dist/resolve/component-resolver.d.ts.map +1 -1
- package/dist/resolve/component-resolver.js +3 -3
- package/dist/resolve/load-directive.d.cts +5 -5
- package/dist/resolve/load-directive.d.ts +5 -5
- package/dist/resolve/load-directive.js +6 -6
- package/dist/resolve/resolve-ir.d.cts +6 -6
- package/dist/resolve/resolve-ir.d.ts +6 -6
- package/dist/resolve/resolve-ir.d.ts.map +1 -1
- package/dist/resolve/resolve-ir.js +1 -1
- package/dist/resolve/write-globals.cjs +3 -3
- package/dist/resolve/write-globals.js +2 -2
- package/dist/resolve/write-globals.mjs +3 -3
- package/dist/{server-fns-4ZXN6DYU.mjs → server-fns-ZYWQTSZU.mjs} +4 -4
- package/dist/{server-functions-V6D6DRIA.mjs → server-functions-PCERFA7A.mjs} +3 -3
- package/dist/transform/bindings.d.cts +1 -1
- package/dist/transform/bindings.d.ts +1 -1
- package/dist/transform/bindings.js +1 -1
- package/dist/transform/index.cjs +3 -3
- package/dist/transform/index.mjs +3 -3
- package/dist/transform/intrinsics.cjs +1 -1
- package/dist/transform/intrinsics.js +1 -1
- package/dist/transform/intrinsics.mjs +1 -1
- package/dist/transform/props.d.cts +1 -1
- package/dist/transform/props.d.ts +1 -1
- package/dist/transform/props.d.ts.map +1 -1
- package/dist/transform/props.js +4 -4
- package/dist/transform/server-fn-id.d.cts +1 -1
- package/dist/transform/server-fn-id.d.ts +1 -1
- package/dist/transform/server-fn-id.js +2 -2
- package/dist/transform/server-fns.js +3 -3
- package/dist/transform/source-locations.cjs +1 -1
- package/dist/transform/source-locations.d.cts +1 -1
- package/dist/transform/source-locations.d.ts +1 -1
- package/dist/transform/source-locations.js +5 -5
- package/dist/transform/source-locations.mjs +1 -1
- package/dist/transform/templates.cjs +2 -2
- package/dist/transform/templates.d.cts +2 -2
- package/dist/transform/templates.d.ts +2 -2
- package/dist/transform/templates.d.ts.map +1 -1
- package/dist/transform/templates.js +7 -7
- package/dist/transform/templates.mjs +2 -2
- package/dist/{transform-BT4MMASR.mjs → transform-RWDTQUF5.mjs} +5 -5
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +3 -3
package/dist/integrations.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.85 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __create = Object.create;
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -157,7 +157,7 @@ var init_intrinsics = __esm({
|
|
|
157
157
|
$store: { export: "store", module: "@fluixi/reactive/store", returns: "store-handle" },
|
|
158
158
|
$resource: { export: "resource", module: REACTIVE_MODULE, returns: "resource-handle" },
|
|
159
159
|
// No short runtime form for these yet, so the intrinsic stands for the `create*`
|
|
160
|
-
// name. Still worth having
|
|
160
|
+
// name. Still worth having: no import to write, and when a shorter form is
|
|
161
161
|
// designed, the change is this line rather than a compiler pass.
|
|
162
162
|
$selector: { export: "createSelector", module: REACTIVE_MODULE, returns: "memo-accessor" },
|
|
163
163
|
$deferred: { export: "createDeferred", module: REACTIVE_MODULE, returns: "memo-accessor" },
|
|
@@ -1596,7 +1596,7 @@ var init_template = __esm({
|
|
|
1596
1596
|
}
|
|
1597
1597
|
];
|
|
1598
1598
|
}
|
|
1599
|
-
/** A plain attribute (incl. lit `?bool`, mixed values)
|
|
1599
|
+
/** A plain attribute (incl. lit `?bool`, mixed values), old `mkProp` behavior. */
|
|
1600
1600
|
plainAttr(a) {
|
|
1601
1601
|
const v = a.value;
|
|
1602
1602
|
let name = a.name;
|
|
@@ -2102,7 +2102,7 @@ function buildIR(node, used = /* @__PURE__ */ new Set(), onNested) {
|
|
|
2102
2102
|
const ir = buildJsxIR(node, {
|
|
2103
2103
|
code: (n) => (
|
|
2104
2104
|
// A member-expression tag (`<ns.Foo/>`) is not an Expression, so it cannot go
|
|
2105
|
-
// through the nested-JSX compile
|
|
2105
|
+
// through the nested-JSX compile: it only ever needs printing.
|
|
2106
2106
|
n.type === "JSXMemberExpression" ? gen2(n) : genExpr(n, used, onNested)
|
|
2107
2107
|
),
|
|
2108
2108
|
used
|
|
@@ -2556,7 +2556,7 @@ var init_plugin = __esm({
|
|
|
2556
2556
|
import_core3.types.identifier(name),
|
|
2557
2557
|
// Just the HTML. Parsing is deferred to `templateNode`, which
|
|
2558
2558
|
// knows whether this is a server render, a hydration or a fresh
|
|
2559
|
-
// client render
|
|
2559
|
+
// client render: a module-scope `createTemplate` would touch
|
|
2560
2560
|
// `document` at import time and break SSR outright.
|
|
2561
2561
|
import_core3.types.stringLiteral(html)
|
|
2562
2562
|
)
|
|
@@ -3872,7 +3872,7 @@ function componentGlobals(rules, options = {}) {
|
|
|
3872
3872
|
return target.export === "default" ? ` const ${name}: typeof ${ns}.default;` : ` export import ${name} = ${ns}.${target.export};`;
|
|
3873
3873
|
});
|
|
3874
3874
|
const note = shadowedByDom.length > 0 ? `//
|
|
3875
|
-
// Import these explicitly
|
|
3875
|
+
// Import these explicitly: lib.dom already declares the name, so an ambient
|
|
3876
3876
|
// declaration cannot win:
|
|
3877
3877
|
` + shadowedByDom.map((n) => {
|
|
3878
3878
|
const module2 = resolver.resolve(n)?.module;
|
|
@@ -3888,7 +3888,7 @@ function componentGlobals(rules, options = {}) {
|
|
|
3888
3888
|
// a pattern matches unboundedly many names, so there is no list to emit. Those
|
|
3889
3889
|
// tags still resolve at build time; declare them by hand if the editor needs them.
|
|
3890
3890
|
` : "";
|
|
3891
|
-
const source = `// GENERATED by ${generator}
|
|
3891
|
+
const source = `// GENERATED by ${generator}, do not edit.
|
|
3892
3892
|
//
|
|
3893
3893
|
// The components \`resolve\` supplies without an import. This describes what the
|
|
3894
3894
|
// compiler already does; it does not enable it.
|
|
@@ -4252,6 +4252,10 @@ function createESBuildPlugin(options = {}) {
|
|
|
4252
4252
|
};
|
|
4253
4253
|
}
|
|
4254
4254
|
var SERVER_FNS_VMOD = "virtual:fluixi-server-fns";
|
|
4255
|
+
function hasServerDirective(source) {
|
|
4256
|
+
const withoutComments = source.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/(^|[^:])\/\/[^\n]*/g, "$1");
|
|
4257
|
+
return /(^|[\s;{(,])['"]use server['"]/.test(withoutComments);
|
|
4258
|
+
}
|
|
4255
4259
|
function findServerFnModules(dir, out = []) {
|
|
4256
4260
|
let entries;
|
|
4257
4261
|
try {
|
|
@@ -4265,7 +4269,7 @@ function findServerFnModules(dir, out = []) {
|
|
|
4265
4269
|
if (e.isDirectory()) findServerFnModules(full, out);
|
|
4266
4270
|
else if (/\.[jt]sx?$/.test(e.name)) {
|
|
4267
4271
|
try {
|
|
4268
|
-
if ((0, import_node_fs2.readFileSync)(full, "utf8")
|
|
4272
|
+
if (hasServerDirective((0, import_node_fs2.readFileSync)(full, "utf8"))) out.push(full);
|
|
4269
4273
|
} catch {
|
|
4270
4274
|
}
|
|
4271
4275
|
}
|
package/dist/integrations.d.cts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @module @fluixi/compiler/integrations
|
|
4
4
|
*
|
|
5
5
|
* vite, webpack, rollup and esbuild adapters. Each is a few lines around
|
|
6
|
-
* `compileModule`, which rewrites the source in place
|
|
6
|
+
* `compileModule`, which rewrites the source in place, JSX and `` html`` `` both
|
|
7
7
|
* lower to the shared IR and the imperative backend. fluixi re-exports
|
|
8
8
|
* createVitePlugin from here.
|
|
9
9
|
*
|
|
@@ -24,7 +24,7 @@ export interface CompilerOptions {
|
|
|
24
24
|
*
|
|
25
25
|
* Relative to the project root; `false` turns generation off. Without this file every
|
|
26
26
|
* resolved tag is a `Cannot find name` error in the editor and in `tsc`, because the
|
|
27
|
-
* import only exists after compilation. Committing it is intended
|
|
27
|
+
* import only exists after compilation. Committing it is intended, it is what makes a
|
|
28
28
|
* fresh clone type-check before anyone runs the dev server.
|
|
29
29
|
*
|
|
30
30
|
* It must be covered by `include` in tsconfig.json, which for the default means adding
|
|
@@ -56,7 +56,7 @@ export interface CompilerOptions {
|
|
|
56
56
|
development?: boolean;
|
|
57
57
|
/**
|
|
58
58
|
* Where the JSX *types* come from, and the `jsxImportSource` handed to esbuild
|
|
59
|
-
* and TypeScript. The compiler never emits `jsx()` calls itself
|
|
59
|
+
* and TypeScript. The compiler never emits `jsx()` calls itself, this is for
|
|
60
60
|
* type resolution and for any JSX the Fluixi transform does not consume.
|
|
61
61
|
* @default '@fluixi/jsx'
|
|
62
62
|
*/
|
|
@@ -69,13 +69,13 @@ export interface CompilerOptions {
|
|
|
69
69
|
format?: 'jsx' | 'lit' | 'both';
|
|
70
70
|
/**
|
|
71
71
|
* Record where each reactive node is created, and serve the running app's graph to a tool
|
|
72
|
-
* that asks for it. Development only
|
|
72
|
+
* that asks for it. Development only: a build never carries either.
|
|
73
73
|
*
|
|
74
74
|
* On by default when the dev server is running and @fluixi/devtools is installed. The
|
|
75
75
|
* marks are what turn `m5` into `double @ src/app.tsx:6`, and the endpoint is what an
|
|
76
76
|
* editor or a graph panel reads.
|
|
77
77
|
*
|
|
78
|
-
* `{ external: true }` marks dependencies too
|
|
78
|
+
* `{ external: true }` marks dependencies too: node_modules and anything outside the
|
|
79
79
|
* project. That is for working on the framework itself: the graph then shows which nodes
|
|
80
80
|
* a library created and which the application did, at the cost of a mark per node in code
|
|
81
81
|
* you are not editing.
|
|
@@ -89,7 +89,7 @@ export interface CompilerOptions {
|
|
|
89
89
|
* The default path parses once and splices the emitted code over the spans it
|
|
90
90
|
* replaces: nothing is reprinted, edits carry a source map, and types are left
|
|
91
91
|
* for esbuild to strip. Babel is kept for the cases that need to sit inside its
|
|
92
|
-
* pipeline
|
|
92
|
+
* pipeline: a `babel.config.js` with other plugins that have to see the
|
|
93
93
|
* output. It needs `@babel/core` and friends installed; they are optional peers.
|
|
94
94
|
* @default false
|
|
95
95
|
*/
|
|
@@ -102,11 +102,11 @@ export interface CompilerOptions {
|
|
|
102
102
|
/**
|
|
103
103
|
* Rewrite a component's destructured props into property reads, so
|
|
104
104
|
* `function Card({ title })` keeps updating instead of reading `title` once.
|
|
105
|
-
* Applies to JSX and html`` alike
|
|
105
|
+
* Applies to JSX and html`` alike: it rewrites the function body before either is
|
|
106
106
|
* compiled. A pattern it can't prove is left as written, so `splitProps` keeps
|
|
107
107
|
* working wherever it's still needed.
|
|
108
108
|
*
|
|
109
|
-
* Turn it off for a package that ships its source to be compiled by the consumer
|
|
109
|
+
* Turn it off for a package that ships its source to be compiled by the consumer ,
|
|
110
110
|
* rewriting there would bake property reads into what you publish.
|
|
111
111
|
*
|
|
112
112
|
* @default true
|
|
@@ -195,7 +195,7 @@ export type { ServerFnTransformOptions } from './frontend/babel/server-functions
|
|
|
195
195
|
import type { ComponentResolverRule } from './resolve/component-resolver.cjs';
|
|
196
196
|
/**
|
|
197
197
|
* Vite plugin for `"use server"`: applies the transform (client→RPC stub, server→register
|
|
198
|
-
* the body), and provides `virtual:fluixi-server-fns
|
|
198
|
+
* the body), and provides `virtual:fluixi-server-fns`, side-effect imports of every
|
|
199
199
|
* module that defines a server function. The server entry imports it so ALL server
|
|
200
200
|
* functions register at startup (including those in lazy routes, which would otherwise
|
|
201
201
|
* register only when their chunk loads → an RPC registry miss). The client never imports
|
package/dist/integrations.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @module @fluixi/compiler/integrations
|
|
4
4
|
*
|
|
5
5
|
* vite, webpack, rollup and esbuild adapters. Each is a few lines around
|
|
6
|
-
* `compileModule`, which rewrites the source in place
|
|
6
|
+
* `compileModule`, which rewrites the source in place, JSX and `` html`` `` both
|
|
7
7
|
* lower to the shared IR and the imperative backend. fluixi re-exports
|
|
8
8
|
* createVitePlugin from here.
|
|
9
9
|
*
|
|
@@ -24,7 +24,7 @@ export interface CompilerOptions {
|
|
|
24
24
|
*
|
|
25
25
|
* Relative to the project root; `false` turns generation off. Without this file every
|
|
26
26
|
* resolved tag is a `Cannot find name` error in the editor and in `tsc`, because the
|
|
27
|
-
* import only exists after compilation. Committing it is intended
|
|
27
|
+
* import only exists after compilation. Committing it is intended, it is what makes a
|
|
28
28
|
* fresh clone type-check before anyone runs the dev server.
|
|
29
29
|
*
|
|
30
30
|
* It must be covered by `include` in tsconfig.json, which for the default means adding
|
|
@@ -56,7 +56,7 @@ export interface CompilerOptions {
|
|
|
56
56
|
development?: boolean;
|
|
57
57
|
/**
|
|
58
58
|
* Where the JSX *types* come from, and the `jsxImportSource` handed to esbuild
|
|
59
|
-
* and TypeScript. The compiler never emits `jsx()` calls itself
|
|
59
|
+
* and TypeScript. The compiler never emits `jsx()` calls itself, this is for
|
|
60
60
|
* type resolution and for any JSX the Fluixi transform does not consume.
|
|
61
61
|
* @default '@fluixi/jsx'
|
|
62
62
|
*/
|
|
@@ -69,13 +69,13 @@ export interface CompilerOptions {
|
|
|
69
69
|
format?: 'jsx' | 'lit' | 'both';
|
|
70
70
|
/**
|
|
71
71
|
* Record where each reactive node is created, and serve the running app's graph to a tool
|
|
72
|
-
* that asks for it. Development only
|
|
72
|
+
* that asks for it. Development only: a build never carries either.
|
|
73
73
|
*
|
|
74
74
|
* On by default when the dev server is running and @fluixi/devtools is installed. The
|
|
75
75
|
* marks are what turn `m5` into `double @ src/app.tsx:6`, and the endpoint is what an
|
|
76
76
|
* editor or a graph panel reads.
|
|
77
77
|
*
|
|
78
|
-
* `{ external: true }` marks dependencies too
|
|
78
|
+
* `{ external: true }` marks dependencies too: node_modules and anything outside the
|
|
79
79
|
* project. That is for working on the framework itself: the graph then shows which nodes
|
|
80
80
|
* a library created and which the application did, at the cost of a mark per node in code
|
|
81
81
|
* you are not editing.
|
|
@@ -89,7 +89,7 @@ export interface CompilerOptions {
|
|
|
89
89
|
* The default path parses once and splices the emitted code over the spans it
|
|
90
90
|
* replaces: nothing is reprinted, edits carry a source map, and types are left
|
|
91
91
|
* for esbuild to strip. Babel is kept for the cases that need to sit inside its
|
|
92
|
-
* pipeline
|
|
92
|
+
* pipeline: a `babel.config.js` with other plugins that have to see the
|
|
93
93
|
* output. It needs `@babel/core` and friends installed; they are optional peers.
|
|
94
94
|
* @default false
|
|
95
95
|
*/
|
|
@@ -102,11 +102,11 @@ export interface CompilerOptions {
|
|
|
102
102
|
/**
|
|
103
103
|
* Rewrite a component's destructured props into property reads, so
|
|
104
104
|
* `function Card({ title })` keeps updating instead of reading `title` once.
|
|
105
|
-
* Applies to JSX and html`` alike
|
|
105
|
+
* Applies to JSX and html`` alike: it rewrites the function body before either is
|
|
106
106
|
* compiled. A pattern it can't prove is left as written, so `splitProps` keeps
|
|
107
107
|
* working wherever it's still needed.
|
|
108
108
|
*
|
|
109
|
-
* Turn it off for a package that ships its source to be compiled by the consumer
|
|
109
|
+
* Turn it off for a package that ships its source to be compiled by the consumer ,
|
|
110
110
|
* rewriting there would bake property reads into what you publish.
|
|
111
111
|
*
|
|
112
112
|
* @default true
|
|
@@ -195,7 +195,7 @@ export type { ServerFnTransformOptions } from './frontend/babel/server-functions
|
|
|
195
195
|
import type { ComponentResolverRule } from './resolve/component-resolver.js';
|
|
196
196
|
/**
|
|
197
197
|
* Vite plugin for `"use server"`: applies the transform (client→RPC stub, server→register
|
|
198
|
-
* the body), and provides `virtual:fluixi-server-fns
|
|
198
|
+
* the body), and provides `virtual:fluixi-server-fns`, side-effect imports of every
|
|
199
199
|
* module that defines a server function. The server entry imports it so ALL server
|
|
200
200
|
* functions register at startup (including those in lazy routes, which would otherwise
|
|
201
201
|
* register only when their chunk loads → an RPC registry miss). The client never imports
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integrations.d.ts","sourceRoot":"","sources":["../src/integrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC3C;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACzB,6FAA6F;IAC7F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAEhC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAE5C;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAMD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,eAAoB;;;;;;;;;;;;;;;;;GAwCpE;AAMD;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,eAAoB,aAIpD,GAAG,MAAM,YAAY,GAAG,SAkB5C;AAqCD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAE,eAAoB,GAAG,CAAC,CAsHpE;AAoID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,eAAoB,IACxC,MAAM,GAAG,EAAE,QAAQ,MAAM,mBAUjD;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,eAAoB;;oBAItC,MAAM,MAAM,MAAM;;;;;;;;;;;;EAK3C;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,eAAoB;;iBAIhD,GAAG;EAwBnB;AAWD,YAAY,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"integrations.d.ts","sourceRoot":"","sources":["../src/integrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC3C;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACzB,6FAA6F;IAC7F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAEhC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAE5C;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAMD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,eAAoB;;;;;;;;;;;;;;;;;GAwCpE;AAMD;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,eAAoB,aAIpD,GAAG,MAAM,YAAY,GAAG,SAkB5C;AAqCD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAE,eAAoB,GAAG,CAAC,CAsHpE;AAoID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,eAAoB,IACxC,MAAM,GAAG,EAAE,QAAQ,MAAM,mBAUjD;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,eAAoB;;oBAItC,MAAM,MAAM,MAAM;;;;;;;;;;;;EAK3C;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,eAAoB;;iBAIhD,GAAG;EAwBnB;AAWD,YAAY,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAoD7E;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,GAAG,GAAG,EAAE,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,CAAC,CAqCvF;;;;;;;;;AAED,wBAOE"}
|
package/dist/integrations.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @module @fluixi/compiler/integrations
|
|
4
4
|
*
|
|
5
5
|
* vite, webpack, rollup and esbuild adapters. Each is a few lines around
|
|
6
|
-
* `compileModule`, which rewrites the source in place
|
|
6
|
+
* `compileModule`, which rewrites the source in place, JSX and `` html`` `` both
|
|
7
7
|
* lower to the shared IR and the imperative backend. fluixi re-exports
|
|
8
8
|
* createVitePlugin from here.
|
|
9
9
|
*
|
|
@@ -161,7 +161,7 @@ export function createVitePlugin(options = {}) {
|
|
|
161
161
|
if (!babel) {
|
|
162
162
|
// No silent fallback. This front-end compiles through babel; without it
|
|
163
163
|
// there is no transform, and emitting the source unchanged would ship a
|
|
164
|
-
// build whose JSX and html`` templates were never compiled
|
|
164
|
+
// build whose JSX and html`` templates were never compiled, a failure
|
|
165
165
|
// that looks exactly like success until the page is opened.
|
|
166
166
|
throw new Error(`[fluixi] @babel/core is required to compile ${id} but could not be loaded. ` +
|
|
167
167
|
`Install it alongside @fluixi/compiler.`);
|
|
@@ -189,7 +189,7 @@ export function createVitePlugin(options = {}) {
|
|
|
189
189
|
]);
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
-
// Only our custom babel plugin handles JSX
|
|
192
|
+
// Only our custom babel plugin handles JSX, never @babel/preset-react, which
|
|
193
193
|
// rewrites spreads with Object.assign and breaks store-proxy reactivity.
|
|
194
194
|
if (babelPlugin && babelPlugin.plugin) {
|
|
195
195
|
plugins.push([babelPlugin.plugin, babelPlugin.getOptions()]);
|
|
@@ -285,7 +285,7 @@ const reported = new Set();
|
|
|
285
285
|
* All of these build cleanly and fail at runtime, which is why they are worth printing: an
|
|
286
286
|
* unresolved tag renders nothing, a `load:` it cannot act on ships the chunk eagerly, and a
|
|
287
287
|
* props pattern the rewrite refused reads its value once instead of tracking it. None leaves
|
|
288
|
-
* a trace anywhere else
|
|
288
|
+
* a trace anywhere else: the last one is a stale value on screen and nothing in the build.
|
|
289
289
|
*
|
|
290
290
|
* `console.warn`, deliberately, not a plugin's `this.warn`: that only exists in the
|
|
291
291
|
* rollup/vite context, and this runs for the esbuild and webpack adapters too. A
|
|
@@ -407,6 +407,27 @@ import { readdirSync, readFileSync } from 'node:fs';
|
|
|
407
407
|
import { join as _join } from 'node:path';
|
|
408
408
|
const SERVER_FNS_VMOD = 'virtual:fluixi-server-fns';
|
|
409
409
|
/** Recursively find source files containing the `"use server"` directive under `dir`. */
|
|
410
|
+
/**
|
|
411
|
+
* Whether a file actually carries a `"use server"` directive.
|
|
412
|
+
*
|
|
413
|
+
* Every module this matches is side-effect imported into the server bundle, so a false
|
|
414
|
+
* positive does more than waste a line: it runs that file on the server. A plain
|
|
415
|
+
* `includes('use server')` matched the words wherever they appeared, and a client entry
|
|
416
|
+
* that merely *mentioned* the directive in a comment was imported into the SSR graph and
|
|
417
|
+
* called `startClient` there, which fails with `document is not defined` from a line
|
|
418
|
+
* nobody wrote.
|
|
419
|
+
*
|
|
420
|
+
* Comments are stripped before the test rather than parsed around, because the answer
|
|
421
|
+
* only has to be good enough to decide whether the real transform should look at the
|
|
422
|
+
* file. A directive inside a string literal still matches, which costs an extra import
|
|
423
|
+
* and nothing else.
|
|
424
|
+
*/
|
|
425
|
+
function hasServerDirective(source) {
|
|
426
|
+
const withoutComments = source
|
|
427
|
+
.replace(/\/\*[\s\S]*?\*\//g, ' ')
|
|
428
|
+
.replace(/(^|[^:])\/\/[^\n]*/g, '$1');
|
|
429
|
+
return /(^|[\s;{(,])['"]use server['"]/.test(withoutComments);
|
|
430
|
+
}
|
|
410
431
|
function findServerFnModules(dir, out = []) {
|
|
411
432
|
let entries;
|
|
412
433
|
try {
|
|
@@ -423,11 +444,11 @@ function findServerFnModules(dir, out = []) {
|
|
|
423
444
|
findServerFnModules(full, out);
|
|
424
445
|
else if (/\.[jt]sx?$/.test(e.name)) {
|
|
425
446
|
try {
|
|
426
|
-
if (readFileSync(full, 'utf8')
|
|
447
|
+
if (hasServerDirective(readFileSync(full, 'utf8')))
|
|
427
448
|
out.push(full);
|
|
428
449
|
}
|
|
429
450
|
catch {
|
|
430
|
-
/* unreadable
|
|
451
|
+
/* unreadable: skip */
|
|
431
452
|
}
|
|
432
453
|
}
|
|
433
454
|
}
|
|
@@ -435,7 +456,7 @@ function findServerFnModules(dir, out = []) {
|
|
|
435
456
|
}
|
|
436
457
|
/**
|
|
437
458
|
* Vite plugin for `"use server"`: applies the transform (client→RPC stub, server→register
|
|
438
|
-
* the body), and provides `virtual:fluixi-server-fns
|
|
459
|
+
* the body), and provides `virtual:fluixi-server-fns`, side-effect imports of every
|
|
439
460
|
* module that defines a server function. The server entry imports it so ALL server
|
|
440
461
|
* functions register at startup (including those in lazy routes, which would otherwise
|
|
441
462
|
* register only when their chunk loads → an RPC registry miss). The client never imports
|
|
@@ -461,7 +482,7 @@ export function serverFunctionsVitePlugin(options = {}) {
|
|
|
461
482
|
// First wire the request-context bridge (server-only), then side-effect import each
|
|
462
483
|
// server-fn module so its top-level $$registerServerFn(...) runs, then re-export the
|
|
463
484
|
// dispatcher so the host can route /_server through THIS module graph (sharing the
|
|
464
|
-
// registry the imports populated)
|
|
485
|
+
// registry the imports populated), apps don't need to re-export it from entry-server.
|
|
465
486
|
const setup = `import '@fluixi/start/server-fn-setup';\n`;
|
|
466
487
|
const imports = mods.map((m) => `import ${JSON.stringify(m)};`).join('\n');
|
|
467
488
|
const dispatcher = `\nexport { isServerFnRequest, handleServerFn } from '@fluixi/start/server-fn';\n`;
|
package/dist/integrations.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.85 | (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-4PLHS2FP.mjs";
|
|
7
7
|
import {
|
|
8
8
|
__require
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-G6QC2WRJ.mjs";
|
|
10
10
|
|
|
11
11
|
// src/resolve/write-globals.ts
|
|
12
12
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
@@ -86,7 +86,7 @@ function componentGlobals(rules, options = {}) {
|
|
|
86
86
|
return target.export === "default" ? ` const ${name}: typeof ${ns}.default;` : ` export import ${name} = ${ns}.${target.export};`;
|
|
87
87
|
});
|
|
88
88
|
const note = shadowedByDom.length > 0 ? `//
|
|
89
|
-
// Import these explicitly
|
|
89
|
+
// Import these explicitly: lib.dom already declares the name, so an ambient
|
|
90
90
|
// declaration cannot win:
|
|
91
91
|
` + shadowedByDom.map((n) => {
|
|
92
92
|
const module = resolver.resolve(n)?.module;
|
|
@@ -102,7 +102,7 @@ function componentGlobals(rules, options = {}) {
|
|
|
102
102
|
// a pattern matches unboundedly many names, so there is no list to emit. Those
|
|
103
103
|
// tags still resolve at build time; declare them by hand if the editor needs them.
|
|
104
104
|
` : "";
|
|
105
|
-
const source = `// GENERATED by ${generator}
|
|
105
|
+
const source = `// GENERATED by ${generator}, do not edit.
|
|
106
106
|
//
|
|
107
107
|
// The components \`resolve\` supplies without an import. This describes what the
|
|
108
108
|
// compiler already does; it does not enable it.
|
|
@@ -204,7 +204,7 @@ import { join as _join } from "node:path";
|
|
|
204
204
|
async function createBabelPlugin(options = {}) {
|
|
205
205
|
let pluginModule = null;
|
|
206
206
|
try {
|
|
207
|
-
pluginModule = await import("./babel-
|
|
207
|
+
pluginModule = await import("./babel-TGY76XJ7.mjs");
|
|
208
208
|
} catch (e) {
|
|
209
209
|
console.warn("Could not load the babel front-end:", e);
|
|
210
210
|
}
|
|
@@ -375,7 +375,7 @@ function transformOptions(options, id) {
|
|
|
375
375
|
}
|
|
376
376
|
async function rewriteProps(code, id, options) {
|
|
377
377
|
if (options.propsDestructure === false) return code;
|
|
378
|
-
const { transformProps } = await import("./transform-
|
|
378
|
+
const { transformProps } = await import("./transform-RWDTQUF5.mjs");
|
|
379
379
|
const result = transformProps(code, id);
|
|
380
380
|
reportDiagnostics({ propsDiagnostics: result.diagnostics }, id);
|
|
381
381
|
return result.rewritten > 0 ? result.code : code;
|
|
@@ -398,7 +398,7 @@ function reportDiagnostics(result, id) {
|
|
|
398
398
|
}
|
|
399
399
|
async function compileModule(code, id, options) {
|
|
400
400
|
if (!options.babel) {
|
|
401
|
-
const { transformTemplates } = await import("./transform-
|
|
401
|
+
const { transformTemplates } = await import("./transform-RWDTQUF5.mjs");
|
|
402
402
|
const result2 = transformTemplates(code, id, transformOptions(options, id));
|
|
403
403
|
reportDiagnostics(result2, id);
|
|
404
404
|
return result2;
|
|
@@ -466,6 +466,10 @@ function createESBuildPlugin(options = {}) {
|
|
|
466
466
|
};
|
|
467
467
|
}
|
|
468
468
|
var SERVER_FNS_VMOD = "virtual:fluixi-server-fns";
|
|
469
|
+
function hasServerDirective(source) {
|
|
470
|
+
const withoutComments = source.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/(^|[^:])\/\/[^\n]*/g, "$1");
|
|
471
|
+
return /(^|[\s;{(,])['"]use server['"]/.test(withoutComments);
|
|
472
|
+
}
|
|
469
473
|
function findServerFnModules(dir, out = []) {
|
|
470
474
|
let entries;
|
|
471
475
|
try {
|
|
@@ -479,7 +483,7 @@ function findServerFnModules(dir, out = []) {
|
|
|
479
483
|
if (e.isDirectory()) findServerFnModules(full, out);
|
|
480
484
|
else if (/\.[jt]sx?$/.test(e.name)) {
|
|
481
485
|
try {
|
|
482
|
-
if (readFileSync2(full, "utf8")
|
|
486
|
+
if (hasServerDirective(readFileSync2(full, "utf8"))) out.push(full);
|
|
483
487
|
} catch {
|
|
484
488
|
}
|
|
485
489
|
}
|
|
@@ -513,10 +517,10 @@ export { isServerFnRequest, handleServerFn } from '@fluixi/start/server-fn';
|
|
|
513
517
|
if (!code.includes("use server")) return null;
|
|
514
518
|
const args = { ssr: !!opts?.ssr, filename: id, root };
|
|
515
519
|
if (options.babel) {
|
|
516
|
-
const { transformServerFunctions } = await import("./server-functions-
|
|
520
|
+
const { transformServerFunctions } = await import("./server-functions-PCERFA7A.mjs");
|
|
517
521
|
return transformServerFunctions(code, args);
|
|
518
522
|
}
|
|
519
|
-
const { transformServerFns } = await import("./server-fns-
|
|
523
|
+
const { transformServerFns } = await import("./server-fns-ZYWQTSZU.mjs");
|
|
520
524
|
return transformServerFns(code, args);
|
|
521
525
|
}
|
|
522
526
|
};
|
package/dist/ir/nodes.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Normalized, host-agnostic IR. Both the babel and (future) swc front-ends
|
|
3
3
|
* produce this; codegen backends consume it. This is the stable contract
|
|
4
|
-
* between parsing and code generation
|
|
4
|
+
* between parsing and code generation: the layer your own improvements
|
|
5
5
|
* (hoisting, islands, resumability hints) transform.
|
|
6
6
|
*/
|
|
7
7
|
import type { IRLoadStrategy } from '../resolve/load-directive.cjs';
|
|
@@ -43,7 +43,7 @@ export interface IRProp {
|
|
|
43
43
|
directive?: string;
|
|
44
44
|
/**
|
|
45
45
|
* `expr` is an inline JSX element/fragment passed as a component prop (e.g.
|
|
46
|
-
* `<Suspense fallback={<div/>}>`). Emitted as a LAZY getter
|
|
46
|
+
* `<Suspense fallback={<div/>}>`). Emitted as a LAZY getter, like children, so the DOM is
|
|
47
47
|
* built only when the component reads the prop, not eagerly when the props object is
|
|
48
48
|
* constructed (which during hydration would walk the cursor and duplicate the tree).
|
|
49
49
|
*/
|
|
@@ -77,7 +77,7 @@ export interface IRElement {
|
|
|
77
77
|
/**
|
|
78
78
|
* Where a component reference comes from, attached to the reference itself.
|
|
79
79
|
*
|
|
80
|
-
* A capitalised tag with no binding in the file is supplied by the compiler
|
|
80
|
+
* A capitalised tag with no binding in the file is supplied by the compiler, from a
|
|
81
81
|
* `resolve` rule, or from the built-in control-flow/router sets. That decision used to
|
|
82
82
|
* live only in the Babel plugin's state, which meant the IR could not see which
|
|
83
83
|
* components a template referenced: no pass could vary a decision per usage, group
|
|
@@ -96,7 +96,7 @@ export interface IRComponentSource {
|
|
|
96
96
|
origin: 'rule' | 'builtin';
|
|
97
97
|
/**
|
|
98
98
|
* When the module is fetched. Set from a `load:` directive at the usage site, and
|
|
99
|
-
* `eager` otherwise
|
|
99
|
+
* `eager` otherwise: resolution decides where a component comes from, this decides
|
|
100
100
|
* when, and the two vary independently.
|
|
101
101
|
*/
|
|
102
102
|
loading: IRLoadStrategy;
|
|
@@ -110,7 +110,7 @@ export interface IRComponent {
|
|
|
110
110
|
children: IRNode[];
|
|
111
111
|
/**
|
|
112
112
|
* Set by the resolve pass when the compiler supplies this reference. Absent when the
|
|
113
|
-
* name is bound in the file
|
|
113
|
+
* name is bound in the file: an ordinary import the author wrote, or when nothing
|
|
114
114
|
* claims it, which is a diagnostic rather than a resolution.
|
|
115
115
|
*/
|
|
116
116
|
source?: IRComponentSource;
|
|
@@ -124,7 +124,7 @@ export interface IRComponent {
|
|
|
124
124
|
column: number;
|
|
125
125
|
};
|
|
126
126
|
/**
|
|
127
|
-
* Where the `${…}` that drives this subtree was written
|
|
127
|
+
* Where the `${…}` that drives this subtree was written, the condition of an `if=`,
|
|
128
128
|
* the list of an `each=`. The insert that adds and removes the subtree is a reactive
|
|
129
129
|
* binding, and this is the position it reports. Distinct from `at`, which marks the
|
|
130
130
|
* node itself rather than the binding that places it.
|
package/dist/ir/nodes.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Normalized, host-agnostic IR. Both the babel and (future) swc front-ends
|
|
3
3
|
* produce this; codegen backends consume it. This is the stable contract
|
|
4
|
-
* between parsing and code generation
|
|
4
|
+
* between parsing and code generation: the layer your own improvements
|
|
5
5
|
* (hoisting, islands, resumability hints) transform.
|
|
6
6
|
*/
|
|
7
7
|
import type { IRLoadStrategy } from '../resolve/load-directive.js';
|
|
@@ -43,7 +43,7 @@ export interface IRProp {
|
|
|
43
43
|
directive?: string;
|
|
44
44
|
/**
|
|
45
45
|
* `expr` is an inline JSX element/fragment passed as a component prop (e.g.
|
|
46
|
-
* `<Suspense fallback={<div/>}>`). Emitted as a LAZY getter
|
|
46
|
+
* `<Suspense fallback={<div/>}>`). Emitted as a LAZY getter, like children, so the DOM is
|
|
47
47
|
* built only when the component reads the prop, not eagerly when the props object is
|
|
48
48
|
* constructed (which during hydration would walk the cursor and duplicate the tree).
|
|
49
49
|
*/
|
|
@@ -77,7 +77,7 @@ export interface IRElement {
|
|
|
77
77
|
/**
|
|
78
78
|
* Where a component reference comes from, attached to the reference itself.
|
|
79
79
|
*
|
|
80
|
-
* A capitalised tag with no binding in the file is supplied by the compiler
|
|
80
|
+
* A capitalised tag with no binding in the file is supplied by the compiler, from a
|
|
81
81
|
* `resolve` rule, or from the built-in control-flow/router sets. That decision used to
|
|
82
82
|
* live only in the Babel plugin's state, which meant the IR could not see which
|
|
83
83
|
* components a template referenced: no pass could vary a decision per usage, group
|
|
@@ -96,7 +96,7 @@ export interface IRComponentSource {
|
|
|
96
96
|
origin: 'rule' | 'builtin';
|
|
97
97
|
/**
|
|
98
98
|
* When the module is fetched. Set from a `load:` directive at the usage site, and
|
|
99
|
-
* `eager` otherwise
|
|
99
|
+
* `eager` otherwise: resolution decides where a component comes from, this decides
|
|
100
100
|
* when, and the two vary independently.
|
|
101
101
|
*/
|
|
102
102
|
loading: IRLoadStrategy;
|
|
@@ -110,7 +110,7 @@ export interface IRComponent {
|
|
|
110
110
|
children: IRNode[];
|
|
111
111
|
/**
|
|
112
112
|
* Set by the resolve pass when the compiler supplies this reference. Absent when the
|
|
113
|
-
* name is bound in the file
|
|
113
|
+
* name is bound in the file: an ordinary import the author wrote, or when nothing
|
|
114
114
|
* claims it, which is a diagnostic rather than a resolution.
|
|
115
115
|
*/
|
|
116
116
|
source?: IRComponentSource;
|
|
@@ -124,7 +124,7 @@ export interface IRComponent {
|
|
|
124
124
|
column: number;
|
|
125
125
|
};
|
|
126
126
|
/**
|
|
127
|
-
* Where the `${…}` that drives this subtree was written
|
|
127
|
+
* Where the `${…}` that drives this subtree was written, the condition of an `if=`,
|
|
128
128
|
* the list of an `each=`. The insert that adds and removes the subtree is a reactive
|
|
129
129
|
* binding, and this is the position it reports. Distinct from `at`, which marks the
|
|
130
130
|
* node itself rather than the binding that places it.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.85 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -469,7 +469,7 @@ var INTRINSICS = {
|
|
|
469
469
|
$store: { export: "store", module: "@fluixi/reactive/store", returns: "store-handle" },
|
|
470
470
|
$resource: { export: "resource", module: REACTIVE_MODULE, returns: "resource-handle" },
|
|
471
471
|
// No short runtime form for these yet, so the intrinsic stands for the `create*`
|
|
472
|
-
// name. Still worth having
|
|
472
|
+
// name. Still worth having: no import to write, and when a shorter form is
|
|
473
473
|
// designed, the change is this line rather than a compiler pass.
|
|
474
474
|
$selector: { export: "createSelector", module: REACTIVE_MODULE, returns: "memo-accessor" },
|
|
475
475
|
$deferred: { export: "createDeferred", module: REACTIVE_MODULE, returns: "memo-accessor" },
|
|
@@ -1259,7 +1259,7 @@ var Lowerer = class {
|
|
|
1259
1259
|
}
|
|
1260
1260
|
];
|
|
1261
1261
|
}
|
|
1262
|
-
/** A plain attribute (incl. lit `?bool`, mixed values)
|
|
1262
|
+
/** A plain attribute (incl. lit `?bool`, mixed values), old `mkProp` behavior. */
|
|
1263
1263
|
plainAttr(a) {
|
|
1264
1264
|
const v = a.value;
|
|
1265
1265
|
let name = a.name;
|
|
@@ -6,7 +6,7 @@ import type { Piece } from '@fluixi/template-parser';
|
|
|
6
6
|
import type { StaticTemplate } from '../codegen/backend.cjs';
|
|
7
7
|
export interface TemplateSource {
|
|
8
8
|
/**
|
|
9
|
-
* The static text runs, in order. Always one more than `holes
|
|
9
|
+
* The static text runs, in order. Always one more than `holes`, the text
|
|
10
10
|
* before the first `${`, between each pair, and after the last `}`.
|
|
11
11
|
*/
|
|
12
12
|
statics: readonly string[];
|
|
@@ -37,7 +37,7 @@ export interface CompileTemplateOptions {
|
|
|
37
37
|
* The author's file, and a way to turn the parser's offsets into positions in it.
|
|
38
38
|
*
|
|
39
39
|
* Only when the host asked for source locations. Together they let a tag written inside a
|
|
40
|
-
* template carry the same mark a JSX tag does
|
|
40
|
+
* template carry the same mark a JSX tag does: without it the nodes it makes are the only
|
|
41
41
|
* ones in a component with no mark of their own, and they take whichever one was left.
|
|
42
42
|
*/
|
|
43
43
|
sourceFile?: string;
|
|
@@ -55,7 +55,7 @@ export interface CompileTemplateResult {
|
|
|
55
55
|
ir: IRNode;
|
|
56
56
|
/**
|
|
57
57
|
* Static templates the code refers to by local `_tmpl$N` id, when the caller
|
|
58
|
-
* asked to hoist them. `compileTemplate` inlines them instead
|
|
58
|
+
* asked to hoist them. `compileTemplate` inlines them instead, it has no module
|
|
59
59
|
* scope to hoist into.
|
|
60
60
|
*/
|
|
61
61
|
templates?: StaticTemplate[];
|
|
@@ -6,7 +6,7 @@ import type { Piece } from '@fluixi/template-parser';
|
|
|
6
6
|
import type { StaticTemplate } from '../codegen/backend.js';
|
|
7
7
|
export interface TemplateSource {
|
|
8
8
|
/**
|
|
9
|
-
* The static text runs, in order. Always one more than `holes
|
|
9
|
+
* The static text runs, in order. Always one more than `holes`, the text
|
|
10
10
|
* before the first `${`, between each pair, and after the last `}`.
|
|
11
11
|
*/
|
|
12
12
|
statics: readonly string[];
|
|
@@ -37,7 +37,7 @@ export interface CompileTemplateOptions {
|
|
|
37
37
|
* The author's file, and a way to turn the parser's offsets into positions in it.
|
|
38
38
|
*
|
|
39
39
|
* Only when the host asked for source locations. Together they let a tag written inside a
|
|
40
|
-
* template carry the same mark a JSX tag does
|
|
40
|
+
* template carry the same mark a JSX tag does: without it the nodes it makes are the only
|
|
41
41
|
* ones in a component with no mark of their own, and they take whichever one was left.
|
|
42
42
|
*/
|
|
43
43
|
sourceFile?: string;
|
|
@@ -55,7 +55,7 @@ export interface CompileTemplateResult {
|
|
|
55
55
|
ir: IRNode;
|
|
56
56
|
/**
|
|
57
57
|
* Static templates the code refers to by local `_tmpl$N` id, when the caller
|
|
58
|
-
* asked to hoist them. `compileTemplate` inlines them instead
|
|
58
|
+
* asked to hoist them. `compileTemplate` inlines them instead, it has no module
|
|
59
59
|
* scope to hoist into.
|
|
60
60
|
*/
|
|
61
61
|
templates?: StaticTemplate[];
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Finding templates in a module and describing each hole still needs a front-end;
|
|
8
8
|
* everything after that point is here. Passes run in the same order as
|
|
9
|
-
* `emitLitViaIR
|
|
9
|
+
* `emitLitViaIR`: compile-template.spec.ts compares the two.
|
|
10
10
|
*/
|
|
11
11
|
import { analyzeStatic } from '../optimize/analyze-static.js';
|
|
12
12
|
import { collapseStrategies } from '../optimize/collapse-strategies.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.85 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
|
|
3
3
|
// src/optimize/analyze-static.ts
|
|
4
4
|
function propReason(prop) {
|
|
@@ -443,7 +443,7 @@ var INTRINSICS = {
|
|
|
443
443
|
$store: { export: "store", module: "@fluixi/reactive/store", returns: "store-handle" },
|
|
444
444
|
$resource: { export: "resource", module: REACTIVE_MODULE, returns: "resource-handle" },
|
|
445
445
|
// No short runtime form for these yet, so the intrinsic stands for the `create*`
|
|
446
|
-
// name. Still worth having
|
|
446
|
+
// name. Still worth having: no import to write, and when a shorter form is
|
|
447
447
|
// designed, the change is this line rather than a compiler pass.
|
|
448
448
|
$selector: { export: "createSelector", module: REACTIVE_MODULE, returns: "memo-accessor" },
|
|
449
449
|
$deferred: { export: "createDeferred", module: REACTIVE_MODULE, returns: "memo-accessor" },
|
|
@@ -1235,7 +1235,7 @@ var Lowerer = class {
|
|
|
1235
1235
|
}
|
|
1236
1236
|
];
|
|
1237
1237
|
}
|
|
1238
|
-
/** A plain attribute (incl. lit `?bool`, mixed values)
|
|
1238
|
+
/** A plain attribute (incl. lit `?bool`, mixed values), old `mkProp` behavior. */
|
|
1239
1239
|
plainAttr(a) {
|
|
1240
1240
|
const v = a.value;
|
|
1241
1241
|
let name = a.name;
|