@fluixi/compiler 1.0.0-alpha.69 → 1.0.0-alpha.70

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.
Files changed (82) hide show
  1. package/dist/babel-NY6FXXLW.mjs +2 -0
  2. package/dist/codegen/backend.cjs +1 -1
  3. package/dist/codegen/backend.d.ts +14 -0
  4. package/dist/codegen/backend.d.ts.map +1 -1
  5. package/dist/codegen/backends/imperative.cjs +1 -1
  6. package/dist/codegen/backends/imperative.d.ts +10 -1
  7. package/dist/codegen/backends/imperative.d.ts.map +1 -1
  8. package/dist/codegen/backends/imperative.js +127 -16
  9. package/dist/codegen/backends/imperative.mjs +1 -1
  10. package/dist/codegen/partial-template.cjs +1 -0
  11. package/dist/codegen/partial-template.d.ts +62 -0
  12. package/dist/codegen/partial-template.d.ts.map +1 -0
  13. package/dist/codegen/partial-template.js +0 -0
  14. package/dist/codegen/partial-template.mjs +1 -0
  15. package/dist/codegen/serialize-static.cjs +1 -0
  16. package/dist/codegen/serialize-static.d.ts +23 -0
  17. package/dist/codegen/serialize-static.d.ts.map +1 -0
  18. package/dist/codegen/serialize-static.js +140 -0
  19. package/dist/codegen/serialize-static.mjs +1 -0
  20. package/dist/frontend/babel/build-ir-lit.cjs +1 -1
  21. package/dist/frontend/babel/build-ir-lit.d.ts.map +1 -1
  22. package/dist/frontend/babel/build-ir-lit.js +5 -1
  23. package/dist/frontend/babel/build-ir-lit.mjs +1 -1
  24. package/dist/frontend/babel/build-ir.cjs +1 -1
  25. package/dist/frontend/babel/build-ir.d.ts.map +1 -1
  26. package/dist/frontend/babel/build-ir.js +36 -8
  27. package/dist/frontend/babel/build-ir.mjs +1 -1
  28. package/dist/frontend/babel/index.cjs +2 -2
  29. package/dist/frontend/babel/index.mjs +2 -2
  30. package/dist/frontend/babel/lower-template.cjs +1 -1
  31. package/dist/frontend/babel/lower-template.d.ts.map +1 -1
  32. package/dist/frontend/babel/lower-template.js +34 -5
  33. package/dist/frontend/babel/lower-template.mjs +1 -1
  34. package/dist/frontend/babel/plugin.cjs +2 -2
  35. package/dist/frontend/babel/plugin.d.ts +4 -0
  36. package/dist/frontend/babel/plugin.d.ts.map +1 -1
  37. package/dist/frontend/babel/plugin.js +258 -50
  38. package/dist/frontend/babel/plugin.mjs +2 -2
  39. package/dist/index.cjs +1 -1
  40. package/dist/index.d.ts +2 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +2 -0
  43. package/dist/index.mjs +1 -1
  44. package/dist/integrations.cjs +8 -8
  45. package/dist/integrations.d.ts +6 -0
  46. package/dist/integrations.d.ts.map +1 -1
  47. package/dist/integrations.js +6 -0
  48. package/dist/integrations.mjs +4 -4
  49. package/dist/ir/nodes.cjs +1 -1
  50. package/dist/ir/nodes.d.ts +43 -0
  51. package/dist/ir/nodes.d.ts.map +1 -1
  52. package/dist/optimize/analyze-static.cjs +1 -0
  53. package/dist/optimize/analyze-static.d.ts +40 -0
  54. package/dist/optimize/analyze-static.d.ts.map +1 -0
  55. package/dist/optimize/analyze-static.js +131 -0
  56. package/dist/optimize/analyze-static.mjs +1 -0
  57. package/dist/optimize/collapse-strategies.cjs +1 -0
  58. package/dist/optimize/collapse-strategies.d.ts +31 -0
  59. package/dist/optimize/collapse-strategies.d.ts.map +1 -0
  60. package/dist/optimize/collapse-strategies.js +33 -0
  61. package/dist/optimize/collapse-strategies.mjs +1 -0
  62. package/dist/options.cjs +1 -1
  63. package/dist/options.d.ts +18 -0
  64. package/dist/options.d.ts.map +1 -1
  65. package/dist/resolve/builtins.cjs +1 -0
  66. package/dist/resolve/builtins.d.ts +69 -0
  67. package/dist/resolve/builtins.d.ts.map +1 -0
  68. package/dist/resolve/builtins.js +64 -0
  69. package/dist/resolve/builtins.mjs +1 -0
  70. package/dist/resolve/load-directive.cjs +1 -0
  71. package/dist/resolve/load-directive.d.ts +54 -0
  72. package/dist/resolve/load-directive.d.ts.map +1 -0
  73. package/dist/resolve/load-directive.js +93 -0
  74. package/dist/resolve/load-directive.mjs +1 -0
  75. package/dist/resolve/resolve-ir.cjs +1 -0
  76. package/dist/resolve/resolve-ir.d.ts +54 -0
  77. package/dist/resolve/resolve-ir.d.ts.map +1 -0
  78. package/dist/resolve/resolve-ir.js +58 -0
  79. package/dist/resolve/resolve-ir.mjs +1 -0
  80. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  81. package/package.json +4 -4
  82. package/dist/babel-UKVEBBZL.mjs +0 -2
@@ -0,0 +1,131 @@
1
+ /**
2
+ * A prop is inert only when it is a plain attribute or property with a literal value.
3
+ *
4
+ * `expr` means arbitrary JS, which may read a signal or allocate, so it is dynamic even
5
+ * when `reactive` is false — a non-reactive expression still has to run per instance.
6
+ */
7
+ function propReason(prop) {
8
+ switch (prop.kind) {
9
+ case 'event':
10
+ return 'event';
11
+ case 'ref':
12
+ return 'ref';
13
+ case 'spread':
14
+ return 'spread';
15
+ case 'class':
16
+ case 'style':
17
+ // classList/style objects are built from expressions even when they look literal.
18
+ return 'class-or-style-directive';
19
+ case 'attr':
20
+ case 'prop':
21
+ if (prop.reactive)
22
+ return 'reactive-prop';
23
+ if (prop.expr !== undefined)
24
+ return 'expression-prop';
25
+ return undefined;
26
+ /* c8 ignore next 2 */
27
+ default:
28
+ return 'expression-prop';
29
+ }
30
+ }
31
+ /**
32
+ * Mark every static element in the tree, returning what was decided.
33
+ *
34
+ * Mutates `IRElement.static` in place, since that field is the contract codegen reads.
35
+ */
36
+ export function analyzeStatic(root) {
37
+ const staticElements = [];
38
+ const reasons = new Map();
39
+ /** Returns whether `node` is static, marking elements bottom-up. */
40
+ const visit = (node) => {
41
+ switch (node.kind) {
42
+ case 'text':
43
+ return true;
44
+ case 'expr':
45
+ // A hole is dynamic even when it is not reactive: its value is computed.
46
+ return false;
47
+ case 'component':
48
+ case 'control':
49
+ // Both produce their own subtree at runtime, so an ancestor cannot be cloned
50
+ // wholesale. Still walk in, so nested elements are marked for their own sake.
51
+ for (const child of node.children)
52
+ visit(child);
53
+ return false;
54
+ case 'fragment':
55
+ // A fragment is not an element and cannot itself be cloned, but its children
56
+ // can be considered independently.
57
+ for (const child of node.children)
58
+ visit(child);
59
+ return false;
60
+ case 'element': {
61
+ // Children are visited first and unconditionally, so a static subtree nested
62
+ // under a dynamic parent is still marked and can be cloned on its own.
63
+ let childrenStatic = true;
64
+ for (const child of node.children) {
65
+ if (!visit(child))
66
+ childrenStatic = false;
67
+ }
68
+ let reason;
69
+ for (const prop of node.props) {
70
+ reason = propReason(prop);
71
+ if (reason)
72
+ break;
73
+ }
74
+ if (!reason && !childrenStatic) {
75
+ reason = childReason(node);
76
+ }
77
+ node.static = !reason;
78
+ if (reason)
79
+ reasons.set(node, reason);
80
+ else
81
+ staticElements.push(node);
82
+ return node.static;
83
+ }
84
+ /* c8 ignore next 2 */
85
+ default:
86
+ return false;
87
+ }
88
+ };
89
+ for (const node of Array.isArray(root) ? root : [root])
90
+ visit(node);
91
+ return { staticElements, reasons };
92
+ }
93
+ /** The most specific reason a child made its parent dynamic. */
94
+ function childReason(node) {
95
+ for (const child of node.children) {
96
+ if (child.kind === 'expr')
97
+ return 'expression-child';
98
+ if (child.kind === 'component')
99
+ return 'component-child';
100
+ if (child.kind === 'control')
101
+ return 'control-child';
102
+ if (child.kind === 'element' && !child.static)
103
+ return 'expression-child';
104
+ if (child.kind === 'fragment')
105
+ return 'expression-child';
106
+ }
107
+ /* c8 ignore next */
108
+ return 'expression-child';
109
+ }
110
+ /**
111
+ * The outermost static elements — the roots worth turning into templates.
112
+ *
113
+ * Cloning a static child of a static parent is wasted: the parent's template already
114
+ * contains it.
115
+ */
116
+ export function staticRoots(root) {
117
+ const roots = [];
118
+ const visit = (node) => {
119
+ if (node.kind === 'element' && node.static) {
120
+ roots.push(node);
121
+ return; // its subtree is inside this template
122
+ }
123
+ const children = node.children;
124
+ if (children)
125
+ for (const child of children)
126
+ visit(child);
127
+ };
128
+ for (const node of Array.isArray(root) ? root : [root])
129
+ visit(node);
130
+ return roots;
131
+ }
@@ -0,0 +1 @@
1
+ function a(r){switch(r.kind){case"event":return"event";case"ref":return"ref";case"spread":return"spread";case"class":case"style":return"class-or-style-directive";case"attr":case"prop":return r.reactive?"reactive-prop":r.expr!==void 0?"expression-prop":void 0;default:return"expression-prop"}}function f(r){let t=[],c=new Map,n=e=>{switch(e.kind){case"text":return!0;case"expr":return!1;case"component":case"control":for(let s of e.children)n(s);return!1;case"fragment":for(let s of e.children)n(s);return!1;case"element":{let s=!0;for(let o of e.children)n(o)||(s=!1);let i;for(let o of e.props)if(i=a(o),i)break;return!i&&!s&&(i=l(e)),e.static=!i,i?c.set(e,i):t.push(e),e.static}default:return!1}};for(let e of Array.isArray(r)?r:[r])n(e);return{staticElements:t,reasons:c}}function l(r){for(let t of r.children){if(t.kind==="expr")return"expression-child";if(t.kind==="component")return"component-child";if(t.kind==="control")return"control-child";if(t.kind==="element"&&!t.static||t.kind==="fragment")return"expression-child"}return"expression-child"}function p(r){let t=[],c=n=>{if(n.kind==="element"&&n.static){t.push(n);return}let e=n.children;if(e)for(let s of e)c(s)};for(let n of Array.isArray(r)?r:[r])c(n);return t}export{f as analyzeStatic,p as staticRoots};
@@ -0,0 +1 @@
1
+ "use strict";var d=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var x=(e,o)=>{for(var t in o)d(e,t,{get:o[t],enumerable:!0})},v=(e,o,t,i)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of g(o))!R.call(e,n)&&n!==t&&d(e,n,{get:()=>o[n],enumerable:!(i=f(o,n))||i.enumerable});return e};var S=e=>v(d({},"__esModule",{value:!0}),e);var E={};x(E,{collapseStrategies:()=>I});module.exports=S(E);function l(e){return e.kind!=="eager"&&e.kind!=="never"}var u=["Show","For","Index","Switch","Match","Portal","Dynamic","ErrorBoundary"],p=["Suspense","SuspenseList","Await"],m=["Router","Outlet","Redirect","Link"],O=[...u,...p,...m],C=new Set([...u,...p]);function c(e,o){let t=Array.isArray(e)?e:[e];for(let i of t){o(i);let n=i.children;n&&c(n,o)}}function I(e){let o=[];c(e,r=>{r.kind==="component"&&r.source&&o.push(r)});let t=new Set,i=new Set;for(let r of o){let{module:s,loading:a}=r.source;a.kind==="eager"&&t.add(s),a.kind==="never"&&i.add(s)}let n=new Map;for(let r of o){let s=r.source;l(s.loading)&&t.has(s.module)&&(s.loading={kind:"eager"},n.set(s.module,(n.get(s.module)??0)+1))}return{collapsed:n,conflicted:[...i].filter(r=>t.has(r))}}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Strategy collapsing — demote a deferred reference whose module is already present.
3
+ *
4
+ * This is not a nice-to-have. Without it the naive feature is a regression: if a module
5
+ * is referenced eagerly anywhere in the compilation unit, it is in the parent chunk
6
+ * already, so a `load:visible` boundary elsewhere adds a wrapper, a promise and a
7
+ * re-render in order to fetch nothing. The bytes are paid twice — once in the chunk,
8
+ * once in the deferral machinery — and the component renders later than it needs to.
9
+ *
10
+ * Collapsing runs per module, not per component name, because a chunk is a module:
11
+ * `<Button>` eager and `<ButtonGroup load:visible>` from the same package means the
12
+ * package is already loaded, so deferring the second buys nothing.
13
+ *
14
+ * `never` is not collapsed. It means "no client code at all", which is a statement about
15
+ * what should exist rather than about when to fetch it; an eager sibling does not make a
16
+ * server-only component suddenly belong in the client bundle. That combination is
17
+ * contradictory and reported instead.
18
+ */
19
+ import type { IRNode } from '../ir/nodes.js';
20
+ export interface CollapseReport {
21
+ /** Modules demoted to eager, with the reference count that was demoted. */
22
+ collapsed: Map<string, number>;
23
+ /**
24
+ * Modules referenced both as `load:never` and in a way that needs client code.
25
+ * Contradictory rather than optimisable, so it is reported and left alone.
26
+ */
27
+ conflicted: string[];
28
+ }
29
+ /** Demote deferred references to modules that are already in the chunk. */
30
+ export declare function collapseStrategies(root: IRNode | IRNode[]): CollapseReport;
31
+ //# sourceMappingURL=collapse-strategies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collapse-strategies.d.ts","sourceRoot":"","sources":["../../src/optimize/collapse-strategies.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,gBAAgB,CAAC;AAI1D,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B;;;OAGG;IACH,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc,CA2B1E"}
@@ -0,0 +1,33 @@
1
+ import { isDeferred } from '../resolve/load-directive.js';
2
+ import { walk } from '../resolve/resolve-ir.js';
3
+ /** Demote deferred references to modules that are already in the chunk. */
4
+ export function collapseStrategies(root) {
5
+ const components = [];
6
+ walk(root, (node) => {
7
+ if (node.kind === 'component' && node.source)
8
+ components.push(node);
9
+ });
10
+ const eager = new Set();
11
+ const never = new Set();
12
+ for (const node of components) {
13
+ const { module, loading } = node.source;
14
+ if (loading.kind === 'eager')
15
+ eager.add(module);
16
+ if (loading.kind === 'never')
17
+ never.add(module);
18
+ }
19
+ const collapsed = new Map();
20
+ for (const node of components) {
21
+ const source = node.source;
22
+ if (!isDeferred(source.loading))
23
+ continue;
24
+ if (!eager.has(source.module))
25
+ continue;
26
+ source.loading = { kind: 'eager' };
27
+ collapsed.set(source.module, (collapsed.get(source.module) ?? 0) + 1);
28
+ }
29
+ return {
30
+ collapsed,
31
+ conflicted: [...never].filter((m) => eager.has(m)),
32
+ };
33
+ }
@@ -0,0 +1 @@
1
+ function a(o){return o.kind!=="eager"&&o.kind!=="never"}var l=["Show","For","Index","Switch","Match","Portal","Dynamic","ErrorBoundary"],u=["Suspense","SuspenseList","Await"],p=["Router","Outlet","Redirect","Link"],g=[...l,...u,...p],m=new Set([...l,...u]);function d(o,t){let i=Array.isArray(o)?o:[o];for(let s of i){t(s);let r=s.children;r&&d(r,t)}}function w(o){let t=[];d(o,e=>{e.kind==="component"&&e.source&&t.push(e)});let i=new Set,s=new Set;for(let e of t){let{module:n,loading:c}=e.source;c.kind==="eager"&&i.add(n),c.kind==="never"&&s.add(n)}let r=new Map;for(let e of t){let n=e.source;a(n.loading)&&i.has(n.module)&&(n.loading={kind:"eager"},r.set(n.module,(r.get(n.module)??0)+1))}return{collapsed:r,conflicted:[...s].filter(e=>i.has(e))}}export{w as collapseStrategies};
package/dist/options.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var r=Object.defineProperty;var n=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var p=(o,e)=>{for(var a in e)r(o,a,{get:e[a],enumerable:!0})},d=(o,e,a,l)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of s(e))!m.call(o,t)&&t!==a&&r(o,t,{get:()=>e[t],enumerable:!(l=n(e,t))||l.enumerable});return o};var i=o=>d(r({},"__esModule",{value:!0}),o);var u={};p(u,{defaultOptions:()=>v});module.exports=i(u);var v={backend:"imperative",generate:"dom",moduleName:"@fluixi/dom",delegateEvents:!0,hydratable:!1,sourceMaps:!0,dev:!1};
1
+ "use strict";var l=Object.defineProperty;var n=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var m=(o,e)=>{for(var t in e)l(o,t,{get:e[t],enumerable:!0})},d=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of s(e))!p.call(o,a)&&a!==t&&l(o,a,{get:()=>e[a],enumerable:!(r=n(e,a))||r.enumerable});return o};var i=o=>d(l({},"__esModule",{value:!0}),o);var b={};m(b,{defaultOptions:()=>v});module.exports=i(b);var v={backend:"imperative",generate:"dom",moduleName:"@fluixi/dom",delegateEvents:!0,hydratable:!1,sourceMaps:!0,dev:!1};
package/dist/options.d.ts CHANGED
@@ -4,6 +4,24 @@ import type { ComponentResolverRule } from './resolve/component-resolver.js';
4
4
  * as backends change. Switching DOM strategy is `backend`, not a rewrite.
5
5
  */
6
6
  export interface CompilerOptions {
7
+ /**
8
+ * Clone static subtrees from a `<template>` instead of building them element by
9
+ * element. Roughly 2x faster to instantiate, but **client-only**: `createTemplate`
10
+ * produces real DOM nodes, which the SSR renderer's ServerElement tree rejects, and a
11
+ * clone creates a fresh node where hydration must adopt the existing one. Opt in for
12
+ * a client-rendered app; leave off wherever SSR or hydration is involved.
13
+ */
14
+ templateClone?: boolean;
15
+ /**
16
+ * Also clone subtrees whose *structure* is static but which contain dynamic holes —
17
+ * the common shape. Roughly halves the emitted code for such a subtree and replaces
18
+ * per-element construction with one clone.
19
+ *
20
+ * Works under SSR and hydration: each hole is bracketed by `<!--fx-->` markers, so its
21
+ * content is exactly the nodes between them and the server's markup has the same shape
22
+ * as the client's template. Hydration adopts those nodes rather than rebuilding them.
23
+ */
24
+ partialTemplates?: boolean;
7
25
  /** which codegen backend to use */
8
26
  backend?: 'imperative' | 'template-clone';
9
27
  /** output target */
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAE7E;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,OAAO,CAAC,EAAE,YAAY,GAAG,gBAAgB,CAAC;IAC1C,oBAAoB;IACpB,QAAQ,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;IACrC,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC5C;AAED,eAAO,MAAM,cAAc,EAAE,eAQ5B,CAAC"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAE7E;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,mCAAmC;IACnC,OAAO,CAAC,EAAE,YAAY,GAAG,gBAAgB,CAAC;IAC1C,oBAAoB;IACpB,QAAQ,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;IACrC,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC5C;AAED,eAAO,MAAM,cAAc,EAAE,eAQ5B,CAAC"}
@@ -0,0 +1 @@
1
+ "use strict";var l=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var M=(o,t)=>{for(var e in t)l(o,e,{get:t[e],enumerable:!0})},O=(o,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of m(t))!d.call(o,n)&&n!==e&&l(o,n,{get:()=>t[n],enumerable:!(s=a(t,n))||s.enumerable});return o};var f=o=>O(l({},"__esModule",{value:!0}),o);var E={};M(E,{BUILTIN_COMPONENTS:()=>x,CORE_CONTROL_FLOW:()=>u,DOM_CONTROL_FLOW:()=>i,RESERVED_COMPONENTS:()=>R,ROUTER_COMPONENTS:()=>c,builtinComponentMap:()=>p,builtinComponents:()=>C,routerComponents:()=>g});module.exports=f(E);var i=["Show","For","Index","Switch","Match","Portal","Dynamic","ErrorBoundary"],u=["Suspense","SuspenseList","Await"],c=["Router","Outlet","Redirect","Link"],x=[...i,...u,...c],R=new Set([...i,...u]);function p(o={}){let{controlFlowModule:t="@fluixi/dom",coreModule:e="@fluixi/core",routerModule:s="@fluixi/core/router-next"}=o,n={};for(let r of i)n[r]=t;for(let r of u)n[r]=e;for(let r of c)n[r]=s;return n}function C(o={}){return{components:p(o)}}function g(o){let t=o??"@fluixi/core/router-next";return{components:Object.fromEntries(c.map(e=>[e,t]))}}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * The components the compiler supplies without an import, as data.
3
+ *
4
+ * Two different things have always been bundled into one hardcoded `Set` per group:
5
+ * *which module a name comes from*, and *whether the name has special lowering*. Only
6
+ * the first is interesting outside the compiler, and every tool needs it — the TS
7
+ * plugin, to resolve `<Show>` for hover and go-to-definition; the language server, to
8
+ * complete and validate tags inside `` html`…` ``; a codemod, to materialise imports.
9
+ * Having no published source, `@fluixi/ts-plugin` duplicated the list and pinned it
10
+ * with a test that fails when the two drift.
11
+ *
12
+ * So the names live here, shaped as {@link ComponentMapRule} so they compose with
13
+ * user-configured `resolve` rules, and the compiler keeps its own sets for the parts
14
+ * that are genuinely about codegen.
15
+ *
16
+ * The split matters: control-flow names cannot become ordinary rules. `Show`, `For`,
17
+ * `Index` and `Match` read a reactive *value* prop inside their own tracking scope, so
18
+ * the compiler emits that prop as a getter — without it `each={items()}` snapshots once
19
+ * and never updates. They are also exempted from `createMemo` wrapping and may be
20
+ * replaced outright by `optimizeControlFlowComponent`. A rule only injects an import,
21
+ * so converting them would keep the import and silently drop the reactivity.
22
+ *
23
+ * Router components have no such behaviour — every reference to them in the plugin is
24
+ * import plumbing — so they are a plain rule.
25
+ */
26
+ import type { ComponentMapRule } from './component-resolver.js';
27
+ /** Where the built-in groups come from when the host does not override the module. */
28
+ export interface BuiltinModules {
29
+ /** Control flow that lives in the DOM package. Default `@fluixi/dom`. */
30
+ controlFlowModule?: string;
31
+ /** Control flow that only exists in core. Default `@fluixi/core`. */
32
+ coreModule?: string;
33
+ /** Router components. Default `@fluixi/core/router-next`. */
34
+ routerModule?: string;
35
+ }
36
+ /** Control flow lowered against the DOM runtime. */
37
+ export declare const DOM_CONTROL_FLOW: readonly ["Show", "For", "Index", "Switch", "Match", "Portal", "Dynamic", "ErrorBoundary"];
38
+ /** Control flow that only `@fluixi/core` exports — importing it from dom resolves to nothing. */
39
+ export declare const CORE_CONTROL_FLOW: readonly ["Suspense", "SuspenseList", "Await"];
40
+ /**
41
+ * Router components.
42
+ *
43
+ * `Routes` is not a component (routing is `<Router routes={…}>`) and `lazy` is a call
44
+ * rather than a tag, so neither can be supplied this way.
45
+ */
46
+ export declare const ROUTER_COMPONENTS: readonly ["Router", "Outlet", "Redirect", "Link"];
47
+ /** Every name the compiler supplies without an import. */
48
+ export declare const BUILTIN_COMPONENTS: readonly string[];
49
+ /**
50
+ * Names whose meaning is fixed by the compiler and cannot be reassigned by a rule.
51
+ *
52
+ * A rule naming one of these is a silent no-op — the compiler matches the built-in
53
+ * first and the tag renders control flow instead of the intended component, with no
54
+ * error. Rule authors should check against this set and report rather than emit.
55
+ */
56
+ export declare const RESERVED_COMPONENTS: ReadonlySet<string>;
57
+ /** Name → module for every built-in, honouring host module overrides. */
58
+ export declare function builtinComponentMap(modules?: BuiltinModules): Record<string, string>;
59
+ /**
60
+ * The built-ins as a resolver rule, for tools that want one uniform lookup.
61
+ *
62
+ * Note this is the *naming* half only. Feeding it to the compiler would not make
63
+ * control flow work through resolution — the compiler still recognises those names
64
+ * itself, for the codegen reasons above.
65
+ */
66
+ export declare function builtinComponents(modules?: BuiltinModules): ComponentMapRule;
67
+ /** Just the router group as a rule — the one group that is purely an import. */
68
+ export declare function routerComponents(routerModule?: string): ComponentMapRule;
69
+ //# sourceMappingURL=builtins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../../src/resolve/builtins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,sFAAsF;AACtF,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,oDAAoD;AACpD,eAAO,MAAM,gBAAgB,4FASnB,CAAC;AAEX,iGAAiG;AACjG,eAAO,MAAM,iBAAiB,gDAAiD,CAAC;AAEhF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,mDAAoD,CAAC;AAEnF,0DAA0D;AAC1D,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAI/C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAGlD,CAAC;AAEH,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,cAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYxF;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,cAAmB,GAAG,gBAAgB,CAEhF;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAGxE"}
@@ -0,0 +1,64 @@
1
+ /** Control flow lowered against the DOM runtime. */
2
+ export const DOM_CONTROL_FLOW = [
3
+ 'Show',
4
+ 'For',
5
+ 'Index',
6
+ 'Switch',
7
+ 'Match',
8
+ 'Portal',
9
+ 'Dynamic',
10
+ 'ErrorBoundary',
11
+ ];
12
+ /** Control flow that only `@fluixi/core` exports — importing it from dom resolves to nothing. */
13
+ export const CORE_CONTROL_FLOW = ['Suspense', 'SuspenseList', 'Await'];
14
+ /**
15
+ * Router components.
16
+ *
17
+ * `Routes` is not a component (routing is `<Router routes={…}>`) and `lazy` is a call
18
+ * rather than a tag, so neither can be supplied this way.
19
+ */
20
+ export const ROUTER_COMPONENTS = ['Router', 'Outlet', 'Redirect', 'Link'];
21
+ /** Every name the compiler supplies without an import. */
22
+ export const BUILTIN_COMPONENTS = [
23
+ ...DOM_CONTROL_FLOW,
24
+ ...CORE_CONTROL_FLOW,
25
+ ...ROUTER_COMPONENTS,
26
+ ];
27
+ /**
28
+ * Names whose meaning is fixed by the compiler and cannot be reassigned by a rule.
29
+ *
30
+ * A rule naming one of these is a silent no-op — the compiler matches the built-in
31
+ * first and the tag renders control flow instead of the intended component, with no
32
+ * error. Rule authors should check against this set and report rather than emit.
33
+ */
34
+ export const RESERVED_COMPONENTS = new Set([
35
+ ...DOM_CONTROL_FLOW,
36
+ ...CORE_CONTROL_FLOW,
37
+ ]);
38
+ /** Name → module for every built-in, honouring host module overrides. */
39
+ export function builtinComponentMap(modules = {}) {
40
+ const { controlFlowModule = '@fluixi/dom', coreModule = '@fluixi/core', routerModule = '@fluixi/core/router-next', } = modules;
41
+ const map = {};
42
+ for (const name of DOM_CONTROL_FLOW)
43
+ map[name] = controlFlowModule;
44
+ for (const name of CORE_CONTROL_FLOW)
45
+ map[name] = coreModule;
46
+ for (const name of ROUTER_COMPONENTS)
47
+ map[name] = routerModule;
48
+ return map;
49
+ }
50
+ /**
51
+ * The built-ins as a resolver rule, for tools that want one uniform lookup.
52
+ *
53
+ * Note this is the *naming* half only. Feeding it to the compiler would not make
54
+ * control flow work through resolution — the compiler still recognises those names
55
+ * itself, for the codegen reasons above.
56
+ */
57
+ export function builtinComponents(modules = {}) {
58
+ return { components: builtinComponentMap(modules) };
59
+ }
60
+ /** Just the router group as a rule — the one group that is purely an import. */
61
+ export function routerComponents(routerModule) {
62
+ const module = routerModule ?? '@fluixi/core/router-next';
63
+ return { components: Object.fromEntries(ROUTER_COMPONENTS.map((n) => [n, module])) };
64
+ }
@@ -0,0 +1 @@
1
+ var s=["Show","For","Index","Switch","Match","Portal","Dynamic","ErrorBoundary"],i=["Suspense","SuspenseList","Await"],u=["Router","Outlet","Redirect","Link"],p=[...s,...i,...u],a=new Set([...s,...i]);function l(o={}){let{controlFlowModule:e="@fluixi/dom",coreModule:r="@fluixi/core",routerModule:c="@fluixi/core/router-next"}=o,n={};for(let t of s)n[t]=e;for(let t of i)n[t]=r;for(let t of u)n[t]=c;return n}function m(o={}){return{components:l(o)}}function d(o){let e=o??"@fluixi/core/router-next";return{components:Object.fromEntries(u.map(r=>[r,e]))}}export{p as BUILTIN_COMPONENTS,i as CORE_CONTROL_FLOW,s as DOM_CONTROL_FLOW,a as RESERVED_COMPONENTS,u as ROUTER_COMPONENTS,l as builtinComponentMap,m as builtinComponents,d as routerComponents};
@@ -0,0 +1 @@
1
+ "use strict";var o=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var k=(e,n)=>{for(var t in n)o(e,t,{get:n[t],enumerable:!0})},p=(e,n,t,a)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of g(n))!u.call(e,r)&&r!==t&&o(e,r,{get:()=>n[r],enumerable:!(a=l(n,r))||a.enumerable});return e};var w=e=>p(o({},"__esModule",{value:!0}),e);var y={};k(y,{DEFAULT_INTERACTION_EVENTS:()=>c,EAGER:()=>d,LoadDirectiveError:()=>i,isDeferred:()=>m,isLoadDirective:()=>v,parseLoadDirective:()=>f,strategyKey:()=>x});module.exports=w(y);var d={kind:"eager"},c=["pointerdown","focusin","keydown"],s=new Set(["eager","idle","visible","interaction","media","never"]),i=class extends Error{};function v(e){return e.startsWith("load:")}function f(e,n){let t=e.slice(5);if(!s.has(t))throw new i(`Unknown load strategy 'load:${t}'. Expected one of ${[...s].join(", ")}.`);switch(t){case"eager":return d;case"idle":return{kind:"idle"};case"never":return{kind:"never"};case"visible":return n?{kind:"visible",rootMargin:n}:{kind:"visible"};case"interaction":return{kind:"interaction",events:n?h(n):[...c]};case"media":if(!n)throw new i(`'load:media' needs a query, e.g. load:media="(min-width: 1024px)".`);return{kind:"media",query:n};default:throw new i(`Unhandled load strategy '${t}'.`)}}function h(e){let n=e.split(/[\s,]+/).map(t=>t.trim()).filter(Boolean);if(n.length===0)throw new i("'load:interaction' was given no event names.");return n}function m(e){return e.kind!=="eager"&&e.kind!=="never"}function x(e){switch(e.kind){case"visible":return`visible:${e.rootMargin??""}`;case"interaction":return`interaction:${[...e.events].sort().join(",")}`;case"media":return`media:${e.query}`;default:return e.kind}}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The `load:` directive — when a component's code is fetched.
3
+ *
4
+ * Resolution decides *where* a component comes from; this decides *when*. They are
5
+ * separate because they vary independently: the location of `<RevenueChart>` is the
6
+ * same everywhere and belongs in config, while whether this particular usage should
7
+ * wait for the viewport is a property of the usage. Fusing them — `<Chart lazy="./Chart">`
8
+ * — was rejected for exactly that reason.
9
+ *
10
+ * `load:` joins the existing `use:`/`prop:`/`attr:`/`bool:` namespace, so it cannot
11
+ * collide with a real prop and the parser already has a directive taxonomy to hang it on.
12
+ *
13
+ * One parser for both frontends. `load:visible` is already a valid `JSXNamespacedName`,
14
+ * so JSX needs no parser change, and the html`` path produces a `LoadDirective` node —
15
+ * but both funnel through {@link parseLoadDirective}, so the two syntaxes cannot drift.
16
+ */
17
+ /** When a component's module is fetched. */
18
+ export type IRLoadStrategy = {
19
+ kind: 'eager';
20
+ } | {
21
+ kind: 'idle';
22
+ } | {
23
+ kind: 'visible';
24
+ rootMargin?: string;
25
+ } | {
26
+ kind: 'interaction';
27
+ events: string[];
28
+ } | {
29
+ kind: 'media';
30
+ query: string;
31
+ } | {
32
+ kind: 'never';
33
+ };
34
+ /** Everything is eager unless a directive says otherwise. */
35
+ export declare const EAGER: IRLoadStrategy;
36
+ /** Events that trigger an `interaction` load when none are named. */
37
+ export declare const DEFAULT_INTERACTION_EVENTS: readonly ["pointerdown", "focusin", "keydown"];
38
+ export declare class LoadDirectiveError extends Error {
39
+ }
40
+ /** True for an attribute name in the `load:` namespace. */
41
+ export declare function isLoadDirective(name: string): boolean;
42
+ /**
43
+ * Parse `load:<strategy>` plus its optional value into a strategy.
44
+ *
45
+ * `value` is the attribute's literal text — `load:visible="200px"` — or null for a bare
46
+ * directive. A `${…}` hole is rejected: the strategy has to be known at compile time
47
+ * because it decides how the module is emitted, and a runtime value cannot.
48
+ */
49
+ export declare function parseLoadDirective(name: string, value: string | null): IRLoadStrategy;
50
+ /** True when the strategy means "not in the parent chunk". */
51
+ export declare function isDeferred(strategy: IRLoadStrategy): boolean;
52
+ /** A stable key for grouping references that share a strategy. */
53
+ export declare function strategyKey(strategy: IRLoadStrategy): string;
54
+ //# sourceMappingURL=load-directive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-directive.d.ts","sourceRoot":"","sources":["../../src/resolve/load-directive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,4CAA4C;AAC5C,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtB,6DAA6D;AAC7D,eAAO,MAAM,KAAK,EAAE,cAAkC,CAAC;AAEvD,qEAAqE;AACrE,eAAO,MAAM,0BAA0B,gDAAiD,CAAC;AAIzF,qBAAa,kBAAmB,SAAQ,KAAK;CAAG;AAEhD,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CAqCrF;AAaD,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAE5D;AAED,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAW5D"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * The `load:` directive — when a component's code is fetched.
3
+ *
4
+ * Resolution decides *where* a component comes from; this decides *when*. They are
5
+ * separate because they vary independently: the location of `<RevenueChart>` is the
6
+ * same everywhere and belongs in config, while whether this particular usage should
7
+ * wait for the viewport is a property of the usage. Fusing them — `<Chart lazy="./Chart">`
8
+ * — was rejected for exactly that reason.
9
+ *
10
+ * `load:` joins the existing `use:`/`prop:`/`attr:`/`bool:` namespace, so it cannot
11
+ * collide with a real prop and the parser already has a directive taxonomy to hang it on.
12
+ *
13
+ * One parser for both frontends. `load:visible` is already a valid `JSXNamespacedName`,
14
+ * so JSX needs no parser change, and the html`` path produces a `LoadDirective` node —
15
+ * but both funnel through {@link parseLoadDirective}, so the two syntaxes cannot drift.
16
+ */
17
+ /** Everything is eager unless a directive says otherwise. */
18
+ export const EAGER = { kind: 'eager' };
19
+ /** Events that trigger an `interaction` load when none are named. */
20
+ export const DEFAULT_INTERACTION_EVENTS = ['pointerdown', 'focusin', 'keydown'];
21
+ const STRATEGIES = new Set(['eager', 'idle', 'visible', 'interaction', 'media', 'never']);
22
+ export class LoadDirectiveError extends Error {
23
+ }
24
+ /** True for an attribute name in the `load:` namespace. */
25
+ export function isLoadDirective(name) {
26
+ return name.startsWith('load:');
27
+ }
28
+ /**
29
+ * Parse `load:<strategy>` plus its optional value into a strategy.
30
+ *
31
+ * `value` is the attribute's literal text — `load:visible="200px"` — or null for a bare
32
+ * directive. A `${…}` hole is rejected: the strategy has to be known at compile time
33
+ * because it decides how the module is emitted, and a runtime value cannot.
34
+ */
35
+ export function parseLoadDirective(name, value) {
36
+ const strategy = name.slice('load:'.length);
37
+ if (!STRATEGIES.has(strategy)) {
38
+ throw new LoadDirectiveError(`Unknown load strategy 'load:${strategy}'. Expected one of ${[...STRATEGIES].join(', ')}.`);
39
+ }
40
+ switch (strategy) {
41
+ case 'eager':
42
+ return EAGER;
43
+ case 'idle':
44
+ return { kind: 'idle' };
45
+ case 'never':
46
+ return { kind: 'never' };
47
+ case 'visible':
48
+ // `load:visible="200px"` starts the fetch before the element reaches the
49
+ // viewport, which is usually what you want — arriving exactly on intersection
50
+ // means the user waits for the network.
51
+ return value ? { kind: 'visible', rootMargin: value } : { kind: 'visible' };
52
+ case 'interaction':
53
+ return {
54
+ kind: 'interaction',
55
+ events: value ? splitEvents(value) : [...DEFAULT_INTERACTION_EVENTS],
56
+ };
57
+ case 'media':
58
+ if (!value) {
59
+ throw new LoadDirectiveError(`'load:media' needs a query, e.g. load:media="(min-width: 1024px)".`);
60
+ }
61
+ return { kind: 'media', query: value };
62
+ default:
63
+ /* c8 ignore next */
64
+ throw new LoadDirectiveError(`Unhandled load strategy '${strategy}'.`);
65
+ }
66
+ }
67
+ function splitEvents(value) {
68
+ const events = value
69
+ .split(/[\s,]+/)
70
+ .map((e) => e.trim())
71
+ .filter(Boolean);
72
+ if (events.length === 0) {
73
+ throw new LoadDirectiveError(`'load:interaction' was given no event names.`);
74
+ }
75
+ return events;
76
+ }
77
+ /** True when the strategy means "not in the parent chunk". */
78
+ export function isDeferred(strategy) {
79
+ return strategy.kind !== 'eager' && strategy.kind !== 'never';
80
+ }
81
+ /** A stable key for grouping references that share a strategy. */
82
+ export function strategyKey(strategy) {
83
+ switch (strategy.kind) {
84
+ case 'visible':
85
+ return `visible:${strategy.rootMargin ?? ''}`;
86
+ case 'interaction':
87
+ return `interaction:${[...strategy.events].sort().join(',')}`;
88
+ case 'media':
89
+ return `media:${strategy.query}`;
90
+ default:
91
+ return strategy.kind;
92
+ }
93
+ }
@@ -0,0 +1 @@
1
+ var o={kind:"eager"},a=["pointerdown","focusin","keydown"],r=new Set(["eager","idle","visible","interaction","media","never"]),i=class extends Error{};function d(e){return e.startsWith("load:")}function c(e,n){let t=e.slice(5);if(!r.has(t))throw new i(`Unknown load strategy 'load:${t}'. Expected one of ${[...r].join(", ")}.`);switch(t){case"eager":return o;case"idle":return{kind:"idle"};case"never":return{kind:"never"};case"visible":return n?{kind:"visible",rootMargin:n}:{kind:"visible"};case"interaction":return{kind:"interaction",events:n?s(n):[...a]};case"media":if(!n)throw new i(`'load:media' needs a query, e.g. load:media="(min-width: 1024px)".`);return{kind:"media",query:n};default:throw new i(`Unhandled load strategy '${t}'.`)}}function s(e){let n=e.split(/[\s,]+/).map(t=>t.trim()).filter(Boolean);if(n.length===0)throw new i("'load:interaction' was given no event names.");return n}function l(e){return e.kind!=="eager"&&e.kind!=="never"}function g(e){switch(e.kind){case"visible":return`visible:${e.rootMargin??""}`;case"interaction":return`interaction:${[...e.events].sort().join(",")}`;case"media":return`media:${e.query}`;default:return e.kind}}export{a as DEFAULT_INTERACTION_EVENTS,o as EAGER,i as LoadDirectiveError,l as isDeferred,d as isLoadDirective,c as parseLoadDirective,g as strategyKey};
@@ -0,0 +1 @@
1
+ "use strict";var c=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var w=(n,e)=>{for(var i in e)c(n,i,{get:e[i],enumerable:!0})},N=(n,e,i,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of y(e))!I.call(n,o)&&o!==i&&c(n,o,{get:()=>e[o],enumerable:!(s=M(e,o))||s.enumerable});return n};var k=n=>N(c({},"__esModule",{value:!0}),n);var h={};w(h,{resolveComponentSources:()=>b,walk:()=>f});module.exports=k(h);var l=["Show","For","Index","Switch","Match","Portal","Dynamic","ErrorBoundary"],p=["Suspense","SuspenseList","Await"],a=["Router","Outlet","Redirect","Link"],L=[...l,...p,...a],m=new Set([...l,...p]);function S(n={}){let{controlFlowModule:e="@fluixi/dom",coreModule:i="@fluixi/core",routerModule:s="@fluixi/core/router-next"}=n,o={};for(let d of l)o[d]=e;for(let d of p)o[d]=i;for(let d of a)o[d]=s;return o}var R={kind:"eager"};function b(n,e={}){let{resolver:i,isBound:s,modules:o,strategyFor:d}=e,g=S(o),x=new Map,v=new Set,E=t=>{let{name:r}=t;if(!r||r.includes(".")||s?.(r))return;let u=O(r);if(!u){v.add(r);return}let C=u.origin==="builtin"&&m.has(r)?R:d?.(t)??R;t.source={...u,loading:C},x.set(r,t.source)},O=t=>{if(m.has(t))return{module:g[t],export:t,origin:"builtin"};let r=i?.resolve(t);if(r)return{module:r.module,export:r.export,origin:"rule"};if(a.includes(t))return{module:g[t],export:t,origin:"builtin"}};return f(n,t=>{t.kind==="component"&&E(t)}),{resolved:x,unresolved:[...v]}}function f(n,e){let i=Array.isArray(n)?n:[n];for(let s of i){e(s);let o=s.children;o&&f(o,e)}}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The resolve pass: annotate component references in the IR with where they come from.
3
+ *
4
+ * Runs between the frontends and the optimizer, so every later pass reads provenance off
5
+ * the node instead of re-deriving it. Nothing here emits code — the pass only records a
6
+ * decision, which is what lets the same answer drive import injection, chunk grouping,
7
+ * hint planning and diagnostics without any of them agreeing by coincidence.
8
+ *
9
+ * Two suppliers, in precedence order:
10
+ *
11
+ * 1. **Control flow** (`Show`, `For`, `Switch`, …) — the name selects a lowering, so a
12
+ * rule cannot re-point it. Recorded as `builtin` so a later pass can tell the
13
+ * difference between "configured here" and "fixed by the compiler".
14
+ * 2. **Configured rules**, then the **router built-ins**. Router components are only an
15
+ * import, so a project's own `Link` wins; see `builtins.ts`.
16
+ *
17
+ * A name bound in the file is not resolved at all: the author's import always wins, and
18
+ * the caller supplies those bindings via `isBound`.
19
+ */
20
+ import type { IRNode, IRComponent, IRComponentSource } from '../ir/nodes.js';
21
+ import type { ComponentResolver } from './component-resolver.js';
22
+ import { builtinComponentMap } from './builtins.js';
23
+ import { type IRLoadStrategy } from './load-directive.js';
24
+ export interface ResolveOptions {
25
+ /** Rules configured for the project. Omit when the project configures none. */
26
+ resolver?: ComponentResolver;
27
+ /** True when the name already has a binding in the file — an import the author wrote. */
28
+ isBound?: (name: string) => boolean;
29
+ /** Module overrides, so `routerModule` and friends are honoured. */
30
+ modules?: Parameters<typeof builtinComponentMap>[0];
31
+ /**
32
+ * The `load:` strategy for a reference, when the frontend found one on the tag.
33
+ * Keyed by node so two usages of the same component can load differently — the
34
+ * whole reason timing lives at the usage site and location does not.
35
+ */
36
+ strategyFor?: (node: IRComponent) => IRLoadStrategy | undefined;
37
+ }
38
+ export interface ResolveReport {
39
+ /** Every reference the pass annotated, by name. */
40
+ resolved: Map<string, IRComponentSource>;
41
+ /**
42
+ * Capitalised tags nothing supplies and nothing binds.
43
+ *
44
+ * These compile to a reference to an identifier that does not exist — the build
45
+ * succeeds and the page throws at runtime — so they are the pass's most useful
46
+ * output for diagnostics.
47
+ */
48
+ unresolved: string[];
49
+ }
50
+ /** Annotate every component reference in `root`, returning what was decided. */
51
+ export declare function resolveComponentSources(root: IRNode | IRNode[], options?: ResolveOptions): ResolveReport;
52
+ /** Depth-first walk over every node that can contain children. */
53
+ export declare function walk(root: IRNode | IRNode[], visit: (node: IRNode) => void): void;
54
+ //# sourceMappingURL=resolve-ir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-ir.d.ts","sourceRoot":"","sources":["../../src/resolve/resolve-ir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAA0C,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC5F,OAAO,EAAS,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,yFAAyF;IACzF,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACpC,oEAAoE;IACpE,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,cAAc,GAAG,SAAS,CAAC;CACjE;AAED,MAAM,WAAW,aAAa;IAC5B,mDAAmD;IACnD,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACzC;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,gFAAgF;AAChF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,OAAO,GAAE,cAAmB,GAC3B,aAAa,CA8Cf;AAED,kEAAkE;AAClE,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAOjF"}