@fluixi/compiler 1.0.0-alpha.76 → 1.0.0-alpha.77
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/README.md +38 -2
- package/dist/analyze/reactive-bindings.cjs +1 -1
- package/dist/analyze/reactive-bindings.d.ts +9 -0
- package/dist/analyze/reactive-bindings.d.ts.map +1 -1
- package/dist/analyze/reactive-bindings.js +38 -0
- package/dist/analyze/reactive-bindings.mjs +1 -1
- package/dist/integrations.cjs +14 -13
- package/dist/integrations.d.ts +3 -4
- package/dist/integrations.d.ts.map +1 -1
- package/dist/integrations.js +37 -2
- package/dist/integrations.mjs +10 -10
- package/dist/transform/index.cjs +5 -4
- package/dist/transform/index.mjs +12 -11
- package/dist/transform/intrinsics.cjs +1 -1
- package/dist/transform/intrinsics.mjs +2 -2
- package/dist/transform/templates.cjs +4 -3
- package/dist/transform/templates.d.ts +17 -1
- package/dist/transform/templates.d.ts.map +1 -1
- package/dist/transform/templates.js +137 -4
- package/dist/transform/templates.mjs +11 -10
- package/dist/transform-ZGXUDFEZ.mjs +8 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/dist/transform-ZWIHEZVN.mjs +0 -7
package/README.md
CHANGED
|
@@ -38,6 +38,42 @@ gets an RPC stub, the server build keeps and registers the body.
|
|
|
38
38
|
Most apps don't use this package directly — [`@fluixi/vite-plugin`](../vite-plugin) (and
|
|
39
39
|
[`@fluixi/start`](../start)) wrap it.
|
|
40
40
|
|
|
41
|
+
## What it does to your code
|
|
42
|
+
|
|
43
|
+
Beyond turning markup into DOM calls:
|
|
44
|
+
|
|
45
|
+
**Props you destructured stay reactive.** `function Card({ title })` compiles to
|
|
46
|
+
`props.title` at each use, so the binding keeps updating, and `...rest` becomes the
|
|
47
|
+
`splitProps` call you would have written. Anything it can't prove safe — a reassigned
|
|
48
|
+
binding, a computed key, a default it would have to re-run per read — is left exactly as
|
|
49
|
+
written and reported. On by default; set `propsDestructure: false` for a package that ships
|
|
50
|
+
its **source** for consumers to compile, since the rewrite belongs to whoever compiles.
|
|
51
|
+
|
|
52
|
+
**`$` intrinsics resolve without an import.** `$signal`, `$memo`, `$effect`, `$store`,
|
|
53
|
+
`$resource`, `$selector`, `$deferred`, `$untrack`, `$untrackStore` compile to the runtime
|
|
54
|
+
calls they stand for, and the import is added for what a module actually used. A primitive
|
|
55
|
+
is recognised by the binding it came from, never by name: `import { signal as state }` is
|
|
56
|
+
recognised, a local `function signal()` is not. A module that binds a `$` name keeps its
|
|
57
|
+
own meaning and gets a diagnostic.
|
|
58
|
+
|
|
59
|
+
**Unimported tags resolve through rules.** `resolve` says where a capitalised tag comes
|
|
60
|
+
from — an entry per component, or one pattern for a family:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
createVitePlugin({ resolve: [{ match: /^([A-Z]\w+)$/, module: '/src/components/$1.tsx' }] })
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**`load:` splits a component into its own chunk.** `load:visible`, `load:idle`,
|
|
67
|
+
`load:interaction`, `load:media` decide when its module is fetched. It works on a component
|
|
68
|
+
a rule supplies and on one you imported yourself — in the second case the static import is
|
|
69
|
+
removed, which only happens when the name is used nowhere but as a tag.
|
|
70
|
+
|
|
71
|
+
**It says when it couldn't do these things.** A tag nothing supplies and a `load:` that
|
|
72
|
+
can't apply both build cleanly and fail at runtime, so they're reported at build time with
|
|
73
|
+
the reason. The bundler adapters print them; `TransformResult` carries them as
|
|
74
|
+
`propsDiagnostics`, `intrinsicDiagnostics`, `loadDiagnostics` and `unresolvedDiagnostics`
|
|
75
|
+
if you're driving the transform yourself.
|
|
76
|
+
|
|
41
77
|
## 📦 Installation
|
|
42
78
|
|
|
43
79
|
```sh
|
|
@@ -68,8 +104,8 @@ import { transformTemplates } from '@fluixi/compiler/transform';
|
|
|
68
104
|
const { code, map } = transformTemplates(source, 'App.tsx', {})!;
|
|
69
105
|
```
|
|
70
106
|
|
|
71
|
-
`transformTemplates` returns `null` when
|
|
72
|
-
bundler can leave the file untouched.
|
|
107
|
+
`transformTemplates` returns `null` when there is nothing to do — no JSX, no templates, no
|
|
108
|
+
`$` intrinsics and nothing to report — so a bundler can leave the file untouched.
|
|
73
109
|
|
|
74
110
|
### Compiling through Babel
|
|
75
111
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var f=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var
|
|
1
|
+
"use strict";var f=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var I=(r,e)=>{for(var i in e)f(r,i,{get:e[i],enumerable:!0})},x=(r,e,i,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of y(e))!N.call(r,n)&&n!==i&&f(r,n,{get:()=>e[n],enumerable:!(t=g(e,n))||t.enumerable});return r};var v=r=>x(f({},"__esModule",{value:!0}),r);var b={};I(b,{declaredNames:()=>E,resolveReactiveBindings:()=>w});module.exports=v(b);var o="@fluixi/reactive/signal",l={$signal:{export:"signal",module:o,returns:"signal-handle"},$memo:{export:"memo",module:o,returns:"memo-handle"},$effect:{export:"effect",module:o,returns:"effect"},$store:{export:"store",module:"@fluixi/reactive/store",returns:"store-handle"},$resource:{export:"resource",module:o,returns:"resource-handle"},$selector:{export:"createSelector",module:o,returns:"memo-accessor"},$deferred:{export:"createDeferred",module:o,returns:"memo-accessor"},$untrack:{export:"untrack",module:o,returns:"plain"},$untrackStore:{export:"untrackStore",module:"@fluixi/reactive/store",returns:"plain"}},p={signal:"signal-handle",memo:"memo-handle",effect:"effect",store:"store-handle",createSignal:["signal-accessor","signal-setter"],createMemo:"memo-accessor",createEffect:"effect",createRenderEffect:"effect",createStore:"reactive-object",resource:"resource-handle",createResource:"reactive-object",createSelector:"memo-accessor",createDeferred:"memo-accessor"},R=["@fluixi/reactive","@fluixi/reactive/signal","@fluixi/reactive/signal-next","@fluixi/reactive/store","@fluixi/core","@fluixi/core/rx"],D=new RegExp(`\\$(?:${Object.keys(l).map(r=>r.slice(1)).join("|")})\\s*\\(`);function d(r){return R.includes(r)}function s(r,e){if(r)switch(r.type){case"Identifier":e.add(r.name);return;case"ObjectPattern":for(let i of r.properties??[])i.type==="RestElement"?s(i.argument,e):s(i.value,e);return;case"ArrayPattern":for(let i of r.elements??[])s(i,e);return;case"AssignmentPattern":s(r.left,e);return;case"RestElement":s(r.argument,e);return}}function c(r,e){if(!(!r||typeof r!="object"||typeof r.type!="string")){e(r);for(let i of Object.keys(r)){if(i==="loc"||i==="leadingComments"||i==="trailingComments")continue;let t=r[i];if(Array.isArray(t))for(let n of t)c(n,e);else t&&typeof t=="object"&&c(t,e)}}}function S(r,e){if(r.type!=="CallExpression")return;let i=r.callee;if(i?.type!=="Identifier")return;let t=i.name,n=e.primitives.get(t);if(n)return n;let a=l[t];if(a&&!e.shadowed.has(t))return a.returns}function h(r,e,i){if(Array.isArray(e)){r.type==="ArrayPattern"&&r.elements.forEach((t,n)=>{let a=e[n];t?.type==="Identifier"&&a&&i.set(t.name,a)});return}r.type==="Identifier"&&i.set(r.name,e)}function E(r){let e=new Set;return c(r,i=>{switch(i.type){case"VariableDeclarator":s(i.id,e);return;case"FunctionDeclaration":case"FunctionExpression":case"ArrowFunctionExpression":s(i.id,e);for(let t of i.params??[])s(t,e);return;case"ClassDeclaration":case"ClassExpression":s(i.id,e);return;case"ImportSpecifier":case"ImportDefaultSpecifier":case"ImportNamespaceSpecifier":s(i.local,e);return;case"CatchClause":s(i.param,e);return}}),e}function w(r){let e={kinds:new Map,primitives:new Map,shadowed:new Set},i=r;c(i,t=>{let n=new Set;if(t.type==="VariableDeclarator")s(t.id,n);else if(t.type==="FunctionDeclaration"||t.type==="ClassDeclaration")s(t.id,n);else if(t.type==="ImportDefaultSpecifier"||t.type==="ImportNamespaceSpecifier")s(t.local,n);else if(t.type==="ImportSpecifier")s(t.local,n);else if(t.type==="FunctionExpression"||t.type==="ArrowFunctionExpression"||t.type==="FunctionDeclaration")for(let a of t.params??[])s(a,n);for(let a of n)l[a]&&e.shadowed.add(a)});for(let t of i.body??[])if(t.type==="ImportDeclaration"&&d(t.source?.value))for(let n of t.specifiers??[]){if(n.type!=="ImportSpecifier")continue;let a=n.imported,m=a.type==="Identifier"?a.name:a.value,u=p[m];u&&e.primitives.set(n.local.name,u)}return c(i,t=>{if(t.type!=="VariableDeclarator"||!t.init)return;let n=S(t.init,e);n&&h(t.id,n,e.kinds)}),e}
|
|
@@ -24,6 +24,15 @@ export interface ReactiveBindings {
|
|
|
24
24
|
/** `$name`s the module shadows with its own binding, so the intrinsic must not fire. */
|
|
25
25
|
shadowed: Set<string>;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Every name the module binds, in any scope.
|
|
29
|
+
*
|
|
30
|
+
* Deliberately scope-blind: it answers "does this file declare this name anywhere", which
|
|
31
|
+
* is the question a diagnostic needs. A component declared inside a function
|
|
32
|
+
* (`const Row = () => …`) is bound just as much as an import, and warning about it would
|
|
33
|
+
* be noise. Over-permissive on purpose — missing a warning beats inventing one.
|
|
34
|
+
*/
|
|
35
|
+
export declare function declaredNames(program: unknown): Set<string>;
|
|
27
36
|
/**
|
|
28
37
|
* Read a module's reactive bindings.
|
|
29
38
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactive-bindings.d.ts","sourceRoot":"","sources":["../../src/analyze/reactive-bindings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAC;AAOzB,MAAM,WAAW,gBAAgB;IAC/B,kCAAkC;IAClC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjC,gFAAgF;IAChF,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9C,wFAAwF;IACxF,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB;AAsED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB,CA6C1E"}
|
|
1
|
+
{"version":3,"file":"reactive-bindings.d.ts","sourceRoot":"","sources":["../../src/analyze/reactive-bindings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAC;AAOzB,MAAM,WAAW,gBAAgB;IAC/B,kCAAkC;IAClC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjC,gFAAgF;IAChF,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9C,wFAAwF;IACxF,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB;AAsED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CA8B3D;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB,CA6C1E"}
|
|
@@ -93,6 +93,44 @@ function classify(id, returns, kinds) {
|
|
|
93
93
|
if (id.type === 'Identifier')
|
|
94
94
|
kinds.set(id.name, returns);
|
|
95
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Every name the module binds, in any scope.
|
|
98
|
+
*
|
|
99
|
+
* Deliberately scope-blind: it answers "does this file declare this name anywhere", which
|
|
100
|
+
* is the question a diagnostic needs. A component declared inside a function
|
|
101
|
+
* (`const Row = () => …`) is bound just as much as an import, and warning about it would
|
|
102
|
+
* be noise. Over-permissive on purpose — missing a warning beats inventing one.
|
|
103
|
+
*/
|
|
104
|
+
export function declaredNames(program) {
|
|
105
|
+
const names = new Set();
|
|
106
|
+
walk(program, (node) => {
|
|
107
|
+
switch (node.type) {
|
|
108
|
+
case 'VariableDeclarator':
|
|
109
|
+
patternNames(node.id, names);
|
|
110
|
+
return;
|
|
111
|
+
case 'FunctionDeclaration':
|
|
112
|
+
case 'FunctionExpression':
|
|
113
|
+
case 'ArrowFunctionExpression':
|
|
114
|
+
patternNames(node.id, names);
|
|
115
|
+
for (const p of node.params ?? [])
|
|
116
|
+
patternNames(p, names);
|
|
117
|
+
return;
|
|
118
|
+
case 'ClassDeclaration':
|
|
119
|
+
case 'ClassExpression':
|
|
120
|
+
patternNames(node.id, names);
|
|
121
|
+
return;
|
|
122
|
+
case 'ImportSpecifier':
|
|
123
|
+
case 'ImportDefaultSpecifier':
|
|
124
|
+
case 'ImportNamespaceSpecifier':
|
|
125
|
+
patternNames(node.local, names);
|
|
126
|
+
return;
|
|
127
|
+
case 'CatchClause':
|
|
128
|
+
patternNames(node.param, names);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
return names;
|
|
133
|
+
}
|
|
96
134
|
/**
|
|
97
135
|
* Read a module's reactive bindings.
|
|
98
136
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var o="@fluixi/reactive/signal",
|
|
1
|
+
var o="@fluixi/reactive/signal",l={$signal:{export:"signal",module:o,returns:"signal-handle"},$memo:{export:"memo",module:o,returns:"memo-handle"},$effect:{export:"effect",module:o,returns:"effect"},$store:{export:"store",module:"@fluixi/reactive/store",returns:"store-handle"},$resource:{export:"resource",module:o,returns:"resource-handle"},$selector:{export:"createSelector",module:o,returns:"memo-accessor"},$deferred:{export:"createDeferred",module:o,returns:"memo-accessor"},$untrack:{export:"untrack",module:o,returns:"plain"},$untrackStore:{export:"untrackStore",module:"@fluixi/reactive/store",returns:"plain"}},u={signal:"signal-handle",memo:"memo-handle",effect:"effect",store:"store-handle",createSignal:["signal-accessor","signal-setter"],createMemo:"memo-accessor",createEffect:"effect",createRenderEffect:"effect",createStore:"reactive-object",resource:"resource-handle",createResource:"reactive-object",createSelector:"memo-accessor",createDeferred:"memo-accessor"},m=["@fluixi/reactive","@fluixi/reactive/signal","@fluixi/reactive/signal-next","@fluixi/reactive/store","@fluixi/core","@fluixi/core/rx"],N=new RegExp(`\\$(?:${Object.keys(l).map(r=>r.slice(1)).join("|")})\\s*\\(`);function p(r){return m.includes(r)}function s(r,t){if(r)switch(r.type){case"Identifier":t.add(r.name);return;case"ObjectPattern":for(let i of r.properties??[])i.type==="RestElement"?s(i.argument,t):s(i.value,t);return;case"ArrayPattern":for(let i of r.elements??[])s(i,t);return;case"AssignmentPattern":s(r.left,t);return;case"RestElement":s(r.argument,t);return}}function c(r,t){if(!(!r||typeof r!="object"||typeof r.type!="string")){t(r);for(let i of Object.keys(r)){if(i==="loc"||i==="leadingComments"||i==="trailingComments")continue;let e=r[i];if(Array.isArray(e))for(let n of e)c(n,t);else e&&typeof e=="object"&&c(e,t)}}}function g(r,t){if(r.type!=="CallExpression")return;let i=r.callee;if(i?.type!=="Identifier")return;let e=i.name,n=t.primitives.get(e);if(n)return n;let a=l[e];if(a&&!t.shadowed.has(e))return a.returns}function y(r,t,i){if(Array.isArray(t)){r.type==="ArrayPattern"&&r.elements.forEach((e,n)=>{let a=t[n];e?.type==="Identifier"&&a&&i.set(e.name,a)});return}r.type==="Identifier"&&i.set(r.name,t)}function v(r){let t=new Set;return c(r,i=>{switch(i.type){case"VariableDeclarator":s(i.id,t);return;case"FunctionDeclaration":case"FunctionExpression":case"ArrowFunctionExpression":s(i.id,t);for(let e of i.params??[])s(e,t);return;case"ClassDeclaration":case"ClassExpression":s(i.id,t);return;case"ImportSpecifier":case"ImportDefaultSpecifier":case"ImportNamespaceSpecifier":s(i.local,t);return;case"CatchClause":s(i.param,t);return}}),t}function R(r){let t={kinds:new Map,primitives:new Map,shadowed:new Set},i=r;c(i,e=>{let n=new Set;if(e.type==="VariableDeclarator")s(e.id,n);else if(e.type==="FunctionDeclaration"||e.type==="ClassDeclaration")s(e.id,n);else if(e.type==="ImportDefaultSpecifier"||e.type==="ImportNamespaceSpecifier")s(e.local,n);else if(e.type==="ImportSpecifier")s(e.local,n);else if(e.type==="FunctionExpression"||e.type==="ArrowFunctionExpression"||e.type==="FunctionDeclaration")for(let a of e.params??[])s(a,n);for(let a of n)l[a]&&t.shadowed.add(a)});for(let e of i.body??[])if(e.type==="ImportDeclaration"&&p(e.source?.value))for(let n of e.specifiers??[]){if(n.type!=="ImportSpecifier")continue;let a=n.imported,d=a.type==="Identifier"?a.name:a.value,f=u[d];f&&t.primitives.set(n.local.name,f)}return c(i,e=>{if(e.type!=="VariableDeclarator"||!e.init)return;let n=g(e.init,t);n&&y(e.id,n,t.kinds)}),t}export{v as declaredNames,R as resolveReactiveBindings};
|