@aihu/compiler 1.3.2 → 1.3.4
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 +9 -1
- 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/package.json +24 -12
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
|
|
@@ -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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-wrapper.js","names":[],"sources":["../../js/codemods/state-wrapper/migrate.ts"],"sourcesContent":["/**\n * state-wrapper codemod (#487 §7 — waves 1 + 2, the app-corpus migration)\n *\n * Migrates an `.aihu` file's `@state` block from the retired forms to the\n * ratified wrapper model (`docs/plans/state-model/40-spec.md`):\n *\n * Stage 1 — `$`-macros → wrappers / statement calls / directives (§2, §3):\n * $prop: { x: { … } } → const|let x = prop<T>({ … })\n * $computed: { x: fn } → const x = derived(cfg?, fn)\n * $action: { f: fn } → const f = action(cfg?, fn)\n * $resource: { r: fn } → const r = resource(cfg?, fn)\n * $controller: { c: {value} }→ const c = controller(cfg?, factory)\n * $effect: fn / { name: fn } → effect(fn) / effect({ on: […] }, fn)\n * $lifecycle: { mount, … } → onMount(fn), onDispose(fn), …\n * $aria: { … } / $form: { … }→ aria({ … }) / form({ … })\n * $context: {provide,consume}→ provide('k', v) / const k = consume<T>('k')\n * $route name → const name = route()\n * $before/afterNavigate(fn) → beforeNavigate(fn) / afterNavigate(fn)\n * $extends: X / $shadow: 'm' → base: X / shadow: 'm'\n * bare typed decl `x: T = v` → let x = state(v) (reactive) |\n * plain let/const (inert; §3 row 21 + W627)\n *\n * Stage 2 — signal tuples → `state` (§7 wave 2), INCLUDING call sites:\n * const [x, setX] = signal(v) → let x = state(v)\n * x() → x\n * setX(v) → x = v (statement / handler)\n * setX(p => expr) → x = expr[p→x] (updater desugar)\n *\n * Byte-identity contract: `$`-macro migrations lower onto the SAME IR, so a\n * stage-1-only migration emits byte-identical JS (modulo the old parser's\n * `strip_line_comments` artifact — authored `//` comments inside metadata-bag\n * bodies were BLANKED in old emission and are preserved by the wrapper path).\n * To keep even whitespace stable, entry VALUE text is spliced verbatim — the\n * codemod never re-indents running code.\n *\n * Per-file dialect exclusivity (C625): a file either migrates fully or not at\n * all. Any unmappable `$`-form (e.g. the `mount:`-keyed `$controller`, which\n * has no wrapper equivalent) aborts the file with a warning. Authored signal\n * tuples are exempt from C625 (orthogonal), so a tuple pair whose setter is\n * used as a VALUE (not called) is kept authored, per-pair.\n */\n\nexport interface StateWrapperResult {\n readonly rewritten: string\n readonly warnings: readonly string[]\n /** True when the file was left byte-untouched (nothing to do, or aborted). */\n readonly skipped: boolean\n /** Which change classes were applied — drives the verification bucket. */\n readonly changes: {\n macros: boolean\n tuples: boolean\n bareTyped: boolean\n }\n /** Tuple pairs migrated: authored setter name → state binding name. */\n readonly renamedSetters: ReadonlyArray<{ getter: string; setter: string }>\n}\n\nexport interface StateWrapperOptions {\n /** Run only stage 1 ($-macros + bare typed decls). */\n macrosOnly?: boolean\n /** Run only stage 2 (signal tuples + call sites). */\n tuplesOnly?: boolean\n /**\n * Binding names that must stay PLAIN even when the reactive heuristic says\n * `state(…)` (e.g. a fixture guard depends on the plain-let lowering).\n */\n keepPlain?: readonly string[]\n}\n\nconst INDENT = ' '\n\n// ─── JS-aware scanning helpers ──────────────────────────────────────────────\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\n/** Matching `}` for the `{` at `i` (string/comment aware). */\nexport function 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\n/** Matching `)` for the `(` at `i` (string/comment/brace aware). */\nexport function 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/** Split `{…}`-stripped object-literal text at top-level commas. */\nfunction splitTopLevelCommas(s: string): string[] {\n const out: string[] = []\n let start = 0\n let j = 0\n let depthParen = 0\n let depthBrace = 0\n let depthBracket = 0\n const depthAngle = 0\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 === '(') depthParen++\n else if (c === ')') depthParen--\n else if (c === '{') depthBrace++\n else if (c === '}') depthBrace--\n else if (c === '[') depthBracket++\n else if (c === ']') depthBracket--\n else if (c === '<' && depthAngle >= 0 && /[A-Za-z0-9_$>\\s]/.test(s[j + 1] ?? '')) {\n // Track angle depth loosely; `=>` never reaches here because the `=`\n // branch below runs first when scanning left-to-right.\n } else if (\n c === ',' &&\n depthParen === 0 &&\n depthBrace === 0 &&\n depthBracket === 0 &&\n depthAngle === 0\n ) {\n out.push(s.slice(start, j))\n start = j + 1\n }\n j++\n }\n if (s.slice(start).trim() !== '') out.push(s.slice(start))\n return out\n}\n\n/**\n * Parse one collection entry `name: value` — the value keeps its raw text\n * (newlines and indentation included; splicing is verbatim by contract).\n */\ninterface Entry {\n name: string\n value: string\n /** Comment lines preceding the entry inside the collection body. */\n leading: string\n}\n\nfunction parseEntries(inner: string): Entry[] {\n const entries: Entry[] = []\n for (const piece of splitTopLevelCommas(inner)) {\n const withoutLead = piece.replace(/^\\s*\\n/, '')\n // Separate leading comment lines from the entry itself.\n const lines = withoutLead.split('\\n')\n let k = 0\n const leadingLines: string[] = []\n while (k < lines.length) {\n const t = lines[k]!.trim()\n if (t === '' || t.startsWith('//') || t.startsWith('/*') || t.startsWith('*')) {\n leadingLines.push(lines[k]!)\n k++\n continue\n }\n break\n }\n const rest = lines.slice(k).join('\\n')\n const m = /^\\s*([A-Za-z_$][\\w$]*)\\s*:/.exec(rest)\n if (!m) continue\n entries.push({\n name: m[1]!,\n value: rest.slice(m[0].length).replace(/^[ \\t]/, ''),\n leading: leadingLines.join('\\n'),\n })\n }\n return entries\n}\n\n/** Parse a metadata bag `{ key: value, … }` into raw key/value pairs. */\nfunction parseMetaPairs(objText: string): Map<string, string> | null {\n const t = objText.trim()\n if (!t.startsWith('{')) return null\n const close = matchBrace(t, 0)\n if (close < 0) return null\n const inner = t.slice(1, close)\n const pairs = new Map<string, string>()\n for (const piece of splitTopLevelCommas(inner)) {\n const m = /^\\s*([A-Za-z_$][\\w$]*)\\s*:/.exec(piece)\n if (!m) continue\n pairs.set(\n m[1]!,\n piece\n .slice(m[0].length)\n .replace(/^[ \\t]/, '')\n .replace(/\\s+$/, ''),\n )\n }\n return pairs\n}\n\n/** Whether `expr` is a function expression (arrow or `function`). */\nfunction isFnExpr(expr: string): boolean {\n const t = expr.trim()\n if (t.startsWith('function')) return true\n if (/^async\\b/.test(t)) return true\n if (t.startsWith('(')) {\n const close = matchParen(t, 0)\n if (close < 0) return false\n const after = t.slice(close + 1).trimStart()\n if (after.startsWith('=>')) return true\n // Return-type annotation: `(args): Type => …`.\n if (after.startsWith(':')) {\n const arrowAt = after.indexOf('=>')\n return arrowAt > 0\n }\n return false\n }\n return /^[A-Za-z_$][\\w$]*\\s*=>/.test(t)\n}\n\n// ─── Block location ─────────────────────────────────────────────────────────\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: string): 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 start = 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,\n end: closeIdx + 1,\n bodyStart: openIdx + 1,\n bodyEnd: closeIdx,\n body: source.slice(openIdx + 1, closeIdx),\n }\n}\n\n// ─── Write / read detection (the nature + reactivity heuristics) ────────────\n\n/** Escape every regex-special char, not just `$` — `name`/`getter`/`setter`\n * here are always JS/TS identifiers, so backslash never actually appears,\n * but a full escape is one line and removes the ambiguity CodeQL's\n * js/incomplete-sanitization flags in the `$`-only version. */\nfunction escapeRegex(literal: string): string {\n return literal.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/**\n * Does `code` WRITE `name`? Assignment (plain or compound) or update\n * expression. `==`/`===`/`=>`/`<=`/`>=`/`!=` never match: the operator char\n * preceding `=` breaks the `name\\s*OP=` shape, and the lookahead rejects\n * `==`/`=>` after a bare `=`.\n */\nfunction writesName(code: string, name: string): boolean {\n const esc = escapeRegex(name)\n const re = new RegExp(\n `\\\\b${esc}\\\\s*(\\\\+\\\\+|--|(?:\\\\+|-|\\\\*|/|%|\\\\*\\\\*|&&|\\\\|\\\\||\\\\?\\\\?|&|\\\\||\\\\^|<<|>>>?)?=(?![=>]))`,\n )\n return re.test(code)\n}\n\nfunction readsName(code: string, name: string): boolean {\n const esc = escapeRegex(name)\n return new RegExp(`\\\\b${esc}\\\\b`).test(code)\n}\n\n/** Template two-way bindings (`bind:value={name}`) WRITE their target. */\nfunction bindWrites(templateText: string, name: string): boolean {\n const esc = escapeRegex(name)\n return new RegExp(`\\\\bbind:[\\\\w-]+=\\\\{\\\\s*${esc}\\\\s*\\\\}`).test(templateText)\n}\n\n// ─── Stage 1: $-macros + bare typed declarations ────────────────────────────\n\n/** TS spelling for a v2 `type:` value (String → string, quoted → unquoted). */\nfunction tsType(raw: string): string {\n const t = raw.trim()\n // Unquote only a SINGLE string literal (`type: 'string'`); a union of\n // literal types (`'a' | 'b'`) also starts and ends with a quote but must\n // stay verbatim.\n const isOneLiteral =\n ((t.startsWith(\"'\") && t.endsWith(\"'\")) || (t.startsWith('\"') && t.endsWith('\"'))) &&\n !t.slice(1, -1).includes(t[0]!)\n const unq = isOneLiteral ? t.slice(1, -1) : t\n switch (unq) {\n case 'String':\n return 'string'\n case 'Number':\n return 'number'\n case 'Boolean':\n return 'boolean'\n case 'Array':\n return 'unknown[]'\n case 'Object':\n return 'Record<string, unknown>'\n default:\n return unq\n }\n}\n\n/** Is the default literal rich enough that `prop<T>` inference covers it? */\nfunction defaultCarriesType(typeRaw: string | undefined, defaultRaw: string | undefined): boolean {\n if (defaultRaw === undefined) return false\n const d = defaultRaw.trim()\n if (d === 'null' || d === 'undefined' || d === '[]' || d === '{}') return false\n if (!typeRaw) return true\n const t = typeRaw.trim()\n // Constructor hints (String/Number/Boolean/Array/Object) are fully covered\n // by a concrete default; real TS types (unions, generics) are kept.\n return /^(String|Number|Boolean|Array|Object)$/.test(t)\n}\n\n/** `expose: { read: true, write: true }` → the §6.1 shorthand. */\nfunction exposeShorthand(raw: string): string {\n const pairs = parseMetaPairs(raw.trim())\n if (pairs) {\n const read = pairs.get('read')?.trim() === 'true'\n const write = pairs.get('write')?.trim() === 'true'\n const extraneous = [...pairs.keys()].some((k) => k !== 'read' && k !== 'write')\n if (!extraneous) {\n if (read && write) return `'read write'`\n if (read) return `'read'`\n if (write) return `'write'`\n }\n }\n return raw.trim()\n}\n\ninterface StageState {\n warnings: string[]\n changedMacros: boolean\n changedBareTyped: boolean\n aborted: boolean\n}\n\n/**\n * Build the wrapper declaration for one `$prop` entry.\n * `mutable` decides the nature (`let` vs `const`) — the §2.2 axes.\n */\nfunction emitPropDecl(entry: Entry, mutable: boolean): string {\n const meta = parseMetaPairs(entry.value)\n if (!meta) return `${INDENT}// UNMIGRATABLE $prop entry ${entry.name}`\n const typeRaw = meta.get('type')\n const defaultRaw = meta.get('default')\n const parts: string[] = []\n if (defaultRaw !== undefined) parts.push(`default: ${defaultRaw}`)\n const describe = meta.get('describe')\n if (describe !== undefined) parts.push(`describe: ${describe}`)\n const expose = meta.get('expose')\n if (expose !== undefined) parts.push(`expose: ${exposeShorthand(expose)}`)\n const attribute = meta.get('attribute')\n if (attribute !== undefined) parts.push(`attribute: ${attribute}`)\n const reflect = meta.get('reflect')\n if (reflect !== undefined) parts.push(`reflect: ${reflect}`)\n const required = meta.get('required')\n if (required !== undefined) parts.push(`required: ${required}`)\n\n const generic = typeRaw && !defaultCarriesType(typeRaw, defaultRaw) ? `<${tsType(typeRaw)}>` : ''\n const nature = mutable ? 'let' : 'const'\n const head = `${INDENT}${nature} ${entry.name} = prop${generic}(`\n if (parts.length === 0) return `${head})`\n const inline = `${head}{ ${parts.join(', ')} })`\n if (!inline.includes('\\n') && inline.length <= 100) return inline\n // Multi-line config: one key per line. Values keep their raw text.\n const lines = [`${head}{`]\n for (const p of parts) lines.push(`${INDENT}${INDENT}${p},`)\n lines.push(`${INDENT}})`)\n return lines.join('\\n')\n}\n\n/**\n * Config-first wrapper call for computed/action/resource/controller entries.\n * The running-code text is spliced VERBATIM (byte-identity contract).\n */\nfunction emitConfigFirstDecl(\n wrapper: 'derived' | 'action' | 'resource' | 'controller' | 'effect',\n name: string | null,\n meta: Map<string, string> | null,\n fnRaw: string,\n): string {\n const decl = name === null ? `${INDENT}${wrapper}(` : `${INDENT}const ${name} = ${wrapper}(`\n const cfgParts: string[] = []\n if (meta) {\n const describe = meta.get('describe')\n if (describe !== undefined) cfgParts.push(`describe: ${describe}`)\n const expose = meta.get('expose')\n if (expose !== undefined) cfgParts.push(`expose: ${exposeShorthand(expose)}`)\n const on = meta.get('on')\n if (on !== undefined) cfgParts.push(`on: ${on}`)\n }\n const fn = fnRaw.replace(/\\s+$/, '')\n if (cfgParts.length === 0) return `${decl}${fn})`\n const cfgInline = `{ ${cfgParts.join(', ')} }`\n if (!cfgInline.includes('\\n') && decl.length + cfgInline.length <= 98) {\n return `${decl}\\n${INDENT}${INDENT}${cfgInline},\\n${INDENT}${INDENT}${fn})`\n }\n const lines = [`${decl}`, `${INDENT}${INDENT}{ ${cfgParts.join(`,\\n${INDENT}${INDENT} `)} },`]\n lines.push(`${INDENT}${INDENT}${fn})`)\n return lines.join('\\n')\n}\n\n/** One `$computed`/`$action`/`$resource` entry → wrapper declaration. */\nfunction emitValueEntryDecl(\n wrapper: 'derived' | 'action' | 'resource',\n entry: Entry,\n st: StageState,\n): string | null {\n const codeKey = wrapper === 'action' ? 'handler' : 'value'\n if (isFnExpr(entry.value)) {\n return emitConfigFirstDecl(wrapper, entry.name, null, entry.value)\n }\n const meta = parseMetaPairs(entry.value)\n if (!meta) {\n st.warnings.push(`unrecognized ${wrapper} entry shape for '${entry.name}'`)\n return null\n }\n const fn = meta.get(codeKey)\n if (fn === undefined) {\n st.warnings.push(`${wrapper} entry '${entry.name}' has no ${codeKey}: key`)\n return null\n }\n // Refuse silent metadata loss: only describe/expose (+ the code key) map.\n for (const k of meta.keys()) {\n if (k !== 'describe' && k !== 'expose' && k !== codeKey) {\n st.warnings.push(`${wrapper} entry '${entry.name}' carries unmapped key '${k}:'`)\n return null\n }\n }\n return emitConfigFirstDecl(wrapper, entry.name, meta, fn)\n}\n\nfunction migrateStateMacrosBody(\n body: string,\n templateText: string,\n st: StageState,\n keepPlain: ReadonlySet<string>,\n): string {\n // Reactive-read corpus for the bare-typed heuristic: the template plus\n // every derivation-position body ($computed/$form/$aria/$resource values).\n // A colon-form field read there needs real reactivity → state(). $effect\n // bodies are deliberately EXCLUDED: a field both read and written inside\n // one effect (the debounce-timer idiom) would, as a signal, re-trigger its\n // own effect — the inert plain `let` is the faithful migration there.\n let derivationText = ''\n {\n const re = /^[ \\t]*\\$(computed|form|aria|resource)\\s*:\\s*\\{/gm\n let m: RegExpExecArray | null = re.exec(body)\n while (m !== null) {\n const open = m.index + m[0].length - 1\n const close = matchBrace(body, open)\n if (close > 0) derivationText += body.slice(open, close + 1)\n m = re.exec(body)\n }\n }\n const reactiveReadCorpus = `${templateText}\\n${derivationText}`\n\n const out: string[] = []\n let i = 0\n while (i < body.length) {\n const nl = body.indexOf('\\n', i)\n const lineEnd = nl < 0 ? body.length : nl\n const lineRaw = body.slice(i, lineEnd)\n const line = lineRaw.trim()\n const indentLen = lineRaw.length - lineRaw.trimStart().length\n const lineStart = i + indentLen\n\n // ── $-collections ──────────────────────────────────────────────────────\n const coll =\n /^\\$(prop|computed|action|resource|effect|lifecycle|aria|form|context|controller|event|stream|extract)\\s*:\\s*/.exec(\n line,\n )\n if (coll) {\n const kind = coll[1]!\n const afterColon = lineStart + coll[0].length\n // `$effect: () => …` — anonymous statement form.\n if (kind === 'effect' && body[afterColon] !== '{') {\n const fnStart = afterColon\n const end = scanArrowEnd(body, fnStart)\n if (end < 0) {\n st.warnings.push('unparseable anonymous $effect — file left unmigrated')\n st.aborted = true\n return body\n }\n const fn = body.slice(fnStart, end).replace(/\\s+$/, '')\n out.push(`${INDENT}effect(${fn})`)\n st.changedMacros = true\n i = end\n if (body[i] === ';') i++\n if (body[i] === '\\n') i++\n continue\n }\n if (body[afterColon] !== '{') {\n st.warnings.push(`unrecognized $${kind} value shape — file left unmigrated`)\n st.aborted = true\n return body\n }\n const close = matchBrace(body, afterColon)\n if (close < 0) {\n st.aborted = true\n return body\n }\n const inner = body.slice(afterColon + 1, close)\n const entries = parseEntries(inner)\n const decls: string[] = []\n const push = (leading: string, text: string | null) => {\n if (text === null) {\n st.aborted = true\n return\n }\n if (leading.trim()) decls.push(leading.replace(/\\s+$/, ''))\n decls.push(text)\n }\n switch (kind) {\n case 'prop': {\n for (const e of entries) {\n const mutable =\n writesName(body, e.name) ||\n writesName(templateText, e.name) ||\n bindWrites(templateText, e.name)\n push(e.leading, emitPropDecl(e, mutable))\n }\n break\n }\n case 'computed':\n case 'action':\n case 'resource': {\n const wrapper = kind === 'computed' ? 'derived' : (kind as 'action' | 'resource')\n for (const e of entries) push(e.leading, emitValueEntryDecl(wrapper, e, st))\n break\n }\n case 'effect': {\n for (const e of entries) {\n if (isFnExpr(e.value)) {\n push(e.leading, `${INDENT}effect(${e.value.replace(/\\s+$/, '')})`)\n } else {\n const meta = parseMetaPairs(e.value)\n const fn = meta?.get('value')\n if (!meta || fn === undefined) {\n st.warnings.push(`$effect entry '${e.name}' unrecognized — file left unmigrated`)\n st.aborted = true\n return body\n }\n push(e.leading, emitConfigFirstDecl('effect', null, meta, fn))\n }\n }\n break\n }\n case 'lifecycle': {\n const hookFor: Record<string, string> = {\n mount: 'onMount',\n dispose: 'onDispose',\n adopt: 'onAdopt',\n attributeChange: 'onAttributeChange',\n }\n for (const e of entries) {\n const hook = hookFor[e.name]\n if (!hook) {\n st.warnings.push(`unknown $lifecycle key '${e.name}' — file left unmigrated`)\n st.aborted = true\n return body\n }\n push(e.leading, `${INDENT}${hook}(${e.value.replace(/\\s+$/, '')})`)\n }\n break\n }\n case 'aria':\n case 'form': {\n // One config object, inner text verbatim.\n const innerTrimmed = inner.replace(/^\\s*\\n/, '').replace(/\\s+$/, '')\n push('', `${INDENT}${kind}({\\n${innerTrimmed}\\n${INDENT}})`)\n break\n }\n case 'context': {\n for (const e of entries) {\n if (e.name === 'provide') {\n const sub = parseMetaPairs(e.value)\n if (!sub) {\n st.aborted = true\n return body\n }\n for (const [key, valObj] of sub) {\n const valMeta = parseMetaPairs(valObj)\n const value = valMeta?.get('value')\n if (value === undefined) {\n st.warnings.push(`$context provide '${key}' has no value: — file left unmigrated`)\n st.aborted = true\n return body\n }\n push(e.leading, `${INDENT}provide('${key}', ${value})`)\n }\n } else if (e.name === 'consume') {\n const sub = parseMetaPairs(e.value)\n if (!sub) {\n st.aborted = true\n return body\n }\n for (const [key, valObj] of sub) {\n const valMeta = parseMetaPairs(valObj)\n const typeRaw = valMeta?.get('type')\n const generic = typeRaw ? `<${tsType(typeRaw)}>` : ''\n push(e.leading, `${INDENT}const ${key} = consume${generic}('${key}')`)\n }\n } else {\n st.aborted = true\n return body\n }\n }\n break\n }\n case 'controller': {\n for (const e of entries) {\n const meta = parseMetaPairs(e.value)\n const factory = meta?.get('value')\n if (!meta || factory === undefined) {\n st.warnings.push(\n `$controller entry '${e.name}' has no value: factory (the mount:-keyed shape ` +\n `has no wrapper equivalent) — file left unmigrated`,\n )\n st.aborted = true\n return body\n }\n push(e.leading, emitConfigFirstDecl('controller', e.name, meta, factory))\n }\n break\n }\n case 'extract': {\n // Directive rename only; value verbatim.\n push('', `${INDENT}extract: ${body.slice(afterColon, close + 1)}`)\n break\n }\n default: {\n st.warnings.push(`$${kind} has no app-corpus mapping — file left unmigrated`)\n st.aborted = true\n return body\n }\n }\n if (st.aborted) return body\n out.push(decls.join('\\n'))\n st.changedMacros = true\n i = close + 1\n if (body[i] === ';') i++\n if (body[i] === '\\n') i++\n continue\n }\n\n // ── Directives + dedicated forms ───────────────────────────────────────\n const extendsM = /^\\$extends\\s*:\\s*(.+)$/.exec(line)\n if (extendsM) {\n out.push(`${' '.repeat(indentLen)}base: ${extendsM[1]!.trim()}`)\n st.changedMacros = true\n i = lineEnd + 1\n continue\n }\n const shadowM = /^\\$shadow\\s*:\\s*(.+)$/.exec(line)\n if (shadowM) {\n out.push(`${' '.repeat(indentLen)}shadow: ${shadowM[1]!.trim()}`)\n st.changedMacros = true\n i = lineEnd + 1\n continue\n }\n const routeM = /^\\$route\\s+([A-Za-z_$][\\w$]*)\\s*;?$/.exec(line)\n if (routeM) {\n out.push(`${' '.repeat(indentLen)}const ${routeM[1]} = route()`)\n st.changedMacros = true\n i = lineEnd + 1\n continue\n }\n if (/^\\$(beforeNavigate|afterNavigate)\\s*\\(/.test(line)) {\n const parenIdx = body.indexOf('(', lineStart)\n const close = matchParen(body, parenIdx)\n if (close < 0) {\n st.aborted = true\n return body\n }\n let end = close + 1\n if (body[end] === ';') end++\n out.push(`${' '.repeat(indentLen)}${body.slice(lineStart + 1, end)}`)\n st.changedMacros = true\n i = end\n if (body[i] === '\\n') i++\n continue\n }\n if (line.startsWith('$')) {\n st.warnings.push(`unmapped macro form '${line.split(/\\s|\\(|:/)[0]}' — file left unmigrated`)\n st.aborted = true\n return body\n }\n\n // ── Bare typed declaration `name: T = v` (§3 row 21) ───────────────────\n const bare = /^([A-Za-z_$][\\w$]*)\\s*:\\s*([^=\\n]+?)\\s*=\\s*(.+?);?\\s*$/.exec(line)\n if (\n bare &&\n !/^(if|else|for|while|return|case|default|import|export|type|interface)\\b/.test(line)\n ) {\n const name = bare[1]!\n const typeRaw = bare[2]!.trim()\n const init = bare[3]!.trim()\n const ws = ' '.repeat(indentLen)\n const written =\n writesName(stripSpan(body, i, lineEnd), name) ||\n writesName(templateText, name) ||\n bindWrites(templateText, name)\n const reactivelyRead = readsName(reactiveReadCorpus, name)\n if (written && reactivelyRead && !keepPlain.has(name)) {\n const inferrable =\n /^(-?\\d|'|\"|`|true$|false$)/.test(init) && init !== 'null' && init !== 'undefined'\n const generic = inferrable ? '' : `<${typeRaw}>`\n out.push(`${ws}let ${name} = state${generic}(${init})`)\n } else if (written) {\n out.push(`${ws}let ${name}: ${typeRaw} = ${init}`)\n } else {\n out.push(`${ws}const ${name}: ${typeRaw} = ${init}`)\n }\n st.changedBareTyped = true\n i = lineEnd + 1\n continue\n }\n\n // ── Everything else: verbatim, consuming balanced multi-line statements\n const stmtEnd = consumeBalancedStatement(body, i)\n out.push(body.slice(i, stmtEnd).replace(/\\n$/, ''))\n i = stmtEnd\n }\n return out.join('\\n')\n}\n\n/** Remove a span (decl's own line) so self-matches don't count as writes. */\nfunction stripSpan(s: string, start: number, end: number): string {\n return s.slice(0, start) + s.slice(end)\n}\n\n/** Consume one whole statement (through balanced brackets) incl. newline. */\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\n/** End offset (exclusive) of an arrow/function expression at `start`. */\nfunction scanArrowEnd(s: string, start: number): number {\n let p = start\n while (p < s.length && /[ \\t]/.test(s[p]!)) p++\n if (s.slice(p, p + 5) === 'async') {\n p += 5\n while (p < s.length && /[ \\t]/.test(s[p]!)) p++\n }\n if (s.slice(p, p + 8) === 'function') {\n const braceIdx = s.indexOf('{', p)\n if (braceIdx < 0) return -1\n const close = matchBrace(s, braceIdx)\n return close < 0 ? -1 : close + 1\n }\n if (s[p] === '(') {\n const parenClose = matchParen(s, p)\n if (parenClose < 0) return -1\n p = parenClose + 1\n } else {\n // single-ident param\n const m = /^[A-Za-z_$][\\w$]*/.exec(s.slice(p))\n if (!m) return -1\n p += m[0].length\n }\n while (p < s.length && /[ \\t]/.test(s[p]!)) p++\n if (s[p] === ':') {\n const arrowAt = s.indexOf('=>', p)\n if (arrowAt < 0) return -1\n p = arrowAt\n }\n if (s.slice(p, p + 2) !== '=>') return -1\n p += 2\n while (p < s.length && /[ \\t]/.test(s[p]!)) p++\n if (s[p] === '{') {\n const close = matchBrace(s, p)\n return close < 0 ? -1 : close + 1\n }\n // Expression body: to end of line (top-level).\n const nl = s.indexOf('\\n', p)\n return nl < 0 ? s.length : nl\n}\n\n// ─── Stage 2: signal tuples ─────────────────────────────────────────────────\n\ninterface TuplePair {\n getter: string\n setter: string | null\n generic: string\n init: string\n declStart: number\n declEnd: number\n}\n\nfunction findTuples(body: string, offset: number): TuplePair[] {\n const pairs: TuplePair[] = []\n const re =\n /(^|\\n)([ \\t]*)(?:const|let)\\s*\\[\\s*([A-Za-z_$][\\w$]*)\\s*(?:,\\s*([A-Za-z_$][\\w$]*)\\s*)?\\]\\s*=\\s*signal\\b/g\n let m: RegExpExecArray | null = re.exec(body)\n while (m !== null) {\n const declStart = m.index + m[1]!.length + m[2]!.length\n let p = m.index + m[0].length\n let generic = ''\n if (body[p] === '<') {\n // balanced angle scan\n let depth = 1\n let j = p + 1\n while (j < body.length && depth > 0) {\n if (body[j] === '<') depth++\n else if (body[j] === '>') depth--\n j++\n }\n generic = body.slice(p, j)\n p = j\n }\n if (body[p] !== '(') {\n m = re.exec(body)\n continue\n }\n const close = matchParen(body, p)\n if (close < 0) {\n m = re.exec(body)\n continue\n }\n const init = body.slice(p + 1, close)\n let declEnd = close + 1\n if (body[declEnd] === ';') declEnd++\n pairs.push({\n getter: m[3]!,\n setter: m[4] ?? null,\n generic,\n init,\n declStart: declStart + offset,\n declEnd: declEnd + offset,\n })\n m = re.exec(body)\n }\n return pairs\n}\n\n/** All indexes of `name(` call heads in `text` (word-boundary). */\nfunction callSites(text: string, name: string): number[] {\n const out: number[] = []\n const esc = escapeRegex(name)\n const re = new RegExp(`(?<![\\\\w$.])${esc}\\\\s*\\\\(`, 'g')\n let m: RegExpExecArray | null = re.exec(text)\n while (m !== null) {\n out.push(m.index)\n m = re.exec(text)\n }\n return out\n}\n\n/** Rewrite one setter call `setX(ARG)` → assignment text. */\nfunction rewriteSetterCall(\n text: string,\n at: number,\n setter: string,\n getter: string,\n warnings: string[],\n): { replaced: string; start: number; end: number } | null {\n const parenIdx = text.indexOf('(', at + setter.length - 1)\n const open = text.indexOf('(', at)\n const close = matchParen(text, open)\n if (close < 0) return null\n void parenIdx\n const arg = text.slice(open + 1, close).trim()\n\n // Updater form: `p => expr` / `(p) => expr` / `(p: T) => expr`.\n let rhs: string | null = null\n const upd =\n /^(?:\\(\\s*([A-Za-z_$][\\w$]*)\\s*(?::[^)]*)?\\)|([A-Za-z_$][\\w$]*))\\s*=>\\s*([\\s\\S]+)$/.exec(arg)\n if (upd) {\n const param = upd[1] ?? upd[2]!\n const bodyExpr = upd[3]!.trim()\n if (bodyExpr.startsWith('{')) {\n warnings.push(\n `updater with block body at ${setter}(${arg.slice(0, 30)}…) — kept as an IIFE over the current value`,\n )\n rhs = `(${arg})(${getter})`\n } else {\n const esc = escapeRegex(param)\n rhs = bodyExpr.replace(new RegExp(`\\\\b${esc}\\\\b`, 'g'), getter)\n }\n } else {\n rhs = arg\n }\n\n // Context: statement / arrow-body / expression position.\n let k = at - 1\n while (k >= 0 && /[ \\t]/.test(text[k]!)) k--\n const isArrowBody = k >= 1 && text[k] === '>' && text[k - 1] === '='\n // Walk back over `await`.\n let stmtProbe = k\n const beforeWord = /(?:^|[\\s;{}])await$/.exec(text.slice(Math.max(0, k - 6), k + 1))\n if (beforeWord) stmtProbe = k - 5 - 1\n const prevCh = stmtProbe >= 0 ? text[stmtProbe] : '\\n'\n const isStatement = prevCh === '\\n' || prevCh === ';' || prevCh === '{' || stmtProbe < 0\n\n let replaced: string\n if (isArrowBody) {\n replaced = `{ ${getter} = ${rhs} }`\n } else if (isStatement) {\n replaced = `${getter} = ${rhs}`\n } else {\n replaced = `(${getter} = ${rhs})`\n }\n const end = close + 1\n return { replaced, start: at, end }\n}\n\nfunction migrateTuplesIn(\n source: string,\n st: { warnings: string[]; changedTuples: boolean },\n renamed: Array<{ getter: string; setter: string }>,\n): string {\n const state = findBlock(source, 'state')\n if (!state) return source\n const pairs = findTuples(state.body, state.bodyStart)\n if (pairs.length === 0) return source\n\n let text = source\n // Process pairs last-to-first so recorded spans stay valid.\n for (const pair of [...pairs].reverse()) {\n const { getter, setter } = pair\n // Guard: setter referenced as a VALUE (not a call) anywhere → keep pair.\n if (setter) {\n const esc = escapeRegex(setter)\n const valueUse = new RegExp(`(?<![\\\\w$.'\"\\`])${esc}(?![\\\\w$]|\\\\s*\\\\()`)\n const outsideDecl = stripSpan(text, pair.declStart, pair.declEnd)\n if (valueUse.test(outsideDecl)) {\n st.warnings.push(\n `tuple [${getter}, ${setter}] kept authored — the setter is used as a value ` +\n `(cannot be expressed as a state binding during the compat window)`,\n )\n continue\n }\n }\n\n // 1. Setter calls → assignments (whole file: @state body + @template).\n if (setter) {\n let sites = callSites(text, setter)\n // Skip the declaration site itself.\n sites = sites.filter((idx) => idx < pair.declStart || idx >= pair.declEnd)\n for (const idx of sites.reverse()) {\n const r = rewriteSetterCall(text, idx, setter, getter, st.warnings)\n if (!r) {\n st.warnings.push(`unbalanced ${setter}(…) call — left untouched`)\n continue\n }\n text = text.slice(0, r.start) + r.replaced + text.slice(r.end)\n }\n }\n\n // 2. Getter reads `x()` → `x` (whole file; empty-arg calls only).\n {\n const esc = escapeRegex(getter)\n // Reject member reads (`obj.x()`) but allow spread (`...x()`): the\n // preceding dot only blocks when it is not itself part of `...`.\n text = text.replace(\n new RegExp(`(?<![\\\\w$])(?<!(?<!\\\\.)\\\\.)${esc}\\\\s*\\\\(\\\\s*\\\\)`, 'g'),\n getter,\n )\n }\n\n // 3. The declaration itself. Re-locate it (upstream edits shifted spans\n // only AFTER the decl, but re-find defensively).\n {\n const esc = escapeRegex(getter)\n const declRe = new RegExp(\n `(?:const|let)\\\\s*\\\\[\\\\s*${esc}\\\\s*(?:,\\\\s*[A-Za-z_$][\\\\w$]*\\\\s*)?\\\\]\\\\s*=\\\\s*signal(<[^\\\\n]*?>)?\\\\(`,\n )\n const dm = declRe.exec(text)\n if (dm) {\n const open = text.indexOf('(', dm.index + dm[0].length - 1)\n const close = matchParen(text, open)\n if (close > 0) {\n let declEnd = close + 1\n if (text[declEnd] === ';') declEnd++\n const generic = dm[1] ?? ''\n const init = text.slice(open + 1, close)\n // An object-literal initial value must be parenthesized: the\n // one-signature rule parses `state({…})` as the reserved CONFIG\n // bag (split_config_fn), so a bare `{}` init is C629.\n const initOut = init.trim().startsWith('{') ? `(${init})` : init\n text =\n text.slice(0, dm.index) +\n `let ${getter} = state${generic}(${initOut})` +\n text.slice(declEnd)\n }\n }\n }\n\n st.changedTuples = true\n if (setter) renamed.push({ getter, setter })\n }\n\n // Drop the `signal` import when no `signal(`/`signal<` use remains.\n if (!/\\bsignal\\s*[(<]/.test(text)) {\n text = text.replace(\n /^([ \\t]*)import\\s*\\{([^}]*)\\}\\s*from\\s*'@aihu\\/signals'\\s*;?\\s*\\n/m,\n (_full, ws: string, names: string) => {\n const kept = names\n .split(',')\n .map((s) => s.trim())\n .filter((n) => n !== '' && n !== 'signal')\n if (kept.length === 0) return ''\n return `${ws}import { ${kept.join(', ')} } from '@aihu/signals'\\n`\n },\n )\n }\n return text\n}\n\n// ─── Public entry point ─────────────────────────────────────────────────────\n\nexport function migrateStateWrappers(\n source: string,\n options: StateWrapperOptions = {},\n): StateWrapperResult {\n const st: StageState = {\n warnings: [],\n changedMacros: false,\n changedBareTyped: false,\n aborted: false,\n }\n const tupleSt = { warnings: st.warnings, changedTuples: false }\n const renamed: Array<{ getter: string; setter: string }> = []\n const keepPlain = new Set(options.keepPlain ?? [])\n\n let text = source\n\n if (!options.tuplesOnly) {\n const state = findBlock(text, 'state')\n if (state) {\n const template = findBlock(text, 'template')\n const newBody = migrateStateMacrosBody(state.body, template?.body ?? '', st, keepPlain)\n // Statement-call gating guard (state_wrappers.rs module doc): the\n // compiler honors statement-position intrinsics only when the file also\n // declares a binding wrapper or naked directive. A migration whose new\n // dialect would be statement-calls ONLY (e.g. a provide-only file)\n // would silently compile them as plain JS — refuse it.\n if (!st.aborted && st.changedMacros) {\n const hasBinding =\n /^\\s*(?:const|let)\\s+[A-Za-z_$][\\w$]*\\s*=\\s*(?:state|prop|derived|action|resource|stream|controller|route|consume)\\s*[<(]/m.test(\n newBody,\n ) || /^\\s*(?:base|shadow|extract)\\s*:/m.test(newBody)\n const hasStatementCall =\n /^\\s*(?:effect|onMount|onDispose|onAdopt|onAttributeChange|aria|form|provide|event|beforeNavigate|afterNavigate)\\s*[(<]/m.test(\n newBody,\n )\n if (hasStatementCall && !hasBinding) {\n st.warnings.push(\n 'migration would produce only statement-position calls with no binding ' +\n \"wrapper or directive — the compiler's new-dialect gate would treat them \" +\n 'as plain JS; file left unmigrated',\n )\n st.aborted = true\n }\n }\n if (!st.aborted && newBody !== state.body) {\n const trimmed = newBody.replace(/^\\n+/, '').replace(/\\s+$/, '')\n text = `${text.slice(0, state.start)}@state {\\n${trimmed}\\n}${text.slice(state.end)}`\n }\n }\n }\n\n // De-call prop reads (#502). In the wrapper model `prop()` returns a VALUE,\n // so a read is `name`, not `name()`. The macros pass rewrites the `$prop`\n // DECLARATION to `const name = prop(…)` but leaves every read called; fix\n // them across @state + the template, mirroring the tuple-getter de-call in\n // migrateTuplesIn. Empty-arg calls only; member reads (`obj.name()`) are left\n // alone. This is correct even for function-valued props: the retired model\n // read the prop via `name()` and invoked via `name()()`, so de-calling the\n // read's trailing `()` turns an invoke `name()()` into `name()` and a bare\n // read `name()` into `name`.\n if (!options.tuplesOnly && !st.aborted) {\n const migratedState = findBlock(text, 'state')\n if (migratedState) {\n const propNames = [\n ...migratedState.body.matchAll(/(?:const|let)\\s+([A-Za-z_$][\\w$]*)\\s*=\\s*prop\\s*[<(]/g),\n ].map((m) => m[1] ?? '')\n for (const name of propNames) {\n if (!name) continue\n const esc = escapeRegex(name)\n text = text.replace(\n new RegExp(`(?<![\\\\w$])(?<!(?<!\\\\.)\\\\.)${esc}\\\\s*\\\\(\\\\s*\\\\)`, 'g'),\n name,\n )\n }\n }\n }\n\n if (!options.macrosOnly && !st.aborted) {\n text = migrateTuplesIn(text, tupleSt, renamed)\n }\n\n const changed = st.changedMacros || st.changedBareTyped || tupleSt.changedTuples\n return {\n rewritten: st.aborted ? source : text,\n warnings: st.warnings,\n skipped: st.aborted || !changed,\n changes: {\n macros: st.changedMacros,\n tuples: tupleSt.changedTuples,\n bareTyped: st.changedBareTyped,\n },\n renamedSetters: renamed,\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region js/codemods/template-grammar-v2/migrate.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* template-grammar-v2 codemod — migrate v1 template syntax to the
|
|
4
|
+
* prefix-less grammar (docs/plans/template-grammar/40-spec.md).
|
|
5
|
+
*
|
|
6
|
+
* Transforms (template surface only; `@state` bodies are untouched):
|
|
7
|
+
* $if={e} / $if="x" => if={e} / if={x}
|
|
8
|
+
* $each="list as item[, i]" => each={item[, i] of list}
|
|
9
|
+
* $each={list as item} => each={item of list}
|
|
10
|
+
* $each={list} [+ $let={x}] => each={x of list} (default alias: item)
|
|
11
|
+
* $key/$show/$html/$ref/$memo => naked word, braced value
|
|
12
|
+
* $once / $raw => once / raw
|
|
13
|
+
* $on.click={h} / quoted => on:click={h}
|
|
14
|
+
* $bind.value={x} / quoted => bind:value={x}
|
|
15
|
+
* $class:active={c} => class:active={c}
|
|
16
|
+
* $class={e} and any $attr={e} => attr={e} (plain braces)
|
|
17
|
+
* {#if}/{:else if}/{:else}/{/if} => <group if=…>/<group elseif=…>/…
|
|
18
|
+
* {#each … as … (key)}/{:empty}/{/each} => <group each={… of …} key=…>/…
|
|
19
|
+
* {@html e} => <span html={e}></span>
|
|
20
|
+
* {{ident}} => {ident}
|
|
21
|
+
* <$link …>…</$link> => <a …>…</a>
|
|
22
|
+
* <$slot>/<$suspense>/… => <slot>/<suspense>/… (de-`$`-ed)
|
|
23
|
+
*
|
|
24
|
+
* The block conversions are mechanical (`<group>`-wrapping). Authors may
|
|
25
|
+
* hand-tighten single-element branches onto the element itself afterwards —
|
|
26
|
+
* both forms compile to the same arbor structural calls.
|
|
27
|
+
*/
|
|
28
|
+
interface TemplateGrammarResult {
|
|
29
|
+
readonly rewritten: string;
|
|
30
|
+
readonly changed: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Run every template-grammar-v2 pass over one `.aihu` source (or a markdown
|
|
34
|
+
* document containing `.aihu` snippets — the transforms are anchored to
|
|
35
|
+
* template-syntax shapes and leave prose alone).
|
|
36
|
+
*/
|
|
37
|
+
declare function migrateTemplateGrammar(source: string): TemplateGrammarResult;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { TemplateGrammarResult, migrateTemplateGrammar };
|
|
40
|
+
//# sourceMappingURL=template-grammar-v2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-grammar-v2.d.ts","names":[],"sources":["../../js/codemods/template-grammar-v2/migrate.ts"],"mappings":";;AA2BA;AAAsC;AAAA;AAAA;AAEpB;AAkLlB;AAAsC;AAAA;AAAuC;AAAA;;;;;;;;;;;;;;;;UApL5D,qBAAA;EAAA,SACN,SAAA;EAAA,SACA,OAAO;AAAA;;;;;;iBAkLF,sBAAA,CAAuB,MAAA,WAAiB,qBAAqB"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
const e=[`slot`,`suspense`,`shield`,`outlet`,`router`,`navigate`,`guard`,`warp`,`focusTrap`,`liveRegion`,`visuallyHidden`,`skipLink`];function t(e){return e.replace(/<[a-zA-Z$][^<>]*>/g,e=>{if(!e.includes(`$let=`))return e;let t=e.match(/\$let=\{([^}]+)\}|\$let="([^"]+)"/);if(!t)return e;let n=(t[1]??t[2]??``).trim(),r=e.match(/\$each=\{([^}]+)\}|\$each="([^"]+)"/);if(!r)return e;let i=(r[1]??r[2]??``).trim(),a=e.replace(t[0],``);return a=a.replace(r[0],`each={${n} of ${i}}`),a.replace(/\s+(\/?>)$/,`$1`).replace(/\s{2,}/g,e=>e.includes(`
|
|
2
|
+
`)?e:` `)})}function n(e){let t=0,n=-1;for(let r=0;r<e.length;r++){let i=e[r];i===`(`||i===`[`||i===`{`?t++:i===`)`||i===`]`||i===`}`?t--:t===0&&i===` `&&e.startsWith(`as `,r+1)&&n===-1&&(n=r)}if(n===-1)return null;let r=e.slice(0,n).trim(),i=e.slice(n+4).trim(),a;if(i.endsWith(`)`)){let e=0;for(let t=i.length-1;t>=0;t--){let n=i[t];if(n===`)`)e++;else if(n===`(`&&(e--,e===0)){t>0&&/\s/.test(i[t-1]??``)&&(a=i.slice(t+1,i.length-1).trim(),i=i.slice(0,t).trim());break}}}return{list:r,aliases:i,key:a}}function r(e){let t=e;return t=t.replace(/\{#if\s+([^{}]+(?:\{[^{}]*\}[^{}]*)*)\}/g,(e,t)=>`<group if={${t.trim()}}>`),t=t.replace(/\{:else\s+if\s+([^{}]+(?:\{[^{}]*\}[^{}]*)*)\}/g,(e,t)=>`</group><group elseif={${t.trim()}}>`),t=t.replace(/\{:else\}/g,`</group><group else>`),t=t.replace(/\{\/\s*if\s*\}/g,`</group>`),t=t.replace(/\{#each\s+([^{}]+(?:\{[^{}]*\}[^{}]*)*)\}/g,(e,t)=>{let r=n(t.trim());if(!r)return e;let i=r.key?` key={${r.key}}`:``;return`<group each={${r.aliases} of ${r.list}}${i}>`}),t=t.replace(/\{:empty\}/g,`</group><group empty>`),t=t.replace(/\{\/\s*each\s*\}/g,`</group>`),t=t.replace(/\{@html\s+([^{}]+(?:\{[^{}]*\}[^{}]*)*)\}/g,(e,t)=>`<span html={${t.trim()}}></span>`),t}function i(e){let t=e;return t=t.replace(/\$on\.([A-Za-z][\w]*((?:\.[a-z]+)*))=\{/g,`on:$1={`),t=t.replace(/\$on\.([A-Za-z][\w]*)="([^"]*)"/g,`on:$1={$2}`),t=t.replace(/\$bind\.([A-Za-z][\w-]*)=\{/g,`bind:$1={`),t=t.replace(/\$bind\.([A-Za-z][\w-]*)="([^"]*)"/g,`bind:$1={$2}`),t=t.replace(/\$class[:.]([A-Za-z][\w-]*)=\{/g,`class:$1={`),t=t.replace(/\$class[:.]([A-Za-z][\w-]*)="([^"]*)"/g,`class:$1={$2}`),t=t.replace(/\$each="([^"]+?) as ([^"]+?)"/g,`each={$2 of $1}`),t=t.replace(/\$each=\{([^}]+?) as ([^}]+?)\}/g,`each={$2 of $1}`),t=t.replace(/\$each=\{([^}]+)\}/g,`each={item of $1}`),t=t.replace(/\$each="([^"]+)"/g,`each={item of $1}`),t=t.replace(/\$(if|key|show|html|ref|memo)=\{/g,`$1={`),t=t.replace(/\$(if|key|show|html|ref|memo)="([^"]*)"/g,`$1={$2}`),t=t.replace(/\$once(?=[\s/>])/g,`once`),t=t.replace(/\$raw(?=[\s/>])/g,`raw`),t=t.replace(/(?<![\w$])\$([a-zA-Z][\w-]*)=\{/g,`$1={`),t}function a(t){let n=t;n=n.replace(/<\$link\b/g,`<a`),n=n.replace(/<\/\$link>/g,`</a>`);for(let t of e)n=n.replace(RegExp(`<\\$${t}\\b`,`g`),`<${t}`),n=n.replace(RegExp(`</\\$${t}>`,`g`),`</${t}>`);return n}function o(e){return e.replace(/\{\{\s*([A-Za-z_$][\w$]*)\s*\}\}/g,`{$1}`)}function s(e){let n=e;return n=t(n),n=r(n),n=i(n),n=a(n),n=o(n),{rewritten:n,changed:n!==e}}export{s as migrateTemplateGrammar};
|
|
3
|
+
//# sourceMappingURL=template-grammar-v2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-grammar-v2.js","names":[],"sources":["../../js/codemods/template-grammar-v2/migrate.ts"],"sourcesContent":["/**\n * template-grammar-v2 codemod — migrate v1 template syntax to the\n * prefix-less grammar (docs/plans/template-grammar/40-spec.md).\n *\n * Transforms (template surface only; `@state` bodies are untouched):\n * $if={e} / $if=\"x\" => if={e} / if={x}\n * $each=\"list as item[, i]\" => each={item[, i] of list}\n * $each={list as item} => each={item of list}\n * $each={list} [+ $let={x}] => each={x of list} (default alias: item)\n * $key/$show/$html/$ref/$memo => naked word, braced value\n * $once / $raw => once / raw\n * $on.click={h} / quoted => on:click={h}\n * $bind.value={x} / quoted => bind:value={x}\n * $class:active={c} => class:active={c}\n * $class={e} and any $attr={e} => attr={e} (plain braces)\n * {#if}/{:else if}/{:else}/{/if} => <group if=…>/<group elseif=…>/…\n * {#each … as … (key)}/{:empty}/{/each} => <group each={… of …} key=…>/…\n * {@html e} => <span html={e}></span>\n * {{ident}} => {ident}\n * <$link …>…</$link> => <a …>…</a>\n * <$slot>/<$suspense>/… => <slot>/<suspense>/… (de-`$`-ed)\n *\n * The block conversions are mechanical (`<group>`-wrapping). Authors may\n * hand-tighten single-element branches onto the element itself afterwards —\n * both forms compile to the same arbor structural calls.\n */\n\nexport interface TemplateGrammarResult {\n readonly rewritten: string\n readonly changed: boolean\n}\n\nconst MACRO_ELEMENTS = [\n 'slot',\n 'suspense',\n 'shield',\n 'outlet',\n 'router',\n 'navigate',\n 'guard',\n 'warp',\n 'focusTrap',\n 'liveRegion',\n 'visuallyHidden',\n 'skipLink',\n] as const\n\n/** Fold `$each={list}` + `$let={alias}` on one tag into `each={alias of list}`. */\nfunction foldEachLet(src: string): string {\n return src.replace(/<[a-zA-Z$][^<>]*>/g, (tag) => {\n if (!tag.includes('$let=')) return tag\n const letM = tag.match(/\\$let=\\{([^}]+)\\}|\\$let=\"([^\"]+)\"/)\n if (!letM) return tag\n const alias = (letM[1] ?? letM[2] ?? '').trim()\n const eachM = tag.match(/\\$each=\\{([^}]+)\\}|\\$each=\"([^\"]+)\"/)\n if (!eachM) return tag\n const list = (eachM[1] ?? eachM[2] ?? '').trim()\n let out = tag.replace(letM[0], '')\n out = out.replace(eachM[0], `each={${alias} of ${list}}`)\n return out\n .replace(/\\s+(\\/?>)$/, '$1')\n .replace(/\\s{2,}/g, (ws) => (ws.includes('\\n') ? ws : ' '))\n })\n}\n\n/** `{#each LIST as ALIASES (KEY)}` head split, scanner-lite (paren/bracket depth). */\nfunction splitEachHead(\n head: string,\n): { list: string; aliases: string; key: string | undefined } | null {\n // Locate top-level ` as `.\n let depth = 0\n let asAt = -1\n for (let i = 0; i < head.length; i++) {\n const c = head[i]\n if (c === '(' || c === '[' || c === '{') depth++\n else if (c === ')' || c === ']' || c === '}') depth--\n else if (depth === 0 && c === ' ' && head.startsWith('as ', i + 1) && asAt === -1) {\n asAt = i\n }\n }\n if (asAt === -1) return null\n const list = head.slice(0, asAt).trim()\n let rest = head.slice(asAt + 4).trim()\n // Optional trailing `(key)` group.\n let key: string | undefined\n if (rest.endsWith(')')) {\n let d = 0\n for (let i = rest.length - 1; i >= 0; i--) {\n const c = rest[i]\n if (c === ')') d++\n else if (c === '(') {\n d--\n if (d === 0) {\n if (i > 0 && /\\s/.test(rest[i - 1] ?? '')) {\n key = rest.slice(i + 1, rest.length - 1).trim()\n rest = rest.slice(0, i).trim()\n }\n break\n }\n }\n }\n }\n return { list, aliases: rest, key }\n}\n\n/** Convert `{#if}` / `{#each}` / `{@html}` block forms to element/attribute form. */\nfunction migrateBlocks(src: string): string {\n let out = src\n\n // {#if cond} → <group if={cond}>\n out = out.replace(/\\{#if\\s+([^{}]+(?:\\{[^{}]*\\}[^{}]*)*)\\}/g, (_m, cond: string) => {\n return `<group if={${cond.trim()}}>`\n })\n // {:else if cond} → </group><group elseif={cond}>\n out = out.replace(\n /\\{:else\\s+if\\s+([^{}]+(?:\\{[^{}]*\\}[^{}]*)*)\\}/g,\n (_m, cond: string) => `</group><group elseif={${cond.trim()}}>`,\n )\n // {:else} → </group><group else>\n out = out.replace(/\\{:else\\}/g, '</group><group else>')\n // {/if} → </group>\n out = out.replace(/\\{\\/\\s*if\\s*\\}/g, '</group>')\n\n // {#each head} → <group each={aliases of list} key={key}>\n out = out.replace(/\\{#each\\s+([^{}]+(?:\\{[^{}]*\\}[^{}]*)*)\\}/g, (m, head: string) => {\n const parts = splitEachHead(head.trim())\n if (!parts) return m\n const keyPart = parts.key ? ` key={${parts.key}}` : ''\n return `<group each={${parts.aliases} of ${parts.list}}${keyPart}>`\n })\n // {:empty} → </group><group empty>\n out = out.replace(/\\{:empty\\}/g, '</group><group empty>')\n // {/each} → </group>\n out = out.replace(/\\{\\/\\s*each\\s*\\}/g, '</group>')\n\n // {@html expr} → <span html={expr}></span> (same placeholder-element\n // lowering the block form compiled to).\n out = out.replace(\n /\\{@html\\s+([^{}]+(?:\\{[^{}]*\\}[^{}]*)*)\\}/g,\n (_m, expr: string) => `<span html={${expr.trim()}}></span>`,\n )\n\n return out\n}\n\n/** v1 `$`-attribute layer → naked words / colon directives / plain braces. */\nfunction migrateAttrs(src: string): string {\n let out = src\n\n // Events + two-way binds, dot-form → colon directives (curly + quoted).\n out = out.replace(/\\$on\\.([A-Za-z][\\w]*((?:\\.[a-z]+)*))=\\{/g, 'on:$1={')\n out = out.replace(/\\$on\\.([A-Za-z][\\w]*)=\"([^\"]*)\"/g, 'on:$1={$2}')\n out = out.replace(/\\$bind\\.([A-Za-z][\\w-]*)=\\{/g, 'bind:$1={')\n out = out.replace(/\\$bind\\.([A-Za-z][\\w-]*)=\"([^\"]*)\"/g, 'bind:$1={$2}')\n\n // Class toggles. Accept BOTH the colon spelling (`$class:active`) and the\n // dot spelling (`$class.active`) — the v1 attribute layer permitted the dot\n // form by analogy with `$on.`/`$bind.`, and it was silently passed through\n // untouched (#502). Both normalize to the v2 `class:` directive.\n out = out.replace(/\\$class[:.]([A-Za-z][\\w-]*)=\\{/g, 'class:$1={')\n out = out.replace(/\\$class[:.]([A-Za-z][\\w-]*)=\"([^\"]*)\"/g, 'class:$1={$2}')\n\n // $each string-DSL and curly `list as alias` forms → item-first `of` head.\n out = out.replace(/\\$each=\"([^\"]+?) as ([^\"]+?)\"/g, 'each={$2 of $1}')\n out = out.replace(/\\$each=\\{([^}]+?) as ([^}]+?)\\}/g, 'each={$2 of $1}')\n // Remaining `$each={list}` — the v1 default alias was `item`.\n out = out.replace(/\\$each=\\{([^}]+)\\}/g, 'each={item of $1}')\n out = out.replace(/\\$each=\"([^\"]+)\"/g, 'each={item of $1}')\n\n // Braced control words pass through de-`$`-ed; quoted forms gain braces.\n out = out.replace(/\\$(if|key|show|html|ref|memo)=\\{/g, '$1={')\n out = out.replace(/\\$(if|key|show|html|ref|memo)=\"([^\"]*)\"/g, '$1={$2}')\n\n // Boolean words (attribute position only — require tag-ish delimiter after).\n out = out.replace(/\\$once(?=[\\s/>])/g, 'once')\n out = out.replace(/\\$raw(?=[\\s/>])/g, 'raw')\n\n // Any remaining `$name={expr}` binding (incl. $class= / $href= / $aria-*=)\n // → plain braces. Guard against `${…}` template-literal holes (no name) and\n // identifiers containing `$` (require a non-word char before `$`).\n out = out.replace(/(?<![\\w$])\\$([a-zA-Z][\\w-]*)=\\{/g, '$1={')\n\n return out\n}\n\n/** `<$macro>` elements → naked framework elements; `<$link>` → `<a>`. */\nfunction migrateElements(src: string): string {\n let out = src\n out = out.replace(/<\\$link\\b/g, '<a')\n out = out.replace(/<\\/\\$link>/g, '</a>')\n for (const name of MACRO_ELEMENTS) {\n out = out.replace(new RegExp(`<\\\\$${name}\\\\b`, 'g'), `<${name}`)\n out = out.replace(new RegExp(`</\\\\$${name}>`, 'g'), `</${name}>`)\n }\n return out\n}\n\n/** v0 `{{ident}}` double-brace interpolation → single braces. */\nfunction migrateDoubleBrace(src: string): string {\n return src.replace(/\\{\\{\\s*([A-Za-z_$][\\w$]*)\\s*\\}\\}/g, '{$1}')\n}\n\n/**\n * Run every template-grammar-v2 pass over one `.aihu` source (or a markdown\n * document containing `.aihu` snippets — the transforms are anchored to\n * template-syntax shapes and leave prose alone).\n */\nexport function migrateTemplateGrammar(source: string): TemplateGrammarResult {\n let out = source\n out = foldEachLet(out)\n out = migrateBlocks(out)\n out = migrateAttrs(out)\n out = migrateElements(out)\n out = migrateDoubleBrace(out)\n return { rewritten: out, changed: out !== source }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aihu/compiler",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -10,6 +10,18 @@
|
|
|
10
10
|
".": {
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
12
|
"import": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./codemods/macro-simplification": {
|
|
15
|
+
"types": "./dist/codemods/macro-simplification.d.ts",
|
|
16
|
+
"import": "./dist/codemods/macro-simplification.js"
|
|
17
|
+
},
|
|
18
|
+
"./codemods/state-wrapper": {
|
|
19
|
+
"types": "./dist/codemods/state-wrapper.d.ts",
|
|
20
|
+
"import": "./dist/codemods/state-wrapper.js"
|
|
21
|
+
},
|
|
22
|
+
"./codemods/template-grammar-v2": {
|
|
23
|
+
"types": "./dist/codemods/template-grammar-v2.d.ts",
|
|
24
|
+
"import": "./dist/codemods/template-grammar-v2.js"
|
|
13
25
|
}
|
|
14
26
|
},
|
|
15
27
|
"bin": {
|
|
@@ -25,22 +37,22 @@
|
|
|
25
37
|
"scripts": {
|
|
26
38
|
"build": "rolldown -c",
|
|
27
39
|
"build:native": "bun scripts/build-native.ts",
|
|
28
|
-
"build:wasm": "
|
|
40
|
+
"build:wasm": "bun ../../scripts/build-wasm.ts",
|
|
29
41
|
"typecheck": "tsc --noEmit",
|
|
30
42
|
"prepublishOnly": "bun run build",
|
|
31
43
|
"codemod:template-syntax": "bun js/codemods/template-syntax/run-migration.ts"
|
|
32
44
|
},
|
|
33
45
|
"optionalDependencies": {
|
|
34
|
-
"@aihu/compiler-darwin-arm64": "1.3.
|
|
35
|
-
"@aihu/compiler-darwin-x64": "1.3.
|
|
36
|
-
"@aihu/compiler-linux-x64-gnu": "1.3.
|
|
37
|
-
"@aihu/compiler-linux-arm64-gnu": "1.3.
|
|
38
|
-
"@aihu/compiler-win32-x64-msvc": "1.3.
|
|
39
|
-
"@aihu/compiler-native-darwin-arm64": "1.3.
|
|
40
|
-
"@aihu/compiler-native-darwin-x64": "1.3.
|
|
41
|
-
"@aihu/compiler-native-linux-x64-gnu": "1.3.
|
|
42
|
-
"@aihu/compiler-native-linux-arm64-gnu": "1.3.
|
|
43
|
-
"@aihu/compiler-native-win32-x64-msvc": "1.3.
|
|
46
|
+
"@aihu/compiler-darwin-arm64": "1.3.4",
|
|
47
|
+
"@aihu/compiler-darwin-x64": "1.3.4",
|
|
48
|
+
"@aihu/compiler-linux-x64-gnu": "1.3.4",
|
|
49
|
+
"@aihu/compiler-linux-arm64-gnu": "1.3.4",
|
|
50
|
+
"@aihu/compiler-win32-x64-msvc": "1.3.4",
|
|
51
|
+
"@aihu/compiler-native-darwin-arm64": "1.3.4",
|
|
52
|
+
"@aihu/compiler-native-darwin-x64": "1.3.4",
|
|
53
|
+
"@aihu/compiler-native-linux-x64-gnu": "1.3.4",
|
|
54
|
+
"@aihu/compiler-native-linux-arm64-gnu": "1.3.4",
|
|
55
|
+
"@aihu/compiler-native-win32-x64-msvc": "1.3.4"
|
|
44
56
|
},
|
|
45
57
|
"peerDependencies": {
|
|
46
58
|
"vite": ">=5.0.0",
|