@fluixi/compiler 1.0.0-alpha.100
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/LICENSE +21 -0
- package/README.md +131 -0
- package/dist/analyze/expr-shape.cjs +62 -0
- package/dist/analyze/expr-shape.d.cts +14 -0
- package/dist/analyze/expr-shape.d.ts +15 -0
- package/dist/analyze/expr-shape.d.ts.map +1 -0
- package/dist/analyze/expr-shape.js +37 -0
- package/dist/analyze/expr-shape.mjs +41 -0
- package/dist/analyze/intrinsics.cjs +112 -0
- package/dist/analyze/intrinsics.d.cts +80 -0
- package/dist/analyze/intrinsics.d.ts +81 -0
- package/dist/analyze/intrinsics.d.ts.map +1 -0
- package/dist/analyze/intrinsics.js +126 -0
- package/dist/analyze/intrinsics.mjs +91 -0
- package/dist/analyze/paren.cjs +134 -0
- package/dist/analyze/paren.d.cts +23 -0
- package/dist/analyze/paren.d.ts +24 -0
- package/dist/analyze/paren.d.ts.map +1 -0
- package/dist/analyze/paren.js +168 -0
- package/dist/analyze/paren.mjs +113 -0
- package/dist/analyze/props-destructure.cjs +226 -0
- package/dist/analyze/props-destructure.d.cts +83 -0
- package/dist/analyze/props-destructure.d.ts +84 -0
- package/dist/analyze/props-destructure.d.ts.map +1 -0
- package/dist/analyze/props-destructure.js +272 -0
- package/dist/analyze/props-destructure.mjs +205 -0
- package/dist/analyze/reactive-bindings.cjs +210 -0
- package/dist/analyze/reactive-bindings.d.cts +42 -0
- package/dist/analyze/reactive-bindings.d.ts +43 -0
- package/dist/analyze/reactive-bindings.d.ts.map +1 -0
- package/dist/analyze/reactive-bindings.js +191 -0
- package/dist/analyze/reactive-bindings.mjs +187 -0
- package/dist/analyze/reactive-expr.cjs +38 -0
- package/dist/analyze/reactive-expr.d.cts +38 -0
- package/dist/analyze/reactive-expr.d.ts +39 -0
- package/dist/analyze/reactive-expr.d.ts.map +1 -0
- package/dist/analyze/reactive-expr.js +31 -0
- package/dist/analyze/reactive-expr.mjs +17 -0
- package/dist/analyze/static-graph.cjs +831 -0
- package/dist/analyze/static-graph.d.cts +102 -0
- package/dist/analyze/static-graph.d.ts +103 -0
- package/dist/analyze/static-graph.d.ts.map +1 -0
- package/dist/analyze/static-graph.js +871 -0
- package/dist/analyze/static-graph.mjs +813 -0
- package/dist/babel-I6BUWUCU.mjs +636 -0
- package/dist/chunk-3AICWNF7.mjs +92 -0
- package/dist/chunk-6CWJWGE2.mjs +2170 -0
- package/dist/chunk-C3XPDB4Y.mjs +16 -0
- package/dist/chunk-GX5XV6Z7.mjs +190 -0
- package/dist/chunk-HXEXPWJ2.mjs +999 -0
- package/dist/chunk-NU3W67UZ.mjs +584 -0
- package/dist/chunk-SKAVY75W.mjs +11 -0
- package/dist/codegen/backend.cjs +18 -0
- package/dist/codegen/backend.d.cts +35 -0
- package/dist/codegen/backend.d.ts +36 -0
- package/dist/codegen/backend.d.ts.map +1 -0
- package/dist/codegen/backend.js +1 -0
- package/dist/codegen/backend.mjs +0 -0
- package/dist/codegen/backends/imperative.cjs +577 -0
- package/dist/codegen/backends/imperative.d.cts +11 -0
- package/dist/codegen/backends/imperative.d.ts +12 -0
- package/dist/codegen/backends/imperative.d.ts.map +1 -0
- package/dist/codegen/backends/imperative.js +362 -0
- package/dist/codegen/backends/imperative.mjs +554 -0
- package/dist/codegen/contract.cjs +52 -0
- package/dist/codegen/contract.d.cts +24 -0
- package/dist/codegen/contract.d.ts +25 -0
- package/dist/codegen/contract.d.ts.map +1 -0
- package/dist/codegen/contract.js +30 -0
- package/dist/codegen/contract.mjs +31 -0
- package/dist/codegen/partial-template.cjs +176 -0
- package/dist/codegen/partial-template.d.cts +61 -0
- package/dist/codegen/partial-template.d.ts +62 -0
- package/dist/codegen/partial-template.d.ts.map +1 -0
- package/dist/codegen/partial-template.js +0 -0
- package/dist/codegen/partial-template.mjs +153 -0
- package/dist/codegen/serialize-static.cjs +125 -0
- package/dist/codegen/serialize-static.d.cts +38 -0
- package/dist/codegen/serialize-static.d.ts +39 -0
- package/dist/codegen/serialize-static.d.ts.map +1 -0
- package/dist/codegen/serialize-static.js +165 -0
- package/dist/codegen/serialize-static.mjs +104 -0
- package/dist/frontend/babel/build-ir-lit.cjs +1933 -0
- package/dist/frontend/babel/build-ir-lit.d.cts +26 -0
- package/dist/frontend/babel/build-ir-lit.d.ts +27 -0
- package/dist/frontend/babel/build-ir-lit.d.ts.map +1 -0
- package/dist/frontend/babel/build-ir-lit.js +13 -0
- package/dist/frontend/babel/build-ir-lit.mjs +1902 -0
- package/dist/frontend/babel/build-ir.cjs +1948 -0
- package/dist/frontend/babel/build-ir.d.cts +35 -0
- package/dist/frontend/babel/build-ir.d.ts +36 -0
- package/dist/frontend/babel/build-ir.d.ts.map +1 -0
- package/dist/frontend/babel/build-ir.js +124 -0
- package/dist/frontend/babel/build-ir.mjs +1919 -0
- package/dist/frontend/babel/index.cjs +2610 -0
- package/dist/frontend/babel/index.d.cts +33 -0
- package/dist/frontend/babel/index.d.ts +34 -0
- package/dist/frontend/babel/index.d.ts.map +1 -0
- package/dist/frontend/babel/index.js +65 -0
- package/dist/frontend/babel/index.mjs +2580 -0
- package/dist/frontend/babel/lower-template.cjs +1931 -0
- package/dist/frontend/babel/lower-template.d.cts +23 -0
- package/dist/frontend/babel/lower-template.d.ts +24 -0
- package/dist/frontend/babel/lower-template.d.ts.map +1 -0
- package/dist/frontend/babel/lower-template.js +64 -0
- package/dist/frontend/babel/lower-template.mjs +1902 -0
- package/dist/frontend/babel/plugin.cjs +2556 -0
- package/dist/frontend/babel/plugin.d.cts +95 -0
- package/dist/frontend/babel/plugin.d.ts +96 -0
- package/dist/frontend/babel/plugin.d.ts.map +1 -0
- package/dist/frontend/babel/plugin.js +523 -0
- package/dist/frontend/babel/plugin.mjs +2527 -0
- package/dist/frontend/babel/server-functions.cjs +110 -0
- package/dist/frontend/babel/server-functions.d.cts +10 -0
- package/dist/frontend/babel/server-functions.d.ts +11 -0
- package/dist/frontend/babel/server-functions.d.ts.map +1 -0
- package/dist/frontend/babel/server-functions.js +81 -0
- package/dist/frontend/babel/server-functions.mjs +89 -0
- package/dist/frontend/babel/types.cjs +18 -0
- package/dist/frontend/babel/types.d.cts +33 -0
- package/dist/frontend/babel/types.d.ts +34 -0
- package/dist/frontend/babel/types.d.ts.map +1 -0
- package/dist/frontend/babel/types.js +1 -0
- package/dist/frontend/babel/types.mjs +0 -0
- package/dist/frontend/types.cjs +18 -0
- package/dist/frontend/types.d.cts +25 -0
- package/dist/frontend/types.d.ts +26 -0
- package/dist/frontend/types.d.ts.map +1 -0
- package/dist/frontend/types.js +1 -0
- package/dist/frontend/types.mjs +0 -0
- package/dist/frontend/vocabulary.cjs +98 -0
- package/dist/frontend/vocabulary.d.cts +79 -0
- package/dist/frontend/vocabulary.d.ts +80 -0
- package/dist/frontend/vocabulary.d.ts.map +1 -0
- package/dist/frontend/vocabulary.js +124 -0
- package/dist/frontend/vocabulary.mjs +77 -0
- package/dist/index.cjs +1957 -0
- package/dist/index.d.cts +27 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.mjs +1949 -0
- package/dist/integrations.cjs +5705 -0
- package/dist/integrations.d.cts +215 -0
- package/dist/integrations.d.ts +216 -0
- package/dist/integrations.d.ts.map +1 -0
- package/dist/integrations.js +566 -0
- package/dist/integrations.mjs +810 -0
- package/dist/ir/nodes.cjs +18 -0
- package/dist/ir/nodes.d.cts +168 -0
- package/dist/ir/nodes.d.ts +169 -0
- package/dist/ir/nodes.d.ts.map +1 -0
- package/dist/ir/nodes.js +1 -0
- package/dist/ir/nodes.mjs +0 -0
- package/dist/lower/compile-template.cjs +1670 -0
- package/dist/lower/compile-template.d.cts +82 -0
- package/dist/lower/compile-template.d.ts +83 -0
- package/dist/lower/compile-template.d.ts.map +1 -0
- package/dist/lower/compile-template.js +79 -0
- package/dist/lower/compile-template.mjs +1662 -0
- package/dist/lower/entities.cjs +288 -0
- package/dist/lower/entities.d.cts +1 -0
- package/dist/lower/entities.d.ts +2 -0
- package/dist/lower/entities.d.ts.map +1 -0
- package/dist/lower/entities.js +54 -0
- package/dist/lower/entities.mjs +267 -0
- package/dist/lower/jsx.cjs +1101 -0
- package/dist/lower/jsx.d.cts +33 -0
- package/dist/lower/jsx.d.ts +34 -0
- package/dist/lower/jsx.d.ts.map +1 -0
- package/dist/lower/jsx.js +414 -0
- package/dist/lower/jsx.mjs +1078 -0
- package/dist/lower/template.cjs +1354 -0
- package/dist/lower/template.d.cts +53 -0
- package/dist/lower/template.d.ts +54 -0
- package/dist/lower/template.d.ts.map +1 -0
- package/dist/lower/template.js +542 -0
- package/dist/lower/template.mjs +1335 -0
- package/dist/lower/text.cjs +42 -0
- package/dist/lower/text.d.cts +10 -0
- package/dist/lower/text.d.ts +11 -0
- package/dist/lower/text.d.ts.map +1 -0
- package/dist/lower/text.js +31 -0
- package/dist/lower/text.mjs +21 -0
- package/dist/optimize/analyze-static.cjs +112 -0
- package/dist/optimize/analyze-static.d.cts +39 -0
- package/dist/optimize/analyze-static.d.ts +40 -0
- package/dist/optimize/analyze-static.d.ts.map +1 -0
- package/dist/optimize/analyze-static.js +131 -0
- package/dist/optimize/analyze-static.mjs +91 -0
- package/dist/optimize/collapse-strategies.cjs +90 -0
- package/dist/optimize/collapse-strategies.d.cts +30 -0
- package/dist/optimize/collapse-strategies.d.ts +31 -0
- package/dist/optimize/collapse-strategies.d.ts.map +1 -0
- package/dist/optimize/collapse-strategies.js +33 -0
- package/dist/optimize/collapse-strategies.mjs +67 -0
- package/dist/options.cjs +33 -0
- package/dist/options.d.cts +39 -0
- package/dist/options.d.ts +40 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +8 -0
- package/dist/options.mjs +12 -0
- package/dist/resolve/builtins.cjs +73 -0
- package/dist/resolve/builtins.d.cts +68 -0
- package/dist/resolve/builtins.d.ts +69 -0
- package/dist/resolve/builtins.d.ts.map +1 -0
- package/dist/resolve/builtins.js +64 -0
- package/dist/resolve/builtins.mjs +53 -0
- package/dist/resolve/component-globals.cjs +272 -0
- package/dist/resolve/component-globals.d.cts +88 -0
- package/dist/resolve/component-globals.d.ts +89 -0
- package/dist/resolve/component-globals.d.ts.map +1 -0
- package/dist/resolve/component-globals.js +160 -0
- package/dist/resolve/component-globals.mjs +249 -0
- package/dist/resolve/component-resolver.cjs +80 -0
- package/dist/resolve/component-resolver.d.cts +68 -0
- package/dist/resolve/component-resolver.d.ts +69 -0
- package/dist/resolve/component-resolver.d.ts.map +1 -0
- package/dist/resolve/component-resolver.js +95 -0
- package/dist/resolve/component-resolver.mjs +59 -0
- package/dist/resolve/load-directive.cjs +93 -0
- package/dist/resolve/load-directive.d.cts +53 -0
- package/dist/resolve/load-directive.d.ts +54 -0
- package/dist/resolve/load-directive.d.ts.map +1 -0
- package/dist/resolve/load-directive.js +93 -0
- package/dist/resolve/load-directive.mjs +72 -0
- package/dist/resolve/resolve-ir.cjs +108 -0
- package/dist/resolve/resolve-ir.d.cts +53 -0
- package/dist/resolve/resolve-ir.d.ts +54 -0
- package/dist/resolve/resolve-ir.d.ts.map +1 -0
- package/dist/resolve/resolve-ir.js +58 -0
- package/dist/resolve/resolve-ir.mjs +85 -0
- package/dist/resolve/write-globals.cjs +383 -0
- package/dist/resolve/write-globals.d.cts +36 -0
- package/dist/resolve/write-globals.d.ts +37 -0
- package/dist/resolve/write-globals.d.ts.map +1 -0
- package/dist/resolve/write-globals.js +169 -0
- package/dist/resolve/write-globals.mjs +362 -0
- package/dist/server-fns-VZLHMQTC.mjs +79 -0
- package/dist/server-functions-UAZKOLZW.mjs +82 -0
- package/dist/transform/bindings.cjs +71 -0
- package/dist/transform/bindings.d.cts +16 -0
- package/dist/transform/bindings.d.ts +17 -0
- package/dist/transform/bindings.d.ts.map +1 -0
- package/dist/transform/bindings.js +69 -0
- package/dist/transform/bindings.mjs +50 -0
- package/dist/transform/index.cjs +3837 -0
- package/dist/transform/index.d.cts +15 -0
- package/dist/transform/index.d.ts +16 -0
- package/dist/transform/index.d.ts.map +1 -0
- package/dist/transform/index.js +12 -0
- package/dist/transform/index.mjs +4882 -0
- package/dist/transform/intrinsics.cjs +261 -0
- package/dist/transform/intrinsics.d.cts +33 -0
- package/dist/transform/intrinsics.d.ts +34 -0
- package/dist/transform/intrinsics.d.ts.map +1 -0
- package/dist/transform/intrinsics.js +120 -0
- package/dist/transform/intrinsics.mjs +238 -0
- package/dist/transform/props.cjs +441 -0
- package/dist/transform/props.d.cts +45 -0
- package/dist/transform/props.d.ts +46 -0
- package/dist/transform/props.d.ts.map +1 -0
- package/dist/transform/props.js +221 -0
- package/dist/transform/props.mjs +1487 -0
- package/dist/transform/server-fn-id.cjs +35 -0
- package/dist/transform/server-fn-id.d.cts +9 -0
- package/dist/transform/server-fn-id.d.ts +10 -0
- package/dist/transform/server-fn-id.d.ts.map +1 -0
- package/dist/transform/server-fn-id.js +18 -0
- package/dist/transform/server-fn-id.mjs +14 -0
- package/dist/transform/server-fns.cjs +114 -0
- package/dist/transform/server-fns.d.cts +12 -0
- package/dist/transform/server-fns.d.ts +13 -0
- package/dist/transform/server-fns.d.ts.map +1 -0
- package/dist/transform/server-fns.js +94 -0
- package/dist/transform/server-fns.mjs +1160 -0
- package/dist/transform/source-locations.cjs +393 -0
- package/dist/transform/source-locations.d.cts +48 -0
- package/dist/transform/source-locations.d.ts +49 -0
- package/dist/transform/source-locations.d.ts.map +1 -0
- package/dist/transform/source-locations.js +303 -0
- package/dist/transform/source-locations.mjs +370 -0
- package/dist/transform/styles.cjs +606 -0
- package/dist/transform/styles.d.cts +237 -0
- package/dist/transform/styles.d.ts +238 -0
- package/dist/transform/styles.d.ts.map +1 -0
- package/dist/transform/styles.js +743 -0
- package/dist/transform/styles.mjs +671 -0
- package/dist/transform/templates.cjs +3806 -0
- package/dist/transform/templates.d.cts +82 -0
- package/dist/transform/templates.d.ts +83 -0
- package/dist/transform/templates.d.ts.map +1 -0
- package/dist/transform/templates.js +613 -0
- package/dist/transform/templates.mjs +4852 -0
- package/dist/transform-3W45L3EA.mjs +951 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/dist/vite-styles.cjs +223 -0
- package/dist/vite-styles.d.cts +68 -0
- package/dist/vite-styles.d.ts +69 -0
- package/dist/vite-styles.d.ts.map +1 -0
- package/dist/vite-styles.js +241 -0
- package/dist/vite-styles.mjs +214 -0
- package/package.json +141 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ibrahima Touré
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/fluixi/assets/main/logos/128x128.png" alt="Fluixi" width="120" height="120" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# @fluixi/compiler
|
|
6
|
+
|
|
7
|
+
**The Fluixi compiler — parses, lowers and emits. Not a Babel plugin.**
|
|
8
|
+
|
|
9
|
+
[](./LICENSE)
|
|
10
|
+

|
|
11
|
+
[](https://www.npmjs.com/package/@fluixi/compiler)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## ✨ Overview
|
|
16
|
+
|
|
17
|
+
`@fluixi/compiler` turns Fluixi source into fine-grained reactive output. Both authoring
|
|
18
|
+
syntaxes — JSX and `` html`...` `` templates — lower to the **same host-agnostic IR**, and
|
|
19
|
+
the **imperative backend** compiles that straight into [`@fluixi/dom`](../dom) runtime
|
|
20
|
+
calls (`createNativeElement`/`spread`/`insert`/`createComponent`/…). No VDOM, and no
|
|
21
|
+
`jsx()` dispatch at runtime.
|
|
22
|
+
|
|
23
|
+
It owns the transform rather than running inside someone else's: parse once, splice the
|
|
24
|
+
emitted code over the spans it replaces. Nothing is reprinted, so a hole keeps the text the
|
|
25
|
+
author wrote and every edit carries a source map; types are left in place for the bundler
|
|
26
|
+
to strip.
|
|
27
|
+
|
|
28
|
+
`@babel/parser` is the only package it takes from that namespace, used as a parser — the
|
|
29
|
+
same position Vue's compiler is in. `@babel/core` and the plugin machinery are optional
|
|
30
|
+
peers, needed only by `babel: true`.
|
|
31
|
+
|
|
32
|
+
The `@fluixi/jsx` automatic runtime is still what esbuild and TypeScript's
|
|
33
|
+
`jsxImportSource` point at; this compiler simply never emits a call into it.
|
|
34
|
+
|
|
35
|
+
It also provides the **`"use server"`** transform (server functions): the client build
|
|
36
|
+
gets an RPC stub, the server build keeps and registers the body.
|
|
37
|
+
|
|
38
|
+
Most apps don't use this package directly — [`@fluixi/vite-plugin`](../vite-plugin) (and
|
|
39
|
+
[`@fluixi/start`](../start)) wrap it.
|
|
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
|
+
|
|
77
|
+
## 📦 Installation
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
pnpm add -D @fluixi/compiler
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## 🚀 Usage
|
|
84
|
+
|
|
85
|
+
Via the Vite integration (the common path):
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { defineConfig } from 'vite';
|
|
89
|
+
import { createVitePlugin, serverFunctionsVitePlugin } from '@fluixi/compiler/integrations';
|
|
90
|
+
|
|
91
|
+
export default defineConfig({
|
|
92
|
+
plugins: [
|
|
93
|
+
serverFunctionsVitePlugin(), // "use server" transform
|
|
94
|
+
createVitePlugin(),
|
|
95
|
+
],
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Or compile a module directly:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import { transformTemplates } from '@fluixi/compiler/transform';
|
|
103
|
+
|
|
104
|
+
const { code, map } = transformTemplates(source, 'App.tsx', {})!;
|
|
105
|
+
```
|
|
106
|
+
|
|
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.
|
|
109
|
+
|
|
110
|
+
### Compiling through Babel
|
|
111
|
+
|
|
112
|
+
`fluixi({ babel: true })` routes through the Babel front-end instead. It exists for a
|
|
113
|
+
project whose own Babel plugins have to see the compiled output; it needs `@babel/core`
|
|
114
|
+
and friends installed, and says so rather than degrading. Everything else — the IR, the
|
|
115
|
+
passes, the backend — is the same code either way.
|
|
116
|
+
|
|
117
|
+
## 🔌 Subpaths
|
|
118
|
+
|
|
119
|
+
| Import | What | Babel |
|
|
120
|
+
| --- | --- | --- |
|
|
121
|
+
| `@fluixi/compiler` | IR, codegen backends, resolve/optimize passes, options | none |
|
|
122
|
+
| `@fluixi/compiler/builtins` | the control-flow / router component names | none |
|
|
123
|
+
| `@fluixi/compiler/transform` | `transformTemplates`, `transformServerFns` | parser only |
|
|
124
|
+
| `@fluixi/compiler/integrations` | vite, webpack, rollup and esbuild adapters | parser only |
|
|
125
|
+
| `@fluixi/compiler/babel` | the Babel plugin front-end | `@babel/core` |
|
|
126
|
+
|
|
127
|
+
`no-babel-in-core.spec.ts` fails the build if that column stops being true.
|
|
128
|
+
|
|
129
|
+
## 📄 License
|
|
130
|
+
|
|
131
|
+
[MIT](./LICENSE) © [Fluixi](https://fluixi.dev)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/analyze/expr-shape.ts
|
|
21
|
+
var expr_shape_exports = {};
|
|
22
|
+
__export(expr_shape_exports, {
|
|
23
|
+
shapeOf: () => shapeOf
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(expr_shape_exports);
|
|
26
|
+
var CALL = /* @__PURE__ */ new Set(["CallExpression", "OptionalCallExpression"]);
|
|
27
|
+
var MEMBER = /* @__PURE__ */ new Set(["MemberExpression", "OptionalMemberExpression"]);
|
|
28
|
+
function shapeOf(node) {
|
|
29
|
+
if (!node) return { kind: "opaque" };
|
|
30
|
+
if (CALL.has(node.type)) return { kind: "call" };
|
|
31
|
+
if (MEMBER.has(node.type)) {
|
|
32
|
+
const property = node.property;
|
|
33
|
+
const computed = node.computed === true;
|
|
34
|
+
return {
|
|
35
|
+
kind: "member",
|
|
36
|
+
property: !computed && property?.type === "Identifier" ? property.name : null
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (node.type === "ConditionalExpression") {
|
|
40
|
+
return { kind: "compound", parts: [node.test, node.consequent, node.alternate].map(part) };
|
|
41
|
+
}
|
|
42
|
+
if (node.type === "LogicalExpression" || node.type === "BinaryExpression") {
|
|
43
|
+
return { kind: "compound", parts: [node.left, node.right].map(part) };
|
|
44
|
+
}
|
|
45
|
+
if (node.type === "TemplateLiteral") {
|
|
46
|
+
return { kind: "compound", parts: node.expressions.map(part) };
|
|
47
|
+
}
|
|
48
|
+
if (node.type === "ObjectExpression") {
|
|
49
|
+
const props = node.properties.filter(
|
|
50
|
+
(p) => (p.type === "ObjectProperty" || p.type === "Property") && p.computed !== true
|
|
51
|
+
);
|
|
52
|
+
return { kind: "compound", parts: props.map((p) => part(p.value)) };
|
|
53
|
+
}
|
|
54
|
+
if (node.type === "ArrayExpression") {
|
|
55
|
+
const items = node.elements.filter(
|
|
56
|
+
(e) => e != null && e.type !== "SpreadElement"
|
|
57
|
+
);
|
|
58
|
+
return { kind: "compound", parts: items.map(part) };
|
|
59
|
+
}
|
|
60
|
+
return { kind: "opaque" };
|
|
61
|
+
}
|
|
62
|
+
var part = (n) => shapeOf(n);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map a parsed expression node to an `ExprShape`.
|
|
3
|
+
*
|
|
4
|
+
* Works off `node.type` strings, so it takes any ESTree-shaped AST, @babel/parser,
|
|
5
|
+
* acorn, or whatever replaces them: and accepts the few names Babel spells
|
|
6
|
+
* differently (`ObjectProperty`, `Optional*Expression`).
|
|
7
|
+
*/
|
|
8
|
+
import type { ExprShape } from './reactive-expr.cjs';
|
|
9
|
+
interface Node {
|
|
10
|
+
type: string;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
export declare function shapeOf(node: Node | null | undefined): ExprShape;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map a parsed expression node to an `ExprShape`.
|
|
3
|
+
*
|
|
4
|
+
* Works off `node.type` strings, so it takes any ESTree-shaped AST, @babel/parser,
|
|
5
|
+
* acorn, or whatever replaces them: and accepts the few names Babel spells
|
|
6
|
+
* differently (`ObjectProperty`, `Optional*Expression`).
|
|
7
|
+
*/
|
|
8
|
+
import type { ExprShape } from './reactive-expr.js';
|
|
9
|
+
interface Node {
|
|
10
|
+
type: string;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
export declare function shapeOf(node: Node | null | undefined): ExprShape;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=expr-shape.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expr-shape.d.ts","sourceRoot":"","sources":["../../src/analyze/expr-shape.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,UAAU,IAAI;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAKD,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,CAuChE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const CALL = new Set(['CallExpression', 'OptionalCallExpression']);
|
|
2
|
+
const MEMBER = new Set(['MemberExpression', 'OptionalMemberExpression']);
|
|
3
|
+
export function shapeOf(node) {
|
|
4
|
+
if (!node)
|
|
5
|
+
return { kind: 'opaque' };
|
|
6
|
+
if (CALL.has(node.type))
|
|
7
|
+
return { kind: 'call' };
|
|
8
|
+
if (MEMBER.has(node.type)) {
|
|
9
|
+
const property = node.property;
|
|
10
|
+
const computed = node.computed === true;
|
|
11
|
+
return {
|
|
12
|
+
kind: 'member',
|
|
13
|
+
property: !computed && property?.type === 'Identifier' ? property.name : null,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
if (node.type === 'ConditionalExpression') {
|
|
17
|
+
return { kind: 'compound', parts: [node.test, node.consequent, node.alternate].map(part) };
|
|
18
|
+
}
|
|
19
|
+
if (node.type === 'LogicalExpression' || node.type === 'BinaryExpression') {
|
|
20
|
+
return { kind: 'compound', parts: [node.left, node.right].map(part) };
|
|
21
|
+
}
|
|
22
|
+
if (node.type === 'TemplateLiteral') {
|
|
23
|
+
return { kind: 'compound', parts: node.expressions.map(part) };
|
|
24
|
+
}
|
|
25
|
+
// A computed key or a spread contributes nothing, we cannot see what it
|
|
26
|
+
// introduces, so we must not claim it is inert.
|
|
27
|
+
if (node.type === 'ObjectExpression') {
|
|
28
|
+
const props = node.properties.filter((p) => (p.type === 'ObjectProperty' || p.type === 'Property') && p.computed !== true);
|
|
29
|
+
return { kind: 'compound', parts: props.map((p) => part(p.value)) };
|
|
30
|
+
}
|
|
31
|
+
if (node.type === 'ArrayExpression') {
|
|
32
|
+
const items = node.elements.filter((e) => e != null && e.type !== 'SpreadElement');
|
|
33
|
+
return { kind: 'compound', parts: items.map(part) };
|
|
34
|
+
}
|
|
35
|
+
return { kind: 'opaque' };
|
|
36
|
+
}
|
|
37
|
+
const part = (n) => shapeOf(n);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// src/analyze/expr-shape.ts
|
|
2
|
+
var CALL = /* @__PURE__ */ new Set(["CallExpression", "OptionalCallExpression"]);
|
|
3
|
+
var MEMBER = /* @__PURE__ */ new Set(["MemberExpression", "OptionalMemberExpression"]);
|
|
4
|
+
function shapeOf(node) {
|
|
5
|
+
if (!node) return { kind: "opaque" };
|
|
6
|
+
if (CALL.has(node.type)) return { kind: "call" };
|
|
7
|
+
if (MEMBER.has(node.type)) {
|
|
8
|
+
const property = node.property;
|
|
9
|
+
const computed = node.computed === true;
|
|
10
|
+
return {
|
|
11
|
+
kind: "member",
|
|
12
|
+
property: !computed && property?.type === "Identifier" ? property.name : null
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
if (node.type === "ConditionalExpression") {
|
|
16
|
+
return { kind: "compound", parts: [node.test, node.consequent, node.alternate].map(part) };
|
|
17
|
+
}
|
|
18
|
+
if (node.type === "LogicalExpression" || node.type === "BinaryExpression") {
|
|
19
|
+
return { kind: "compound", parts: [node.left, node.right].map(part) };
|
|
20
|
+
}
|
|
21
|
+
if (node.type === "TemplateLiteral") {
|
|
22
|
+
return { kind: "compound", parts: node.expressions.map(part) };
|
|
23
|
+
}
|
|
24
|
+
if (node.type === "ObjectExpression") {
|
|
25
|
+
const props = node.properties.filter(
|
|
26
|
+
(p) => (p.type === "ObjectProperty" || p.type === "Property") && p.computed !== true
|
|
27
|
+
);
|
|
28
|
+
return { kind: "compound", parts: props.map((p) => part(p.value)) };
|
|
29
|
+
}
|
|
30
|
+
if (node.type === "ArrayExpression") {
|
|
31
|
+
const items = node.elements.filter(
|
|
32
|
+
(e) => e != null && e.type !== "SpreadElement"
|
|
33
|
+
);
|
|
34
|
+
return { kind: "compound", parts: items.map(part) };
|
|
35
|
+
}
|
|
36
|
+
return { kind: "opaque" };
|
|
37
|
+
}
|
|
38
|
+
var part = (n) => shapeOf(n);
|
|
39
|
+
export {
|
|
40
|
+
shapeOf
|
|
41
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/analyze/intrinsics.ts
|
|
21
|
+
var intrinsics_exports = {};
|
|
22
|
+
__export(intrinsics_exports, {
|
|
23
|
+
INTRINSICS: () => INTRINSICS,
|
|
24
|
+
PRIMITIVE_MODULES: () => PRIMITIVE_MODULES,
|
|
25
|
+
REACTIVE_MODULE: () => REACTIVE_MODULE,
|
|
26
|
+
RUNTIME_PRIMITIVES: () => RUNTIME_PRIMITIVES,
|
|
27
|
+
TAG_INTRINSICS: () => TAG_INTRINSICS,
|
|
28
|
+
isIntrinsicName: () => isIntrinsicName,
|
|
29
|
+
isPrimitiveModule: () => isPrimitiveModule,
|
|
30
|
+
mayHaveIntrinsic: () => mayHaveIntrinsic,
|
|
31
|
+
tagIntrinsics: () => tagIntrinsics
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(intrinsics_exports);
|
|
34
|
+
var REACTIVE_MODULE = "@fluixi/reactive/signal";
|
|
35
|
+
var INTRINSICS = {
|
|
36
|
+
$signal: { export: "signal", module: REACTIVE_MODULE, returns: "signal-handle" },
|
|
37
|
+
$memo: { export: "memo", module: REACTIVE_MODULE, returns: "memo-handle" },
|
|
38
|
+
$effect: { export: "effect", module: REACTIVE_MODULE, returns: "effect" },
|
|
39
|
+
$store: { export: "store", module: "@fluixi/reactive/store", returns: "store-handle" },
|
|
40
|
+
$resource: { export: "resource", module: REACTIVE_MODULE, returns: "resource-handle" },
|
|
41
|
+
$cachedResource: { export: "cachedResource", module: "@fluixi/reactive/cached-resource", returns: "resource-handle" },
|
|
42
|
+
// No short runtime form for these yet, so the intrinsic stands for the `create*`
|
|
43
|
+
// name. Still worth having: no import to write, and when a shorter form is
|
|
44
|
+
// designed, the change is this line rather than a compiler pass.
|
|
45
|
+
$selector: { export: "createSelector", module: REACTIVE_MODULE, returns: "memo-accessor" },
|
|
46
|
+
$deferred: { export: "createDeferred", module: REACTIVE_MODULE, returns: "memo-accessor" },
|
|
47
|
+
// Not value constructors, but the compiler has to know them: they change what a read
|
|
48
|
+
// does. `untrack` suppresses dependency collection, which is exactly the kind of thing
|
|
49
|
+
// dependency analysis must not guess at.
|
|
50
|
+
$untrack: { export: "untrack", module: REACTIVE_MODULE, returns: "plain" },
|
|
51
|
+
$untrackStore: { export: "untrackStore", module: "@fluixi/reactive/store", returns: "plain" },
|
|
52
|
+
// Scopes, scheduling and lifecycle: no value to classify, but the same authoring promise,
|
|
53
|
+
// no import to write. `$cleanup` registers a callback on the current owner (`onCleanup`).
|
|
54
|
+
$batch: { export: "batch", module: REACTIVE_MODULE, returns: "plain" },
|
|
55
|
+
$cleanup: { export: "onCleanup", module: REACTIVE_MODULE, returns: "plain" },
|
|
56
|
+
$root: { export: "root", module: REACTIVE_MODULE, returns: "plain" },
|
|
57
|
+
$context: { export: "context", module: REACTIVE_MODULE, returns: "plain" },
|
|
58
|
+
$renderEffect: { export: "renderEffect", module: REACTIVE_MODULE, returns: "effect" },
|
|
59
|
+
$computed: { export: "computed", module: REACTIVE_MODULE, returns: "effect" },
|
|
60
|
+
// Storage for where the code runs, and a signal kept in it. `$persisted` is a signal
|
|
61
|
+
// handle as far as reads go: the same accessor with `set` on it.
|
|
62
|
+
$storage: { export: "useStorage", module: "@fluixi/core/storage", returns: "plain" },
|
|
63
|
+
$asyncStorage: { export: "useAsyncStorage", module: "@fluixi/core/storage", returns: "plain" },
|
|
64
|
+
$persisted: { export: "persisted", module: "@fluixi/core/storage", returns: "signal-handle" },
|
|
65
|
+
// An environment variable, public or server-only; the browser build refuses a secret.
|
|
66
|
+
$env: { export: "env", module: "@fluixi/start/env", returns: "plain" }
|
|
67
|
+
};
|
|
68
|
+
var RUNTIME_PRIMITIVES = {
|
|
69
|
+
signal: "signal-handle",
|
|
70
|
+
memo: "memo-handle",
|
|
71
|
+
effect: "effect",
|
|
72
|
+
store: "store-handle",
|
|
73
|
+
createSignal: ["signal-accessor", "signal-setter"],
|
|
74
|
+
createMemo: "memo-accessor",
|
|
75
|
+
createEffect: "effect",
|
|
76
|
+
createRenderEffect: "effect",
|
|
77
|
+
renderEffect: "effect",
|
|
78
|
+
computed: "effect",
|
|
79
|
+
createStore: "reactive-object",
|
|
80
|
+
resource: "resource-handle",
|
|
81
|
+
cachedResource: "resource-handle",
|
|
82
|
+
createResource: "reactive-object",
|
|
83
|
+
createSelector: "memo-accessor",
|
|
84
|
+
createDeferred: "memo-accessor"
|
|
85
|
+
};
|
|
86
|
+
var PRIMITIVE_MODULES = [
|
|
87
|
+
"@fluixi/reactive",
|
|
88
|
+
"@fluixi/reactive/signal",
|
|
89
|
+
"@fluixi/reactive/store",
|
|
90
|
+
"@fluixi/reactive/cached-resource",
|
|
91
|
+
"@fluixi/core"
|
|
92
|
+
];
|
|
93
|
+
var TAG_INTRINSICS = {
|
|
94
|
+
$html: { export: "html", module: "@fluixi/core" },
|
|
95
|
+
$svg: { export: "svg", module: "@fluixi/core" },
|
|
96
|
+
$css: { export: "css", module: "@fluixi/core" }
|
|
97
|
+
};
|
|
98
|
+
function tagIntrinsics(bound) {
|
|
99
|
+
const tags = /* @__PURE__ */ new Map();
|
|
100
|
+
for (const [name, tag] of Object.entries(TAG_INTRINSICS)) if (!bound.has(name)) tags.set(name, tag.export);
|
|
101
|
+
return tags;
|
|
102
|
+
}
|
|
103
|
+
var INTRINSIC_CALL = new RegExp(`\\$(?:${Object.keys(INTRINSICS).map((n) => n.slice(1)).join("|")})\\s*\\(`);
|
|
104
|
+
function mayHaveIntrinsic(code) {
|
|
105
|
+
return INTRINSIC_CALL.test(code);
|
|
106
|
+
}
|
|
107
|
+
function isIntrinsicName(name) {
|
|
108
|
+
return Object.prototype.hasOwnProperty.call(INTRINSICS, name);
|
|
109
|
+
}
|
|
110
|
+
function isPrimitiveModule(source) {
|
|
111
|
+
return PRIMITIVE_MODULES.includes(source);
|
|
112
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The reactive primitives the compiler knows by name, in one place.
|
|
3
|
+
*
|
|
4
|
+
* Two ways to write the same thing. The runtime call, which needs an import and works
|
|
5
|
+
* without us:
|
|
6
|
+
*
|
|
7
|
+
* import { createSignal } from '@fluixi/reactive/signal';
|
|
8
|
+
* const count = createSignal(0);
|
|
9
|
+
*
|
|
10
|
+
* And the intrinsic, which the compiler resolves and imports for you:
|
|
11
|
+
*
|
|
12
|
+
* const count = $signal(0);
|
|
13
|
+
*
|
|
14
|
+
* They are not two reactive systems. `$signal` compiles to the same `createSignal` call,
|
|
15
|
+
* so there's one graph, one lifecycle, one SSR story. The `$` form is authoring sugar
|
|
16
|
+
* the compiler understands; the runtime form stays public, because a library that never
|
|
17
|
+
* runs this compiler still has to be able to write reactive code.
|
|
18
|
+
*
|
|
19
|
+
* Everything the compiler needs to know about a primitive lives in this table rather
|
|
20
|
+
* than spread across passes, so adding one is an entry, not a new code path.
|
|
21
|
+
*/
|
|
22
|
+
/** What a binding holds, once we know where it came from. */
|
|
23
|
+
export type ReactiveKind = 'plain'
|
|
24
|
+
/** `signal(0)`: one object, read with `.get()` and written with `.set()`. */
|
|
25
|
+
| 'signal-handle'
|
|
26
|
+
/** `memo(fn)`: read-only, so `.get()` only. */
|
|
27
|
+
| 'memo-handle'
|
|
28
|
+
/** `store(obj)`: read properties directly, `.set()` writes. */
|
|
29
|
+
| 'store-handle'
|
|
30
|
+
/** `resource(fn)`: `.get()` reads, with `.loading`/`.latest`/`.refetch()` on it. */
|
|
31
|
+
| 'resource-handle'
|
|
32
|
+
/** The accessor half of the tuple form, `const [count] = createSignal(0)`. */
|
|
33
|
+
| 'signal-accessor' | 'signal-setter' | 'memo-accessor' | 'effect' | 'reactive-object';
|
|
34
|
+
export interface Intrinsic {
|
|
35
|
+
/** Runtime export this compiles to. */
|
|
36
|
+
export: string;
|
|
37
|
+
/** Module it comes from. */
|
|
38
|
+
module: string;
|
|
39
|
+
/**
|
|
40
|
+
* What the call yields. A tuple means the call is destructured into that many
|
|
41
|
+
* bindings: `createSignal` gives an accessor and a setter, in that order.
|
|
42
|
+
*/
|
|
43
|
+
returns: ReactiveKind | readonly ReactiveKind[];
|
|
44
|
+
}
|
|
45
|
+
/** Module the reactive primitives are imported from when the compiler adds the import. */
|
|
46
|
+
export declare const REACTIVE_MODULE = "@fluixi/reactive/signal";
|
|
47
|
+
/**
|
|
48
|
+
* `$name` → the runtime it stands for.
|
|
49
|
+
*
|
|
50
|
+
* The `$` prefix is reserved. A local binding of the same name wins, it has to, or the
|
|
51
|
+
* compiler would rewrite code that means something else, and that's reported rather
|
|
52
|
+
* than done quietly.
|
|
53
|
+
*/
|
|
54
|
+
export declare const INTRINSICS: Readonly<Record<string, Intrinsic>>;
|
|
55
|
+
/**
|
|
56
|
+
* The runtime names, for the other direction: source that imports `createSignal` gets
|
|
57
|
+
* classified the same way as source that writes `$signal`, so later passes see one
|
|
58
|
+
* vocabulary whichever form the author used.
|
|
59
|
+
*/
|
|
60
|
+
export declare const RUNTIME_PRIMITIVES: Readonly<Record<string, Intrinsic['returns']>>;
|
|
61
|
+
/** Modules whose exports count as reactive primitives. */
|
|
62
|
+
export declare const PRIMITIVE_MODULES: readonly string[];
|
|
63
|
+
/**
|
|
64
|
+
* Cheap text check for the file-skipping fast path: a module with no `$` call never
|
|
65
|
+
* needs parsing. Non-global, so it has no lastIndex to carry between calls.
|
|
66
|
+
*/
|
|
67
|
+
/**
|
|
68
|
+
* Template tags an app writes without importing them. Each compiles exactly like the marker
|
|
69
|
+
* it names; a module that binds the name itself keeps its own meaning.
|
|
70
|
+
*/
|
|
71
|
+
export declare const TAG_INTRINSICS: Readonly<Record<string, {
|
|
72
|
+
export: 'html' | 'svg' | 'css';
|
|
73
|
+
module: string;
|
|
74
|
+
}>>;
|
|
75
|
+
/** The `$` tags this module can use: all of them, less the ones it binds. */
|
|
76
|
+
export declare function tagIntrinsics(bound: Set<string>): Map<string, 'html' | 'svg' | 'css'>;
|
|
77
|
+
export declare function mayHaveIntrinsic(code: string): boolean;
|
|
78
|
+
export declare function isIntrinsicName(name: string): boolean;
|
|
79
|
+
/** Whether a module path exports the reactive primitives. */
|
|
80
|
+
export declare function isPrimitiveModule(source: string): boolean;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The reactive primitives the compiler knows by name, in one place.
|
|
3
|
+
*
|
|
4
|
+
* Two ways to write the same thing. The runtime call, which needs an import and works
|
|
5
|
+
* without us:
|
|
6
|
+
*
|
|
7
|
+
* import { createSignal } from '@fluixi/reactive/signal';
|
|
8
|
+
* const count = createSignal(0);
|
|
9
|
+
*
|
|
10
|
+
* And the intrinsic, which the compiler resolves and imports for you:
|
|
11
|
+
*
|
|
12
|
+
* const count = $signal(0);
|
|
13
|
+
*
|
|
14
|
+
* They are not two reactive systems. `$signal` compiles to the same `createSignal` call,
|
|
15
|
+
* so there's one graph, one lifecycle, one SSR story. The `$` form is authoring sugar
|
|
16
|
+
* the compiler understands; the runtime form stays public, because a library that never
|
|
17
|
+
* runs this compiler still has to be able to write reactive code.
|
|
18
|
+
*
|
|
19
|
+
* Everything the compiler needs to know about a primitive lives in this table rather
|
|
20
|
+
* than spread across passes, so adding one is an entry, not a new code path.
|
|
21
|
+
*/
|
|
22
|
+
/** What a binding holds, once we know where it came from. */
|
|
23
|
+
export type ReactiveKind = 'plain'
|
|
24
|
+
/** `signal(0)`: one object, read with `.get()` and written with `.set()`. */
|
|
25
|
+
| 'signal-handle'
|
|
26
|
+
/** `memo(fn)`: read-only, so `.get()` only. */
|
|
27
|
+
| 'memo-handle'
|
|
28
|
+
/** `store(obj)`: read properties directly, `.set()` writes. */
|
|
29
|
+
| 'store-handle'
|
|
30
|
+
/** `resource(fn)`: `.get()` reads, with `.loading`/`.latest`/`.refetch()` on it. */
|
|
31
|
+
| 'resource-handle'
|
|
32
|
+
/** The accessor half of the tuple form, `const [count] = createSignal(0)`. */
|
|
33
|
+
| 'signal-accessor' | 'signal-setter' | 'memo-accessor' | 'effect' | 'reactive-object';
|
|
34
|
+
export interface Intrinsic {
|
|
35
|
+
/** Runtime export this compiles to. */
|
|
36
|
+
export: string;
|
|
37
|
+
/** Module it comes from. */
|
|
38
|
+
module: string;
|
|
39
|
+
/**
|
|
40
|
+
* What the call yields. A tuple means the call is destructured into that many
|
|
41
|
+
* bindings: `createSignal` gives an accessor and a setter, in that order.
|
|
42
|
+
*/
|
|
43
|
+
returns: ReactiveKind | readonly ReactiveKind[];
|
|
44
|
+
}
|
|
45
|
+
/** Module the reactive primitives are imported from when the compiler adds the import. */
|
|
46
|
+
export declare const REACTIVE_MODULE = "@fluixi/reactive/signal";
|
|
47
|
+
/**
|
|
48
|
+
* `$name` → the runtime it stands for.
|
|
49
|
+
*
|
|
50
|
+
* The `$` prefix is reserved. A local binding of the same name wins, it has to, or the
|
|
51
|
+
* compiler would rewrite code that means something else, and that's reported rather
|
|
52
|
+
* than done quietly.
|
|
53
|
+
*/
|
|
54
|
+
export declare const INTRINSICS: Readonly<Record<string, Intrinsic>>;
|
|
55
|
+
/**
|
|
56
|
+
* The runtime names, for the other direction: source that imports `createSignal` gets
|
|
57
|
+
* classified the same way as source that writes `$signal`, so later passes see one
|
|
58
|
+
* vocabulary whichever form the author used.
|
|
59
|
+
*/
|
|
60
|
+
export declare const RUNTIME_PRIMITIVES: Readonly<Record<string, Intrinsic['returns']>>;
|
|
61
|
+
/** Modules whose exports count as reactive primitives. */
|
|
62
|
+
export declare const PRIMITIVE_MODULES: readonly string[];
|
|
63
|
+
/**
|
|
64
|
+
* Cheap text check for the file-skipping fast path: a module with no `$` call never
|
|
65
|
+
* needs parsing. Non-global, so it has no lastIndex to carry between calls.
|
|
66
|
+
*/
|
|
67
|
+
/**
|
|
68
|
+
* Template tags an app writes without importing them. Each compiles exactly like the marker
|
|
69
|
+
* it names; a module that binds the name itself keeps its own meaning.
|
|
70
|
+
*/
|
|
71
|
+
export declare const TAG_INTRINSICS: Readonly<Record<string, {
|
|
72
|
+
export: 'html' | 'svg' | 'css';
|
|
73
|
+
module: string;
|
|
74
|
+
}>>;
|
|
75
|
+
/** The `$` tags this module can use: all of them, less the ones it binds. */
|
|
76
|
+
export declare function tagIntrinsics(bound: Set<string>): Map<string, 'html' | 'svg' | 'css'>;
|
|
77
|
+
export declare function mayHaveIntrinsic(code: string): boolean;
|
|
78
|
+
export declare function isIntrinsicName(name: string): boolean;
|
|
79
|
+
/** Whether a module path exports the reactive primitives. */
|
|
80
|
+
export declare function isPrimitiveModule(source: string): boolean;
|
|
81
|
+
//# sourceMappingURL=intrinsics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intrinsics.d.ts","sourceRoot":"","sources":["../../src/analyze/intrinsics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,6DAA6D;AAC7D,MAAM,MAAM,YAAY,GACpB,OAAO;AACT,6EAA6E;GAC3E,eAAe;AACjB,+CAA+C;GAC7C,aAAa;AACf,+DAA+D;GAC7D,cAAc;AAChB,oFAAoF;GAClF,iBAAiB;AACnB,8EAA8E;GAC5E,iBAAiB,GACjB,eAAe,GACf,eAAe,GACf,QAAQ,GACR,iBAAiB,CAAC;AAEtB,MAAM,WAAW,SAAS;IACxB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,EAAE,YAAY,GAAG,SAAS,YAAY,EAAE,CAAC;CACjD;AAED,0FAA0F;AAC1F,eAAO,MAAM,eAAe,4BAA4B,CAAC;AAEzD;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAsC1D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,CAiB7E,CAAC;AAEF,0DAA0D;AAC1D,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAM9C,CAAC;AAEF;;;GAGG;AACH;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAIvG,CAAC;AAEF,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC,CAIrF;AAID,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEzD"}
|