what-compiler 0.5.5 → 0.6.0

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.
@@ -0,0 +1,397 @@
1
+ var xe=new Set(["preventDefault","stopPropagation","once","capture","passive","self"]),Ee=new Set(["once","capture","passive"]),be=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),Se=new Set(["click","input","change","keydown","keyup","submit","focusin","focusout","mousedown","mouseup"]),R=new Set(["Math","Number","String","Boolean","parseInt","parseFloat","isNaN","isFinite","encodeURIComponent","decodeURIComponent","encodeURI","decodeURI","JSON","Date","Array","Object","console","RegExp"]),te=new Set(["useSignal","signal","computed","useComputed","useState","useReducer","createResource","useSWR","useQuery","useInfiniteQuery"]);function W({types:e}){function f(n){let i=n.split("|"),r=i[0],t=i.slice(1).filter(a=>xe.has(a));return{eventName:r,modifiers:t}}function x(n){return n.startsWith("bind:")}function k(n){return n.slice(5)}function E(n){return/^[A-Z]/.test(n)}function L(n){return be.has(String(n).toLowerCase())}function b(n){return n?e.isJSXExpressionContainer(n)?n.expression:e.isStringLiteral(n)?n:e.stringLiteral(n.value||""):e.booleanLiteral(!0)}function v(n){return n==="className"?"class":n==="htmlFor"?"for":n}function y(n){return e.isJSXNamespacedName(n.name)?`${n.name.namespace.name}:${n.name.name.name}`:typeof n.name.name=="string"?n.name.name:String(n.name.name)}function _(n,i){if(i.length===0)return n;let r=n;for(let t of i)switch(t){case"preventDefault":r=e.arrowFunctionExpression([e.identifier("e")],e.blockStatement([e.expressionStatement(e.callExpression(e.memberExpression(e.identifier("e"),e.identifier("preventDefault")),[])),e.expressionStatement(e.callExpression(r,[e.identifier("e")]))]));break;case"stopPropagation":r=e.arrowFunctionExpression([e.identifier("e")],e.blockStatement([e.expressionStatement(e.callExpression(e.memberExpression(e.identifier("e"),e.identifier("stopPropagation")),[])),e.expressionStatement(e.callExpression(r,[e.identifier("e")]))]));break;case"self":r=e.arrowFunctionExpression([e.identifier("e")],e.blockStatement([e.ifStatement(e.binaryExpression("===",e.memberExpression(e.identifier("e"),e.identifier("target")),e.memberExpression(e.identifier("e"),e.identifier("currentTarget"))),e.expressionStatement(e.callExpression(r,[e.identifier("e")])))]));break;case"once":case"capture":case"passive":break}return r}function p(n,i){return i.has(n)}function u(n){let i=new Set;function r(a){let s=a.init;if(!s||!e.isCallExpression(s))return;let o=s.callee,l="";if(e.isIdentifier(o)?l=o.name:e.isMemberExpression(o)&&e.isIdentifier(o.property)&&(l=o.property.name),te.has(l)){let c=a.id;if(e.isIdentifier(c))i.add(c.name);else if(e.isArrayPattern(c))for(let d of c.elements)e.isIdentifier(d)&&i.add(d.name);else if(e.isObjectPattern(c))for(let d of c.properties)e.isObjectProperty(d)&&e.isIdentifier(d.value)&&i.add(d.value.name)}}let t=n.scope;for(;t;){for(let[a,s]of Object.entries(t.bindings))if(s.path.isVariableDeclarator()&&r(s.path.node),s.path.isIdentifier()||s.kind==="param"){let o=s.scope.path;if(o&&o.node&&o.node.params){for(let l of o.node.params)if(e.isObjectPattern(l))for(let c of l.properties)e.isObjectProperty(c)&&e.isIdentifier(c.value)?i.add(c.value.name):e.isRestElement(c)&&e.isIdentifier(c.argument)&&i.add(c.argument.name)}}t=t.parent}return i}function g(n){return u(n)}function h(n){if(!e.isCallExpression(n))return!1;let i=n.callee;return e.isMemberExpression(i)&&e.isIdentifier(i.object)?R.has(i.object.name):e.isIdentifier(i)?R.has(i.name):!1}function M(n,i,r){if(!i)return!1;if(e.isCallExpression(n)){if(e.isIdentifier(n.callee)&&p(n.callee.name,i)||r&&e.isIdentifier(n.callee)&&r.has(n.callee.name)&&!R.has(n.callee.name)||e.isMemberExpression(n.callee)&&e.isIdentifier(n.callee.object)&&p(n.callee.object.name,i)||h(n))return!1;if(n.arguments.some(t=>w(t,i,r)))return!0}return!1}function w(n,i,r){return i||(i=new Set),e.isCallExpression(n)?e.isIdentifier(n.callee)&&p(n.callee.name,i)||r&&e.isIdentifier(n.callee)&&r.has(n.callee.name)&&!R.has(n.callee.name)||e.isMemberExpression(n.callee)&&e.isIdentifier(n.callee.object)&&p(n.callee.object.name,i)?!0:h(n)?n.arguments.some(t=>w(t,i,r)):e.isIdentifier(n.callee)?n.arguments.some(t=>w(t,i,r)):w(n.callee,i,r)||n.arguments.some(t=>w(t,i,r)):e.isIdentifier(n)?p(n.name,i):e.isMemberExpression(n)?w(n.object,i,r):e.isConditionalExpression(n)?w(n.test,i,r)||w(n.consequent,i,r)||w(n.alternate,i,r):e.isBinaryExpression(n)||e.isLogicalExpression(n)?w(n.left,i,r)||w(n.right,i,r):e.isUnaryExpression(n)?w(n.argument,i,r):e.isTemplateLiteral(n)?n.expressions.some(t=>w(t,i,r)):e.isObjectExpression(n)?n.properties.some(t=>e.isObjectProperty(t)&&w(t.value,i,r)):e.isArrayExpression(n)?n.elements.some(t=>t&&w(t,i,r)):(e.isArrowFunctionExpression(n)||e.isFunctionExpression(n),!1)}function J(n){if(e.isJSXText(n))return!0;if(e.isJSXExpressionContainer(n))return!1;if(e.isJSXElement(n)){let i=n.openingElement,r=i.name.name;if(E(r))return!1;for(let t of i.attributes){if(e.isJSXSpreadAttribute(t))return!1;let a=t.value;if(e.isJSXExpressionContainer(a))return!1}return n.children.every(J)}return!1}function D(n){return e.isJSXSpreadAttribute(n)?!0:n.value?e.isJSXExpressionContainer(n.value):!1}function V(n){if(e.isJSXText(n)){let s=n.value.replace(/\n\s+/g," ").trim();return s?K(s):""}if(e.isJSXExpressionContainer(n))return e.isJSXEmptyExpression(n.expression)?"":"<!--$-->";if(!e.isJSXElement(n))return"";let i=n.openingElement,r=i.name.name;if(E(r))return"";let t=`<${r}`;for(let s of i.attributes){if(e.isJSXSpreadAttribute(s))continue;let o=y(s);if(o.startsWith("on")||o.startsWith("bind:")||o.includes("|"))continue;let l=o;if(o==="className"&&(l="class"),o==="htmlFor"&&(l="for"),!s.value)t+=` ${l}`;else if(e.isStringLiteral(s.value))t+=` ${l}="${ue(s.value.value)}"`;else if(e.isJSXExpressionContainer(s.value))continue}let a=n.openingElement.selfClosing;if(a&&L(r))return t+=">",t;if(a)return t+=`></${r}>`,t;t+=">";for(let s of n.children)if(e.isJSXText(s)){let o=s.value.replace(/\n\s+/g," ").trim();o&&(t+=K(o))}else e.isJSXExpressionContainer(s)?e.isJSXEmptyExpression(s.expression)||(t+="<!--$-->"):e.isJSXElement(s)&&(E(s.openingElement.name.name)?t+="<!--$-->":t+=V(s));return t+=`</${r}>`,t}function K(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function ue(n){return n.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function X(n,i){let{node:r}=n,t=r.openingElement,a=t.name.name;if(E(a))return ie(n,i);if(a==="For")return de(n,i);if(a==="Show")return me(n,i);let s=t.attributes,o=r.children,l=o.every(J),c=s.every($=>!D($)),d=s.every($=>{if(e.isJSXSpreadAttribute($))return!1;let m=y($);return!m?.startsWith("on")&&!m?.startsWith("bind:")});if(l&&c&&d){let $=V(r);if($){let m=re(i,$);return i.needsTemplate=!0,e.callExpression(e.identifier(m),[])}}let C=V(r);if(!C){let $=r.loc,m=i.filename||i.file?.opts?.filename||"<unknown>",S=$?`:${$.start.line}:${$.start.column}`:"";return console.warn(`[what-compiler] Could not extract template for <${a}> at ${m}${S}. Falling back to h() for this element. This element could not be statically analyzed. Consider simplifying the JSX.`),i.needsH=!0,U(n,i)}let F=re(i,C);i.needsTemplate=!0;let P=i.nextVarId(),T=[e.variableDeclaration("const",[e.variableDeclarator(e.identifier(P),e.callExpression(e.identifier(F),[]))])];return ee(T,P,s,i),ne(T,P,o,r,i),i._pendingSetup||(i._pendingSetup=[]),i._pendingSetup.push(...T),e.identifier(P)}function U(n,i){let{node:r}=n,t=r.openingElement,a=t.name.name,s=t.attributes,o=r.children,l=[];for(let C of s){if(e.isJSXSpreadAttribute(C))continue;let F=y(C),P=b(C.value),T=v(F);l.push(e.objectProperty(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(T)?e.identifier(T):e.stringLiteral(T),P))}let c=[];for(let C of o)if(e.isJSXText(C)){let F=C.value.replace(/\n\s+/g," ").trim();F&&c.push(e.stringLiteral(F))}else e.isJSXExpressionContainer(C)?e.isJSXEmptyExpression(C.expression)||c.push(C.expression):e.isJSXElement(C)?c.push(X({node:C},i)):e.isJSXFragment(C)&&c.push(H({node:C},i));let d=l.length>0?e.objectExpression(l):e.nullLiteral();return e.callExpression(e.identifier("h"),[e.stringLiteral(a),d,...c])}function ee(n,i,r,t){function a(s,o){return t.needsSetProp=!0,e.callExpression(e.identifier("_$setProp"),[e.identifier(i),e.stringLiteral(s),o])}for(let s of r){if(e.isJSXSpreadAttribute(s)){t.needsSpread=!0,n.push(e.expressionStatement(e.callExpression(e.identifier("_$spread"),[e.identifier(i),s.argument])));continue}let o=y(s);if(o.startsWith("on")&&!o.includes("|")){let l=o.slice(2).toLowerCase(),c=b(s.value);Se.has(l)?(t.needsDelegation=!0,t.delegatedEvents||(t.delegatedEvents=new Set),t.delegatedEvents.add(l),n.push(e.expressionStatement(e.assignmentExpression("=",e.memberExpression(e.identifier(i),e.identifier(`__${l}`)),c)))):n.push(e.expressionStatement(e.callExpression(e.memberExpression(e.identifier(i),e.identifier("addEventListener")),[e.stringLiteral(l),c])));continue}if(o.startsWith("on")&&o.includes("|")){let{eventName:l,modifiers:c}=f(o),d=b(s.value),C=_(d,c),F=l.slice(2).toLowerCase(),P=c.filter($=>Ee.has($)),T=[e.stringLiteral(F),C];if(P.length>0){let $=P.map(m=>e.objectProperty(e.identifier(m),e.booleanLiteral(!0)));T.push(e.objectExpression($))}n.push(e.expressionStatement(e.callExpression(e.memberExpression(e.identifier(i),e.identifier("addEventListener")),T)));continue}if(x(o)){let l=k(o),c=s.value.expression;t.needsEffect=!0,l==="value"?(n.push(e.expressionStatement(e.callExpression(e.identifier("_$effect"),[e.arrowFunctionExpression([],e.assignmentExpression("=",e.memberExpression(e.identifier(i),e.identifier("value")),e.callExpression(e.cloneNode(c),[])))]))),n.push(e.expressionStatement(e.callExpression(e.memberExpression(e.identifier(i),e.identifier("addEventListener")),[e.stringLiteral("input"),e.arrowFunctionExpression([e.identifier("e")],e.callExpression(e.memberExpression(e.cloneNode(c),e.identifier("set")),[e.memberExpression(e.memberExpression(e.identifier("e"),e.identifier("target")),e.identifier("value"))]))])))):l==="checked"&&(t.needsEffect=!0,n.push(e.expressionStatement(e.callExpression(e.identifier("_$effect"),[e.arrowFunctionExpression([],e.assignmentExpression("=",e.memberExpression(e.identifier(i),e.identifier("checked")),e.callExpression(e.cloneNode(c),[])))]))),n.push(e.expressionStatement(e.callExpression(e.memberExpression(e.identifier(i),e.identifier("addEventListener")),[e.stringLiteral("change"),e.arrowFunctionExpression([e.identifier("e")],e.callExpression(e.memberExpression(e.cloneNode(c),e.identifier("set")),[e.memberExpression(e.memberExpression(e.identifier("e"),e.identifier("target")),e.identifier("checked"))]))]))));continue}if(e.isJSXExpressionContainer(s.value)){let l=s.value.expression,c=v(o);if(w(l,t.signalNames,t.importedIdentifiers)){t.needsEffect=!0;let d=e.callExpression(e.identifier("_$effect"),[e.arrowFunctionExpression([],a(c,l))]);M(l,t.signalNames,t.importedIdentifiers)&&e.addComment(d,"leading"," @what-dev: effect wrapping may be unnecessary \u2014 expression contains a non-signal function call with reactive args ",!1),n.push(e.expressionStatement(d))}else n.push(e.expressionStatement(a(c,l)))}}}function ne(n,i,r,t,a){let s=0;for(let o of r){if(e.isJSXText(o)){o.value.replace(/\n\s+/g," ").trim()&&s++;continue}if(e.isJSXExpressionContainer(o)){if(e.isJSXEmptyExpression(o.expression))continue;let l=o.expression,c=G(i,s);if(a.needsInsert=!0,w(l,a.signalNames,a.importedIdentifiers)){let d=e.callExpression(e.identifier("_$insert"),[e.identifier(i),e.arrowFunctionExpression([],l),c]);M(l,a.signalNames,a.importedIdentifiers)&&e.addComment(d,"leading"," @what-dev: reactive wrapping may be unnecessary \u2014 expression contains a non-signal function call with reactive args ",!1),n.push(e.expressionStatement(d))}else n.push(e.expressionStatement(e.callExpression(e.identifier("_$insert"),[e.identifier(i),l,c])));s++;continue}if(e.isJSXElement(o)){let l=o.openingElement.name.name;if(E(l)||l==="For"||l==="Show"){let c=X({node:o},a),d=G(i,s);a.needsInsert=!0,n.push(e.expressionStatement(e.callExpression(e.identifier("_$insert"),[e.identifier(i),c,d]))),s++}else{if(o.openingElement.attributes.some(D)||o.openingElement.attributes.some(d=>!e.isJSXSpreadAttribute(d)&&y(d)?.startsWith("on"))||!o.children.every(J)){let d=a.nextVarId();n.push(e.variableDeclaration("const",[e.variableDeclarator(e.identifier(d),G(i,s))])),ee(n,d,o.openingElement.attributes,a),ne(n,d,o.children,o,a)}s++}continue}if(e.isJSXFragment(o)){for(let l of o.children)if(e.isJSXExpressionContainer(l)&&!e.isJSXEmptyExpression(l.expression)){a.needsInsert=!0;let c=l.expression;w(c,a.signalNames,a.importedIdentifiers)?n.push(e.expressionStatement(e.callExpression(e.identifier("_$insert"),[e.identifier(i),e.arrowFunctionExpression([],c)]))):n.push(e.expressionStatement(e.callExpression(e.identifier("_$insert"),[e.identifier(i),c])))}}}}function G(n,i){if(i===0)return e.memberExpression(e.identifier(n),e.identifier("firstChild"));let r=e.memberExpression(e.identifier(n),e.identifier("firstChild"));for(let t=0;t<i;t++)r=e.memberExpression(r,e.identifier("nextSibling"));return r}function ie(n,i){let{node:r}=n,t=r.openingElement,a=t.name.name,s=t.attributes,o=r.children,l=null,c=[];for(let m of s){if(e.isJSXAttribute(m)){let S;if(e.isJSXNamespacedName(m.name)?S=`${m.name.namespace.name}:${m.name.name.name}`:S=m.name.name,S&&typeof S=="string"&&S.startsWith("client:")){let I=S.slice(7);m.value?l={type:I,value:m.value.value}:l={type:I};continue}}c.push(m)}if(l){i.needsCreateComponent=!0,i.needsIsland=!0;let m=[e.objectProperty(e.identifier("component"),e.identifier(a)),e.objectProperty(e.identifier("mode"),e.stringLiteral(l.type))];l.value&&m.push(e.objectProperty(e.identifier("mediaQuery"),e.stringLiteral(l.value)));for(let S of c){if(e.isJSXSpreadAttribute(S))continue;let I=y(S),A=b(S.value);m.push(e.objectProperty(e.identifier(I),A))}return e.callExpression(e.identifier("_$createComponent"),[e.identifier("Island"),e.objectExpression(m),e.arrayExpression([])])}i.needsCreateComponent=!0;let d=[],C=!1,F=null;for(let m of c){if(e.isJSXSpreadAttribute(m)){C=!0,F=m.argument;continue}let S=y(m);if(x(S)){let A=k(S),N=m.value.expression;A==="value"?(d.push(e.objectProperty(e.identifier("value"),e.callExpression(e.cloneNode(N),[]))),d.push(e.objectProperty(e.identifier("onInput"),e.arrowFunctionExpression([e.identifier("e")],e.callExpression(e.memberExpression(e.cloneNode(N),e.identifier("set")),[e.memberExpression(e.memberExpression(e.identifier("e"),e.identifier("target")),e.identifier("value"))]))))):A==="checked"&&(d.push(e.objectProperty(e.identifier("checked"),e.callExpression(e.cloneNode(N),[]))),d.push(e.objectProperty(e.identifier("onChange"),e.arrowFunctionExpression([e.identifier("e")],e.callExpression(e.memberExpression(e.cloneNode(N),e.identifier("set")),[e.memberExpression(e.memberExpression(e.identifier("e"),e.identifier("target")),e.identifier("checked"))])))));continue}if(S.startsWith("on")&&S.includes("|")){let{eventName:A,modifiers:N}=f(S),he=b(m.value),ge=_(he,N);d.push(e.objectProperty(e.identifier(A),ge));continue}let I=b(m.value);d.push(e.objectProperty(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(S)?e.identifier(S):e.stringLiteral(S),I))}let P=[];for(let m of o)if(e.isJSXText(m)){let S=m.value.replace(/\n\s+/g," ").trim();S&&P.push(e.stringLiteral(S))}else e.isJSXExpressionContainer(m)?e.isJSXEmptyExpression(m.expression)||P.push(m.expression):e.isJSXElement(m)?P.push(X({node:m},i)):e.isJSXFragment(m)&&P.push(H({node:m},i));let T;C?d.length>0?T=e.callExpression(e.memberExpression(e.identifier("Object"),e.identifier("assign")),[e.objectExpression([]),F,e.objectExpression(d)]):T=F:d.length>0?T=e.objectExpression(d):T=e.nullLiteral();let $=P.length>0?e.arrayExpression(P):e.arrayExpression([]);return e.callExpression(e.identifier("_$createComponent"),[e.identifier(a),T,$])}function de(n,i){let{node:r}=n,t=r.openingElement.attributes,a=r.children,s=null;for(let l of t)e.isJSXAttribute(l)&&y(l)==="each"&&(s=b(l.value));if(!s)return console.warn('[what-compiler] <For> element missing "each" attribute.'),i.needsH=!0,U(n,i);let o=null;for(let l of a)if(e.isJSXExpressionContainer(l)&&!e.isJSXEmptyExpression(l.expression)){o=l.expression;break}return o?(i.needsMapArray=!0,e.callExpression(e.identifier("_$mapArray"),[s,o])):(console.warn("[what-compiler] <For> element missing render function child."),i.needsH=!0,U(n,i))}function me(n,i){return i.needsCreateComponent=!0,ie(n,i)}function H(n,i){let{node:r}=n,t=r.children,a=[];for(let s of t)if(e.isJSXText(s)){let o=s.value.replace(/\n\s+/g," ").trim();o&&a.push(e.stringLiteral(o))}else e.isJSXExpressionContainer(s)?e.isJSXEmptyExpression(s.expression)||a.push(s.expression):e.isJSXElement(s)?a.push(X({node:s},i)):e.isJSXFragment(s)&&a.push(H({node:s},i));return a.length===1?a[0]:e.arrayExpression(a)}function re(n,i){if(n.templateMap.has(i))return n.templateMap.get(i);let r=`_tmpl$${n.templateCount++}`;return n.templateMap.set(i,r),n.templates.push({id:r,html:i}),r}return{name:"what-jsx-transform",visitor:{Program:{enter(n,i){i.needsTemplate=!1,i.needsInsert=!1,i.needsEffect=!1,i.needsMapArray=!1,i.needsSpread=!1,i.needsSetProp=!1,i.needsH=!1,i.needsCreateComponent=!1,i.needsFragment=!1,i.needsIsland=!1,i.needsDelegation=!1,i.delegatedEvents=new Set,i.templates=[],i.templateMap=new Map,i.templateCount=0,i._varCounter=0,i._pendingSetup=[],i.nextVarId=()=>`_el$${i._varCounter++}`,i.signalNames=new Set,i.importedIdentifiers=new Set;for(let r of n.node.body)if(e.isImportDeclaration(r)){let t=r.source.value,a=t==="what-framework"||t.startsWith("what-framework/")||t==="what-core"||t.startsWith("what-core/")||t.startsWith("./")||t.startsWith("../");for(let s of r.specifiers){let o=null;(e.isImportSpecifier(s)&&e.isIdentifier(s.local)||e.isImportDefaultSpecifier(s)&&e.isIdentifier(s.local)||e.isImportNamespaceSpecifier(s)&&e.isIdentifier(s.local))&&(o=s.local.name),o&&(a||/^(use|create)[A-Z]/.test(o))&&i.importedIdentifiers.add(o)}}n.traverse({VariableDeclarator(r){let t=r.node.init;if(!t||!e.isCallExpression(t))return;let a=t.callee,s="";if(e.isIdentifier(a)?s=a.name:e.isMemberExpression(a)&&e.isIdentifier(a.property)&&(s=a.property.name),te.has(s)){let o=r.node.id;if(e.isIdentifier(o))i.signalNames.add(o.name);else if(e.isArrayPattern(o))for(let l of o.elements)e.isIdentifier(l)&&i.signalNames.add(l.name);else if(e.isObjectPattern(o))for(let l of o.properties)e.isObjectProperty(l)&&e.isIdentifier(l.value)&&i.signalNames.add(l.value.name)}}})},exit(n,i){for(let a of i.templates.reverse())n.unshiftContainer("body",e.variableDeclaration("const",[e.variableDeclarator(e.identifier(a.id),e.callExpression(e.identifier("_$template"),[e.stringLiteral(a.html)]))]));let r=[];i.needsTemplate&&r.push(e.importSpecifier(e.identifier("_$template"),e.identifier("template"))),i.needsInsert&&r.push(e.importSpecifier(e.identifier("_$insert"),e.identifier("insert"))),i.needsEffect&&r.push(e.importSpecifier(e.identifier("_$effect"),e.identifier("effect"))),i.needsMapArray&&r.push(e.importSpecifier(e.identifier("_$mapArray"),e.identifier("mapArray"))),i.needsSpread&&r.push(e.importSpecifier(e.identifier("_$spread"),e.identifier("spread"))),i.needsSetProp&&r.push(e.importSpecifier(e.identifier("_$setProp"),e.identifier("setProp"))),i.needsCreateComponent&&r.push(e.importSpecifier(e.identifier("_$createComponent"),e.identifier("_$createComponent"))),i.needsDelegation&&r.push(e.importSpecifier(e.identifier("_$delegateEvents"),e.identifier("delegateEvents")));let t=[];if(i.needsH&&t.push(e.importSpecifier(e.identifier("h"),e.identifier("h"))),i.needsFragment&&t.push(e.importSpecifier(e.identifier("Fragment"),e.identifier("Fragment"))),i.needsIsland&&t.push(e.importSpecifier(e.identifier("Island"),e.identifier("Island"))),r.length>0){let a=null;for(let s of n.node.body)if(e.isImportDeclaration(s)&&(s.source.value==="what-framework/render"||s.source.value==="what-core/render")){a=s;break}if(a){let s=new Set(a.specifiers.filter(o=>e.isImportSpecifier(o)).map(o=>o.imported.name));for(let o of r)s.has(o.imported.name)||a.specifiers.push(o)}else n.unshiftContainer("body",e.importDeclaration(r,e.stringLiteral("what-framework/render")))}if(t.length>0&&ve(n,e,t),i.needsDelegation&&i.delegatedEvents&&i.delegatedEvents.size>0){let a=e.arrayExpression([...i.delegatedEvents].map(s=>e.stringLiteral(s)));n.pushContainer("body",e.expressionStatement(e.callExpression(e.identifier("_$delegateEvents"),[a])))}}},JSXElement(n,i){i.signalNames=u(n),i._pendingSetup=[];let r=X(n,i),t=i._pendingSetup;if(i._pendingSetup=[],t.length>0){let a=n;for(;a&&!a.isStatement();)a=a.parentPath;if(a&&a.isStatement()){for(let s of t)a.insertBefore(s);n.replaceWith(r)}else t.push(e.returnStatement(r)),n.replaceWith(e.callExpression(e.arrowFunctionExpression([],e.blockStatement(t)),[]))}else n.replaceWith(r)},JSXFragment(n,i){let r=H(n,i);n.replaceWith(r)}}}}function ve(e,f,x){let k=null;for(let E of e.node.body)if(f.isImportDeclaration(E)&&(E.source.value==="what-core"||E.source.value==="what-framework")){k=E;break}if(k){let E=new Set(k.specifiers.filter(L=>f.isImportSpecifier(L)).map(L=>L.imported.name));for(let L of x)E.has(L.imported.name)||k.specifiers.push(L)}else{let E=f.importDeclaration(x,f.stringLiteral("what-framework"));e.unshiftContainer("body",E)}}import Y from"path";import{transformSync as Ce}from"@babel/core";import j from"fs";import O from"path";var se=new Set([".jsx",".tsx",".js",".ts"]),ye=new Set(["_layout","_error","_loading","_404"]);function le(e){let f=[],x=[],k=[];function E(b,v=""){if(!j.existsSync(b))return;let y=j.readdirSync(b,{withFileTypes:!0});for(let _ of y){let p=O.join(b,_.name);if(_.isDirectory()){if(_.name.match(/^\((.+)\)$/)){E(p,v);continue}if(_.name==="api"&&v===""){L(p,"/api");continue}E(p,v+"/"+B(_.name));continue}let u=O.extname(_.name);if(!se.has(u))continue;let g=O.basename(_.name,u);if(g==="_layout"){x.push({filePath:p,urlPrefix:v||"/"});continue}if(ye.has(g))continue;let h=B(g),M=g==="index"?v||"/":v+"/"+h;f.push({filePath:p,routePath:oe(M),isDynamic:M.includes(":")||M.includes("*")})}}function L(b,v){if(!j.existsSync(b))return;let y=j.readdirSync(b,{withFileTypes:!0});for(let _ of y){let p=O.join(b,_.name);if(_.isDirectory()){L(p,v+"/"+B(_.name));continue}let u=O.extname(_.name);if(!se.has(u))continue;let g=O.basename(_.name,u),h=B(g),M=g==="index"?v:v+"/"+h;k.push({filePath:p,routePath:oe(M)})}}return E(e),f.sort((b,v)=>{let y=ae(b.routePath),_=ae(v.routePath);return y-_}),{pages:f,layouts:x,apiRoutes:k}}function B(e){let f=e.match(/^\[\.\.\.(\w+)\]$/);if(f)return"*"+f[1];let x=e.match(/^\[(\w+)\]$/);return x?":"+x[1]:e.toLowerCase()}function oe(e){let f=e.replace(/\/+/g,"/");return f.length>1&&f.endsWith("/")&&(f=f.slice(0,-1)),f||"/"}function ae(e){return e.includes("*")?100:e.includes(":")?10:0}function ce(e){let f=e.match(/export\s+const\s+page\s*=\s*(\{[^}]*\})/s);if(!f)return{mode:"client"};try{let x=f[1].replace(/'/g,'"').replace(/(\w+)\s*:/g,'"$1":').replace(/,\s*}/g,"}").replace(/\/\/[^\n]*/g,"");return{mode:"client",...JSON.parse(x)}}catch{return{mode:"client"}}}function Z(e,f){let{pages:x,layouts:k,apiRoutes:E}=le(e),L=[],b=[],v=new Map;k.forEach((p,u)=>{let g=`_layout${u}`,h=q(p.filePath,f);L.push(`import ${g} from '${h}';`),v.set(p.urlPrefix,g)}),x.forEach((p,u)=>{let g=`_page${u}`,h=q(p.filePath,f);L.push(`import ${g} from '${h}';`);let M={mode:"client"};try{let D=j.readFileSync(p.filePath,"utf-8");M=ce(D)}catch{}let w=we(p.routePath,v),J={path:p.routePath,component:g,mode:M.mode||"client",layout:w||null};b.push(J)});let y=[];return E.forEach((p,u)=>{let g=`_api${u}`,h=q(p.filePath,f);L.push(`import * as ${g} from '${h}';`),y.push({path:p.routePath,handlers:g})}),["// Auto-generated by What Framework file router","// Do not edit \u2014 changes will be overwritten","",...L,"","export const routes = [",...b.map(p=>` { path: '${p.path}', component: ${p.component}, mode: '${p.mode}'${p.layout?`, layout: ${p.layout}`:""} },`),"];","","export const apiRoutes = [",...y.map(p=>` { path: '${p.path}', handlers: ${p.handlers} },`),"];","","export const pageModes = {",...b.map(p=>` '${p.path}': '${p.mode}',`),"};"].join(`
2
+ `)}function q(e,f){return"/"+O.relative(f,e).split(O.sep).join("/")}function we(e,f){let x=e.split("/").filter(Boolean);for(;x.length>0;){let k="/"+x.join("/");if(f.has(k))return f.get(k);x.pop()}return f.has("/")?f.get("/"):null}var _e=`
3
+ :host {
4
+ position: fixed;
5
+ inset: 0;
6
+ z-index: 99999;
7
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
8
+ }
9
+
10
+ .backdrop {
11
+ position: fixed;
12
+ inset: 0;
13
+ background: rgba(0, 0, 0, 0.66);
14
+ }
15
+
16
+ .panel {
17
+ position: fixed;
18
+ inset: 2rem;
19
+ overflow: auto;
20
+ background: #1a1a2e;
21
+ border: 1px solid #2a2a4a;
22
+ border-radius: 12px;
23
+ box-shadow: 0 25px 80px rgba(0, 0, 0, 0.5);
24
+ color: #e0e0e0;
25
+ }
26
+
27
+ .header {
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: space-between;
31
+ padding: 1rem 1.5rem;
32
+ border-bottom: 1px solid #2a2a4a;
33
+ background: #16163a;
34
+ border-radius: 12px 12px 0 0;
35
+ }
36
+
37
+ .header-left {
38
+ display: flex;
39
+ align-items: center;
40
+ gap: 0.75rem;
41
+ }
42
+
43
+ .header-right {
44
+ display: flex;
45
+ align-items: center;
46
+ gap: 0.5rem;
47
+ }
48
+
49
+ .logo {
50
+ width: 28px;
51
+ height: 28px;
52
+ background: linear-gradient(135deg, #2563eb, #1d4ed8);
53
+ border-radius: 6px;
54
+ display: grid;
55
+ place-items: center;
56
+ font-weight: 800;
57
+ font-size: 14px;
58
+ color: #fff;
59
+ }
60
+
61
+ .brand {
62
+ font-size: 14px;
63
+ font-weight: 600;
64
+ color: #a0a0c0;
65
+ }
66
+
67
+ .tag {
68
+ font-size: 11px;
69
+ padding: 2px 8px;
70
+ border-radius: 4px;
71
+ font-weight: 600;
72
+ }
73
+
74
+ .tag-error {
75
+ background: #3b1219;
76
+ color: #f87171;
77
+ }
78
+
79
+ .tag-warning {
80
+ background: #3b2f19;
81
+ color: #fbbf24;
82
+ }
83
+
84
+ .close-btn, .copy-btn {
85
+ background: none;
86
+ border: 1px solid #3a3a5a;
87
+ color: #a0a0c0;
88
+ border-radius: 6px;
89
+ padding: 4px 12px;
90
+ cursor: pointer;
91
+ font-family: inherit;
92
+ font-size: 12px;
93
+ }
94
+
95
+ .close-btn:hover, .copy-btn:hover {
96
+ background: #2a2a4a;
97
+ color: #fff;
98
+ }
99
+
100
+ .copy-btn.copied {
101
+ border-color: #22c55e;
102
+ color: #22c55e;
103
+ }
104
+
105
+ .body {
106
+ padding: 1.5rem;
107
+ }
108
+
109
+ .error-title {
110
+ font-size: 16px;
111
+ font-weight: 700;
112
+ color: #f87171;
113
+ margin: 0 0 0.5rem;
114
+ }
115
+
116
+ .error-message {
117
+ font-size: 14px;
118
+ color: #e0e0e0;
119
+ margin: 0 0 1rem;
120
+ line-height: 1.6;
121
+ white-space: pre-wrap;
122
+ }
123
+
124
+ .file-path {
125
+ display: inline-flex;
126
+ align-items: center;
127
+ gap: 0.5rem;
128
+ font-size: 12px;
129
+ color: #818cf8;
130
+ margin-bottom: 1rem;
131
+ padding: 0.25rem 0;
132
+ }
133
+
134
+ .code-frame {
135
+ background: #0d0d1a;
136
+ border: 1px solid #2a2a4a;
137
+ border-radius: 8px;
138
+ overflow-x: auto;
139
+ margin-bottom: 1rem;
140
+ }
141
+
142
+ .code-line {
143
+ display: flex;
144
+ padding: 0 1rem;
145
+ font-size: 13px;
146
+ line-height: 1.7;
147
+ }
148
+
149
+ .code-line.highlight {
150
+ background: rgba(248, 113, 113, 0.1);
151
+ }
152
+
153
+ .line-number {
154
+ color: #4a4a6a;
155
+ min-width: 3ch;
156
+ text-align: right;
157
+ margin-right: 1rem;
158
+ user-select: none;
159
+ }
160
+
161
+ .line-content {
162
+ white-space: pre;
163
+ }
164
+
165
+ .tip {
166
+ margin-top: 1rem;
167
+ padding: 0.75rem 1rem;
168
+ background: #1a2744;
169
+ border: 1px solid #1e3a5f;
170
+ border-radius: 8px;
171
+ font-size: 13px;
172
+ color: #93c5fd;
173
+ line-height: 1.5;
174
+ }
175
+
176
+ .tip-label {
177
+ font-weight: 700;
178
+ color: #60a5fa;
179
+ }
180
+
181
+ .stack {
182
+ margin-top: 1rem;
183
+ font-size: 12px;
184
+ color: #6a6a8a;
185
+ white-space: pre-wrap;
186
+ line-height: 1.5;
187
+ }
188
+ `,Ae=`
189
+ class WhatErrorOverlay extends HTMLElement {
190
+ constructor(err) {
191
+ super();
192
+ this.root = this.attachShadow({ mode: 'open' });
193
+ this.root.innerHTML = '<style>${_e}</style>';
194
+ this._err = err;
195
+ this.show(err);
196
+ }
197
+
198
+ // --- Inlined helper: escapeHTML ---
199
+ _escapeHTML(str) {
200
+ return String(str)
201
+ .replace(/&/g, '&amp;')
202
+ .replace(/</g, '&lt;')
203
+ .replace(/>/g, '&gt;')
204
+ .replace(/"/g, '&quot;');
205
+ }
206
+
207
+ // --- Inlined helper: cleanStack ---
208
+ _cleanStack(stack) {
209
+ return stack
210
+ .split('\\n')
211
+ .filter(function(line) { return line.indexOf('node_modules') === -1; })
212
+ .slice(0, 10)
213
+ .join('\\n');
214
+ }
215
+
216
+ // --- Inlined helper: getTip ---
217
+ _getTip(err) {
218
+ var msg = (err.message || '').toLowerCase();
219
+
220
+ if (msg.indexOf('infinite') !== -1 && msg.indexOf('effect') !== -1) {
221
+ return 'An effect is writing to a signal it also reads. Use untrack() to read without subscribing, or move the write to a different effect.';
222
+ }
223
+ if (msg.indexOf('jsx') !== -1 && msg.indexOf('unexpected') !== -1) {
224
+ return 'Make sure your vite.config includes the What compiler plugin: import what from "what-compiler/vite"';
225
+ }
226
+ if (msg.indexOf('not a function') !== -1 && msg.indexOf('signal') !== -1) {
227
+ return 'Signals are functions: call sig() to read, sig(value) to write. Check you are not destructuring a signal.';
228
+ }
229
+ if (msg.indexOf('hydrat') !== -1) {
230
+ return 'Hydration mismatches happen when SSR output differs from client render. Ensure server and client see the same initial state.';
231
+ }
232
+ // New tips for common mistakes
233
+ if (msg.indexOf('signal') !== -1 && msg.indexOf('without') !== -1 && msg.indexOf('call') !== -1) {
234
+ return 'Signals must be called to read their value. Use {count()} in JSX, not {count}. The parentheses trigger the reactive subscription.';
235
+ }
236
+ if (msg.indexOf('innerhtml') !== -1 && msg.indexOf('__html') !== -1) {
237
+ return 'Raw innerHTML is blocked for security. Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead.';
238
+ }
239
+ if ((msg.indexOf('innerhtml') !== -1 || msg.indexOf('xss') !== -1) && msg.indexOf('raw string') !== -1) {
240
+ return 'Raw innerHTML is a security risk (XSS). Wrap your HTML in an object: innerHTML={{ __html: yourString }}.';
241
+ }
242
+ if (msg.indexOf('cleanup') !== -1 && (msg.indexOf('effect') !== -1 || msg.indexOf('listener') !== -1)) {
243
+ return 'Effects that add event listeners or timers should return a cleanup function: effect(() => { el.addEventListener(...); return () => el.removeEventListener(...); })';
244
+ }
245
+ if (msg.indexOf('route') !== -1 && (msg.indexOf('not found') !== -1 || msg.indexOf('404') !== -1 || msg.indexOf('no match') !== -1)) {
246
+ return 'No route matched the current URL. Check that your route paths are correct and you have a catch-all or 404 route defined.';
247
+ }
248
+ if (msg.indexOf('key') !== -1 && (msg.indexOf('missing') !== -1 || msg.indexOf('list') !== -1 || msg.indexOf('each') !== -1)) {
249
+ return 'Lists need unique keys for efficient DOM updates. Add a key prop: items.map(item => <Item key={item.id} />)';
250
+ }
251
+ return '';
252
+ }
253
+
254
+ // --- Build overlay HTML ---
255
+ _buildHTML(err) {
256
+ var isCompilerError = err._isCompilerError || err.plugin === 'vite-plugin-what';
257
+ var type = isCompilerError ? 'Compiler Error' : 'Runtime Error';
258
+ var tagClass = isCompilerError ? 'tag-error' : 'tag-warning';
259
+
260
+ var codeFrame = '';
261
+ var rawFrame = err.frame || err._frame;
262
+ if (rawFrame) {
263
+ var lines = rawFrame.split('\\n');
264
+ var frameLines = '';
265
+ for (var i = 0; i < lines.length; i++) {
266
+ var line = lines[i];
267
+ var isHighlight = line.trimStart().startsWith('>');
268
+ var cleaned = line.replace(/^\\s*>\\s?/, ' ').replace(/^\\s{2}/, '');
269
+ var match = cleaned.match(/^(\\s*\\d+)\\s*\\|(.*)$/);
270
+ if (match) {
271
+ frameLines += '<div class="code-line' + (isHighlight ? ' highlight' : '') + '"><span class="line-number">' + match[1].trim() + '</span><span class="line-content">' + this._escapeHTML(match[2]) + '</span></div>';
272
+ } else if (cleaned.trim().startsWith('|')) {
273
+ frameLines += '<div class="code-line highlight"><span class="line-number"></span><span class="line-content" style="color:#f87171">' + this._escapeHTML(cleaned.replace(/^\\s*\\|/, '')) + '</span></div>';
274
+ }
275
+ }
276
+ if (frameLines) {
277
+ codeFrame = '<div class="code-frame">' + frameLines + '</div>';
278
+ }
279
+ }
280
+
281
+ var filePath = err.id || (err.loc && err.loc.file) || '';
282
+ var lineNum = (err.loc && err.loc.line != null) ? err.loc.line : '';
283
+ var col = (err.loc && err.loc.column != null) ? err.loc.column : '';
284
+ var location = filePath
285
+ ? '<div class="file-path">' + this._escapeHTML(filePath) + (lineNum ? ':' + lineNum : '') + (col ? ':' + col : '') + '</div>'
286
+ : '';
287
+
288
+ var tip = this._getTip(err);
289
+ var tipHTML = tip ? '<div class="tip"><span class="tip-label">Tip: </span>' + this._escapeHTML(tip) + '</div>' : '';
290
+
291
+ var stack = (err.stack && !isCompilerError)
292
+ ? '<div class="stack">' + this._escapeHTML(this._cleanStack(err.stack)) + '</div>'
293
+ : '';
294
+
295
+ return '<div class="backdrop"></div>'
296
+ + '<div class="panel">'
297
+ + '<div class="header">'
298
+ + '<div class="header-left">'
299
+ + '<div class="logo">W</div>'
300
+ + '<span class="brand">What Framework</span>'
301
+ + '<span class="tag ' + tagClass + '">' + type + '</span>'
302
+ + '</div>'
303
+ + '<div class="header-right">'
304
+ + '<button class="copy-btn">Copy Error</button>'
305
+ + '<button class="close-btn">Dismiss (Esc)</button>'
306
+ + '</div>'
307
+ + '</div>'
308
+ + '<div class="body">'
309
+ + '<h2 class="error-title">' + this._escapeHTML(err.name || 'Error') + '</h2>'
310
+ + location
311
+ + '<pre class="error-message">' + this._escapeHTML(err.message || String(err)) + '</pre>'
312
+ + codeFrame
313
+ + tipHTML
314
+ + stack
315
+ + '</div>'
316
+ + '</div>';
317
+ }
318
+
319
+ show(err) {
320
+ var template = document.createElement('template');
321
+ template.innerHTML = this._buildHTML(err);
322
+ this.root.appendChild(template.content.cloneNode(true));
323
+
324
+ // Close handlers
325
+ var self = this;
326
+ var closeBtn = this.root.querySelector('.close-btn');
327
+ if (closeBtn) closeBtn.addEventListener('click', function() { self.close(); });
328
+ var backdrop = this.root.querySelector('.backdrop');
329
+ if (backdrop) backdrop.addEventListener('click', function() { self.close(); });
330
+ document.addEventListener('keydown', this._onKey = function(e) {
331
+ if (e.key === 'Escape') self.close();
332
+ });
333
+
334
+ // Copy Error button
335
+ var copyBtn = this.root.querySelector('.copy-btn');
336
+ if (copyBtn) {
337
+ copyBtn.addEventListener('click', function() {
338
+ self._copyError(copyBtn);
339
+ });
340
+ }
341
+ }
342
+
343
+ _copyError(btn) {
344
+ var err = this._err;
345
+ var data = {
346
+ name: err.name || 'Error',
347
+ message: err.message || String(err),
348
+ file: err.id || (err.loc && err.loc.file) || null,
349
+ line: (err.loc && err.loc.line != null) ? err.loc.line : null,
350
+ column: (err.loc && err.loc.column != null) ? err.loc.column : null,
351
+ stack: err.stack ? this._cleanStack(err.stack) : null,
352
+ framework: 'What Framework',
353
+ timestamp: new Date().toISOString()
354
+ };
355
+
356
+ var text = JSON.stringify(data, null, 2);
357
+ if (navigator.clipboard && navigator.clipboard.writeText) {
358
+ navigator.clipboard.writeText(text).then(function() {
359
+ btn.textContent = 'Copied!';
360
+ btn.classList.add('copied');
361
+ setTimeout(function() {
362
+ btn.textContent = 'Copy Error';
363
+ btn.classList.remove('copied');
364
+ }, 2000);
365
+ }).catch(function() {
366
+ // Fallback: select text
367
+ prompt('Copy error details:', text);
368
+ });
369
+ } else {
370
+ prompt('Copy error details:', text);
371
+ }
372
+ }
373
+
374
+ close() {
375
+ document.removeEventListener('keydown', this._onKey);
376
+ this.remove();
377
+ }
378
+ }
379
+
380
+ if (!customElements.get('what-error-overlay')) {
381
+ customElements.define('what-error-overlay', WhatErrorOverlay);
382
+ }
383
+ `;function fe(e){let f=e.ws.send.bind(e.ws);e.ws.send=function(x){return x?.type==="error"&&x.err?.plugin==="vite-plugin-what"&&(x.err._isCompilerError=!0),f(x)}}var pe="virtual:what-routes",z="\0"+pe,Le=/export\s+(?:default\s+)?function\s+([A-Z]\w*)/,ke=/(?:store|signal|state|context|util|helper|lib|config)\b/i;function Q(e={}){let{include:f=/\.[jt]sx$/,exclude:x=/node_modules/,sourceMaps:k=!0,production:E=!0,pages:L="src/pages",hot:b=!E}=e,v="",y="",_=null,p=!1;return{name:"vite-plugin-what",configResolved(u){v=u.root,y=Y.resolve(v,L),p=u.command==="serve"},configureServer(u){_=u,fe(u),u.watcher.on("add",g=>{if(g.startsWith(y)){let h=u.moduleGraph.getModuleById(z);h&&(u.moduleGraph.invalidateModule(h),u.ws.send({type:"full-reload"}))}}),u.watcher.on("unlink",g=>{if(g.startsWith(y)){let h=u.moduleGraph.getModuleById(z);h&&(u.moduleGraph.invalidateModule(h),u.ws.send({type:"full-reload"}))}})},resolveId(u){if(u===pe)return z},load(u){if(u===z)return Z(y,v)},transform(u,g){if(!f.test(g)||x&&x.test(g))return null;try{let h=Ce(u,{filename:g,sourceMaps:k,plugins:[[W,{production:E}]],parserOpts:{plugins:["jsx","typescript"]}});if(!h||!h.code)return null;let M=h.code;return b&&p&&!E&&$e(u,g)&&(M+=Te(g)),{code:M,map:h.map}}catch(h){throw h.plugin="vite-plugin-what",h.id||(h.id=g),h.loc===void 0&&h._loc&&(h.loc={file:g,line:h._loc.line,column:h._loc.column}),console.error(`[what] Error transforming ${g}:`,h.message),h}},handleHotUpdate({file:u,server:g,modules:h}){if(b&&f.test(u)&&!(x&&x.test(u))&&Pe(u))return g.ws.send({type:"full-reload"}),[]},config(u,{mode:g}){return{esbuild:{jsx:"preserve"},optimizeDeps:{include:["what-framework"]}}}}}function $e(e,f){return!!(Le.test(e)||f.includes("/pages/")||f.includes("\\pages\\"))}function Pe(e){let f=Y.basename(e,Y.extname(e));return ke.test(f)}function Te(e){return`
384
+
385
+ // --- What Framework HMR Boundary ---
386
+ if (import.meta.hot) {
387
+ import.meta.hot.accept((newModule) => {
388
+ if (newModule) {
389
+ // Signal to the What runtime that this module was hot-updated
390
+ if (window.__WHAT_HMR_ACCEPT__) {
391
+ window.__WHAT_HMR_ACCEPT__(${JSON.stringify(e)}, newModule);
392
+ }
393
+ }
394
+ });
395
+ }
396
+ `}import{h as Ve,Fragment as Ue,mount as Ge,Island as qe}from"what-core";export{Ue as Fragment,qe as Island,W as babelPlugin,ce as extractPageConfig,Z as generateRoutesModule,Ve as h,Ge as mount,le as scanPages,Q as vitePlugin,Q as what};
397
+ //# sourceMappingURL=index.min.js.map