@aihu/compiler 1.3.3 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -18
- package/dist/codemods/macro-simplification.d.ts +24 -0
- package/dist/codemods/macro-simplification.d.ts.map +1 -0
- package/dist/codemods/macro-simplification.js +65 -0
- package/dist/codemods/macro-simplification.js.map +1 -0
- package/dist/codemods/state-wrapper.d.ts +78 -0
- package/dist/codemods/state-wrapper.d.ts.map +1 -0
- package/dist/codemods/state-wrapper.js +25 -0
- package/dist/codemods/state-wrapper.js.map +1 -0
- package/dist/codemods/template-grammar-v2.d.ts +40 -0
- package/dist/codemods/template-grammar-v2.d.ts.map +1 -0
- package/dist/codemods/template-grammar-v2.js +3 -0
- package/dist/codemods/template-grammar-v2.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +23 -11
package/README.md
CHANGED
|
@@ -7,7 +7,15 @@ Single File Component (.aihu) compiler — Rust binary + JS glue.
|
|
|
7
7
|
Part of the **compiler + toolchain** layer of Aihu. Build-time only — does not ship to the client. The compiler reads `.aihu` SFC source (per the [Block Structure spec](../../docs/superpowers/specs/2026-05-02-spec-block-structure.md)) and emits standards-compliant Web Components.
|
|
8
8
|
|
|
9
9
|
<!-- BEGIN_HANDWRITTEN: prose -->
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
The package exposes the compiler plugin and transform API from its root entry point. Migration tools are available as stable subpath exports so framework tooling does not need to import compiler source files:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { migrate } from '@aihu/compiler/codemods/macro-simplification'
|
|
15
|
+
import { migrateStateWrappers } from '@aihu/compiler/codemods/state-wrapper'
|
|
16
|
+
import { migrateTemplateGrammar } from '@aihu/compiler/codemods/template-grammar-v2'
|
|
17
|
+
```
|
|
18
|
+
|
|
11
19
|
<!-- END_HANDWRITTEN: prose -->
|
|
12
20
|
|
|
13
21
|
## Install
|
|
@@ -21,7 +29,7 @@ npm install @aihu/compiler
|
|
|
21
29
|
bun add @aihu/compiler
|
|
22
30
|
```
|
|
23
31
|
|
|
24
|
-
<sub><i>Auto-generated against `@aihu/compiler@1.3.
|
|
32
|
+
<sub><i>Auto-generated against `@aihu/compiler@1.3.5`.</i></sub>
|
|
25
33
|
|
|
26
34
|
<!-- END_AUTOGEN: install -->
|
|
27
35
|
|
|
@@ -32,12 +40,12 @@ bun add @aihu/compiler
|
|
|
32
40
|
|
|
33
41
|
| | |
|
|
34
42
|
|---|---|
|
|
35
|
-
| **Version** | `1.3.
|
|
43
|
+
| **Version** | `1.3.5` |
|
|
36
44
|
| **Tier** | D — Compiler — Single-File Component (.aihu) → Web Component |
|
|
37
45
|
| **Published files** | 4 entries |
|
|
38
46
|
| **License** | MIT |
|
|
39
47
|
|
|
40
|
-
<sub><i>Auto-generated against `@aihu/compiler@1.3.
|
|
48
|
+
<sub><i>Auto-generated against `@aihu/compiler@1.3.5`.</i></sub>
|
|
41
49
|
|
|
42
50
|
<!-- END_AUTOGEN: stats -->
|
|
43
51
|
|
|
@@ -49,8 +57,11 @@ bun add @aihu/compiler
|
|
|
49
57
|
| Subpath | ESM | CJS |
|
|
50
58
|
|---|---|---|
|
|
51
59
|
| `.` | `./dist/index.js` | `—` |
|
|
60
|
+
| `./codemods/macro-simplification` | `./dist/codemods/macro-simplification.js` | `—` |
|
|
61
|
+
| `./codemods/state-wrapper` | `./dist/codemods/state-wrapper.js` | `—` |
|
|
62
|
+
| `./codemods/template-grammar-v2` | `./dist/codemods/template-grammar-v2.js` | `—` |
|
|
52
63
|
|
|
53
|
-
<sub><i>Auto-generated against `@aihu/compiler@1.3.
|
|
64
|
+
<sub><i>Auto-generated against `@aihu/compiler@1.3.5`.</i></sub>
|
|
54
65
|
|
|
55
66
|
<!-- END_AUTOGEN: exports -->
|
|
56
67
|
|
|
@@ -62,21 +73,22 @@ bun add @aihu/compiler
|
|
|
62
73
|
**Peer dependencies:**
|
|
63
74
|
|
|
64
75
|
- `vite` — `>=5.0.0`
|
|
76
|
+
- `@aihu/css-engine` — `>=0.6.1`
|
|
65
77
|
|
|
66
78
|
**Optional dependencies (platform-specific):**
|
|
67
79
|
|
|
68
|
-
- `@aihu/compiler-darwin-arm64` — `1.3.
|
|
69
|
-
- `@aihu/compiler-darwin-x64` — `1.3.
|
|
70
|
-
- `@aihu/compiler-linux-x64-gnu` — `1.3.
|
|
71
|
-
- `@aihu/compiler-linux-arm64-gnu` — `1.3.
|
|
72
|
-
- `@aihu/compiler-win32-x64-msvc` — `1.3.
|
|
73
|
-
- `@aihu/compiler-native-darwin-arm64` — `1.3.
|
|
74
|
-
- `@aihu/compiler-native-darwin-x64` — `1.3.
|
|
75
|
-
- `@aihu/compiler-native-linux-x64-gnu` — `1.3.
|
|
76
|
-
- `@aihu/compiler-native-linux-arm64-gnu` — `1.3.
|
|
77
|
-
- `@aihu/compiler-native-win32-x64-msvc` — `1.3.
|
|
80
|
+
- `@aihu/compiler-darwin-arm64` — `1.3.4`
|
|
81
|
+
- `@aihu/compiler-darwin-x64` — `1.3.4`
|
|
82
|
+
- `@aihu/compiler-linux-x64-gnu` — `1.3.4`
|
|
83
|
+
- `@aihu/compiler-linux-arm64-gnu` — `1.3.4`
|
|
84
|
+
- `@aihu/compiler-win32-x64-msvc` — `1.3.4`
|
|
85
|
+
- `@aihu/compiler-native-darwin-arm64` — `1.3.4`
|
|
86
|
+
- `@aihu/compiler-native-darwin-x64` — `1.3.4`
|
|
87
|
+
- `@aihu/compiler-native-linux-x64-gnu` — `1.3.4`
|
|
88
|
+
- `@aihu/compiler-native-linux-arm64-gnu` — `1.3.4`
|
|
89
|
+
- `@aihu/compiler-native-win32-x64-msvc` — `1.3.4`
|
|
78
90
|
|
|
79
|
-
<sub><i>Auto-generated against `@aihu/compiler@1.3.
|
|
91
|
+
<sub><i>Auto-generated against `@aihu/compiler@1.3.5`.</i></sub>
|
|
80
92
|
|
|
81
93
|
<!-- END_AUTOGEN: deps -->
|
|
82
94
|
|
|
@@ -90,7 +102,7 @@ bun add @aihu/compiler
|
|
|
90
102
|
- [Macro Vocabulary spec](../../docs/superpowers/specs/2026-05-02-spec-macro-vocabulary.md)
|
|
91
103
|
- [Aihu framework root](../../README.md)
|
|
92
104
|
|
|
93
|
-
<sub><i>Auto-generated against `@aihu/compiler@1.3.
|
|
105
|
+
<sub><i>Auto-generated against `@aihu/compiler@1.3.5`.</i></sub>
|
|
94
106
|
|
|
95
107
|
<!-- END_AUTOGEN: see-also -->
|
|
96
108
|
|
|
@@ -101,6 +113,6 @@ bun add @aihu/compiler
|
|
|
101
113
|
|
|
102
114
|
MIT — see [LICENSE](../../LICENSE).
|
|
103
115
|
|
|
104
|
-
<sub><i>Auto-generated against `@aihu/compiler@1.3.
|
|
116
|
+
<sub><i>Auto-generated against `@aihu/compiler@1.3.5`.</i></sub>
|
|
105
117
|
|
|
106
118
|
<!-- END_AUTOGEN: license -->
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region js/codemods/macro-simplification/migrate.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* macro-simplification codemod (B6.2)
|
|
4
|
+
*
|
|
5
|
+
* Transforms v1 `.aihu` source into v2 collection-form per
|
|
6
|
+
* `docs/superpowers/specs/2026-05-05-spec-macro-vocabulary-v2.md`.
|
|
7
|
+
*
|
|
8
|
+
* Scope (in-spec macros only): `$prop`, `$computed`, `$action`,
|
|
9
|
+
* `$resource`, `$effect`, `$lifecycle.{mount,dispose}` inside `@state`;
|
|
10
|
+
* `$expose`, `$expose.write`, agent-bare `$action`, `$describe` inside
|
|
11
|
+
* `@agent` (folded into matching `@state` collection entries).
|
|
12
|
+
*
|
|
13
|
+
* Out of scope: `@template`, `@style`, `@route`, `$watch`, `$shared`,
|
|
14
|
+
* `$cookie`, `$server`, `$meta`, `$beforeNavigate`, `$afterNavigate`,
|
|
15
|
+
* `$effect.on`, plain TS imports/decls (passed through verbatim).
|
|
16
|
+
*/
|
|
17
|
+
interface MigrateResult {
|
|
18
|
+
readonly rewritten: string;
|
|
19
|
+
readonly warnings: readonly string[];
|
|
20
|
+
}
|
|
21
|
+
declare function migrate(source: string): MigrateResult;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { MigrateResult, migrate };
|
|
24
|
+
//# sourceMappingURL=macro-simplification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"macro-simplification.d.ts","names":[],"sources":["../../js/codemods/macro-simplification/migrate.ts"],"mappings":";;AAgBA;AAA8B;AAAA;AAAA;AAEX;AAwEnB;AAAuB;AAAA;AAA+B;AAAA;;;;;UA1ErC,aAAA;EAAA,SACN,SAAA;EAAA,SACA,QAAQ;AAAA;AAAA,iBAwEH,OAAA,CAAQ,MAAA,WAAiB,aAAa"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
function e(e){let n=[],r=t(e,`state`),i=t(e,`agent`),o=new Map,c=[];if(i&&a(i.body,o,c,n),!r)return{rewritten:e,warnings:n};let l=s(r.body,o,n),u=`@state {\n${T(l)}\n}`,d=c.length>0?`@agent {\n${c.join(`
|
|
2
|
+
`)}\n}`:null,f=e.slice(0,r.start)+u+e.slice(r.end);if(i){let e=t(f,`agent`);if(e){if(d)f=f.slice(0,e.start)+d+f.slice(e.end);else{let t=G(f,e.start),n=K(f,e.end);f=f.slice(0,t)+f.slice(n)}}}let p=new Set([...l.props.map(e=>e.name),...l.computed.map(e=>e.name),...l.action.map(e=>e.name),...l.resource.map(e=>e.name),...l.effectNamed.map(e=>e.name),...l.plain.map(e=>e.name).filter(e=>!!e)]);for(let[e]of o)p.has(e)||n.push(`@agent references '${e}' but no @state declaration found`);return{rewritten:f,warnings:n}}function t(e,t){let r=RegExp(`(^|\\n)([ \\t]*)@${t}\\s*\\{`,`g`).exec(e);if(!r)return null;let i=r.index+ +(r[1]===`
|
|
3
|
+
`),a=r.index+r[0].length-1,o=n(e,a);return o<0?null:{start:i,end:o+1,bodyStart:a+1,bodyEnd:o,body:e.slice(a+1,o)}}function n(e,t){if(e[t]!==`{`)return-1;let n=0,i=t;for(;i<e.length;){let t=e[i];if(t===`/`&&e[i+1]===`/`){let t=e.indexOf(`
|
|
4
|
+
`,i);i=t<0?e.length:t;continue}if(t===`/`&&e[i+1]===`*`){let t=e.indexOf(`*/`,i+2);i=t<0?e.length:t+2;continue}if(t===`"`||t===`'`||t==="`"){i=r(e,i);continue}if(t===`{`)n++;else if(t===`}`&&(n--,n===0))return i;i++}return-1}function r(e,t){let r=e[t],i=t+1;for(;i<e.length;){let t=e[i];if(t===`\\`){i+=2;continue}if(r==="`"&&t===`$`&&e[i+1]===`{`){let t=n(e,i+1);i=t<0?e.length:t+1;continue}if(t===r)return i+1;i++}return e.length}function i(e,t){if(e[t]!==`(`)return-1;let i=0,a=t;for(;a<e.length;){let t=e[a];if(t===`/`&&e[a+1]===`/`){let t=e.indexOf(`
|
|
5
|
+
`,a);a=t<0?e.length:t;continue}if(t===`/`&&e[a+1]===`*`){let t=e.indexOf(`*/`,a+2);a=t<0?e.length:t+2;continue}if(t===`"`||t===`'`||t==="`"){a=r(e,a);continue}if(t===`{`){let t=n(e,a);a=t<0?e.length:t+1;continue}if(t===`(`)i++;else if(t===`)`&&(i--,i===0))return a;a++}return-1}function a(e,t,n,r){let i=(e,n)=>{t.set(e,{...t.get(e)??{},...n})};for(let t of e.split(`
|
|
6
|
+
`)){let e=t.trim();if(!(e===``||e.startsWith(`//`)||e.startsWith(`/*`)||e.startsWith(`*`))){if(e.startsWith(`$expose.write `)){let t=o(e.slice(14));for(let e of t)i(e,{exposeRead:!0,exposeWrite:!0});continue}if(e.startsWith(`$expose `)){let t=o(e.slice(8));for(let e of t)i(e,{exposeRead:!0});continue}if(e.startsWith(`$action `)){let t=e.slice(8).trim(),n=/^([A-Za-z_$][\w$]*)/.exec(t);n&&i(n[1],{isAction:!0,exposeRead:!0,exposeWrite:!0});continue}if(e.startsWith(`$describe `)){let t=e.slice(10).trim(),n=/^([A-Za-z_$][\w$]*)\s+(["'])([\s\S]*)\2\s*$/.exec(t);n&&i(n[1],{describe:n[3]});continue}if(e.startsWith(`$scope `)){n.push(` ${e}`);continue}e.startsWith(`$rate-limit `)&&n.push(` ${e}`)}}}function o(e){return e.split(`,`).map(e=>e.trim()).filter(e=>/^[A-Za-z_$][\w$]*$/.test(e))}function s(e,t,n){let r={props:[],computed:[],action:[],resource:[],effectNamed:[],effectAnon:[],lifecycle:[],plain:[],passthrough:[]},i=0;for(;i<e.length&&(e[i]===`
|
|
7
|
+
`||e[i]===`\r`);)i++;let a=``,o=0,s=()=>{for(;i<e.length;){let t=e.indexOf(`
|
|
8
|
+
`,i),n=t<0?e.length:t,r=e.slice(i,n),o=r.trim();if(o===``){a+=`${r}\n`,i=n+1;continue}if(o.startsWith(`//`)){a+=`${r}\n`,i=n+1;continue}if(o.startsWith(`/*`)){let t=e.indexOf(`*/`,i);if(t<0){a+=e.slice(i),i=e.length;return}let n=e.indexOf(`
|
|
9
|
+
`,t),r=n<0?e.length:n+1;a+=e.slice(i,r),i=r;continue}return}};for(;i<e.length&&(s(),!(i>=e.length));){let s=i,y=e.indexOf(`
|
|
10
|
+
`,i),b=y<0?e.length:y,x=e.slice(s,b),S=x.trim(),C=a;a=``;let w=s+(x.length-x.trimStart().length);if(S.startsWith(`import `)){let t=b,n=x;if(!(/\bfrom\s*['"]/.test(x)||/^import\s+['"]/.test(S))){let r=b+1;for(;r<e.length;){let i=e.indexOf(`
|
|
11
|
+
`,r),a=i<0?e.length:i,o=e.slice(r,a);if(n+=`\n${o}`,t=a,r=a+1,/\bfrom\s*['"]/.test(o))break}}r.passthrough.push({raw:n.trim(),leading:C,position:o++}),i=t+1;continue}{let n=q(e,w,t,r,C,()=>o++);if(n!==null){i=n;continue}}if(/^\$effect\s*:\s*(?:\(|async\b)/.test(S)){let t=J(e,w,r,C,o++);if(t!==null){i=t;continue}}if(S.startsWith(`$prop `)){let n=l(e,w,t,r,C);if(n!==null){i=n;continue}r.passthrough.push({raw:S,leading:C,position:o++}),i=b+1;continue}if(S.startsWith(`$computed `)){let n=u(e,w,t,r,C);if(n!==null){i=n;continue}r.passthrough.push({raw:S,leading:C,position:o++}),i=b+1;continue}if(S.startsWith(`$resource `)){let n=d(e,w,t,r,C);if(n!==null){i=n;continue}r.passthrough.push({raw:S,leading:C,position:o++}),i=b+1;continue}if(S.startsWith(`$action `)){let n=f(e,w,t,r,C);if(n!==null){i=n;continue}r.passthrough.push({raw:S,leading:C,position:o++}),i=b+1;continue}if(S.startsWith(`$lifecycle.mount(`)||S.startsWith(`$lifecycle.dispose(`)){let t=p(e,w,r,C,o++);if(t!==null){i=t;continue}r.passthrough.push({raw:S,leading:C,position:o++}),i=b+1;continue}if(/^\$lifecycle\.(mount|dispose)\s*:/.test(S)){let t=m(e,w,r,C,o++);if(t!==null){i=t;continue}r.passthrough.push({raw:S,leading:C,position:o++}),i=b+1;continue}if(S.startsWith(`$effect(`)){let t=h(e,w,r,C,o++,n);if(t!==null){i=t;continue}r.passthrough.push({raw:S,leading:C,position:o++}),i=b+1;continue}if(S.startsWith(`$effect.on(`)){let t=_(e,w);r.passthrough.push({raw:e.slice(w,t).trim(),leading:C,position:o++}),i=t;continue}if(/^\$[A-Za-z_][\w.$]*\s*\(/.test(S)){let t=_(e,w);r.passthrough.push({raw:e.slice(w,t).trimEnd(),leading:C,position:o++}),i=t;continue}if(/^\$[A-Za-z_][\w.$-]*\s+[A-Za-z_$]/.test(S)){r.passthrough.push({raw:S,leading:C,position:o++}),i=b+1;continue}let T=v(e,w);if(T!==null){let e=T.name?t.get(T.name):void 0;e?r.props.push({name:T.name,rawType:T.rawType,rawDefault:T.rawDefault,describe:e.describe,expose:c(e),leading:C}):r.plain.push({raw:T.raw,leading:C,name:T.name,rawType:T.rawType,rawDefault:T.rawDefault}),i=T.endIdx;continue}let E=g(e,w),D=e.slice(w,E).replace(/\n+$/,``);r.passthrough.push({raw:D,leading:C,position:o++}),i=E}return a.trim()&&r.passthrough.push({raw:z(a),leading:``,position:o++}),r}function c(e){if(e.exposeRead||e.exposeWrite||e.isAction)return{read:!!e.exposeRead,write:!!e.exposeWrite}}function l(e,t,n,r,i){let a=t+6,o=/^\s*([A-Za-z_$][\w$]*)\s*:/.exec(e.slice(a));if(!o)return null;let s=o[1],l=a+o[0].length,u=l,d=x(e,l,[`=`,`
|
|
12
|
+
`,`;`]),f=e.slice(u,d).trim();l=d;let p;if(e[l]===`=`){l++;let t=l,n=x(e,l,[`
|
|
13
|
+
`,`;`]);p=e.slice(t,n).trim(),l=n}(e[l]===`;`||e[l]===`
|
|
14
|
+
`)&&l++;let m=n.get(s);return r.props.push({name:s,rawType:H(f),rawDefault:p===void 0?void 0:H(p),describe:m?.describe,expose:m?c(m):void 0,leading:i}),l}function u(e,t,n,r,i){let a=t+10,o=/^\s*([A-Za-z_$][\w$]*)\s*=/.exec(e.slice(a));if(!o)return null;let s=o[1],l=a+o[0].length,u=l,d=C(e,l),f=e.slice(u,d).trim();l=d;let p=n.get(s);return r.computed.push({name:s,expr:f,describe:p?.describe,expose:p?c(p):void 0,leading:i}),l}function d(e,t,n,r,i){let a=t+10,o=/^\s*([A-Za-z_$][\w$]*)\s*=/.exec(e.slice(a));if(!o)return null;let s=o[1],l=a+o[0].length,u=l,d=C(e,l),f=e.slice(u,d).trim();l=d;let p=n.get(s);return r.resource.push({name:s,expr:f,describe:p?.describe,expose:p?c(p):void 0,leading:i}),l}function f(e,t,r,a,o){let s=t+8,l=/^\s*([A-Za-z_$][\w$]*)\s*\(/.exec(e.slice(s));if(!l)return null;let u=l[1],d=s+l[0].length-1,f=i(e,d);if(f<0)return null;let p=e.slice(d+1,f).trim(),m=f+1,h,g=m;for(;m<e.length&&e[m]!==`{`&&e[m]!==`
|
|
15
|
+
`;)m++;let _=e.slice(g,m).trim();if(_.startsWith(`:`)&&(h=_.slice(1).trim()),e[m]!==`{`)return null;let v=n(e,m);if(v<0)return null;let y=e.slice(m+1,v);m=v+1;let b=r.get(u);return a.action.push({name:u,args:p,retType:h,body:y,describe:b?.describe,expose:b?c(b):void 0,leading:o}),m}function p(e,t,n,r,a){let o=e.slice(t).trim().startsWith(`$lifecycle.mount(`)?`mount`:`dispose`,s=e.indexOf(`(`,t);if(s<0)return null;let c=i(e,s);if(c<0)return null;let l=e.slice(s+1,c).trim(),u=y(l);n.lifecycle.push({kind:o,body:u?u.body:l,leading:r,position:a,isAsync:u?.isAsync??!1});let d=c+1;return(e[d]===`;`||e[d]===`
|
|
16
|
+
`)&&d++,d}function m(e,t,r,i,a){let o=/^\$lifecycle\.(mount|dispose)\s*:\s*/.exec(e.slice(t));if(!o)return null;let s=o[1],c=t+o[0].length;if(e[c]===`(`||e.slice(c,c+5)===`async`){let t=y(e.slice(c));if(!t)return null;let n=Y(e,c);if(n<0)return null;r.lifecycle.push({kind:s,body:t.body,leading:i,position:a,isAsync:t.isAsync});let o=n;return e[o]===`;`&&o++,e[o]===`
|
|
17
|
+
`&&o++,o}if(e[c]!==`{`)return null;let l=n(e,c);if(l<0)return null;r.lifecycle.push({kind:s,body:e.slice(c+1,l),leading:i,position:a});let u=l+1;return e[u]===`;`&&u++,e[u]===`
|
|
18
|
+
`&&u++,u}function h(e,t,n,r,a,o){let s=e.indexOf(`(`,t);if(s<0)return null;let c=i(e,s);if(c<0)return null;let l=e.slice(s+1,c).trim(),u=y(l);n.effectAnon.push({body:u?u.body:l,leading:r,position:a,isAsync:u?.isAsync??!1});let d=c+1;return(e[d]===`;`||e[d]===`
|
|
19
|
+
`)&&d++,d}function g(e,t){let n=0,i=t;for(;i<e.length;){let t=e[i];if(t===`/`&&e[i+1]===`/`){let t=e.indexOf(`
|
|
20
|
+
`,i);i=t<0?e.length:t;continue}if(t===`/`&&e[i+1]===`*`){let t=e.indexOf(`*/`,i+2);i=t<0?e.length:t+2;continue}if(t===`"`||t===`'`||t==="`"){i=r(e,i);continue}if(t===`(`||t===`{`||t===`[`)n++;else if(t===`)`||t===`}`||t===`]`)n--;else if(t===`
|
|
21
|
+
`&&n<=0)return i+1;i++}return e.length}function _(e,t){let n=e.indexOf(`(`,t);if(n<0){let n=e.indexOf(`
|
|
22
|
+
`,t);return n<0?e.length:n+1}let r=i(e,n);if(r<0){let n=e.indexOf(`
|
|
23
|
+
`,t);return n<0?e.length:n+1}let a=r+1;return(e[a]===`;`||e[a]===`
|
|
24
|
+
`)&&a++,a}function v(e,t){let n=/^([ \t]*)([A-Za-z_$][\w$]*)\s*:/.exec(e.slice(t));if(!n)return null;let r=n[2],i=t+n[0].length,a=i,o=x(e,i,[`=`,`
|
|
25
|
+
`,`;`]),s=e.slice(a,o).trim();i=o;let c;if(e[i]===`=`){i++;let t=i,n=x(e,i,[`
|
|
26
|
+
`,`;`]);c=e.slice(t,n).trim(),i=n}return e[i]===`;`&&i++,e[i]===`
|
|
27
|
+
`&&i++,{name:r,rawType:s,rawDefault:c,raw:e.slice(t,i).replace(/\n+$/,``),endIdx:i}}function y(e){e=e.trim();let t=!1;/^async[\s(]/.test(e)&&(t=!0,e=e.slice(5).trim());let n=b(e);return n?{...n,isAsync:t}:null}function b(e){if(e.startsWith(`(`)){let t=i(e,0);if(t<0)return null;let r=e.slice(1,t),a=t+1;for(;a<e.length&&/\s/.test(e[a]);)a++;let o;if(e[a]===`:`){a++;let t=e.indexOf(`=>`,a);if(t<0)return null;o=e.slice(a,t).trim(),a=t}if(e.slice(a,a+2)!==`=>`)return null;for(a+=2;a<e.length&&/\s/.test(e[a]);)a++;if(e[a]===`{`){let t=n(e,a);return t<0?null:{args:r,body:e.slice(a+1,t),retType:o,isArrow:!0}}return{args:r,body:` return ${e.slice(a).trim()} `,retType:o,isArrow:!0}}let t=/^function\s*(?:[A-Za-z_$][\w$]*)?\s*\(/.exec(e);if(t){let r=t[0].length-1,a=i(e,r);if(a<0)return null;let o=e.slice(r+1,a),s=a+1;for(;s<e.length&&/\s/.test(e[s]);)s++;let c;if(e[s]===`:`){s++;let t=e.indexOf(`{`,s);if(t<0)return null;c=e.slice(s,t).trim(),s=t}if(e[s]!==`{`)return null;let l=n(e,s);return l<0?null:{args:o,body:e.slice(s+1,l),retType:c,isArrow:!1}}return null}function x(e,t,a){let o=t;for(;o<e.length;){let t=e[o];if(t===`/`&&e[o+1]===`/`){let t=e.indexOf(`
|
|
28
|
+
`,o);if(a.includes(`
|
|
29
|
+
`))return t<0?e.length:t;o=t<0?e.length:t+1;continue}if(t===`/`&&e[o+1]===`*`){let t=e.indexOf(`*/`,o+2);o=t<0?e.length:t+2;continue}if(t===`"`||t===`'`||t==="`"){o=r(e,o);continue}if(t===`{`){let t=n(e,o);o=t<0?e.length:t+1;continue}if(t===`(`){let t=i(e,o);o=t<0?e.length:t+1;continue}if(t===`<`){let t=S(e,o);if(t>o){o=t;continue}}if(a.includes(t))return o;o++}return e.length}function S(e,t){if(e[t]!==`<`)return t;let n=0,r=t;for(;r<e.length;){let i=e[r];if(i===`<`)n++;else if(i===`>`){if(n--,n===0)return r+1}else if(i===`
|
|
30
|
+
`)return t;else if(i===`(`||i===`{`)return t;else if(i===`=`||i===`;`)return t;r++}return t}function C(e,t){let n=w(e,e.lastIndexOf(`
|
|
31
|
+
`,t-1)+1),r=t,i=e.indexOf(`
|
|
32
|
+
`,r);if(i<0)return e.length;for(r=i+1;r<e.length;){let t=e.indexOf(`
|
|
33
|
+
`,r),i=t<0?e.length:t,a=e.slice(r,i).trim();if(a===``)return r;let o=w(e,r);if(o>n||o===n&&/^[?:&|+\-*/<>=,.[\](){}]/.test(a)&&!a.startsWith(`//`)){r=t<0?e.length:t+1;continue}return r}return r}function w(e,t){let n=0;for(;t+n<e.length;){let r=e[t+n];if(r===` `||r===` `)n++;else break}return n}function T(e){let t=[],n=e.passthrough.filter(e=>e.raw.startsWith(`import `)),r=e.passthrough.filter(e=>!e.raw.startsWith(`import `));for(let e of n)e.leading.trim()&&t.push(z(e.leading)),t.push(` ${e.raw}`);n.length>0&&t.push(``),e.props.length>0&&E(t,O(e.props));for(let n of e.plain)n.leading.trim()&&t.push(z(n.leading)),t.push(B(n.raw,` `)),t.push(``);D(t),e.computed.length>0&&E(t,ne(e.computed)),e.action.length>0&&E(t,N(e.action)),e.resource.length>0&&E(t,k(e.resource)),e.effectNamed.length>0&&E(t,A(e.effectNamed)),e.lifecycle.length>0&&E(t,F(e.lifecycle)),e.effectAnon.length>0&&E(t,I(e.effectAnon));for(let e of r)e.leading.trim()&&t.push(z(e.leading)),e.raw.includes(`
|
|
34
|
+
`)?t.push(B(e.raw,` `)):t.push(` ${e.raw}`),t.push(``);return D(t),t.join(`
|
|
35
|
+
`)}function E(e,t){e.length>0&&e[e.length-1]!==``&&e.push(``),e.push(t),e.push(``)}function D(e){for(;e.length>0&&e[e.length-1]===``;)e.pop()}function O(e){let t=[],n=e[0]?.leading,r=n?.trim()?n:``,i=[];for(let[t,n]of e.entries())t>0&&n.leading.trim()&&i.push(z(V(n.leading,` `))),i.push(ee(n));return r&&t.push(z(r)),t.push(` $prop: {`),t.push(...i),t.push(` }`),t.join(`
|
|
36
|
+
`)}function ee(e){let t=[];te(e.rawType,e.rawDefault)&&e.rawType&&t.push({k:`type`,v:e.rawType}),e.rawDefault!==void 0&&t.push({k:`default`,v:e.rawDefault}),e.describe&&t.push({k:`describe`,v:R(e.describe)}),e.expose&&t.push({k:`expose`,v:L(e.expose)});let n=`${e.name}: { ${t.map(({k:e,v:t})=>`${e}: ${t}`).join(`, `)} }`,r=` `.repeat(4);if(t.length<=3&&4+n.length+1<=100)return`${r}${n},`;let i=[`${r}${e.name}: {`],a=` `.repeat(6);for(let{k:e,v:n}of t)i.push(`${a}${e}: ${n},`);return i.push(`${r}},`),i.join(`
|
|
37
|
+
`)}function te(e,t){if(!e)return!1;if(t===void 0)return!0;let n=t.trim();return n===`null`||n===`undefined`||n===`[]`||n===`{}`||/^['"`]/.test(n)&&e.includes(`|`)?!0:/[<>{}]/.test(e)?(/^[0-9.+-]/.test(n)||n===`true`||n===`false`||/^['"`]/.test(n),!0):!1}function ne(e){return j(`$computed`,e)}function k(e){return j(`$resource`,e)}function A(e){return j(`$effect`,e)}function j(e,t){let n=t[0]?.leading,r=n?.trim()?n:``,i=[];for(let[e,n]of t.entries())e>0&&n.leading.trim()&&i.push(z(V(n.leading,` `))),i.push(M(n));let a=[];return r&&a.push(z(r)),a.push(` ${e}: {`),a.push(...i),a.push(` }`),a.join(`
|
|
38
|
+
`)}function M(e){let t=` `.repeat(4),n=`${e.isAsync?`async `:``}() => `;if(!e.describe&&!e.expose){if(!e.expr.includes(`
|
|
39
|
+
`)){let r=`${t}${e.name}: ${n}${e.expr},`;if(r.length<=100)return r}let r=W(e.expr,6);return`${t}${e.name}: ${n}${r},`}let r=[];e.describe&&r.push({k:`describe`,v:R(e.describe)}),e.expose&&r.push({k:`expose`,v:L(e.expose)});let i=e.expr.includes(`
|
|
40
|
+
`)?`${n}${W(e.expr,8)}`:`${n}${e.expr}`;r.push({k:`value`,v:i});let a=[`${t}${e.name}: {`],o=` `.repeat(6);for(let{k:e,v:t}of r)a.push(`${o}${e}: ${t},`);return a.push(`${t}},`),a.join(`
|
|
41
|
+
`)}function N(e){let t=e[0]?.leading,n=t?.trim()?t:``,r=[];for(let[t,n]of e.entries())t>0&&n.leading.trim()&&r.push(z(V(n.leading,` `))),r.push(P(n));let i=[];return n&&i.push(z(n)),i.push(` $action: {`),i.push(...r),i.push(` }`),i.join(`
|
|
42
|
+
`)}function P(e){let t=e.retType?`: ${e.retType}`:``,n=`${e.isAsync?`async `:``}(${e.args})${t} => `,r=` `.repeat(4);if(e.describe||e.expose){let t=[];e.describe&&t.push({k:`describe`,v:R(e.describe)}),e.expose&&t.push({k:`expose`,v:L(e.expose)});let i=U(e.body,8);t.push({k:`handler`,v:`${n}{${i}}`});let a=[`${r}${e.name}: {`],o=` `.repeat(6);for(let{k:e,v:n}of t)a.push(`${o}${e}: ${n},`);return a.push(`${r}},`),a.join(`
|
|
43
|
+
`)}let i=U(e.body,6);return`${r}${e.name}: ${n}{${i}},`}function F(e){let t=e[0]?.leading,n=t?.trim()?t:``,r=[],i=` `.repeat(4);for(let[t,n]of e.entries()){t>0&&n.leading.trim()&&r.push(z(V(n.leading,i)));let e=U(n.body,6);r.push(`${i}${n.kind}: ${n.isAsync?`async `:``}() => {${e}},`)}let a=[];return n&&a.push(z(n)),a.push(` $lifecycle: {`),a.push(...r),a.push(` }`),a.join(`
|
|
44
|
+
`)}function I(e){let t=[],n=` `.repeat(2);for(let[r,i]of e.entries()){r>0&&t.push(``),i.leading.trim()&&t.push(z(i.leading));let e=U(i.body,4);t.push(`${n}$effect: ${i.isAsync?`async `:``}() => {${e}}`)}return t.join(`
|
|
45
|
+
`)}function L(e){let t=[];return e.read&&t.push(`read: true`),e.write&&t.push(`write: true`),`{ ${t.join(`, `)} }`}function R(e){return`'${e.replace(/\\/g,`\\\\`).replace(/'/g,`\\'`)}'`}function z(e){return e.replace(/[ \t]+(\n|$)/g,`$1`).replace(/^\n+/,``).replace(/\n+$/g,``)}function B(e,t){let n=e.split(`
|
|
46
|
+
`),r=n[0]??``,i=0;for(;i<r.length&&(r[i]===` `||r[i]===` `);)i++;return i===0?[t+r,...n.slice(1)].join(`
|
|
47
|
+
`):n.map(e=>{if(e.length===0)return e;let n=0;for(;n<e.length&&n<i&&(e[n]===` `||e[n]===` `);)n++;return t+e.slice(n)}).join(`
|
|
48
|
+
`)}function V(e,t){return e.split(`
|
|
49
|
+
`).map(e=>e.length>0?t+e:e).join(`
|
|
50
|
+
`)}function H(e){return e.replace(/\s+/g,` `).trim()}function U(e,t){let n=e.split(`
|
|
51
|
+
`),r=0;for(;r<n.length&&n[r].trim()===``;)r++;let i=n.length-1;for(;i>=0&&n[i].trim()===``;)i--;if(r>i)return``;let a=1/0;for(let e=r;e<=i;e++){let t=n[e];if(t.trim()===``)continue;let r=0;for(;r<t.length&&(t[r]===` `||t[r]===` `);)r++;r<a&&(a=r)}Number.isFinite(a)||(a=0);let o=[``],s=` `.repeat(t);for(let e=r;e<=i;e++){let t=n[e];if(t.trim()===``){o.push(``);continue}o.push((s+t.slice(a)).replace(/[ \t]+$/,``))}return o.push(` `.repeat(Math.max(t-2,0))),o.join(`
|
|
52
|
+
`)}function W(e,t){let n=e.split(`
|
|
53
|
+
`);if(n.length===1)return e;let r=n[0],i=n.slice(1),a=1/0;for(let e of i){if(e.trim()===``)continue;let t=0;for(;t<e.length&&(e[t]===` `||e[t]===` `);)t++;t<a&&(a=t)}Number.isFinite(a)||(a=0);let o=` `.repeat(t);return[r,...i.map(e=>e.trim()===``?``:o+e.slice(a))].join(`
|
|
54
|
+
`)}function G(e,t){let n=t;for(;n>0&&e[n-1]!==`
|
|
55
|
+
`;)n--;if(n>0&&e[n-1]===`
|
|
56
|
+
`){let t=n-1;for(;t>0&&(e[t-1]===` `||e[t-1]===` `);)t--;t>0&&e[t-1]===`
|
|
57
|
+
`&&(n=t)}return n}function K(e,t){let n=t;for(;n<e.length&&(e[n]===` `||e[n]===` `);)n++;for(e[n]===`
|
|
58
|
+
`&&n++;n<e.length;){let t=n;for(;t<e.length&&(e[t]===` `||e[t]===` `);)t++;if(e[t]===`
|
|
59
|
+
`){n=t+1;continue}break}return n}function q(e,t,r,i,a,o){let s=/^\$(prop|computed|action|resource|effect|lifecycle)\s*:\s*\{/.exec(e.slice(t));if(!s)return null;let c=s[1],l=t+s[0].length-1,u=n(e,l);if(u<0)return null;let d=X(e.slice(l+1,u)),f=!1;for(let e of d){let t=re(e.text);if(!t)continue;let n;f?n=e.leading.trim()?e.leading:``:(n=e.leading.trim()?e.leading:a,f=!0),oe(c,t,r,i,n,o)}let p=u+1;return e[p]===`;`&&p++,e[p]===`
|
|
60
|
+
`&&p++,p}function J(e,t,n,r,i){let a=e.indexOf(`:`,t);if(a<0)return null;let o=a+1;for(;o<e.length&&/[ \t]/.test(e[o]);)o++;let s=o;if(e[s]!==`(`&&e.slice(s,s+5)!==`async`)return null;let c=y(e.slice(s));if(!c)return null;let l=Y(e,s);if(l<0)return null;n.effectAnon.push({body:c.body,leading:r,position:i,isAsync:c.isAsync});let u=l;return e[u]===`;`&&u++,e[u]===`
|
|
61
|
+
`&&u++,u}function Y(e,t){if(e.slice(t,t+5)===`async`)for(t+=5;t<e.length&&/[ \t]/.test(e[t]);)t++;if(e[t]!==`(`)return-1;let r=i(e,t);if(r<0)return-1;let a=r+1;for(;a<e.length&&/[ \t]/.test(e[a]);)a++;if(e[a]===`:`){a++;let t=e.indexOf(`=>`,a);if(t<0)return-1;a=t}if(e.slice(a,a+2)!==`=>`)return-1;for(a+=2;a<e.length&&/[ \t\n]/.test(e[a]);)a++;if(e[a]===`{`){let t=n(e,a);return t<0?-1:t+1}let o=e.indexOf(`
|
|
62
|
+
`,a);return o<0?e.length:o}function X(e){let t=[],n=0,i=0,a=0,o=0,s=0;for(;s<e.length;){let c=e[s];if(c===`/`&&e[s+1]===`/`){let t=e.indexOf(`
|
|
63
|
+
`,s);s=t<0?e.length:t;continue}if(c===`/`&&e[s+1]===`*`){let t=e.indexOf(`*/`,s+2);s=t<0?e.length:t+2;continue}if(c===`"`||c===`'`||c==="`"){s=r(e,s);continue}c===`{`?n++:c===`}`?n--:c===`(`?i++:c===`)`?i--:c===`[`?a++:c===`]`?a--:c===`,`&&n===0&&i===0&&a===0&&(Z(t,e.slice(o,s)),o=s+1),s++}return o<e.length&&Z(t,e.slice(o)),t}function Z(e,t){let n=``,r=0;for(;r<t.length;){let e=t.indexOf(`
|
|
64
|
+
`,r),i=e<0?t.length:e,a=t.slice(r,i);if(a.trim()===``||a.trim().startsWith(`//`)||a.trim().startsWith(`/*`)){if(n+=`${a}\n`,r=i+1,e<0)break;continue}break}let i=t.slice(r).trim();i!==``&&e.push({text:i,leading:n})}function re(e){let t=/^([A-Za-z_$][\w$]*)\s*:\s*/.exec(e);if(!t)return null;let r=t[1],i=e.slice(t[0].length).trim();if(i.startsWith(`{`)){let e=n(i,0);return e<0?null:{name:r,rhs:i.slice(1,e).trim(),isWrapped:!0}}return{name:r,rhs:i,isWrapped:!1}}function Q(e){let t={},n=X(e);for(let e of n){let n=/^([A-Za-z_$][\w$]*)\s*:\s*/.exec(e.text);if(!n)continue;let r=n[1],i=e.text.slice(n[0].length).trim();if(r===`describe`)t.describe=ie(i);else if(r===`expose`){let e=ae(i);e&&(t.expose=e)}else r===`value`?t.value=i:r===`handler`?t.handler=i:r==="default"?t.default=i:r===`type`?t.type=i:r===`on`&&(t.on=i)}return t}function ie(e){return e=e.trim(),e.startsWith(`'`)&&e.endsWith(`'`)||e.startsWith(`"`)&&e.endsWith(`"`)?e.slice(1,-1).replace(/\\'/g,`'`).replace(/\\"/g,`"`).replace(/\\\\/g,`\\`):e}function ae(e){if(e=e.trim(),!e.startsWith(`{`))return;let t=n(e,0);if(t<0)return;let r=e.slice(1,t);return{read:/\bread\s*:\s*true\b/.test(r),write:/\bwrite\s*:\s*true\b/.test(r)}}function oe(e,t,n,r,i,a){if(e===`prop`){if(t.isWrapped){let e=Q(t.rhs);r.props.push({name:t.name,rawType:e.type,rawDefault:e.default,describe:e.describe,expose:e.expose,leading:i})}return}if(e===`computed`||e===`resource`){let n,a,o;if(t.isWrapped){let e=Q(t.rhs);n=$(e.value??``),a=e.describe,o=e.expose}else n=$(t.rhs);(e===`computed`?r.computed:r.resource).push({name:t.name,expr:n.expr,describe:a,expose:o,leading:i,isAsync:n.isAsync});return}if(e===`action`){let e,n,a;if(t.isWrapped){let r=Q(t.rhs);e=r.handler??``,n=r.describe,a=r.expose}else e=t.rhs;let o=y(e);if(!o)return;r.action.push({name:t.name,args:o.args,retType:o.retType,body:o.body,describe:n,expose:a,leading:i,isAsync:o.isAsync});return}if(e===`effect`){let e,n,a;if(t.isWrapped){let r=Q(t.rhs);e=$(r.value??``),n=r.describe,a=r.expose}else e=$(t.rhs);r.effectNamed.push({name:t.name,expr:e.expr,describe:n,expose:a,leading:i,isAsync:e.isAsync});return}if(e===`lifecycle`){if(t.name!==`mount`&&t.name!==`dispose`)return;let e=y((t.isWrapped,t.rhs));if(!e)return;r.lifecycle.push({kind:t.name,body:e.body,leading:i,position:a(),isAsync:e.isAsync});return}}function $(e){e=e.trim();let t=/^(async\s+)?\(\s*\)\s*(?::\s*[^=]+)?=>\s*/.exec(e);if(!t)return{expr:e,isAsync:!1};let r=!!t[1],i=e.slice(t[0].length);if(i.startsWith(`{`)){let e=n(i,0);return e<0?{expr:i,isAsync:r}:{expr:i.slice(1,e).trim(),isAsync:r}}return{expr:i.trim(),isAsync:r}}export{e as migrate};
|
|
65
|
+
//# sourceMappingURL=macro-simplification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"macro-simplification.js","names":[],"sources":["../../js/codemods/macro-simplification/migrate.ts"],"sourcesContent":["/**\n * macro-simplification codemod (B6.2)\n *\n * Transforms v1 `.aihu` source into v2 collection-form per\n * `docs/superpowers/specs/2026-05-05-spec-macro-vocabulary-v2.md`.\n *\n * Scope (in-spec macros only): `$prop`, `$computed`, `$action`,\n * `$resource`, `$effect`, `$lifecycle.{mount,dispose}` inside `@state`;\n * `$expose`, `$expose.write`, agent-bare `$action`, `$describe` inside\n * `@agent` (folded into matching `@state` collection entries).\n *\n * Out of scope: `@template`, `@style`, `@route`, `$watch`, `$shared`,\n * `$cookie`, `$server`, `$meta`, `$beforeNavigate`, `$afterNavigate`,\n * `$effect.on`, plain TS imports/decls (passed through verbatim).\n */\n\nexport interface MigrateResult {\n readonly rewritten: string\n readonly warnings: readonly string[]\n}\n\ninterface Sidecar {\n describe?: string\n exposeRead?: boolean\n exposeWrite?: boolean\n isAction?: boolean\n}\n\ninterface PropEntry {\n name: string\n rawType: string | undefined\n rawDefault: string | undefined\n describe: string | undefined\n expose: { read: boolean; write: boolean } | undefined\n leading: string\n}\n\ninterface FunctionishEntry {\n name: string\n args: string\n retType: string | undefined\n body: string\n describe: string | undefined\n expose: { read: boolean; write: boolean } | undefined\n leading: string\n isAsync?: boolean\n}\n\ninterface ValueEntry {\n name: string\n expr: string\n describe: string | undefined\n expose: { read: boolean; write: boolean } | undefined\n leading: string\n isAsync?: boolean\n}\n\ninterface AnonEffect {\n body: string\n leading: string\n position: number\n isAsync?: boolean\n}\n\ninterface LifecycleHook {\n kind: 'mount' | 'dispose'\n body: string\n leading: string\n position: number\n isAsync?: boolean\n}\n\ninterface PlainDecl {\n raw: string\n leading: string\n name: string | undefined\n rawType: string | undefined\n rawDefault: string | undefined\n}\n\ninterface Passthrough {\n raw: string\n leading: string\n position: number\n}\n\nconst INDENT = ' '\n\n// Public entry point\n\nexport function migrate(source: string): MigrateResult {\n const warnings: string[] = []\n\n const stateBlock = findBlock(source, 'state')\n const agentBlock = findBlock(source, 'agent')\n\n // Phase 1 - sidecar from @agent\n const sidecar = new Map<string, Sidecar>()\n const preservedAgentLines: string[] = []\n if (agentBlock) {\n parseAgent(agentBlock.body, sidecar, preservedAgentLines, warnings)\n }\n\n if (!stateBlock) {\n return { rewritten: source, warnings }\n }\n\n // Phase 2 - walk @state, bucket\n const buckets = walkState(stateBlock.body, sidecar, warnings)\n\n // Phase 3 - emit new @state body and (possibly empty) @agent block\n const newStateBody = emitStateBody(buckets)\n const newStateBlock = `@state {\\n${newStateBody}\\n}`\n\n const newAgentBlock =\n preservedAgentLines.length > 0 ? `@agent {\\n${preservedAgentLines.join('\\n')}\\n}` : null\n\n let out = source.slice(0, stateBlock.start) + newStateBlock + source.slice(stateBlock.end)\n\n if (agentBlock) {\n const agentRelocated = findBlock(out, 'agent')\n if (agentRelocated) {\n if (newAgentBlock) {\n out = out.slice(0, agentRelocated.start) + newAgentBlock + out.slice(agentRelocated.end)\n } else {\n const dropStart = expandLeftToLineStart(out, agentRelocated.start)\n const dropEnd = expandRightThroughBlankLines(out, agentRelocated.end)\n out = out.slice(0, dropStart) + out.slice(dropEnd)\n }\n }\n }\n\n // Validate every sidecar name resolves in @state\n const stateNames = new Set<string>([\n ...buckets.props.map((p) => p.name),\n ...buckets.computed.map((c) => c.name),\n ...buckets.action.map((a) => a.name),\n ...buckets.resource.map((r) => r.name),\n ...buckets.effectNamed.map((e) => e.name),\n ...buckets.plain.map((p) => p.name).filter((x): x is string => !!x),\n ])\n for (const [name] of sidecar) {\n if (!stateNames.has(name)) {\n warnings.push(`@agent references '${name}' but no @state declaration found`)\n }\n }\n\n return { rewritten: out, warnings }\n}\n\n// Block location (brace-balanced, string/comment aware)\n\ninterface BlockSpan {\n start: number\n end: number\n bodyStart: number\n bodyEnd: number\n body: string\n}\n\nfunction findBlock(source: string, name: 'state' | 'agent'): BlockSpan | null {\n const re = new RegExp(`(^|\\\\n)([ \\\\t]*)@${name}\\\\s*\\\\{`, 'g')\n const m = re.exec(source)\n if (!m) return null\n const startMatch = m.index + (m[1] === '\\n' ? 1 : 0)\n const openIdx = m.index + m[0].length - 1\n const closeIdx = matchBrace(source, openIdx)\n if (closeIdx < 0) return null\n return {\n start: startMatch,\n end: closeIdx + 1,\n bodyStart: openIdx + 1,\n bodyEnd: closeIdx,\n body: source.slice(openIdx + 1, closeIdx),\n }\n}\n\nfunction matchBrace(s: string, i: number): number {\n if (s[i] !== '{') return -1\n let depth = 0\n let j = i\n while (j < s.length) {\n const c = s[j]\n if (c === '/' && s[j + 1] === '/') {\n const nl = s.indexOf('\\n', j)\n j = nl < 0 ? s.length : nl\n continue\n }\n if (c === '/' && s[j + 1] === '*') {\n const end = s.indexOf('*/', j + 2)\n j = end < 0 ? s.length : end + 2\n continue\n }\n if (c === '\"' || c === \"'\" || c === '`') {\n j = skipString(s, j)\n continue\n }\n if (c === '{') depth++\n else if (c === '}') {\n depth--\n if (depth === 0) return j\n }\n j++\n }\n return -1\n}\n\nfunction skipString(s: string, i: number): number {\n const quote = s[i]!\n let j = i + 1\n while (j < s.length) {\n const c = s[j]\n if (c === '\\\\') {\n j += 2\n continue\n }\n if (quote === '`' && c === '$' && s[j + 1] === '{') {\n const close = matchBrace(s, j + 1)\n j = close < 0 ? s.length : close + 1\n continue\n }\n if (c === quote) return j + 1\n j++\n }\n return s.length\n}\n\nfunction matchParen(s: string, i: number): number {\n if (s[i] !== '(') return -1\n let depth = 0\n let j = i\n while (j < s.length) {\n const c = s[j]\n if (c === '/' && s[j + 1] === '/') {\n const nl = s.indexOf('\\n', j)\n j = nl < 0 ? s.length : nl\n continue\n }\n if (c === '/' && s[j + 1] === '*') {\n const end = s.indexOf('*/', j + 2)\n j = end < 0 ? s.length : end + 2\n continue\n }\n if (c === '\"' || c === \"'\" || c === '`') {\n j = skipString(s, j)\n continue\n }\n if (c === '{') {\n const close = matchBrace(s, j)\n j = close < 0 ? s.length : close + 1\n continue\n }\n if (c === '(') depth++\n else if (c === ')') {\n depth--\n if (depth === 0) return j\n }\n j++\n }\n return -1\n}\n\n// @agent parsing -> sidecar\n\nfunction parseAgent(\n body: string,\n sidecar: Map<string, Sidecar>,\n preservedAgentLines: string[],\n _warnings: string[],\n): void {\n const upsert = (name: string, patch: Partial<Sidecar>) => {\n sidecar.set(name, { ...(sidecar.get(name) ?? {}), ...patch })\n }\n for (const rawLine of body.split('\\n')) {\n const line = rawLine.trim()\n if (line === '' || line.startsWith('//') || line.startsWith('/*') || line.startsWith('*')) {\n continue\n }\n if (line.startsWith('$expose.write ')) {\n const names = parseNameList(line.slice('$expose.write '.length))\n for (const n of names) upsert(n, { exposeRead: true, exposeWrite: true })\n continue\n }\n if (line.startsWith('$expose ')) {\n const names = parseNameList(line.slice('$expose '.length))\n for (const n of names) {\n upsert(n, { exposeRead: true })\n }\n continue\n }\n if (line.startsWith('$action ')) {\n const rest = line.slice('$action '.length).trim()\n const m = /^([A-Za-z_$][\\w$]*)/.exec(rest)\n if (m) upsert(m[1]!, { isAction: true, exposeRead: true, exposeWrite: true })\n continue\n }\n if (line.startsWith('$describe ')) {\n const rest = line.slice('$describe '.length).trim()\n const nameMatch = /^([A-Za-z_$][\\w$]*)\\s+([\"'])([\\s\\S]*)\\2\\s*$/.exec(rest)\n if (nameMatch) {\n upsert(nameMatch[1]!, { describe: nameMatch[3]! })\n }\n continue\n }\n if (line.startsWith('$scope ')) {\n preservedAgentLines.push(` ${line}`)\n continue\n }\n if (line.startsWith('$rate-limit ')) {\n preservedAgentLines.push(` ${line}`)\n }\n }\n}\n\nfunction parseNameList(s: string): string[] {\n return s\n .split(',')\n .map((x) => x.trim())\n .filter((x) => /^[A-Za-z_$][\\w$]*$/.test(x))\n}\n\n// @state walker - produces buckets in source order\n\ninterface Buckets {\n props: PropEntry[]\n computed: ValueEntry[]\n action: FunctionishEntry[]\n resource: ValueEntry[]\n effectNamed: ValueEntry[]\n effectAnon: AnonEffect[]\n lifecycle: LifecycleHook[]\n plain: PlainDecl[]\n passthrough: Passthrough[]\n}\n\nfunction walkState(body: string, sidecar: Map<string, Sidecar>, warnings: string[]): Buckets {\n const buckets: Buckets = {\n props: [],\n computed: [],\n action: [],\n resource: [],\n effectNamed: [],\n effectAnon: [],\n lifecycle: [],\n plain: [],\n passthrough: [],\n }\n\n let i = 0\n while (i < body.length && (body[i] === '\\n' || body[i] === '\\r')) i++\n\n let leadingBuf = ''\n let position = 0\n\n const consumeWS = () => {\n while (i < body.length) {\n const lineEnd = body.indexOf('\\n', i)\n const end = lineEnd < 0 ? body.length : lineEnd\n const line = body.slice(i, end)\n const trimmed = line.trim()\n if (trimmed === '') {\n leadingBuf += `${line}\\n`\n i = end + 1\n continue\n }\n if (trimmed.startsWith('//')) {\n leadingBuf += `${line}\\n`\n i = end + 1\n continue\n }\n if (trimmed.startsWith('/*')) {\n const close = body.indexOf('*/', i)\n if (close < 0) {\n leadingBuf += body.slice(i)\n i = body.length\n return\n }\n const commentEnd = body.indexOf('\\n', close)\n const realEnd = commentEnd < 0 ? body.length : commentEnd + 1\n leadingBuf += body.slice(i, realEnd)\n i = realEnd\n continue\n }\n return\n }\n }\n\n while (i < body.length) {\n consumeWS()\n if (i >= body.length) break\n const lineStart = i\n const lineEnd = body.indexOf('\\n', i)\n const lineEndIdx = lineEnd < 0 ? body.length : lineEnd\n const lineText = body.slice(lineStart, lineEndIdx)\n const trimmed = lineText.trim()\n const leading = leadingBuf\n leadingBuf = ''\n // Position where trimmed content begins (skipping leading whitespace).\n const trimStart = lineStart + (lineText.length - lineText.trimStart().length)\n\n if (trimmed.startsWith('import ')) {\n // A multi-line `import { … } from '…'` must be consumed as ONE statement.\n // If only the opener line is taken, the member lines and the `} from '…'`\n // closing bucket as separate passthroughs and drift out of the import\n // group at emit time (imports are hoisted, the orphaned members are not) —\n // the #502 import-scrambling defect. A statement is complete once a line\n // carries the source specifier (`from '…'`) or the opener is a bare\n // side-effect import (`import '…'`).\n let stmtEndIdx = lineEndIdx\n let stmt = lineText\n const carriesSource = /\\bfrom\\s*['\"]/.test(lineText) || /^import\\s+['\"]/.test(trimmed)\n if (!carriesSource) {\n let j = lineEndIdx + 1\n while (j < body.length) {\n const nl = body.indexOf('\\n', j)\n const e = nl < 0 ? body.length : nl\n const l = body.slice(j, e)\n stmt += `\\n${l}`\n stmtEndIdx = e\n j = e + 1\n if (/\\bfrom\\s*['\"]/.test(l)) break\n }\n }\n buckets.passthrough.push({ raw: stmt.trim(), leading, position: position++ })\n i = stmtEndIdx + 1\n continue\n }\n\n // v2 collection-form passthrough (idempotency path): if the source already\n // uses `$<macro>: {` collection-form, re-parse the inner entries into the\n // same buckets so emit is byte-identical on re-run.\n {\n const v2 = tryParseV2Collection(body, trimStart, sidecar, buckets, leading, () => position++)\n if (v2 !== null) {\n i = v2\n continue\n }\n }\n\n // v2 anonymous effect form: `$effect: () => { ... }` or `$effect: () => expr`.\n if (/^\\$effect\\s*:\\s*(?:\\(|async\\b)/.test(trimmed)) {\n const handled = tryParseV2AnonEffect(body, trimStart, buckets, leading, position++)\n if (handled !== null) {\n i = handled\n continue\n }\n }\n\n if (trimmed.startsWith('$prop ')) {\n const handled = handleProp(body, trimStart, sidecar, buckets, leading)\n if (handled !== null) {\n i = handled\n continue\n }\n buckets.passthrough.push({ raw: trimmed, leading, position: position++ })\n i = lineEndIdx + 1\n continue\n }\n\n if (trimmed.startsWith('$computed ')) {\n const handled = handleComputed(body, trimStart, sidecar, buckets, leading)\n if (handled !== null) {\n i = handled\n continue\n }\n buckets.passthrough.push({ raw: trimmed, leading, position: position++ })\n i = lineEndIdx + 1\n continue\n }\n\n if (trimmed.startsWith('$resource ')) {\n const handled = handleResource(body, trimStart, sidecar, buckets, leading)\n if (handled !== null) {\n i = handled\n continue\n }\n buckets.passthrough.push({ raw: trimmed, leading, position: position++ })\n i = lineEndIdx + 1\n continue\n }\n\n if (trimmed.startsWith('$action ')) {\n const handled = handleAction(body, trimStart, sidecar, buckets, leading)\n if (handled !== null) {\n i = handled\n continue\n }\n buckets.passthrough.push({ raw: trimmed, leading, position: position++ })\n i = lineEndIdx + 1\n continue\n }\n\n if (trimmed.startsWith('$lifecycle.mount(') || trimmed.startsWith('$lifecycle.dispose(')) {\n const handled = handleLifecycle(body, trimStart, buckets, leading, position++)\n if (handled !== null) {\n i = handled\n continue\n }\n buckets.passthrough.push({ raw: trimmed, leading, position: position++ })\n i = lineEndIdx + 1\n continue\n }\n\n // Defect fix (#425 a): colon form — `$lifecycle.mount: { ... }` (bare\n // block) and `$lifecycle.mount: () => { ... }` (arrow). Previously fell\n // through to the bare-`$macro <ident>` passthrough, which consumed only\n // the header line and left the orphaned body braces to mangle the file.\n if (/^\\$lifecycle\\.(mount|dispose)\\s*:/.test(trimmed)) {\n const handled = handleLifecycleColon(body, trimStart, buckets, leading, position++)\n if (handled !== null) {\n i = handled\n continue\n }\n buckets.passthrough.push({ raw: trimmed, leading, position: position++ })\n i = lineEndIdx + 1\n continue\n }\n\n if (trimmed.startsWith('$effect(')) {\n const handled = handleEffectAnon(body, trimStart, buckets, leading, position++, warnings)\n if (handled !== null) {\n i = handled\n continue\n }\n buckets.passthrough.push({ raw: trimmed, leading, position: position++ })\n i = lineEndIdx + 1\n continue\n }\n\n if (trimmed.startsWith('$effect.on(')) {\n const handled = consumePassthroughCall(body, trimStart)\n buckets.passthrough.push({\n raw: body.slice(trimStart, handled).trim(),\n leading,\n position: position++,\n })\n i = handled\n continue\n }\n\n // Any other `$macro(...)` invocation at top level: pass through preserving\n // the multi-line callback body. Covers `$afterNavigate`, `$beforeNavigate`,\n // `$watch`, etc. — out of v2 redesign scope per spec §1.2.\n if (/^\\$[A-Za-z_][\\w.$]*\\s*\\(/.test(trimmed)) {\n const handled = consumePassthroughCall(body, trimStart)\n buckets.passthrough.push({\n raw: body.slice(trimStart, handled).trimEnd(),\n leading,\n position: position++,\n })\n i = handled\n continue\n }\n\n // Bare `$macro <ident>` form (e.g., `$route currentRoute`, `$shared foo`).\n if (/^\\$[A-Za-z_][\\w.$-]*\\s+[A-Za-z_$]/.test(trimmed)) {\n buckets.passthrough.push({ raw: trimmed, leading, position: position++ })\n i = lineEndIdx + 1\n continue\n }\n\n const plain = tryParsePlainDecl(body, trimStart)\n if (plain !== null) {\n const sc = plain.name ? sidecar.get(plain.name) : undefined\n if (sc) {\n buckets.props.push({\n name: plain.name!,\n rawType: plain.rawType,\n rawDefault: plain.rawDefault,\n describe: sc.describe,\n expose: sidecarToExpose(sc),\n leading,\n })\n } else {\n buckets.plain.push({\n raw: plain.raw,\n leading,\n name: plain.name,\n rawType: plain.rawType,\n rawDefault: plain.rawDefault,\n })\n }\n i = plain.endIdx\n continue\n }\n\n // Statement-aware passthrough (#425): consume the WHOLE statement —\n // through any open `(`/`{`/`[` — not just the first line. The previous\n // line-by-line fallback shredded multi-line `const x = call(\\n…\\n)` and\n // `function f() { … }` statements into one passthrough entry per line,\n // scrambling the emitted @state body.\n const stmtEnd = consumeBalancedStatement(body, trimStart)\n const raw = body.slice(trimStart, stmtEnd).replace(/\\n+$/, '')\n buckets.passthrough.push({ raw, leading, position: position++ })\n i = stmtEnd\n }\n\n // Trailing comments at the end of @state (accumulated into leadingBuf with\n // no following statement to attach to) were silently discarded (#425).\n // Preserve them as a final passthrough entry.\n if (leadingBuf.trim()) {\n buckets.passthrough.push({ raw: rstrip(leadingBuf), leading: '', position: position++ })\n }\n\n return buckets\n}\n\nfunction sidecarToExpose(sc: Sidecar): { read: boolean; write: boolean } | undefined {\n if (!sc.exposeRead && !sc.exposeWrite && !sc.isAction) return undefined\n return { read: !!sc.exposeRead, write: !!sc.exposeWrite }\n}\n\n// handlers - each returns the index just past the consumed statement\n\nfunction handleProp(\n body: string,\n start: number,\n sidecar: Map<string, Sidecar>,\n buckets: Buckets,\n leading: string,\n): number | null {\n const after = start + '$prop '.length\n const nameMatch = /^\\s*([A-Za-z_$][\\w$]*)\\s*:/.exec(body.slice(after))\n if (!nameMatch) return null\n const name = nameMatch[1]!\n let cursor = after + nameMatch[0].length\n const typeStart = cursor\n const typeEnd = scanUntilTopLevel(body, cursor, ['=', '\\n', ';'])\n const rawType = body.slice(typeStart, typeEnd).trim()\n cursor = typeEnd\n let rawDefault: string | undefined\n if (body[cursor] === '=') {\n cursor++\n const defStart = cursor\n const defEnd = scanUntilTopLevel(body, cursor, ['\\n', ';'])\n rawDefault = body.slice(defStart, defEnd).trim()\n cursor = defEnd\n }\n if (body[cursor] === ';' || body[cursor] === '\\n') cursor++\n\n const sc = sidecar.get(name)\n buckets.props.push({\n name,\n rawType: flattenWhitespace(rawType),\n rawDefault: rawDefault !== undefined ? flattenWhitespace(rawDefault) : undefined,\n describe: sc?.describe,\n expose: sc ? sidecarToExpose(sc) : undefined,\n leading,\n })\n return cursor\n}\n\nfunction handleComputed(\n body: string,\n start: number,\n sidecar: Map<string, Sidecar>,\n buckets: Buckets,\n leading: string,\n): number | null {\n const after = start + '$computed '.length\n const nameMatch = /^\\s*([A-Za-z_$][\\w$]*)\\s*=/.exec(body.slice(after))\n if (!nameMatch) return null\n const name = nameMatch[1]!\n let cursor = after + nameMatch[0].length\n const exprStart = cursor\n const exprEnd = scanComputedOrResourceExpr(body, cursor)\n const expr = body.slice(exprStart, exprEnd).trim()\n cursor = exprEnd\n\n const sc = sidecar.get(name)\n buckets.computed.push({\n name,\n expr,\n describe: sc?.describe,\n expose: sc ? sidecarToExpose(sc) : undefined,\n leading,\n })\n return cursor\n}\n\nfunction handleResource(\n body: string,\n start: number,\n sidecar: Map<string, Sidecar>,\n buckets: Buckets,\n leading: string,\n): number | null {\n const after = start + '$resource '.length\n const nameMatch = /^\\s*([A-Za-z_$][\\w$]*)\\s*=/.exec(body.slice(after))\n if (!nameMatch) return null\n const name = nameMatch[1]!\n let cursor = after + nameMatch[0].length\n const exprStart = cursor\n const exprEnd = scanComputedOrResourceExpr(body, cursor)\n const expr = body.slice(exprStart, exprEnd).trim()\n cursor = exprEnd\n\n const sc = sidecar.get(name)\n buckets.resource.push({\n name,\n expr,\n describe: sc?.describe,\n expose: sc ? sidecarToExpose(sc) : undefined,\n leading,\n })\n return cursor\n}\n\nfunction handleAction(\n body: string,\n start: number,\n sidecar: Map<string, Sidecar>,\n buckets: Buckets,\n leading: string,\n): number | null {\n const after = start + '$action '.length\n const nameMatch = /^\\s*([A-Za-z_$][\\w$]*)\\s*\\(/.exec(body.slice(after))\n if (!nameMatch) return null\n const name = nameMatch[1]!\n const parenIdx = after + nameMatch[0].length - 1\n const parenClose = matchParen(body, parenIdx)\n if (parenClose < 0) return null\n const args = body.slice(parenIdx + 1, parenClose).trim()\n let cursor = parenClose + 1\n let retType: string | undefined\n const retStart = cursor\n while (cursor < body.length && body[cursor] !== '{') {\n if (body[cursor] === '\\n') break\n cursor++\n }\n const between = body.slice(retStart, cursor).trim()\n if (between.startsWith(':')) {\n retType = between.slice(1).trim()\n }\n if (body[cursor] !== '{') return null\n const braceClose = matchBrace(body, cursor)\n if (braceClose < 0) return null\n const bodySrc = body.slice(cursor + 1, braceClose)\n cursor = braceClose + 1\n\n const sc = sidecar.get(name)\n buckets.action.push({\n name,\n args,\n retType,\n body: bodySrc,\n describe: sc?.describe,\n expose: sc ? sidecarToExpose(sc) : undefined,\n leading,\n })\n return cursor\n}\n\nfunction handleLifecycle(\n body: string,\n start: number,\n buckets: Buckets,\n leading: string,\n position: number,\n): number | null {\n const trimmedStart = body.slice(start).trim()\n const kind = trimmedStart.startsWith('$lifecycle.mount(') ? 'mount' : 'dispose'\n const parenIdx = body.indexOf('(', start)\n if (parenIdx < 0) return null\n const parenClose = matchParen(body, parenIdx)\n if (parenClose < 0) return null\n const cb = body.slice(parenIdx + 1, parenClose).trim()\n const fn = parseArrowOrFunctionExpr(cb)\n buckets.lifecycle.push({\n kind,\n body: fn ? fn.body : cb,\n leading,\n position,\n isAsync: fn?.isAsync ?? false,\n })\n let cursor = parenClose + 1\n if (body[cursor] === ';' || body[cursor] === '\\n') cursor++\n return cursor\n}\n\n// Colon form (#425 defect a): `$lifecycle.mount: { ... }` or\n// `$lifecycle.mount: () => { ... }` (arrow, optionally async). Returns the\n// index just past the consumed statement, or null when the form is not\n// recognized (caller falls back to passthrough).\nfunction handleLifecycleColon(\n body: string,\n start: number,\n buckets: Buckets,\n leading: string,\n position: number,\n): number | null {\n const m = /^\\$lifecycle\\.(mount|dispose)\\s*:\\s*/.exec(body.slice(start))\n if (!m) return null\n const kind = m[1] as 'mount' | 'dispose'\n const cursor = start + m[0].length\n if (body[cursor] === '(' || body.slice(cursor, cursor + 5) === 'async') {\n // Arrow form: `() => { ... }` / `async () => { ... }`.\n const fn = parseArrowOrFunctionExpr(body.slice(cursor))\n if (!fn) return null\n const end = scanArrowExprEnd(body, cursor)\n if (end < 0) return null\n buckets.lifecycle.push({ kind, body: fn.body, leading, position, isAsync: fn.isAsync })\n let c = end\n if (body[c] === ';') c++\n if (body[c] === '\\n') c++\n return c\n }\n if (body[cursor] !== '{') return null\n // Bare-block form: `$lifecycle.mount: { ... }`.\n const close = matchBrace(body, cursor)\n if (close < 0) return null\n buckets.lifecycle.push({\n kind,\n body: body.slice(cursor + 1, close),\n leading,\n position,\n })\n let c = close + 1\n if (body[c] === ';') c++\n if (body[c] === '\\n') c++\n return c\n}\n\nfunction handleEffectAnon(\n body: string,\n start: number,\n buckets: Buckets,\n leading: string,\n position: number,\n _warnings: string[],\n): number | null {\n const parenIdx = body.indexOf('(', start)\n if (parenIdx < 0) return null\n const parenClose = matchParen(body, parenIdx)\n if (parenClose < 0) return null\n const cb = body.slice(parenIdx + 1, parenClose).trim()\n const fn = parseArrowOrFunctionExpr(cb)\n buckets.effectAnon.push({\n body: fn ? fn.body : cb,\n leading,\n position,\n isAsync: fn?.isAsync ?? false,\n })\n let cursor = parenClose + 1\n if (body[cursor] === ';' || body[cursor] === '\\n') cursor++\n return cursor\n}\n\n// Consume a complete statement starting at `start`: scan forward (string/\n// comment aware) and stop at the first newline where all bracket depths are\n// balanced. Returns the index just past that newline (or body.length).\nfunction consumeBalancedStatement(body: string, start: number): number {\n let depth = 0\n let j = start\n while (j < body.length) {\n const c = body[j]!\n if (c === '/' && body[j + 1] === '/') {\n const nl = body.indexOf('\\n', j)\n j = nl < 0 ? body.length : nl\n continue\n }\n if (c === '/' && body[j + 1] === '*') {\n const end = body.indexOf('*/', j + 2)\n j = end < 0 ? body.length : end + 2\n continue\n }\n if (c === '\"' || c === \"'\" || c === '`') {\n j = skipString(body, j)\n continue\n }\n if (c === '(' || c === '{' || c === '[') depth++\n else if (c === ')' || c === '}' || c === ']') depth--\n else if (c === '\\n' && depth <= 0) return j + 1\n j++\n }\n return body.length\n}\n\nfunction consumePassthroughCall(body: string, start: number): number {\n const parenIdx = body.indexOf('(', start)\n if (parenIdx < 0) {\n const nl = body.indexOf('\\n', start)\n return nl < 0 ? body.length : nl + 1\n }\n const close = matchParen(body, parenIdx)\n if (close < 0) {\n const nl = body.indexOf('\\n', start)\n return nl < 0 ? body.length : nl + 1\n }\n let cursor = close + 1\n if (body[cursor] === ';' || body[cursor] === '\\n') cursor++\n return cursor\n}\n\ninterface PlainDeclParse {\n name: string | undefined\n rawType: string | undefined\n rawDefault: string | undefined\n raw: string\n endIdx: number\n}\n\nfunction tryParsePlainDecl(body: string, start: number): PlainDeclParse | null {\n const m = /^([ \\t]*)([A-Za-z_$][\\w$]*)\\s*:/.exec(body.slice(start))\n if (!m) return null\n const name = m[2]!\n let cursor = start + m[0].length\n const typeStart = cursor\n const typeEnd = scanUntilTopLevel(body, cursor, ['=', '\\n', ';'])\n const rawType = body.slice(typeStart, typeEnd).trim()\n cursor = typeEnd\n let rawDefault: string | undefined\n if (body[cursor] === '=') {\n cursor++\n const defStart = cursor\n const defEnd = scanUntilTopLevel(body, cursor, ['\\n', ';'])\n rawDefault = body.slice(defStart, defEnd).trim()\n cursor = defEnd\n }\n if (body[cursor] === ';') cursor++\n if (body[cursor] === '\\n') cursor++\n return {\n name,\n rawType,\n rawDefault,\n raw: body.slice(start, cursor).replace(/\\n+$/, ''),\n endIdx: cursor,\n }\n}\n\ninterface ParsedFn {\n args: string\n body: string\n retType: string | undefined\n isArrow: boolean\n isAsync: boolean\n}\n\nfunction parseArrowOrFunctionExpr(s: string): ParsedFn | null {\n s = s.trim()\n // #425 — `async` arrows/functions were unrecognized, which silently DROPPED\n // async entries on the v2 idempotency re-parse path. Strip the prefix here\n // and carry the flag so emit can restore it.\n let isAsync = false\n if (/^async[\\s(]/.test(s)) {\n isAsync = true\n s = s.slice(5).trim()\n }\n const inner = parseArrowOrFunctionExprInner(s)\n if (!inner) return null\n return { ...inner, isAsync }\n}\n\nfunction parseArrowOrFunctionExprInner(s: string): Omit<ParsedFn, 'isAsync'> | null {\n if (s.startsWith('(')) {\n const closeIdx = matchParen(s, 0)\n if (closeIdx < 0) return null\n const args = s.slice(1, closeIdx)\n let cur = closeIdx + 1\n while (cur < s.length && /\\s/.test(s[cur]!)) cur++\n let retType: string | undefined\n if (s[cur] === ':') {\n cur++\n const arrowAt = s.indexOf('=>', cur)\n if (arrowAt < 0) return null\n retType = s.slice(cur, arrowAt).trim()\n cur = arrowAt\n }\n if (s.slice(cur, cur + 2) !== '=>') return null\n cur += 2\n while (cur < s.length && /\\s/.test(s[cur]!)) cur++\n if (s[cur] === '{') {\n const close = matchBrace(s, cur)\n if (close < 0) return null\n return {\n args,\n body: s.slice(cur + 1, close),\n retType,\n isArrow: true,\n }\n }\n return { args, body: ` return ${s.slice(cur).trim()} `, retType, isArrow: true }\n }\n const fnMatch = /^function\\s*(?:[A-Za-z_$][\\w$]*)?\\s*\\(/.exec(s)\n if (fnMatch) {\n const parenIdx = fnMatch[0].length - 1\n const parenClose = matchParen(s, parenIdx)\n if (parenClose < 0) return null\n const args = s.slice(parenIdx + 1, parenClose)\n let cur = parenClose + 1\n while (cur < s.length && /\\s/.test(s[cur]!)) cur++\n let retType: string | undefined\n if (s[cur] === ':') {\n cur++\n const braceAt = s.indexOf('{', cur)\n if (braceAt < 0) return null\n retType = s.slice(cur, braceAt).trim()\n cur = braceAt\n }\n if (s[cur] !== '{') return null\n const close = matchBrace(s, cur)\n if (close < 0) return null\n return {\n args,\n body: s.slice(cur + 1, close),\n retType,\n isArrow: false,\n }\n }\n return null\n}\n\nfunction scanUntilTopLevel(s: string, start: number, stops: readonly string[]): number {\n let j = start\n while (j < s.length) {\n const c = s[j]!\n if (c === '/' && s[j + 1] === '/') {\n const nl = s.indexOf('\\n', j)\n if (stops.includes('\\n')) return nl < 0 ? s.length : nl\n j = nl < 0 ? s.length : nl + 1\n continue\n }\n if (c === '/' && s[j + 1] === '*') {\n const end = s.indexOf('*/', j + 2)\n j = end < 0 ? s.length : end + 2\n continue\n }\n if (c === '\"' || c === \"'\" || c === '`') {\n j = skipString(s, j)\n continue\n }\n if (c === '{') {\n const close = matchBrace(s, j)\n j = close < 0 ? s.length : close + 1\n continue\n }\n if (c === '(') {\n const close = matchParen(s, j)\n j = close < 0 ? s.length : close + 1\n continue\n }\n if (c === '<') {\n const close = scanGeneric(s, j)\n if (close > j) {\n j = close\n continue\n }\n }\n if (stops.includes(c)) return j\n j++\n }\n return s.length\n}\n\nfunction scanGeneric(s: string, start: number): number {\n if (s[start] !== '<') return start\n let depth = 0\n let j = start\n while (j < s.length) {\n const c = s[j]!\n if (c === '<') depth++\n else if (c === '>') {\n depth--\n if (depth === 0) return j + 1\n } else if (c === '\\n') {\n return start\n } else if (c === '(' || c === '{') {\n return start\n } else if (c === '=' || c === ';') {\n return start\n }\n j++\n }\n return start\n}\n\nfunction scanComputedOrResourceExpr(body: string, start: number): number {\n const lineStart = body.lastIndexOf('\\n', start - 1) + 1\n const startLineIndent = countIndent(body, lineStart)\n let j = start\n const lineEnd = body.indexOf('\\n', j)\n if (lineEnd < 0) return body.length\n j = lineEnd + 1\n while (j < body.length) {\n const nextLineEnd = body.indexOf('\\n', j)\n const lineEndIdx = nextLineEnd < 0 ? body.length : nextLineEnd\n const line = body.slice(j, lineEndIdx)\n const trimmed = line.trim()\n if (trimmed === '') {\n return j\n }\n const indent = countIndent(body, j)\n if (\n indent > startLineIndent ||\n (indent === startLineIndent &&\n /^[?:&|+\\-*/<>=,.[\\](){}]/.test(trimmed) &&\n !trimmed.startsWith('//'))\n ) {\n j = nextLineEnd < 0 ? body.length : nextLineEnd + 1\n continue\n }\n return j\n }\n return j\n}\n\nfunction countIndent(body: string, lineStart: number): number {\n let n = 0\n while (lineStart + n < body.length) {\n const c = body[lineStart + n]\n if (c === ' ' || c === '\\t') n++\n else break\n }\n return n\n}\n\n// Emit\n\nfunction emitStateBody(buckets: Buckets): string {\n const out: string[] = []\n const imports = buckets.passthrough.filter((p) => p.raw.startsWith('import '))\n const otherPassthrough = buckets.passthrough.filter((p) => !p.raw.startsWith('import '))\n\n for (const imp of imports) {\n if (imp.leading.trim()) out.push(rstrip(imp.leading))\n out.push(`${INDENT}${imp.raw}`)\n }\n if (imports.length > 0) out.push('')\n\n if (buckets.props.length > 0) {\n pushBlock(out, emitProps(buckets.props))\n }\n\n for (const p of buckets.plain) {\n if (p.leading.trim()) out.push(rstrip(p.leading))\n // raw already includes the original leading indent of the outer line.\n // Don't re-indent — but normalize so the outer line is at INDENT (2 spaces).\n out.push(rebaseLeadingIndent(p.raw, INDENT))\n out.push('')\n }\n trimTrailingBlanks(out)\n\n if (buckets.computed.length > 0) {\n pushBlock(out, emitComputed(buckets.computed))\n }\n\n if (buckets.action.length > 0) {\n pushBlock(out, emitAction(buckets.action))\n }\n\n if (buckets.resource.length > 0) {\n pushBlock(out, emitResource(buckets.resource))\n }\n\n if (buckets.effectNamed.length > 0) {\n pushBlock(out, emitEffectNamed(buckets.effectNamed))\n }\n\n if (buckets.lifecycle.length > 0) {\n pushBlock(out, emitLifecycle(buckets.lifecycle))\n }\n\n if (buckets.effectAnon.length > 0) {\n pushBlock(out, emitEffectAnon(buckets.effectAnon))\n }\n\n for (const p of otherPassthrough) {\n if (p.leading.trim()) out.push(rstrip(p.leading))\n if (p.raw.includes('\\n')) {\n out.push(rebaseLeadingIndent(p.raw, INDENT))\n } else {\n out.push(`${INDENT}${p.raw}`)\n }\n out.push('')\n }\n trimTrailingBlanks(out)\n\n return out.join('\\n')\n}\n\nfunction pushBlock(out: string[], block: string): void {\n if (out.length > 0 && out[out.length - 1] !== '') out.push('')\n out.push(block)\n out.push('')\n}\n\nfunction trimTrailingBlanks(out: string[]): void {\n while (out.length > 0 && out[out.length - 1] === '') out.pop()\n}\n\nfunction emitProps(entries: PropEntry[]): string {\n const lines: string[] = []\n const firstLeading = entries[0]?.leading\n const headerLeading = firstLeading?.trim() ? firstLeading : ''\n const inner: string[] = []\n for (const [idx, e] of entries.entries()) {\n if (idx > 0 && e.leading.trim()) {\n inner.push(rstrip(indentBlock(e.leading, `${INDENT}${INDENT}`)))\n }\n inner.push(formatPropEntry(e))\n }\n if (headerLeading) lines.push(rstrip(headerLeading))\n lines.push(`${INDENT}$prop: {`)\n lines.push(...inner)\n lines.push(`${INDENT}}`)\n return lines.join('\\n')\n}\n\nfunction formatPropEntry(e: PropEntry): string {\n const keys: { k: string; v: string }[] = []\n const needsType = shouldKeepType(e.rawType, e.rawDefault)\n if (needsType && e.rawType) keys.push({ k: 'type', v: e.rawType })\n if (e.rawDefault !== undefined) keys.push({ k: 'default', v: e.rawDefault })\n if (e.describe) keys.push({ k: 'describe', v: quoteSingle(e.describe) })\n if (e.expose) keys.push({ k: 'expose', v: formatExpose(e.expose) })\n\n const inline = `${e.name}: { ${keys.map(({ k, v }) => `${k}: ${v}`).join(', ')} }`\n const baseIndent = INDENT.length * 2\n const linePrefix = ' '.repeat(baseIndent)\n if (keys.length <= 3 && baseIndent + inline.length + 1 <= 100) {\n return `${linePrefix}${inline},`\n }\n const lines: string[] = [`${linePrefix}${e.name}: {`]\n const inner = ' '.repeat(baseIndent + INDENT.length)\n for (const { k, v } of keys) {\n lines.push(`${inner}${k}: ${v},`)\n }\n lines.push(`${linePrefix}},`)\n return lines.join('\\n')\n}\n\nfunction shouldKeepType(rawType: string | undefined, rawDefault: string | undefined): boolean {\n if (!rawType) return false\n if (rawDefault === undefined) return true\n const trimmed = rawDefault.trim()\n if (trimmed === 'null' || trimmed === 'undefined') return true\n if (trimmed === '[]') return true\n if (trimmed === '{}') return true\n if (/^['\"`]/.test(trimmed) && rawType.includes('|')) return true\n if (/[<>{}]/.test(rawType)) {\n if (/^[0-9.+-]/.test(trimmed) || trimmed === 'true' || trimmed === 'false') return true\n if (/^['\"`]/.test(trimmed)) return true\n return true\n }\n return false\n}\n\nfunction emitComputed(entries: ValueEntry[]): string {\n return emitValueCollection('$computed', entries)\n}\n\nfunction emitResource(entries: ValueEntry[]): string {\n return emitValueCollection('$resource', entries)\n}\n\nfunction emitEffectNamed(entries: ValueEntry[]): string {\n return emitValueCollection('$effect', entries)\n}\n\nfunction emitValueCollection(macro: string, entries: ValueEntry[]): string {\n const firstLeading = entries[0]?.leading\n const headerLeading = firstLeading?.trim() ? firstLeading : ''\n const inner: string[] = []\n for (const [idx, e] of entries.entries()) {\n if (idx > 0 && e.leading.trim()) {\n inner.push(rstrip(indentBlock(e.leading, `${INDENT}${INDENT}`)))\n }\n inner.push(formatValueEntry(e))\n }\n const lines: string[] = []\n if (headerLeading) lines.push(rstrip(headerLeading))\n lines.push(`${INDENT}${macro}: {`)\n lines.push(...inner)\n lines.push(`${INDENT}}`)\n return lines.join('\\n')\n}\n\nfunction formatValueEntry(e: ValueEntry): string {\n const baseIndent = INDENT.length * 2\n const linePrefix = ' '.repeat(baseIndent)\n const thunkPrefix = `${e.isAsync ? 'async ' : ''}() => `\n if (!e.describe && !e.expose) {\n if (!e.expr.includes('\\n')) {\n const inline = `${linePrefix}${e.name}: ${thunkPrefix}${e.expr},`\n if (inline.length <= 100) return inline\n }\n const indented = reindentExpr(e.expr, baseIndent + INDENT.length)\n return `${linePrefix}${e.name}: ${thunkPrefix}${indented},`\n }\n const keys: { k: string; v: string }[] = []\n if (e.describe) keys.push({ k: 'describe', v: quoteSingle(e.describe) })\n if (e.expose) keys.push({ k: 'expose', v: formatExpose(e.expose) })\n const valueExpr = e.expr.includes('\\n')\n ? `${thunkPrefix}${reindentExpr(e.expr, baseIndent + INDENT.length * 2)}`\n : `${thunkPrefix}${e.expr}`\n keys.push({ k: 'value', v: valueExpr })\n\n const lines: string[] = [`${linePrefix}${e.name}: {`]\n const inner = ' '.repeat(baseIndent + INDENT.length)\n for (const { k, v } of keys) {\n lines.push(`${inner}${k}: ${v},`)\n }\n lines.push(`${linePrefix}},`)\n return lines.join('\\n')\n}\n\nfunction emitAction(entries: FunctionishEntry[]): string {\n const firstLeading = entries[0]?.leading\n const headerLeading = firstLeading?.trim() ? firstLeading : ''\n const inner: string[] = []\n for (const [idx, e] of entries.entries()) {\n if (idx > 0 && e.leading.trim()) {\n inner.push(rstrip(indentBlock(e.leading, `${INDENT}${INDENT}`)))\n }\n inner.push(formatActionEntry(e))\n }\n const lines: string[] = []\n if (headerLeading) lines.push(rstrip(headerLeading))\n lines.push(`${INDENT}$action: {`)\n lines.push(...inner)\n lines.push(`${INDENT}}`)\n return lines.join('\\n')\n}\n\nfunction formatActionEntry(e: FunctionishEntry): string {\n const ret = e.retType ? `: ${e.retType}` : ''\n const arrow = `${e.isAsync ? 'async ' : ''}(${e.args})${ret} => `\n const baseIndent = INDENT.length * 2\n const linePrefix = ' '.repeat(baseIndent)\n if (e.describe || e.expose) {\n const keys: { k: string; v: string }[] = []\n if (e.describe) keys.push({ k: 'describe', v: quoteSingle(e.describe) })\n if (e.expose) keys.push({ k: 'expose', v: formatExpose(e.expose) })\n const bodyIndented = reindentBlockBody(e.body, baseIndent + INDENT.length * 2)\n keys.push({ k: 'handler', v: `${arrow}{${bodyIndented}}` })\n const lines: string[] = [`${linePrefix}${e.name}: {`]\n const inner = ' '.repeat(baseIndent + INDENT.length)\n for (const { k, v } of keys) {\n lines.push(`${inner}${k}: ${v},`)\n }\n lines.push(`${linePrefix}},`)\n return lines.join('\\n')\n }\n const bodyIndented = reindentBlockBody(e.body, baseIndent + INDENT.length)\n return `${linePrefix}${e.name}: ${arrow}{${bodyIndented}},`\n}\n\nfunction emitLifecycle(hooks: LifecycleHook[]): string {\n const firstLeading = hooks[0]?.leading\n const headerLeading = firstLeading?.trim() ? firstLeading : ''\n const inner: string[] = []\n const baseIndent = INDENT.length * 2\n const linePrefix = ' '.repeat(baseIndent)\n for (const [idx, h] of hooks.entries()) {\n if (idx > 0 && h.leading.trim()) {\n inner.push(rstrip(indentBlock(h.leading, linePrefix)))\n }\n const bodyIndented = reindentBlockBody(h.body, baseIndent + INDENT.length)\n inner.push(`${linePrefix}${h.kind}: ${h.isAsync ? 'async ' : ''}() => {${bodyIndented}},`)\n }\n const lines: string[] = []\n if (headerLeading) lines.push(rstrip(headerLeading))\n lines.push(`${INDENT}$lifecycle: {`)\n lines.push(...inner)\n lines.push(`${INDENT}}`)\n return lines.join('\\n')\n}\n\nfunction emitEffectAnon(effects: AnonEffect[]): string {\n const out: string[] = []\n const baseIndent = INDENT.length\n const linePrefix = ' '.repeat(baseIndent)\n for (const [idx, e] of effects.entries()) {\n if (idx > 0) out.push('')\n if (e.leading.trim()) out.push(rstrip(e.leading))\n const bodyIndented = reindentBlockBody(e.body, baseIndent + INDENT.length)\n out.push(`${linePrefix}$effect: ${e.isAsync ? 'async ' : ''}() => {${bodyIndented}}`)\n }\n return out.join('\\n')\n}\n\nfunction formatExpose(e: { read: boolean; write: boolean }): string {\n const parts: string[] = []\n if (e.read) parts.push('read: true')\n if (e.write) parts.push('write: true')\n return `{ ${parts.join(', ')} }`\n}\n\nfunction quoteSingle(s: string): string {\n return `'${s.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`\n}\n\n// Whitespace helpers\n\nfunction rstrip(s: string): string {\n return s\n .replace(/[ \\t]+(\\n|$)/g, '$1')\n .replace(/^\\n+/, '')\n .replace(/\\n+$/g, '')\n}\n\nfunction rebaseLeadingIndent(s: string, indent: string): string {\n const lines = s.split('\\n')\n const first = lines[0] ?? ''\n // determine first-line indent\n let n = 0\n while (n < first.length && (first[n] === ' ' || first[n] === '\\t')) n++\n if (n === 0) {\n return [indent + first, ...lines.slice(1)].join('\\n')\n }\n // Strip n chars from each line that has at least n leading WS, prepend indent\n const rebased = lines.map((line) => {\n if (line.length === 0) return line\n let m = 0\n while (m < line.length && m < n && (line[m] === ' ' || line[m] === '\\t')) m++\n return indent + line.slice(m)\n })\n return rebased.join('\\n')\n}\n\nfunction indentBlock(s: string, indent: string): string {\n return s\n .split('\\n')\n .map((line) => (line.length > 0 ? indent + line : line))\n .join('\\n')\n}\n\nfunction flattenWhitespace(s: string): string {\n return s.replace(/\\s+/g, ' ').trim()\n}\n\nfunction reindentBlockBody(bodyText: string, targetInner: number): string {\n const lines = bodyText.split('\\n')\n let firstReal = 0\n while (firstReal < lines.length && lines[firstReal]!.trim() === '') firstReal++\n let lastReal = lines.length - 1\n while (lastReal >= 0 && lines[lastReal]!.trim() === '') lastReal--\n if (firstReal > lastReal) {\n return ''\n }\n let minIndent = Infinity\n for (let k = firstReal; k <= lastReal; k++) {\n const line = lines[k]!\n if (line.trim() === '') continue\n let n = 0\n while (n < line.length && (line[n] === ' ' || line[n] === '\\t')) n++\n if (n < minIndent) minIndent = n\n }\n if (!Number.isFinite(minIndent)) minIndent = 0\n const rebased: string[] = ['']\n const targetSpaces = ' '.repeat(targetInner)\n for (let k = firstReal; k <= lastReal; k++) {\n const line = lines[k]!\n if (line.trim() === '') {\n rebased.push('')\n continue\n }\n rebased.push((targetSpaces + line.slice(minIndent)).replace(/[ \\t]+$/, ''))\n }\n rebased.push(' '.repeat(Math.max(targetInner - INDENT.length, 0)))\n return rebased.join('\\n')\n}\n\nfunction reindentExpr(expr: string, targetInner: number): string {\n const lines = expr.split('\\n')\n if (lines.length === 1) return expr\n const firstLine = lines[0]!\n const rest = lines.slice(1)\n let minIndent = Infinity\n for (const line of rest) {\n if (line.trim() === '') continue\n let n = 0\n while (n < line.length && (line[n] === ' ' || line[n] === '\\t')) n++\n if (n < minIndent) minIndent = n\n }\n if (!Number.isFinite(minIndent)) minIndent = 0\n const targetSpaces = ' '.repeat(targetInner)\n const rebasedRest = rest.map((line) =>\n line.trim() === '' ? '' : targetSpaces + line.slice(minIndent),\n )\n return [firstLine, ...rebasedRest].join('\\n')\n}\n\nfunction expandLeftToLineStart(s: string, idx: number): number {\n let j = idx\n while (j > 0 && s[j - 1] !== '\\n') j--\n if (j > 0 && s[j - 1] === '\\n') {\n let k = j - 1\n while (k > 0 && (s[k - 1] === ' ' || s[k - 1] === '\\t')) k--\n if (k > 0 && s[k - 1] === '\\n') j = k\n }\n return j\n}\n\nfunction expandRightThroughBlankLines(s: string, idx: number): number {\n let j = idx\n while (j < s.length && (s[j] === ' ' || s[j] === '\\t')) j++\n if (s[j] === '\\n') j++\n while (j < s.length) {\n let k = j\n while (k < s.length && (s[k] === ' ' || s[k] === '\\t')) k++\n if (s[k] === '\\n') {\n j = k + 1\n continue\n }\n break\n }\n return j\n}\n\n// v2 collection-form re-parser - idempotency path\n// Recognizes `$<macro>: { <entries> }` for prop/computed/action/resource/\n// effect/lifecycle, splits the inner object literal at top-level commas, and\n// re-buckets each entry. Returns the cursor past the closing `}` (and any\n// trailing `;`/`\\n`), or null if the line is not a v2 collection.\nfunction tryParseV2Collection(\n body: string,\n start: number,\n sidecar: Map<string, Sidecar>,\n buckets: Buckets,\n leading: string,\n nextPosition: () => number,\n): number | null {\n const m = /^\\$(prop|computed|action|resource|effect|lifecycle)\\s*:\\s*\\{/.exec(body.slice(start))\n if (!m) return null\n const macro = m[1]!\n const braceIdx = start + m[0].length - 1\n const closeIdx = matchBrace(body, braceIdx)\n if (closeIdx < 0) return null\n const inner = body.slice(braceIdx + 1, closeIdx)\n const entries = splitTopLevelEntries(inner)\n let outerLeadingConsumed = false\n for (const e of entries) {\n const parsed = parseV2Entry(e.text)\n if (!parsed) continue\n // Outer block's leading (comments above `$<macro>: {`) attaches to the\n // first parseable entry. Subsequent entries take their own piece-leading\n // only when it carries non-whitespace content (e.g., a comment block).\n let entryLeading: string\n if (!outerLeadingConsumed) {\n entryLeading = e.leading.trim() ? e.leading : leading\n outerLeadingConsumed = true\n } else {\n entryLeading = e.leading.trim() ? e.leading : ''\n }\n routeV2Entry(macro, parsed, sidecar, buckets, entryLeading, nextPosition)\n }\n let cursor = closeIdx + 1\n if (body[cursor] === ';') cursor++\n if (body[cursor] === '\\n') cursor++\n return cursor\n}\n\n// v2 anonymous-effect re-parser - `$effect: () => { ... }`.\nfunction tryParseV2AnonEffect(\n body: string,\n start: number,\n buckets: Buckets,\n leading: string,\n position: number,\n): number | null {\n const colonIdx = body.indexOf(':', start)\n if (colonIdx < 0) return null\n let cursor = colonIdx + 1\n while (cursor < body.length && /[ \\t]/.test(body[cursor]!)) cursor++\n const exprStart = cursor\n if (body[exprStart] !== '(' && body.slice(exprStart, exprStart + 5) !== 'async') return null\n // Consume the rest of the line up to the matching brace (or end of expr).\n // Simplest: parse the arrow expression by finding `=>` and then the body.\n // parseArrowOrFunctionExpr handles an `async` prefix and reports it (#425).\n const fn = parseArrowOrFunctionExpr(body.slice(exprStart))\n if (!fn) return null\n // Compute end position: scan from exprStart forward consuming the arrow body.\n // parseArrowOrFunctionExpr reports a body but not the end offset; recompute\n // by counting through the same structure here.\n const closeIdx = scanArrowExprEnd(body, exprStart)\n if (closeIdx < 0) return null\n buckets.effectAnon.push({ body: fn.body, leading, position, isAsync: fn.isAsync })\n let c = closeIdx\n if (body[c] === ';') c++\n if (body[c] === '\\n') c++\n return c\n}\n\n// Helper: scan past an arrow-function expression starting at `(` (optionally\n// prefixed with `async`), return idx just past the closing brace (or\n// end-of-expr).\nfunction scanArrowExprEnd(s: string, start: number): number {\n if (s.slice(start, start + 5) === 'async') {\n start += 5\n while (start < s.length && /[ \\t]/.test(s[start]!)) start++\n }\n if (s[start] !== '(') return -1\n const parenClose = matchParen(s, start)\n if (parenClose < 0) return -1\n let cur = parenClose + 1\n while (cur < s.length && /[ \\t]/.test(s[cur]!)) cur++\n if (s[cur] === ':') {\n cur++\n const arrowAt = s.indexOf('=>', cur)\n if (arrowAt < 0) return -1\n cur = arrowAt\n }\n if (s.slice(cur, cur + 2) !== '=>') return -1\n cur += 2\n while (cur < s.length && /[ \\t\\n]/.test(s[cur]!)) cur++\n if (s[cur] === '{') {\n const close = matchBrace(s, cur)\n if (close < 0) return -1\n return close + 1\n }\n // expression-bodied arrow: read to end of line\n const nl = s.indexOf('\\n', cur)\n return nl < 0 ? s.length : nl\n}\n\n// Split the inner of `{ ... }` at top-level commas. Each piece keeps its\n// original whitespace but is trimmed on the boundaries.\ninterface SplitEntry {\n text: string\n leading: string\n}\nfunction splitTopLevelEntries(inner: string): SplitEntry[] {\n const out: SplitEntry[] = []\n let depthBrace = 0\n let depthParen = 0\n let depthBracket = 0\n let start = 0\n let j = 0\n while (j < inner.length) {\n const c = inner[j]!\n if (c === '/' && inner[j + 1] === '/') {\n const nl = inner.indexOf('\\n', j)\n j = nl < 0 ? inner.length : nl\n continue\n }\n if (c === '/' && inner[j + 1] === '*') {\n const end = inner.indexOf('*/', j + 2)\n j = end < 0 ? inner.length : end + 2\n continue\n }\n if (c === '\"' || c === \"'\" || c === '`') {\n j = skipString(inner, j)\n continue\n }\n if (c === '{') depthBrace++\n else if (c === '}') depthBrace--\n else if (c === '(') depthParen++\n else if (c === ')') depthParen--\n else if (c === '[') depthBracket++\n else if (c === ']') depthBracket--\n else if (c === ',' && depthBrace === 0 && depthParen === 0 && depthBracket === 0) {\n const piece = inner.slice(start, j)\n pushSplitEntry(out, piece)\n start = j + 1\n }\n j++\n }\n if (start < inner.length) {\n const piece = inner.slice(start)\n pushSplitEntry(out, piece)\n }\n return out\n}\n\nfunction pushSplitEntry(out: SplitEntry[], piece: string): void {\n // Separate leading whitespace/comments from the entry body.\n let head = ''\n let i = 0\n while (i < piece.length) {\n const lineEnd = piece.indexOf('\\n', i)\n const end = lineEnd < 0 ? piece.length : lineEnd\n const line = piece.slice(i, end)\n if (line.trim() === '' || line.trim().startsWith('//') || line.trim().startsWith('/*')) {\n head += `${line}\\n`\n i = end + 1\n if (lineEnd < 0) break\n continue\n }\n break\n }\n const text = piece.slice(i).trim()\n if (text === '') return\n out.push({ text, leading: head })\n}\n\ninterface ParsedV2Entry {\n name: string\n // Either a bare RHS (e.g. arrow function or expression) or a wrapped `{...}` body.\n rhs: string\n isWrapped: boolean\n}\n\nfunction parseV2Entry(text: string): ParsedV2Entry | null {\n const m = /^([A-Za-z_$][\\w$]*)\\s*:\\s*/.exec(text)\n if (!m) return null\n const name = m[1]!\n const rest = text.slice(m[0].length).trim()\n if (rest.startsWith('{')) {\n // Could be either a wrapped metadata-bag OR a JS object expression that's\n // itself the value (rare in v2, e.g. a `$prop` `default: {}`). For our\n // collection-form, the wrapped form is `{ describe?, expose?, value? | handler? | type?, default? }`.\n const close = matchBrace(rest, 0)\n if (close < 0) return null\n const body = rest.slice(1, close).trim()\n return { name, rhs: body, isWrapped: true }\n }\n return { name, rhs: rest, isWrapped: false }\n}\n\n// Parse the inside of a wrapped object `{ describe: ..., expose: ..., value: ..., handler: ..., default: ..., type: ... }`.\ninterface WrappedFields {\n describe?: string\n expose?: { read: boolean; write: boolean }\n value?: string\n handler?: string\n default?: string\n type?: string\n on?: string\n}\nfunction parseWrappedFields(body: string): WrappedFields {\n const out: WrappedFields = {}\n const entries = splitTopLevelEntries(body)\n for (const e of entries) {\n const m = /^([A-Za-z_$][\\w$]*)\\s*:\\s*/.exec(e.text)\n if (!m) continue\n const k = m[1]!\n const v = e.text.slice(m[0].length).trim()\n if (k === 'describe') out.describe = unquoteString(v)\n else if (k === 'expose') {\n const parsed = parseExposeLiteral(v)\n if (parsed) out.expose = parsed\n } else if (k === 'value') out.value = v\n else if (k === 'handler') out.handler = v\n else if (k === 'default') out.default = v\n else if (k === 'type') out.type = v\n else if (k === 'on') out.on = v\n }\n return out\n}\n\nfunction unquoteString(s: string): string {\n s = s.trim()\n if ((s.startsWith(\"'\") && s.endsWith(\"'\")) || (s.startsWith('\"') && s.endsWith('\"'))) {\n return s.slice(1, -1).replace(/\\\\'/g, \"'\").replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, '\\\\')\n }\n return s\n}\n\nfunction parseExposeLiteral(s: string): { read: boolean; write: boolean } | undefined {\n s = s.trim()\n if (!s.startsWith('{')) return undefined\n const close = matchBrace(s, 0)\n if (close < 0) return undefined\n const body = s.slice(1, close)\n const read = /\\bread\\s*:\\s*true\\b/.test(body)\n const write = /\\bwrite\\s*:\\s*true\\b/.test(body)\n return { read, write }\n}\n\nfunction routeV2Entry(\n macro: string,\n entry: ParsedV2Entry,\n _sidecar: Map<string, Sidecar>,\n buckets: Buckets,\n leading: string,\n nextPosition: () => number,\n): void {\n if (macro === 'prop') {\n if (entry.isWrapped) {\n const f = parseWrappedFields(entry.rhs)\n buckets.props.push({\n name: entry.name,\n rawType: f.type,\n rawDefault: f.default,\n describe: f.describe,\n expose: f.expose,\n leading,\n })\n }\n return\n }\n if (macro === 'computed' || macro === 'resource') {\n let thunk: { expr: string; isAsync: boolean }\n let describe: string | undefined\n let expose: { read: boolean; write: boolean } | undefined\n if (entry.isWrapped) {\n const f = parseWrappedFields(entry.rhs)\n thunk = stripThunk(f.value ?? '')\n describe = f.describe\n expose = f.expose\n } else {\n thunk = stripThunk(entry.rhs)\n }\n const target = macro === 'computed' ? buckets.computed : buckets.resource\n target.push({\n name: entry.name,\n expr: thunk.expr,\n describe,\n expose,\n leading,\n isAsync: thunk.isAsync,\n })\n return\n }\n if (macro === 'action') {\n let handlerSrc: string\n let describe: string | undefined\n let expose: { read: boolean; write: boolean } | undefined\n if (entry.isWrapped) {\n const f = parseWrappedFields(entry.rhs)\n handlerSrc = f.handler ?? ''\n describe = f.describe\n expose = f.expose\n } else {\n handlerSrc = entry.rhs\n }\n const fn = parseArrowOrFunctionExpr(handlerSrc)\n if (!fn) return\n buckets.action.push({\n name: entry.name,\n args: fn.args,\n retType: fn.retType,\n body: fn.body,\n describe,\n expose,\n leading,\n isAsync: fn.isAsync,\n })\n return\n }\n if (macro === 'effect') {\n let thunk: { expr: string; isAsync: boolean }\n let describe: string | undefined\n let expose: { read: boolean; write: boolean } | undefined\n if (entry.isWrapped) {\n const f = parseWrappedFields(entry.rhs)\n thunk = stripThunk(f.value ?? '')\n describe = f.describe\n expose = f.expose\n } else {\n thunk = stripThunk(entry.rhs)\n }\n buckets.effectNamed.push({\n name: entry.name,\n expr: thunk.expr,\n describe,\n expose,\n leading,\n isAsync: thunk.isAsync,\n })\n return\n }\n if (macro === 'lifecycle') {\n if (entry.name !== 'mount' && entry.name !== 'dispose') return\n const src = entry.isWrapped ? entry.rhs : entry.rhs\n const fn = parseArrowOrFunctionExpr(src)\n if (!fn) return\n buckets.lifecycle.push({\n kind: entry.name,\n body: fn.body,\n leading,\n position: nextPosition(),\n isAsync: fn.isAsync,\n })\n return\n }\n}\n\n// Strip a leading `() =>` (or `async () =>`, #425) from a thunk if present,\n// returning the inner expr plus the async flag so re-emit can restore it.\n// For wrapped `value: () => expr`, we want to round-trip the bare arrow form\n// so re-emit produces `name: () => expr` identically.\nfunction stripThunk(s: string): { expr: string; isAsync: boolean } {\n s = s.trim()\n const m = /^(async\\s+)?\\(\\s*\\)\\s*(?::\\s*[^=]+)?=>\\s*/.exec(s)\n if (!m) return { expr: s, isAsync: false }\n const isAsync = !!m[1]\n const rest = s.slice(m[0].length)\n if (rest.startsWith('{')) {\n const close = matchBrace(rest, 0)\n if (close < 0) return { expr: rest, isAsync }\n return { expr: rest.slice(1, close).trim(), isAsync }\n }\n return { expr: rest.trim(), isAsync }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
//#region js/codemods/state-wrapper/migrate.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* state-wrapper codemod (#487 §7 — waves 1 + 2, the app-corpus migration)
|
|
4
|
+
*
|
|
5
|
+
* Migrates an `.aihu` file's `@state` block from the retired forms to the
|
|
6
|
+
* ratified wrapper model (`docs/plans/state-model/40-spec.md`):
|
|
7
|
+
*
|
|
8
|
+
* Stage 1 — `$`-macros → wrappers / statement calls / directives (§2, §3):
|
|
9
|
+
* $prop: { x: { … } } → const|let x = prop<T>({ … })
|
|
10
|
+
* $computed: { x: fn } → const x = derived(cfg?, fn)
|
|
11
|
+
* $action: { f: fn } → const f = action(cfg?, fn)
|
|
12
|
+
* $resource: { r: fn } → const r = resource(cfg?, fn)
|
|
13
|
+
* $controller: { c: {value} }→ const c = controller(cfg?, factory)
|
|
14
|
+
* $effect: fn / { name: fn } → effect(fn) / effect({ on: […] }, fn)
|
|
15
|
+
* $lifecycle: { mount, … } → onMount(fn), onDispose(fn), …
|
|
16
|
+
* $aria: { … } / $form: { … }→ aria({ … }) / form({ … })
|
|
17
|
+
* $context: {provide,consume}→ provide('k', v) / const k = consume<T>('k')
|
|
18
|
+
* $route name → const name = route()
|
|
19
|
+
* $before/afterNavigate(fn) → beforeNavigate(fn) / afterNavigate(fn)
|
|
20
|
+
* $extends: X / $shadow: 'm' → base: X / shadow: 'm'
|
|
21
|
+
* bare typed decl `x: T = v` → let x = state(v) (reactive) |
|
|
22
|
+
* plain let/const (inert; §3 row 21 + W627)
|
|
23
|
+
*
|
|
24
|
+
* Stage 2 — signal tuples → `state` (§7 wave 2), INCLUDING call sites:
|
|
25
|
+
* const [x, setX] = signal(v) → let x = state(v)
|
|
26
|
+
* x() → x
|
|
27
|
+
* setX(v) → x = v (statement / handler)
|
|
28
|
+
* setX(p => expr) → x = expr[p→x] (updater desugar)
|
|
29
|
+
*
|
|
30
|
+
* Byte-identity contract: `$`-macro migrations lower onto the SAME IR, so a
|
|
31
|
+
* stage-1-only migration emits byte-identical JS (modulo the old parser's
|
|
32
|
+
* `strip_line_comments` artifact — authored `//` comments inside metadata-bag
|
|
33
|
+
* bodies were BLANKED in old emission and are preserved by the wrapper path).
|
|
34
|
+
* To keep even whitespace stable, entry VALUE text is spliced verbatim — the
|
|
35
|
+
* codemod never re-indents running code.
|
|
36
|
+
*
|
|
37
|
+
* Per-file dialect exclusivity (C625): a file either migrates fully or not at
|
|
38
|
+
* all. Any unmappable `$`-form (e.g. the `mount:`-keyed `$controller`, which
|
|
39
|
+
* has no wrapper equivalent) aborts the file with a warning. Authored signal
|
|
40
|
+
* tuples are exempt from C625 (orthogonal), so a tuple pair whose setter is
|
|
41
|
+
* used as a VALUE (not called) is kept authored, per-pair.
|
|
42
|
+
*/
|
|
43
|
+
interface StateWrapperResult {
|
|
44
|
+
readonly rewritten: string;
|
|
45
|
+
readonly warnings: readonly string[];
|
|
46
|
+
/** True when the file was left byte-untouched (nothing to do, or aborted). */
|
|
47
|
+
readonly skipped: boolean;
|
|
48
|
+
/** Which change classes were applied — drives the verification bucket. */
|
|
49
|
+
readonly changes: {
|
|
50
|
+
macros: boolean;
|
|
51
|
+
tuples: boolean;
|
|
52
|
+
bareTyped: boolean;
|
|
53
|
+
};
|
|
54
|
+
/** Tuple pairs migrated: authored setter name → state binding name. */
|
|
55
|
+
readonly renamedSetters: ReadonlyArray<{
|
|
56
|
+
getter: string;
|
|
57
|
+
setter: string;
|
|
58
|
+
}>;
|
|
59
|
+
}
|
|
60
|
+
interface StateWrapperOptions {
|
|
61
|
+
/** Run only stage 1 ($-macros + bare typed decls). */
|
|
62
|
+
macrosOnly?: boolean;
|
|
63
|
+
/** Run only stage 2 (signal tuples + call sites). */
|
|
64
|
+
tuplesOnly?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Binding names that must stay PLAIN even when the reactive heuristic says
|
|
67
|
+
* `state(…)` (e.g. a fixture guard depends on the plain-let lowering).
|
|
68
|
+
*/
|
|
69
|
+
keepPlain?: readonly string[];
|
|
70
|
+
}
|
|
71
|
+
/** Matching `}` for the `{` at `i` (string/comment aware). */
|
|
72
|
+
declare function matchBrace(s: string, i: number): number;
|
|
73
|
+
/** Matching `)` for the `(` at `i` (string/comment/brace aware). */
|
|
74
|
+
declare function matchParen(s: string, i: number): number;
|
|
75
|
+
declare function migrateStateWrappers(source: string, options?: StateWrapperOptions): StateWrapperResult;
|
|
76
|
+
//#endregion
|
|
77
|
+
export { StateWrapperOptions, StateWrapperResult, matchBrace, matchParen, migrateStateWrappers };
|
|
78
|
+
//# sourceMappingURL=state-wrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-wrapper.d.ts","names":[],"sources":["../../js/codemods/state-wrapper/migrate.ts"],"mappings":";;AA0CA;AAAmC;AAAA;AAYK;AAX7B;AACA;AAEA;AAEA;AACP;AACA;AACA;AAGO;AAAgB;AAAgB;AAAgB;AAAM;AAAA;AAGjE;AAAoC;AAAA;AAAA;AAElC;AAEA;AAKA;AAAS;AAAA;AA4BX;AAA0B;AAAA;AAAA;AAAqB;AA+B/C;AAA0B;AAAA;AAAA;AAAqB;AA+9B/C;AAAoC;AAAA;AAGf;UArjCJ,kBAAA;EAAA,SACN,SAAA;EAAA,SACA,QAAA;EAmjCR;EAAA,SAjjCQ,OAAA;EAijCU;EAAA,SA/iCV,OAAA;IACP,MAAA;IACA,MAAA;IACA,SAAA;EAAA;;WAGO,cAAA,EAAgB,aAAa;IAAG,MAAA;IAAgB,MAAA;EAAA;AAAA;AAAA,UAG1C,mBAAA;;EAEf,UAAA;;EAEA,UAAA;;;;;EAKA,SAAA;AAAA;;iBA4Bc,UAAA,CAAW,CAAA,UAAW,CAAS;;iBA+B/B,UAAA,CAAW,CAAA,UAAW,CAAS;AAAA,iBA+9B/B,oBAAA,CACd,MAAA,UACA,OAAA,GAAS,mBAAA,GACR,kBAAkB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
function e(e,n){let r=e[n],i=n+1;for(;i<e.length;){let n=e[i];if(n===`\\`){i+=2;continue}if(r==="`"&&n===`$`&&e[i+1]===`{`){let n=t(e,i+1);i=n<0?e.length:n+1;continue}if(n===r)return i+1;i++}return e.length}function t(t,n){if(t[n]!==`{`)return-1;let r=0,i=n;for(;i<t.length;){let n=t[i];if(n===`/`&&t[i+1]===`/`){let e=t.indexOf(`
|
|
2
|
+
`,i);i=e<0?t.length:e;continue}if(n===`/`&&t[i+1]===`*`){let e=t.indexOf(`*/`,i+2);i=e<0?t.length:e+2;continue}if(n===`"`||n===`'`||n==="`"){i=e(t,i);continue}if(n===`{`)r++;else if(n===`}`&&(r--,r===0))return i;i++}return-1}function n(n,r){if(n[r]!==`(`)return-1;let i=0,a=r;for(;a<n.length;){let r=n[a];if(r===`/`&&n[a+1]===`/`){let e=n.indexOf(`
|
|
3
|
+
`,a);a=e<0?n.length:e;continue}if(r===`/`&&n[a+1]===`*`){let e=n.indexOf(`*/`,a+2);a=e<0?n.length:e+2;continue}if(r===`"`||r===`'`||r==="`"){a=e(n,a);continue}if(r===`{`){let e=t(n,a);a=e<0?n.length:e+1;continue}if(r===`(`)i++;else if(r===`)`&&(i--,i===0))return a;a++}return-1}function r(t){let n=[],r=0,i=0,a=0,o=0,s=0;for(;i<t.length;){let c=t[i];if(c===`/`&&t[i+1]===`/`){let e=t.indexOf(`
|
|
4
|
+
`,i);i=e<0?t.length:e;continue}if(c===`/`&&t[i+1]===`*`){let e=t.indexOf(`*/`,i+2);i=e<0?t.length:e+2;continue}if(c===`"`||c===`'`||c==="`"){i=e(t,i);continue}c===`(`?a++:c===`)`?a--:c===`{`?o++:c===`}`?o--:c===`[`?s++:c===`]`?s--:c===`<`&&/[A-Za-z0-9_$>\s]/.test(t[i+1]??``)||c===`,`&&a===0&&o===0&&s===0&&(n.push(t.slice(r,i)),r=i+1),i++}return t.slice(r).trim()!==``&&n.push(t.slice(r)),n}function i(e){let t=[];for(let n of r(e)){let e=n.replace(/^\s*\n/,``).split(`
|
|
5
|
+
`),r=0,i=[];for(;r<e.length;){let t=e[r].trim();if(t===``||t.startsWith(`//`)||t.startsWith(`/*`)||t.startsWith(`*`)){i.push(e[r]),r++;continue}break}let a=e.slice(r).join(`
|
|
6
|
+
`),o=/^\s*([A-Za-z_$][\w$]*)\s*:/.exec(a);o&&t.push({name:o[1],value:a.slice(o[0].length).replace(/^[ \t]/,``),leading:i.join(`
|
|
7
|
+
`)})}return t}function a(e){let n=e.trim();if(!n.startsWith(`{`))return null;let i=t(n,0);if(i<0)return null;let a=n.slice(1,i),o=new Map;for(let e of r(a)){let t=/^\s*([A-Za-z_$][\w$]*)\s*:/.exec(e);t&&o.set(t[1],e.slice(t[0].length).replace(/^[ \t]/,``).replace(/\s+$/,``))}return o}function o(e){let t=e.trim();if(t.startsWith(`function`)||/^async\b/.test(t))return!0;if(t.startsWith(`(`)){let e=n(t,0);if(e<0)return!1;let r=t.slice(e+1).trimStart();return r.startsWith(`=>`)?!0:r.startsWith(`:`)?r.indexOf(`=>`)>0:!1}return/^[A-Za-z_$][\w$]*\s*=>/.test(t)}function s(e,n){let r=RegExp(`(^|\\n)([ \\t]*)@${n}\\s*\\{`,`g`).exec(e);if(!r)return null;let i=r.index+ +(r[1]===`
|
|
8
|
+
`),a=r.index+r[0].length-1,o=t(e,a);return o<0?null:{start:i,end:o+1,bodyStart:a+1,bodyEnd:o,body:e.slice(a+1,o)}}function c(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function l(e,t){let n=c(t);return RegExp(`\\b${n}\\s*(\\+\\+|--|(?:\\+|-|\\*|/|%|\\*\\*|&&|\\|\\||\\?\\?|&|\\||\\^|<<|>>>?)?=(?![=>]))`).test(e)}function u(e,t){let n=c(t);return RegExp(`\\b${n}\\b`).test(e)}function d(e,t){let n=c(t);return RegExp(`\\bbind:[\\w-]+=\\{\\s*${n}\\s*\\}`).test(e)}function f(e){let t=e.trim(),n=(t.startsWith(`'`)&&t.endsWith(`'`)||t.startsWith(`"`)&&t.endsWith(`"`))&&!t.slice(1,-1).includes(t[0])?t.slice(1,-1):t;switch(n){case`String`:return`string`;case`Number`:return`number`;case`Boolean`:return`boolean`;case`Array`:return`unknown[]`;case`Object`:return`Record<string, unknown>`;default:return n}}function p(e,t){if(t===void 0)return!1;let n=t.trim();if(n===`null`||n===`undefined`||n===`[]`||n===`{}`)return!1;if(!e)return!0;let r=e.trim();return/^(String|Number|Boolean|Array|Object)$/.test(r)}function m(e){let t=a(e.trim());if(t){let e=t.get(`read`)?.trim()===`true`,n=t.get(`write`)?.trim()===`true`;if(![...t.keys()].some(e=>e!==`read`&&e!==`write`)){if(e&&n)return`'read write'`;if(e)return`'read'`;if(n)return`'write'`}}return e.trim()}function h(e,t){let n=a(e.value);if(!n)return` // UNMIGRATABLE $prop entry ${e.name}`;let r=n.get(`type`),i=n.get(`default`),o=[];i!==void 0&&o.push(`default: ${i}`);let s=n.get(`describe`);s!==void 0&&o.push(`describe: ${s}`);let c=n.get(`expose`);c!==void 0&&o.push(`expose: ${m(c)}`);let l=n.get(`attribute`);l!==void 0&&o.push(`attribute: ${l}`);let u=n.get(`reflect`);u!==void 0&&o.push(`reflect: ${u}`);let d=n.get(`required`);d!==void 0&&o.push(`required: ${d}`);let h=r&&!p(r,i)?`<${f(r)}>`:``,g=` ${t?`let`:`const`} ${e.name} = prop${h}(`;if(o.length===0)return`${g})`;let _=`${g}{ ${o.join(`, `)} })`;if(!_.includes(`
|
|
9
|
+
`)&&_.length<=100)return _;let v=[`${g}{`];for(let e of o)v.push(` ${e},`);return v.push(` })`),v.join(`
|
|
10
|
+
`)}function g(e,t,n,r){let i=t===null?` ${e}(`:` const ${t} = ${e}(`,a=[];if(n){let e=n.get(`describe`);e!==void 0&&a.push(`describe: ${e}`);let t=n.get(`expose`);t!==void 0&&a.push(`expose: ${m(t)}`);let r=n.get(`on`);r!==void 0&&a.push(`on: ${r}`)}let o=r.replace(/\s+$/,``);if(a.length===0)return`${i}${o})`;let s=`{ ${a.join(`, `)} }`;if(!s.includes(`
|
|
11
|
+
`)&&i.length+s.length<=98)return`${i}\n ${s},\n ${o})`;let c=[`${i}`,` { ${a.join(`,
|
|
12
|
+
`)} },`];return c.push(` ${o})`),c.join(`
|
|
13
|
+
`)}function _(e,t,n){let r=e===`action`?`handler`:`value`;if(o(t.value))return g(e,t.name,null,t.value);let i=a(t.value);if(!i)return n.warnings.push(`unrecognized ${e} entry shape for '${t.name}'`),null;let s=i.get(r);if(s===void 0)return n.warnings.push(`${e} entry '${t.name}' has no ${r}: key`),null;for(let a of i.keys())if(a!==`describe`&&a!==`expose`&&a!==r)return n.warnings.push(`${e} entry '${t.name}' carries unmapped key '${a}:'`),null;return g(e,t.name,i,s)}function v(e,r,s,c){let p=``;{let n=/^[ \t]*\$(computed|form|aria|resource)\s*:\s*\{/gm,r=n.exec(e);for(;r!==null;){let i=r.index+r[0].length-1,a=t(e,i);a>0&&(p+=e.slice(i,a+1)),r=n.exec(e)}}let m=`${r}\n${p}`,v=[],S=0;for(;S<e.length;){let p=e.indexOf(`
|
|
14
|
+
`,S),C=p<0?e.length:p,w=e.slice(S,C),T=w.trim(),E=w.length-w.trimStart().length,D=S+E,O=/^\$(prop|computed|action|resource|effect|lifecycle|aria|form|context|controller|event|stream|extract)\s*:\s*/.exec(T);if(O){let n=O[1],c=D+O[0].length;if(n===`effect`&&e[c]!==`{`){let t=c,n=x(e,t);if(n<0)return s.warnings.push(`unparseable anonymous $effect — file left unmigrated`),s.aborted=!0,e;let r=e.slice(t,n).replace(/\s+$/,``);v.push(` effect(${r})`),s.changedMacros=!0,S=n,e[S]===`;`&&S++,e[S]===`
|
|
15
|
+
`&&S++;continue}if(e[c]!==`{`)return s.warnings.push(`unrecognized $${n} value shape — file left unmigrated`),s.aborted=!0,e;let u=t(e,c);if(u<0)return s.aborted=!0,e;let p=e.slice(c+1,u),m=i(p),y=[],b=(e,t)=>{if(t===null){s.aborted=!0;return}e.trim()&&y.push(e.replace(/\s+$/,``)),y.push(t)};switch(n){case`prop`:for(let t of m){let n=l(e,t.name)||l(r,t.name)||d(r,t.name);b(t.leading,h(t,n))}break;case`computed`:case`action`:case`resource`:{let e=n===`computed`?`derived`:n;for(let t of m)b(t.leading,_(e,t,s));break}case`effect`:for(let t of m)if(o(t.value))b(t.leading,` effect(${t.value.replace(/\s+$/,``)})`);else{let n=a(t.value),r=n?.get(`value`);if(!n||r===void 0)return s.warnings.push(`$effect entry '${t.name}' unrecognized — file left unmigrated`),s.aborted=!0,e;b(t.leading,g(`effect`,null,n,r))}break;case`lifecycle`:{let t={mount:`onMount`,dispose:`onDispose`,adopt:`onAdopt`,attributeChange:`onAttributeChange`};for(let n of m){let r=t[n.name];if(!r)return s.warnings.push(`unknown $lifecycle key '${n.name}' — file left unmigrated`),s.aborted=!0,e;b(n.leading,` ${r}(${n.value.replace(/\s+$/,``)})`)}break}case`aria`:case`form`:b(``,` ${n}({\n${p.replace(/^\s*\n/,``).replace(/\s+$/,``)}\n })`);break;case`context`:for(let t of m)if(t.name===`provide`){let n=a(t.value);if(!n)return s.aborted=!0,e;for(let[r,i]of n){let n=a(i)?.get(`value`);if(n===void 0)return s.warnings.push(`$context provide '${r}' has no value: — file left unmigrated`),s.aborted=!0,e;b(t.leading,` provide('${r}', ${n})`)}}else if(t.name===`consume`){let n=a(t.value);if(!n)return s.aborted=!0,e;for(let[e,r]of n){let n=a(r)?.get(`type`),i=n?`<${f(n)}>`:``;b(t.leading,` const ${e} = consume${i}('${e}')`)}}else return s.aborted=!0,e;break;case`controller`:for(let t of m){let n=a(t.value),r=n?.get(`value`);if(!n||r===void 0)return s.warnings.push(`$controller entry '${t.name}' has no value: factory (the mount:-keyed shape has no wrapper equivalent) — file left unmigrated`),s.aborted=!0,e;b(t.leading,g(`controller`,t.name,n,r))}break;case`extract`:b(``,` extract: ${e.slice(c,u+1)}`);break;default:return s.warnings.push(`$${n} has no app-corpus mapping — file left unmigrated`),s.aborted=!0,e}if(s.aborted)return e;v.push(y.join(`
|
|
16
|
+
`)),s.changedMacros=!0,S=u+1,e[S]===`;`&&S++,e[S]===`
|
|
17
|
+
`&&S++;continue}let k=/^\$extends\s*:\s*(.+)$/.exec(T);if(k){v.push(`${` `.repeat(E)}base: ${k[1].trim()}`),s.changedMacros=!0,S=C+1;continue}let A=/^\$shadow\s*:\s*(.+)$/.exec(T);if(A){v.push(`${` `.repeat(E)}shadow: ${A[1].trim()}`),s.changedMacros=!0,S=C+1;continue}let j=/^\$route\s+([A-Za-z_$][\w$]*)\s*;?$/.exec(T);if(j){v.push(`${` `.repeat(E)}const ${j[1]} = route()`),s.changedMacros=!0,S=C+1;continue}if(/^\$(beforeNavigate|afterNavigate)\s*\(/.test(T)){let t=n(e,e.indexOf(`(`,D));if(t<0)return s.aborted=!0,e;let r=t+1;e[r]===`;`&&r++,v.push(`${` `.repeat(E)}${e.slice(D+1,r)}`),s.changedMacros=!0,S=r,e[S]===`
|
|
18
|
+
`&&S++;continue}if(T.startsWith(`$`))return s.warnings.push(`unmapped macro form '${T.split(/\s|\(|:/)[0]}' — file left unmigrated`),s.aborted=!0,e;let M=/^([A-Za-z_$][\w$]*)\s*:\s*([^=\n]+?)\s*=\s*(.+?);?\s*$/.exec(T);if(M&&!/^(if|else|for|while|return|case|default|import|export|type|interface)\b/.test(T)){let t=M[1],n=M[2].trim(),i=M[3].trim(),a=` `.repeat(E),o=l(y(e,S,C),t)||l(r,t)||d(r,t),f=u(m,t);if(o&&f&&!c.has(t)){let e=/^(-?\d|'|"|`|true$|false$)/.test(i)&&i!==`null`&&i!==`undefined`?``:`<${n}>`;v.push(`${a}let ${t} = state${e}(${i})`)}else o?v.push(`${a}let ${t}: ${n} = ${i}`):v.push(`${a}const ${t}: ${n} = ${i}`);s.changedBareTyped=!0,S=C+1;continue}let N=b(e,S);v.push(e.slice(S,N).replace(/\n$/,``)),S=N}return v.join(`
|
|
19
|
+
`)}function y(e,t,n){return e.slice(0,t)+e.slice(n)}function b(t,n){let r=0,i=n;for(;i<t.length;){let n=t[i];if(n===`/`&&t[i+1]===`/`){let e=t.indexOf(`
|
|
20
|
+
`,i);i=e<0?t.length:e;continue}if(n===`/`&&t[i+1]===`*`){let e=t.indexOf(`*/`,i+2);i=e<0?t.length:e+2;continue}if(n===`"`||n===`'`||n==="`"){i=e(t,i);continue}if(n===`(`||n===`{`||n===`[`)r++;else if(n===`)`||n===`}`||n===`]`)r--;else if(n===`
|
|
21
|
+
`&&r<=0)return i+1;i++}return t.length}function x(e,r){let i=r;for(;i<e.length&&/[ \t]/.test(e[i]);)i++;if(e.slice(i,i+5)===`async`)for(i+=5;i<e.length&&/[ \t]/.test(e[i]);)i++;if(e.slice(i,i+8)===`function`){let n=e.indexOf(`{`,i);if(n<0)return-1;let r=t(e,n);return r<0?-1:r+1}if(e[i]===`(`){let t=n(e,i);if(t<0)return-1;i=t+1}else{let t=/^[A-Za-z_$][\w$]*/.exec(e.slice(i));if(!t)return-1;i+=t[0].length}for(;i<e.length&&/[ \t]/.test(e[i]);)i++;if(e[i]===`:`){let t=e.indexOf(`=>`,i);if(t<0)return-1;i=t}if(e.slice(i,i+2)!==`=>`)return-1;for(i+=2;i<e.length&&/[ \t]/.test(e[i]);)i++;if(e[i]===`{`){let n=t(e,i);return n<0?-1:n+1}let a=e.indexOf(`
|
|
22
|
+
`,i);return a<0?e.length:a}function S(e,t){let r=[],i=/(^|\n)([ \t]*)(?:const|let)\s*\[\s*([A-Za-z_$][\w$]*)\s*(?:,\s*([A-Za-z_$][\w$]*)\s*)?\]\s*=\s*signal\b/g,a=i.exec(e);for(;a!==null;){let o=a.index+a[1].length+a[2].length,s=a.index+a[0].length,c=``;if(e[s]===`<`){let t=1,n=s+1;for(;n<e.length&&t>0;)e[n]===`<`?t++:e[n]===`>`&&t--,n++;c=e.slice(s,n),s=n}if(e[s]!==`(`){a=i.exec(e);continue}let l=n(e,s);if(l<0){a=i.exec(e);continue}let u=e.slice(s+1,l),d=l+1;e[d]===`;`&&d++,r.push({getter:a[3],setter:a[4]??null,generic:c,init:u,declStart:o+t,declEnd:d+t}),a=i.exec(e)}return r}function C(e,t){let n=[],r=c(t),i=RegExp(`(?<![\\w$.])${r}\\s*\\(`,`g`),a=i.exec(e);for(;a!==null;)n.push(a.index),a=i.exec(e);return n}function w(e,t,r,i,a){e.indexOf(`(`,t+r.length-1);let o=e.indexOf(`(`,t),s=n(e,o);if(s<0)return null;let l=e.slice(o+1,s).trim(),u=null,d=/^(?:\(\s*([A-Za-z_$][\w$]*)\s*(?::[^)]*)?\)|([A-Za-z_$][\w$]*))\s*=>\s*([\s\S]+)$/.exec(l);if(d){let e=d[1]??d[2],t=d[3].trim();if(t.startsWith(`{`))a.push(`updater with block body at ${r}(${l.slice(0,30)}…) — kept as an IIFE over the current value`),u=`(${l})(${i})`;else{let n=c(e);u=t.replace(RegExp(`\\b${n}\\b`,`g`),i)}}else u=l;let f=t-1;for(;f>=0&&/[ \t]/.test(e[f]);)f--;let p=f>=1&&e[f]===`>`&&e[f-1]===`=`,m=f;/(?:^|[\s;{}])await$/.exec(e.slice(Math.max(0,f-6),f+1))&&(m=f-5-1);let h=m>=0?e[m]:`
|
|
23
|
+
`,g=h===`
|
|
24
|
+
`||h===`;`||h===`{`||m<0,_;_=p?`{ ${i} = ${u} }`:g?`${i} = ${u}`:`(${i} = ${u})`;let v=s+1;return{replaced:_,start:t,end:v}}function T(e,t,r){let i=s(e,`state`);if(!i)return e;let a=S(i.body,i.bodyStart);if(a.length===0)return e;let o=e;for(let e of[...a].reverse()){let{getter:i,setter:a}=e;if(a){let n=c(a),r=RegExp(`(?<![\\w$.'"\`])${n}(?![\\w$]|\\s*\\()`),s=y(o,e.declStart,e.declEnd);if(r.test(s)){t.warnings.push(`tuple [${i}, ${a}] kept authored — the setter is used as a value (cannot be expressed as a state binding during the compat window)`);continue}}if(a){let n=C(o,a);n=n.filter(t=>t<e.declStart||t>=e.declEnd);for(let e of n.reverse()){let n=w(o,e,a,i,t.warnings);if(!n){t.warnings.push(`unbalanced ${a}(…) call — left untouched`);continue}o=o.slice(0,n.start)+n.replaced+o.slice(n.end)}}{let e=c(i);o=o.replace(RegExp(`(?<![\\w$])(?<!(?<!\\.)\\.)${e}\\s*\\(\\s*\\)`,`g`),i)}{let e=c(i),t=RegExp(`(?:const|let)\\s*\\[\\s*${e}\\s*(?:,\\s*[A-Za-z_$][\\w$]*\\s*)?\\]\\s*=\\s*signal(<[^\\n]*?>)?\\(`).exec(o);if(t){let e=o.indexOf(`(`,t.index+t[0].length-1),r=n(o,e);if(r>0){let n=r+1;o[n]===`;`&&n++;let a=t[1]??``,s=o.slice(e+1,r),c=s.trim().startsWith(`{`)?`(${s})`:s;o=o.slice(0,t.index)+`let ${i} = state${a}(${c})`+o.slice(n)}}}t.changedTuples=!0,a&&r.push({getter:i,setter:a})}return/\bsignal\s*[(<]/.test(o)||(o=o.replace(/^([ \t]*)import\s*\{([^}]*)\}\s*from\s*'@aihu\/signals'\s*;?\s*\n/m,(e,t,n)=>{let r=n.split(`,`).map(e=>e.trim()).filter(e=>e!==``&&e!==`signal`);return r.length===0?``:`${t}import { ${r.join(`, `)} } from '@aihu/signals'\n`})),o}function E(e,t={}){let n={warnings:[],changedMacros:!1,changedBareTyped:!1,aborted:!1},r={warnings:n.warnings,changedTuples:!1},i=[],a=new Set(t.keepPlain??[]),o=e;if(!t.tuplesOnly){let e=s(o,`state`);if(e){let t=s(o,`template`),r=v(e.body,t?.body??``,n,a);if(!n.aborted&&n.changedMacros){let e=/^\s*(?:const|let)\s+[A-Za-z_$][\w$]*\s*=\s*(?:state|prop|derived|action|resource|stream|controller|route|consume)\s*[<(]/m.test(r)||/^\s*(?:base|shadow|extract)\s*:/m.test(r);/^\s*(?:effect|onMount|onDispose|onAdopt|onAttributeChange|aria|form|provide|event|beforeNavigate|afterNavigate)\s*[(<]/m.test(r)&&!e&&(n.warnings.push(`migration would produce only statement-position calls with no binding wrapper or directive — the compiler's new-dialect gate would treat them as plain JS; file left unmigrated`),n.aborted=!0)}if(!n.aborted&&r!==e.body){let t=r.replace(/^\n+/,``).replace(/\s+$/,``);o=`${o.slice(0,e.start)}@state {\n${t}\n}${o.slice(e.end)}`}}}if(!t.tuplesOnly&&!n.aborted){let e=s(o,`state`);if(e){let t=[...e.body.matchAll(/(?:const|let)\s+([A-Za-z_$][\w$]*)\s*=\s*prop\s*[<(]/g)].map(e=>e[1]??``);for(let e of t){if(!e)continue;let t=c(e);o=o.replace(RegExp(`(?<![\\w$])(?<!(?<!\\.)\\.)${t}\\s*\\(\\s*\\)`,`g`),e)}}}!t.macrosOnly&&!n.aborted&&(o=T(o,r,i));let l=n.changedMacros||n.changedBareTyped||r.changedTuples;return{rewritten:n.aborted?e:o,warnings:n.warnings,skipped:n.aborted||!l,changes:{macros:n.changedMacros,tuples:r.changedTuples,bareTyped:n.changedBareTyped},renamedSetters:i}}export{t as matchBrace,n as matchParen,E as migrateStateWrappers};
|
|
25
|
+
//# sourceMappingURL=state-wrapper.js.map
|