diff --git a/dist/sigpro.esm.js b/dist/sigpro.esm.js index 39f9b7d..6f3a67d 100644 --- a/dist/sigpro.esm.js +++ b/dist/sigpro.esm.js @@ -406,7 +406,8 @@ var $mount = (component, target) => { MOUNTED_NODES.set(el, instance); return instance; }; -var SigProCore = { $, $watch, $html, $if, $for, $router, $mount }; +var Fragment = ({ children }) => children; +var SigProCore = { $, $watch, $html, $if, $for, $router, $mount, Fragment }; if (typeof window !== "undefined") { const install = (registry) => { Object.keys(registry).forEach((key) => { @@ -419,11 +420,13 @@ if (typeof window !== "undefined") { window[helperName] = (props, content) => $html(tagName, props, content); } }); + window.Fragment = Fragment; window.SigPro = Object.freeze(registry); }; install(SigProCore); } export { + Fragment, $watch, $router, $mount, diff --git a/dist/sigpro.esm.min.js b/dist/sigpro.esm.min.js index 5d234a1..c7b92dd 100644 --- a/dist/sigpro.esm.min.js +++ b/dist/sigpro.esm.min.js @@ -1 +1 @@ -var p=null,w=null,b=new Set,S=!1,N=new WeakMap,B=()=>{if(S)return;S=!0;while(b.size>0){let s=Array.from(b).sort((r,a)=>(r.depth||0)-(a.depth||0));b.clear();for(let r of s)if(!r._deleted)r()}S=!1},k=(s)=>{if(p&&!p._deleted)s.add(p),p._deps.add(s)},x=(s)=>{for(let r of s){if(r===p||r._deleted)continue;if(r._isComputed){if(r.markDirty(),r._subs)x(r._subs)}else b.add(r)}if(!S)queueMicrotask(B)},O=(s)=>{if(s._cleanups)s._cleanups.forEach((r)=>r()),s._cleanups.clear();s.childNodes?.forEach(O)},A=(s)=>{let r=new Set,a=w,c=document.createElement("div");c.style.display="contents",w={cleanups:r};try{let i=s({onCleanup:(e)=>r.add(e)}),n=(e)=>{if(!e)return;if(e._isRuntime)r.add(e.destroy),c.appendChild(e.container);else if(Array.isArray(e))e.forEach(n);else c.appendChild(e instanceof Node?e:document.createTextNode(String(e)))};n(i)}finally{w=a}return{_isRuntime:!0,container:c,destroy:()=>{r.forEach((i)=>i()),O(c),c.remove()}}},T=(s,r=null)=>{if(typeof s==="function"){let i=new Set,n,e=!0,o=()=>{if(o._deleted)return;o._deps.forEach((t)=>t.delete(o)),o._deps.clear();let f=p;p=o;try{let t=s();if(!Object.is(n,t)||e)n=t,e=!1,x(i)}finally{p=f}};if(o._deps=new Set,o._isComputed=!0,o._subs=i,o._deleted=!1,o.markDirty=()=>e=!0,o.stop=()=>{o._deleted=!0,o._deps.forEach((f)=>f.delete(o)),i.clear()},w)w.cleanups.add(o.stop);return()=>{if(e)o();return k(i),n}}let a=s;if(r)try{let i=localStorage.getItem(r);if(i!==null)a=JSON.parse(i)}catch(i){console.warn("SigPro: LocalStorage locked",i)}let c=new Set;return(...i)=>{if(i.length){let n=typeof i[0]==="function"?i[0](a):i[0];if(!Object.is(a,n)){if(a=n,r)localStorage.setItem(r,JSON.stringify(a));x(c)}}return k(c),a}};var _=(s,r)=>{let a=Array.isArray(s),c=a?r:s,i=a?s:null;if(typeof c!=="function")return()=>{};let n=w,e=()=>{if(e._deleted)return;e._deps.forEach((t)=>t.delete(e)),e._deps.clear(),e._cleanups.forEach((t)=>t()),e._cleanups.clear();let o=p,f=w;p=e,w={cleanups:e._cleanups},e.depth=o?o.depth+1:0;try{if(a)p=null,c(),p=e,i.forEach((t)=>typeof t==="function"&&t());else c()}finally{p=o,w=f}};if(e._deps=new Set,e._cleanups=new Set,e._deleted=!1,e.stop=()=>{if(e._deleted)return;if(e._deleted=!0,b.delete(e),e._deps.forEach((o)=>o.delete(e)),e._cleanups.forEach((o)=>o()),n)n.cleanups.delete(e.stop)},n)n.cleanups.add(e.stop);return e(),e.stop},E=(s,r={},a=[])=>{if(r instanceof Node||Array.isArray(r)||typeof r!=="object")a=r,r={};let i=["svg","path","circle","rect","line","polyline","polygon","g","defs","text","tspan","use"].includes(s),n=i?document.createElementNS("http://www.w3.org/2000/svg",s):document.createElement(s),e=(t,d)=>(t==="src"||t==="href")&&String(d).toLowerCase().includes("javascript:")?"#":d;n._cleanups=new Set;let o=["disabled","checked","required","readonly","selected","multiple","autofocus"];for(let[t,d]of Object.entries(r)){if(t==="ref"){typeof d==="function"?d(n):d.current=n;continue}let m=typeof d==="function";if(["INPUT","TEXTAREA","SELECT"].includes(n.tagName)&&(t==="value"||t==="checked")&&m){n._cleanups.add(_(()=>{let g=d();if(n[t]!==g)n[t]=g}));let l=t==="checked"?"change":"input",y=(g)=>d(g.target[t]);n.addEventListener(l,y),n._cleanups.add(()=>n.removeEventListener(l,y))}else if(t.startsWith("on")){let l=t.slice(2).toLowerCase().split(".")[0],y=(g)=>d(g);n.addEventListener(l,y),n._cleanups.add(()=>n.removeEventListener(l,y))}else if(m)n._cleanups.add(_(()=>{let l=e(t,d());if(t==="class")n.className=l||"";else if(o.includes(t))if(l)n.setAttribute(t,""),n[t]=!0;else n.removeAttribute(t),n[t]=!1;else if(l==null)n.removeAttribute(t);else if(i&&typeof l==="number")n.setAttribute(t,l);else n.setAttribute(t,l)}));else if(o.includes(t))if(d)n.setAttribute(t,""),n[t]=!0;else n.removeAttribute(t),n[t]=!1;else n.setAttribute(t,e(t,d))}let f=(t)=>{if(Array.isArray(t))return t.forEach(f);if(t instanceof Node)n.appendChild(t);else if(typeof t==="function"){let d=document.createTextNode("");n.appendChild(d);let m=[];n._cleanups.add(_(()=>{let u=t(),h=(Array.isArray(u)?u:[u]).map((l)=>l?._isRuntime?l.container:l instanceof Node?l:document.createTextNode(l??""));m.forEach((l)=>{O?.(l),l.remove()}),h.forEach((l)=>d.parentNode?.insertBefore(l,d)),m=h}))}else n.appendChild(document.createTextNode(t??""))};return f(a),n},C=(s,r,a=null,c=null)=>{let i=document.createTextNode(""),n=E("div",{style:"display:contents"},[i]),e=null,o=null;return _(()=>{let f=!!(typeof s==="function"?s():s);if(f===o)return;if(o=f,e&&!f&&c?.out)c.out(e.container,()=>{e.destroy(),e=null});else{if(e)e.destroy();e=null}if(f||!f&&a){let t=f?r:a;if(t){if(e=A(()=>typeof t==="function"?t():t),n.insertBefore(e.container,i),f&&c?.in)c.in(e.container)}}}),n};C.not=(s,r,a)=>C(()=>!(typeof s==="function"?s():s),r,a);var L=(s,r,a,c="div",i={style:"display:contents"})=>{let n=document.createTextNode(""),e=E(c,i,[n]),o=new Map;return _(()=>{let f=(typeof s==="function"?s():s)||[],t=new Map,d=[];for(let u=0;ur(h,u));else o.delete(l);t.set(l,y),d.push(l)}o.forEach((u)=>{u.destroy(),u.container.remove()});let m=n;for(let u=d.length-1;u>=0;u--){let h=t.get(d[u]);if(h.container.nextSibling!==m)e.insertBefore(h.container,m);m=h.container}o=t}),e},v=(s)=>{let r=T(window.location.hash.replace(/^#/,"")||"/");window.addEventListener("hashchange",()=>r(window.location.hash.replace(/^#/,"")||"/"));let a=E("div",{class:"router-outlet"}),c=null;return _([r],async()=>{let i=r(),n=s.find((e)=>{let o=e.path.split("/").filter(Boolean),f=i.split("/").filter(Boolean);return o.length===f.length&&o.every((t,d)=>t.startsWith(":")||t===f[d])})||s.find((e)=>e.path==="*");if(n){let e=n.component;if(typeof e==="function"&&e.toString().includes("import"))e=(await e()).default||await e();let o={};if(n.path.split("/").filter(Boolean).forEach((f,t)=>{if(f.startsWith(":"))o[f.slice(1)]=i.split("/").filter(Boolean)[t]}),c)c.destroy();if(v.params)v.params(o);c=A(()=>{try{return typeof e==="function"?e(o):e}catch(f){return E("div",{class:"p-4 text-error"},"Error loading view")}}),a.appendChild(c.container)}}),a};v.params=T({});v.to=(s)=>window.location.hash=s.replace(/^#?\/?/,"#/");v.back=()=>window.history.back();v.path=()=>window.location.hash.replace(/^#/,"")||"/";var $=(s,r)=>{let a=typeof r==="string"?document.querySelector(r):r;if(!a)return;if(N.has(a))N.get(a).destroy();let c=A(typeof s==="function"?s:()=>s);return a.replaceChildren(c.container),N.set(a,c),c},P={$:T,$watch:_,$html:E,$if:C,$for:L,$router:v,$mount:$};if(typeof window<"u")((r)=>{Object.keys(r).forEach((c)=>{window[c]=r[c]}),"div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter".split(/\s+/).forEach((c)=>{let i=c.charAt(0).toUpperCase()+c.slice(1);if(!(i in window))window[i]=(n,e)=>E(c,n,e)}),window.SigPro=Object.freeze(r)})(P);export{_ as $watch,v as $router,$ as $mount,C as $if,E as $html,L as $for,T as $}; +var p=null,w=null,b=new Set,S=!1,N=new WeakMap,L=()=>{if(S)return;S=!0;while(b.size>0){let s=Array.from(b).sort((r,a)=>(r.depth||0)-(a.depth||0));b.clear();for(let r of s)if(!r._deleted)r()}S=!1},k=(s)=>{if(p&&!p._deleted)s.add(p),p._deps.add(s)},x=(s)=>{for(let r of s){if(r===p||r._deleted)continue;if(r._isComputed){if(r.markDirty(),r._subs)x(r._subs)}else b.add(r)}if(!S)queueMicrotask(L)},O=(s)=>{if(s._cleanups)s._cleanups.forEach((r)=>r()),s._cleanups.clear();s.childNodes?.forEach(O)},A=(s)=>{let r=new Set,a=w,c=document.createElement("div");c.style.display="contents",w={cleanups:r};try{let i=s({onCleanup:(e)=>r.add(e)}),n=(e)=>{if(!e)return;if(e._isRuntime)r.add(e.destroy),c.appendChild(e.container);else if(Array.isArray(e))e.forEach(n);else c.appendChild(e instanceof Node?e:document.createTextNode(String(e)))};n(i)}finally{w=a}return{_isRuntime:!0,container:c,destroy:()=>{r.forEach((i)=>i()),O(c),c.remove()}}},T=(s,r=null)=>{if(typeof s==="function"){let i=new Set,n,e=!0,o=()=>{if(o._deleted)return;o._deps.forEach((t)=>t.delete(o)),o._deps.clear();let f=p;p=o;try{let t=s();if(!Object.is(n,t)||e)n=t,e=!1,x(i)}finally{p=f}};if(o._deps=new Set,o._isComputed=!0,o._subs=i,o._deleted=!1,o.markDirty=()=>e=!0,o.stop=()=>{o._deleted=!0,o._deps.forEach((f)=>f.delete(o)),i.clear()},w)w.cleanups.add(o.stop);return()=>{if(e)o();return k(i),n}}let a=s;if(r)try{let i=localStorage.getItem(r);if(i!==null)a=JSON.parse(i)}catch(i){console.warn("SigPro: LocalStorage locked",i)}let c=new Set;return(...i)=>{if(i.length){let n=typeof i[0]==="function"?i[0](a):i[0];if(!Object.is(a,n)){if(a=n,r)localStorage.setItem(r,JSON.stringify(a));x(c)}}return k(c),a}};var _=(s,r)=>{let a=Array.isArray(s),c=a?r:s,i=a?s:null;if(typeof c!=="function")return()=>{};let n=w,e=()=>{if(e._deleted)return;e._deps.forEach((t)=>t.delete(e)),e._deps.clear(),e._cleanups.forEach((t)=>t()),e._cleanups.clear();let o=p,f=w;p=e,w={cleanups:e._cleanups},e.depth=o?o.depth+1:0;try{if(a)p=null,c(),p=e,i.forEach((t)=>typeof t==="function"&&t());else c()}finally{p=o,w=f}};if(e._deps=new Set,e._cleanups=new Set,e._deleted=!1,e.stop=()=>{if(e._deleted)return;if(e._deleted=!0,b.delete(e),e._deps.forEach((o)=>o.delete(e)),e._cleanups.forEach((o)=>o()),n)n.cleanups.delete(e.stop)},n)n.cleanups.add(e.stop);return e(),e.stop},E=(s,r={},a=[])=>{if(r instanceof Node||Array.isArray(r)||typeof r!=="object")a=r,r={};let i=["svg","path","circle","rect","line","polyline","polygon","g","defs","text","tspan","use"].includes(s),n=i?document.createElementNS("http://www.w3.org/2000/svg",s):document.createElement(s),e=(t,d)=>(t==="src"||t==="href")&&String(d).toLowerCase().includes("javascript:")?"#":d;n._cleanups=new Set;let o=["disabled","checked","required","readonly","selected","multiple","autofocus"];for(let[t,d]of Object.entries(r)){if(t==="ref"){typeof d==="function"?d(n):d.current=n;continue}let m=typeof d==="function";if(["INPUT","TEXTAREA","SELECT"].includes(n.tagName)&&(t==="value"||t==="checked")&&m){n._cleanups.add(_(()=>{let g=d();if(n[t]!==g)n[t]=g}));let l=t==="checked"?"change":"input",y=(g)=>d(g.target[t]);n.addEventListener(l,y),n._cleanups.add(()=>n.removeEventListener(l,y))}else if(t.startsWith("on")){let l=t.slice(2).toLowerCase().split(".")[0],y=(g)=>d(g);n.addEventListener(l,y),n._cleanups.add(()=>n.removeEventListener(l,y))}else if(m)n._cleanups.add(_(()=>{let l=e(t,d());if(t==="class")n.className=l||"";else if(o.includes(t))if(l)n.setAttribute(t,""),n[t]=!0;else n.removeAttribute(t),n[t]=!1;else if(l==null)n.removeAttribute(t);else if(i&&typeof l==="number")n.setAttribute(t,l);else n.setAttribute(t,l)}));else if(o.includes(t))if(d)n.setAttribute(t,""),n[t]=!0;else n.removeAttribute(t),n[t]=!1;else n.setAttribute(t,e(t,d))}let f=(t)=>{if(Array.isArray(t))return t.forEach(f);if(t instanceof Node)n.appendChild(t);else if(typeof t==="function"){let d=document.createTextNode("");n.appendChild(d);let m=[];n._cleanups.add(_(()=>{let u=t(),h=(Array.isArray(u)?u:[u]).map((l)=>l?._isRuntime?l.container:l instanceof Node?l:document.createTextNode(l??""));m.forEach((l)=>{O?.(l),l.remove()}),h.forEach((l)=>d.parentNode?.insertBefore(l,d)),m=h}))}else n.appendChild(document.createTextNode(t??""))};return f(a),n},C=(s,r,a=null,c=null)=>{let i=document.createTextNode(""),n=E("div",{style:"display:contents"},[i]),e=null,o=null;return _(()=>{let f=!!(typeof s==="function"?s():s);if(f===o)return;if(o=f,e&&!f&&c?.out)c.out(e.container,()=>{e.destroy(),e=null});else{if(e)e.destroy();e=null}if(f||!f&&a){let t=f?r:a;if(t){if(e=A(()=>typeof t==="function"?t():t),n.insertBefore(e.container,i),f&&c?.in)c.in(e.container)}}}),n};C.not=(s,r,a)=>C(()=>!(typeof s==="function"?s():s),r,a);var $=(s,r,a,c="div",i={style:"display:contents"})=>{let n=document.createTextNode(""),e=E(c,i,[n]),o=new Map;return _(()=>{let f=(typeof s==="function"?s():s)||[],t=new Map,d=[];for(let u=0;ur(h,u));else o.delete(l);t.set(l,y),d.push(l)}o.forEach((u)=>{u.destroy(),u.container.remove()});let m=n;for(let u=d.length-1;u>=0;u--){let h=t.get(d[u]);if(h.container.nextSibling!==m)e.insertBefore(h.container,m);m=h.container}o=t}),e},v=(s)=>{let r=T(window.location.hash.replace(/^#/,"")||"/");window.addEventListener("hashchange",()=>r(window.location.hash.replace(/^#/,"")||"/"));let a=E("div",{class:"router-outlet"}),c=null;return _([r],async()=>{let i=r(),n=s.find((e)=>{let o=e.path.split("/").filter(Boolean),f=i.split("/").filter(Boolean);return o.length===f.length&&o.every((t,d)=>t.startsWith(":")||t===f[d])})||s.find((e)=>e.path==="*");if(n){let e=n.component;if(typeof e==="function"&&e.toString().includes("import"))e=(await e()).default||await e();let o={};if(n.path.split("/").filter(Boolean).forEach((f,t)=>{if(f.startsWith(":"))o[f.slice(1)]=i.split("/").filter(Boolean)[t]}),c)c.destroy();if(v.params)v.params(o);c=A(()=>{try{return typeof e==="function"?e(o):e}catch(f){return E("div",{class:"p-4 text-error"},"Error loading view")}}),a.appendChild(c.container)}}),a};v.params=T({});v.to=(s)=>window.location.hash=s.replace(/^#?\/?/,"#/");v.back=()=>window.history.back();v.path=()=>window.location.hash.replace(/^#/,"")||"/";var P=(s,r)=>{let a=typeof r==="string"?document.querySelector(r):r;if(!a)return;if(N.has(a))N.get(a).destroy();let c=A(typeof s==="function"?s:()=>s);return a.replaceChildren(c.container),N.set(a,c),c},B=({children:s})=>s,I={$:T,$watch:_,$html:E,$if:C,$for:$,$router:v,$mount:P,Fragment:B};if(typeof window<"u")((r)=>{Object.keys(r).forEach((c)=>{window[c]=r[c]}),"div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter".split(/\s+/).forEach((c)=>{let i=c.charAt(0).toUpperCase()+c.slice(1);if(!(i in window))window[i]=(n,e)=>E(c,n,e)}),window.Fragment=B,window.SigPro=Object.freeze(r)})(I);export{B as Fragment,_ as $watch,v as $router,P as $mount,C as $if,E as $html,$ as $for,T as $}; diff --git a/dist/sigpro.js b/dist/sigpro.js index a0cb8c8..2d6fa4f 100644 --- a/dist/sigpro.js +++ b/dist/sigpro.js @@ -30,6 +30,7 @@ // index.js var exports_sigpro = {}; __export(exports_sigpro, { + Fragment: () => Fragment, $watch: () => $watch, $router: () => $router, $mount: () => $mount, @@ -447,7 +448,8 @@ MOUNTED_NODES.set(el, instance); return instance; }; - var SigProCore = { $, $watch, $html, $if, $for, $router, $mount }; + var Fragment = ({ children }) => children; + var SigProCore = { $, $watch, $html, $if, $for, $router, $mount, Fragment }; if (typeof window !== "undefined") { const install = (registry) => { Object.keys(registry).forEach((key) => { @@ -460,6 +462,7 @@ window[helperName] = (props, content) => $html(tagName, props, content); } }); + window.Fragment = Fragment; window.SigPro = Object.freeze(registry); }; install(SigProCore); diff --git a/dist/sigpro.min.js b/dist/sigpro.min.js index 23118e5..a478228 100644 --- a/dist/sigpro.min.js +++ b/dist/sigpro.min.js @@ -1 +1 @@ -(()=>{var{defineProperty:C,getOwnPropertyNames:I,getOwnPropertyDescriptor:M}=Object,R=Object.prototype.hasOwnProperty;var B=new WeakMap,j=(s)=>{var t=B.get(s),c;if(t)return t;if(t=C({},"__esModule",{value:!0}),s&&typeof s==="object"||typeof s==="function")I(s).map((o)=>!R.call(t,o)&&C(t,o,{get:()=>s[o],enumerable:!(c=M(s,o))||c.enumerable}));return B.set(s,t),t};var W=(s,t)=>{for(var c in t)C(s,c,{get:t[c],enumerable:!0,configurable:!0,set:(o)=>t[c]=()=>o})};var z={};W(z,{$watch:()=>_,$router:()=>v,$mount:()=>P,$if:()=>A,$html:()=>g,$for:()=>$,$:()=>x});var p=null,w=null,b=new Set,S=!1,O=new WeakMap,q=()=>{if(S)return;S=!0;while(b.size>0){let s=Array.from(b).sort((t,c)=>(t.depth||0)-(c.depth||0));b.clear();for(let t of s)if(!t._deleted)t()}S=!1},L=(s)=>{if(p&&!p._deleted)s.add(p),p._deps.add(s)},T=(s)=>{for(let t of s){if(t===p||t._deleted)continue;if(t._isComputed){if(t.markDirty(),t._subs)T(t._subs)}else b.add(t)}if(!S)queueMicrotask(q)},k=(s)=>{if(s._cleanups)s._cleanups.forEach((t)=>t()),s._cleanups.clear();s.childNodes?.forEach(k)},N=(s)=>{let t=new Set,c=w,o=document.createElement("div");o.style.display="contents",w={cleanups:t};try{let i=s({onCleanup:(e)=>t.add(e)}),r=(e)=>{if(!e)return;if(e._isRuntime)t.add(e.destroy),o.appendChild(e.container);else if(Array.isArray(e))e.forEach(r);else o.appendChild(e instanceof Node?e:document.createTextNode(String(e)))};r(i)}finally{w=c}return{_isRuntime:!0,container:o,destroy:()=>{t.forEach((i)=>i()),k(o),o.remove()}}},x=(s,t=null)=>{if(typeof s==="function"){let i=new Set,r,e=!0,a=()=>{if(a._deleted)return;a._deps.forEach((n)=>n.delete(a)),a._deps.clear();let f=p;p=a;try{let n=s();if(!Object.is(r,n)||e)r=n,e=!1,T(i)}finally{p=f}};if(a._deps=new Set,a._isComputed=!0,a._subs=i,a._deleted=!1,a.markDirty=()=>e=!0,a.stop=()=>{a._deleted=!0,a._deps.forEach((f)=>f.delete(a)),i.clear()},w)w.cleanups.add(a.stop);return()=>{if(e)a();return L(i),r}}let c=s;if(t)try{let i=localStorage.getItem(t);if(i!==null)c=JSON.parse(i)}catch(i){console.warn("SigPro: LocalStorage locked",i)}let o=new Set;return(...i)=>{if(i.length){let r=typeof i[0]==="function"?i[0](c):i[0];if(!Object.is(c,r)){if(c=r,t)localStorage.setItem(t,JSON.stringify(c));T(o)}}return L(o),c}};var _=(s,t)=>{let c=Array.isArray(s),o=c?t:s,i=c?s:null;if(typeof o!=="function")return()=>{};let r=w,e=()=>{if(e._deleted)return;e._deps.forEach((n)=>n.delete(e)),e._deps.clear(),e._cleanups.forEach((n)=>n()),e._cleanups.clear();let a=p,f=w;p=e,w={cleanups:e._cleanups},e.depth=a?a.depth+1:0;try{if(c)p=null,o(),p=e,i.forEach((n)=>typeof n==="function"&&n());else o()}finally{p=a,w=f}};if(e._deps=new Set,e._cleanups=new Set,e._deleted=!1,e.stop=()=>{if(e._deleted)return;if(e._deleted=!0,b.delete(e),e._deps.forEach((a)=>a.delete(e)),e._cleanups.forEach((a)=>a()),r)r.cleanups.delete(e.stop)},r)r.cleanups.add(e.stop);return e(),e.stop},g=(s,t={},c=[])=>{if(t instanceof Node||Array.isArray(t)||typeof t!=="object")c=t,t={};let i=["svg","path","circle","rect","line","polyline","polygon","g","defs","text","tspan","use"].includes(s),r=i?document.createElementNS("http://www.w3.org/2000/svg",s):document.createElement(s),e=(n,d)=>(n==="src"||n==="href")&&String(d).toLowerCase().includes("javascript:")?"#":d;r._cleanups=new Set;let a=["disabled","checked","required","readonly","selected","multiple","autofocus"];for(let[n,d]of Object.entries(t)){if(n==="ref"){typeof d==="function"?d(r):d.current=r;continue}let m=typeof d==="function";if(["INPUT","TEXTAREA","SELECT"].includes(r.tagName)&&(n==="value"||n==="checked")&&m){r._cleanups.add(_(()=>{let E=d();if(r[n]!==E)r[n]=E}));let l=n==="checked"?"change":"input",y=(E)=>d(E.target[n]);r.addEventListener(l,y),r._cleanups.add(()=>r.removeEventListener(l,y))}else if(n.startsWith("on")){let l=n.slice(2).toLowerCase().split(".")[0],y=(E)=>d(E);r.addEventListener(l,y),r._cleanups.add(()=>r.removeEventListener(l,y))}else if(m)r._cleanups.add(_(()=>{let l=e(n,d());if(n==="class")r.className=l||"";else if(a.includes(n))if(l)r.setAttribute(n,""),r[n]=!0;else r.removeAttribute(n),r[n]=!1;else if(l==null)r.removeAttribute(n);else if(i&&typeof l==="number")r.setAttribute(n,l);else r.setAttribute(n,l)}));else if(a.includes(n))if(d)r.setAttribute(n,""),r[n]=!0;else r.removeAttribute(n),r[n]=!1;else r.setAttribute(n,e(n,d))}let f=(n)=>{if(Array.isArray(n))return n.forEach(f);if(n instanceof Node)r.appendChild(n);else if(typeof n==="function"){let d=document.createTextNode("");r.appendChild(d);let m=[];r._cleanups.add(_(()=>{let u=n(),h=(Array.isArray(u)?u:[u]).map((l)=>l?._isRuntime?l.container:l instanceof Node?l:document.createTextNode(l??""));m.forEach((l)=>{k?.(l),l.remove()}),h.forEach((l)=>d.parentNode?.insertBefore(l,d)),m=h}))}else r.appendChild(document.createTextNode(n??""))};return f(c),r},A=(s,t,c=null,o=null)=>{let i=document.createTextNode(""),r=g("div",{style:"display:contents"},[i]),e=null,a=null;return _(()=>{let f=!!(typeof s==="function"?s():s);if(f===a)return;if(a=f,e&&!f&&o?.out)o.out(e.container,()=>{e.destroy(),e=null});else{if(e)e.destroy();e=null}if(f||!f&&c){let n=f?t:c;if(n){if(e=N(()=>typeof n==="function"?n():n),r.insertBefore(e.container,i),f&&o?.in)o.in(e.container)}}}),r};A.not=(s,t,c)=>A(()=>!(typeof s==="function"?s():s),t,c);var $=(s,t,c,o="div",i={style:"display:contents"})=>{let r=document.createTextNode(""),e=g(o,i,[r]),a=new Map;return _(()=>{let f=(typeof s==="function"?s():s)||[],n=new Map,d=[];for(let u=0;ut(h,u));else a.delete(l);n.set(l,y),d.push(l)}a.forEach((u)=>{u.destroy(),u.container.remove()});let m=r;for(let u=d.length-1;u>=0;u--){let h=n.get(d[u]);if(h.container.nextSibling!==m)e.insertBefore(h.container,m);m=h.container}a=n}),e},v=(s)=>{let t=x(window.location.hash.replace(/^#/,"")||"/");window.addEventListener("hashchange",()=>t(window.location.hash.replace(/^#/,"")||"/"));let c=g("div",{class:"router-outlet"}),o=null;return _([t],async()=>{let i=t(),r=s.find((e)=>{let a=e.path.split("/").filter(Boolean),f=i.split("/").filter(Boolean);return a.length===f.length&&a.every((n,d)=>n.startsWith(":")||n===f[d])})||s.find((e)=>e.path==="*");if(r){let e=r.component;if(typeof e==="function"&&e.toString().includes("import"))e=(await e()).default||await e();let a={};if(r.path.split("/").filter(Boolean).forEach((f,n)=>{if(f.startsWith(":"))a[f.slice(1)]=i.split("/").filter(Boolean)[n]}),o)o.destroy();if(v.params)v.params(a);o=N(()=>{try{return typeof e==="function"?e(a):e}catch(f){return g("div",{class:"p-4 text-error"},"Error loading view")}}),c.appendChild(o.container)}}),c};v.params=x({});v.to=(s)=>window.location.hash=s.replace(/^#?\/?/,"#/");v.back=()=>window.history.back();v.path=()=>window.location.hash.replace(/^#/,"")||"/";var P=(s,t)=>{let c=typeof t==="string"?document.querySelector(t):t;if(!c)return;if(O.has(c))O.get(c).destroy();let o=N(typeof s==="function"?s:()=>s);return c.replaceChildren(o.container),O.set(c,o),o},D={$:x,$watch:_,$html:g,$if:A,$for:$,$router:v,$mount:P};if(typeof window<"u")((t)=>{Object.keys(t).forEach((o)=>{window[o]=t[o]}),"div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter".split(/\s+/).forEach((o)=>{let i=o.charAt(0).toUpperCase()+o.slice(1);if(!(i in window))window[i]=(r,e)=>g(o,r,e)}),window.SigPro=Object.freeze(t)})(D);})(); +(()=>{var{defineProperty:C,getOwnPropertyNames:M,getOwnPropertyDescriptor:R}=Object,j=Object.prototype.hasOwnProperty;var L=new WeakMap,W=(r)=>{var t=L.get(r),c;if(t)return t;if(t=C({},"__esModule",{value:!0}),r&&typeof r==="object"||typeof r==="function")M(r).map((o)=>!j.call(t,o)&&C(t,o,{get:()=>r[o],enumerable:!(c=R(r,o))||c.enumerable}));return L.set(r,t),t};var q=(r,t)=>{for(var c in t)C(r,c,{get:t[c],enumerable:!0,configurable:!0,set:(o)=>t[c]=()=>o})};var U={};q(U,{Fragment:()=>B,$watch:()=>_,$router:()=>v,$mount:()=>I,$if:()=>A,$html:()=>g,$for:()=>P,$:()=>x});var p=null,w=null,b=new Set,S=!1,O=new WeakMap,D=()=>{if(S)return;S=!0;while(b.size>0){let r=Array.from(b).sort((t,c)=>(t.depth||0)-(c.depth||0));b.clear();for(let t of r)if(!t._deleted)t()}S=!1},$=(r)=>{if(p&&!p._deleted)r.add(p),p._deps.add(r)},T=(r)=>{for(let t of r){if(t===p||t._deleted)continue;if(t._isComputed){if(t.markDirty(),t._subs)T(t._subs)}else b.add(t)}if(!S)queueMicrotask(D)},k=(r)=>{if(r._cleanups)r._cleanups.forEach((t)=>t()),r._cleanups.clear();r.childNodes?.forEach(k)},N=(r)=>{let t=new Set,c=w,o=document.createElement("div");o.style.display="contents",w={cleanups:t};try{let i=r({onCleanup:(e)=>t.add(e)}),s=(e)=>{if(!e)return;if(e._isRuntime)t.add(e.destroy),o.appendChild(e.container);else if(Array.isArray(e))e.forEach(s);else o.appendChild(e instanceof Node?e:document.createTextNode(String(e)))};s(i)}finally{w=c}return{_isRuntime:!0,container:o,destroy:()=>{t.forEach((i)=>i()),k(o),o.remove()}}},x=(r,t=null)=>{if(typeof r==="function"){let i=new Set,s,e=!0,a=()=>{if(a._deleted)return;a._deps.forEach((n)=>n.delete(a)),a._deps.clear();let f=p;p=a;try{let n=r();if(!Object.is(s,n)||e)s=n,e=!1,T(i)}finally{p=f}};if(a._deps=new Set,a._isComputed=!0,a._subs=i,a._deleted=!1,a.markDirty=()=>e=!0,a.stop=()=>{a._deleted=!0,a._deps.forEach((f)=>f.delete(a)),i.clear()},w)w.cleanups.add(a.stop);return()=>{if(e)a();return $(i),s}}let c=r;if(t)try{let i=localStorage.getItem(t);if(i!==null)c=JSON.parse(i)}catch(i){console.warn("SigPro: LocalStorage locked",i)}let o=new Set;return(...i)=>{if(i.length){let s=typeof i[0]==="function"?i[0](c):i[0];if(!Object.is(c,s)){if(c=s,t)localStorage.setItem(t,JSON.stringify(c));T(o)}}return $(o),c}};var _=(r,t)=>{let c=Array.isArray(r),o=c?t:r,i=c?r:null;if(typeof o!=="function")return()=>{};let s=w,e=()=>{if(e._deleted)return;e._deps.forEach((n)=>n.delete(e)),e._deps.clear(),e._cleanups.forEach((n)=>n()),e._cleanups.clear();let a=p,f=w;p=e,w={cleanups:e._cleanups},e.depth=a?a.depth+1:0;try{if(c)p=null,o(),p=e,i.forEach((n)=>typeof n==="function"&&n());else o()}finally{p=a,w=f}};if(e._deps=new Set,e._cleanups=new Set,e._deleted=!1,e.stop=()=>{if(e._deleted)return;if(e._deleted=!0,b.delete(e),e._deps.forEach((a)=>a.delete(e)),e._cleanups.forEach((a)=>a()),s)s.cleanups.delete(e.stop)},s)s.cleanups.add(e.stop);return e(),e.stop},g=(r,t={},c=[])=>{if(t instanceof Node||Array.isArray(t)||typeof t!=="object")c=t,t={};let i=["svg","path","circle","rect","line","polyline","polygon","g","defs","text","tspan","use"].includes(r),s=i?document.createElementNS("http://www.w3.org/2000/svg",r):document.createElement(r),e=(n,d)=>(n==="src"||n==="href")&&String(d).toLowerCase().includes("javascript:")?"#":d;s._cleanups=new Set;let a=["disabled","checked","required","readonly","selected","multiple","autofocus"];for(let[n,d]of Object.entries(t)){if(n==="ref"){typeof d==="function"?d(s):d.current=s;continue}let m=typeof d==="function";if(["INPUT","TEXTAREA","SELECT"].includes(s.tagName)&&(n==="value"||n==="checked")&&m){s._cleanups.add(_(()=>{let E=d();if(s[n]!==E)s[n]=E}));let l=n==="checked"?"change":"input",y=(E)=>d(E.target[n]);s.addEventListener(l,y),s._cleanups.add(()=>s.removeEventListener(l,y))}else if(n.startsWith("on")){let l=n.slice(2).toLowerCase().split(".")[0],y=(E)=>d(E);s.addEventListener(l,y),s._cleanups.add(()=>s.removeEventListener(l,y))}else if(m)s._cleanups.add(_(()=>{let l=e(n,d());if(n==="class")s.className=l||"";else if(a.includes(n))if(l)s.setAttribute(n,""),s[n]=!0;else s.removeAttribute(n),s[n]=!1;else if(l==null)s.removeAttribute(n);else if(i&&typeof l==="number")s.setAttribute(n,l);else s.setAttribute(n,l)}));else if(a.includes(n))if(d)s.setAttribute(n,""),s[n]=!0;else s.removeAttribute(n),s[n]=!1;else s.setAttribute(n,e(n,d))}let f=(n)=>{if(Array.isArray(n))return n.forEach(f);if(n instanceof Node)s.appendChild(n);else if(typeof n==="function"){let d=document.createTextNode("");s.appendChild(d);let m=[];s._cleanups.add(_(()=>{let u=n(),h=(Array.isArray(u)?u:[u]).map((l)=>l?._isRuntime?l.container:l instanceof Node?l:document.createTextNode(l??""));m.forEach((l)=>{k?.(l),l.remove()}),h.forEach((l)=>d.parentNode?.insertBefore(l,d)),m=h}))}else s.appendChild(document.createTextNode(n??""))};return f(c),s},A=(r,t,c=null,o=null)=>{let i=document.createTextNode(""),s=g("div",{style:"display:contents"},[i]),e=null,a=null;return _(()=>{let f=!!(typeof r==="function"?r():r);if(f===a)return;if(a=f,e&&!f&&o?.out)o.out(e.container,()=>{e.destroy(),e=null});else{if(e)e.destroy();e=null}if(f||!f&&c){let n=f?t:c;if(n){if(e=N(()=>typeof n==="function"?n():n),s.insertBefore(e.container,i),f&&o?.in)o.in(e.container)}}}),s};A.not=(r,t,c)=>A(()=>!(typeof r==="function"?r():r),t,c);var P=(r,t,c,o="div",i={style:"display:contents"})=>{let s=document.createTextNode(""),e=g(o,i,[s]),a=new Map;return _(()=>{let f=(typeof r==="function"?r():r)||[],n=new Map,d=[];for(let u=0;ut(h,u));else a.delete(l);n.set(l,y),d.push(l)}a.forEach((u)=>{u.destroy(),u.container.remove()});let m=s;for(let u=d.length-1;u>=0;u--){let h=n.get(d[u]);if(h.container.nextSibling!==m)e.insertBefore(h.container,m);m=h.container}a=n}),e},v=(r)=>{let t=x(window.location.hash.replace(/^#/,"")||"/");window.addEventListener("hashchange",()=>t(window.location.hash.replace(/^#/,"")||"/"));let c=g("div",{class:"router-outlet"}),o=null;return _([t],async()=>{let i=t(),s=r.find((e)=>{let a=e.path.split("/").filter(Boolean),f=i.split("/").filter(Boolean);return a.length===f.length&&a.every((n,d)=>n.startsWith(":")||n===f[d])})||r.find((e)=>e.path==="*");if(s){let e=s.component;if(typeof e==="function"&&e.toString().includes("import"))e=(await e()).default||await e();let a={};if(s.path.split("/").filter(Boolean).forEach((f,n)=>{if(f.startsWith(":"))a[f.slice(1)]=i.split("/").filter(Boolean)[n]}),o)o.destroy();if(v.params)v.params(a);o=N(()=>{try{return typeof e==="function"?e(a):e}catch(f){return g("div",{class:"p-4 text-error"},"Error loading view")}}),c.appendChild(o.container)}}),c};v.params=x({});v.to=(r)=>window.location.hash=r.replace(/^#?\/?/,"#/");v.back=()=>window.history.back();v.path=()=>window.location.hash.replace(/^#/,"")||"/";var I=(r,t)=>{let c=typeof t==="string"?document.querySelector(t):t;if(!c)return;if(O.has(c))O.get(c).destroy();let o=N(typeof r==="function"?r:()=>r);return c.replaceChildren(o.container),O.set(c,o),o},B=({children:r})=>r,z={$:x,$watch:_,$html:g,$if:A,$for:P,$router:v,$mount:I,Fragment:B};if(typeof window<"u")((t)=>{Object.keys(t).forEach((o)=>{window[o]=t[o]}),"div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter".split(/\s+/).forEach((o)=>{let i=o.charAt(0).toUpperCase()+o.slice(1);if(!(i in window))window[i]=(s,e)=>g(o,s,e)}),window.Fragment=B,window.SigPro=Object.freeze(t)})(z);})(); diff --git a/docs/_sidebar.md b/docs/_sidebar.md index b849f3f..8c9b3b9 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -16,6 +16,7 @@ * [$html](api/html.md) * [Tags](api/tags.md) * [Global Store](api/global.md) + * [JSX Style](api/jsx.md) * **UI Components** * [Quick Start](ui/quick.md) \ No newline at end of file diff --git a/docs/api/jsx.md b/docs/api/jsx.md new file mode 100644 index 0000000..05ea8b5 --- /dev/null +++ b/docs/api/jsx.md @@ -0,0 +1,171 @@ +# JSX with SigPro + +SigPro works seamlessly with JSX. + +## Configuration + +### TypeScript + +```json +// tsconfig.json +{ + "compilerOptions": { + "jsx": "react", + "jsxFactory": "$html", + "jsxFragmentFactory": "Fragment" + } +} +``` + +### Vite + +```js +// vite.config.js +import { defineConfig } from 'vite' + +export default defineConfig({ + esbuild: { + jsxFactory: '$html', + jsxFragmentFactory: 'Fragment' + } +}) +``` + +### Babel + +```js +// babel.config.js +export default { + plugins: [ + ['@babel/plugin-transform-react-jsx', { + pragma: '$html', + pragmaFrag: 'Fragment' + }] + ] +} +``` + +## Usage Example + +```jsx +// App.jsx +import { $, $mount, Fragment } from 'sigpro'; + +const Button = ({ onClick, children }) => ( + +); + +const App = () => { + const count = $(0); + + return ( +
+

SigPro with JSX

+ + + + +

Multiple elements

+

Without extra wrapper

+
+
+ ); +}; + +$mount(App, '#app'); +``` + +## What Gets Compiled + +Your JSX: +```jsx +
+ +
+``` + +Compiles to: +```javascript +$html('div', { class: "container" }, + $html(Button, {}, "Click") +) +``` + +## Without Build Step (CDN) + +SigPro automatically injects `Div()`, `Button()`, `Span()`, and all other HTML tag helpers globally when loaded via CDN. `Fragment` is also available. + +```html + + + + + + +
+ + + + +``` + +## Template Literals Alternative (htm) + +For a JSX-like syntax without a build step, use `htm`: + +```javascript +import { $, $mount } from 'https://unpkg.com/sigpro'; +import htm from 'https://esm.sh/htm'; + +const html = htm.bind($html); + +const App = () => { + const count = $(0); + + return html` +
+

SigPro Demo

+ +
+ `; +}; + +$mount(App, '#app'); +``` + +## Summary + +| Method | Build Step | Syntax | +|--------|------------|--------| +| JSX | Required | `
...
` | +| CDN (Tag Helpers) | Optional | `Div({}, ...)` | +| htm | Optional | `` html`
...
` `` | + +> [!TIP] +> **Recommendation:** Use JSX for large projects, CDN tag helpers (`Div()`, `Button()`) for simple projects, or htm for buildless projects that want HTML-like syntax. diff --git a/docs/install.md b/docs/install.md index 3c011c4..4eb66cc 100644 --- a/docs/install.md +++ b/docs/install.md @@ -42,7 +42,6 @@ bun add sigpro ``` -
@@ -153,17 +152,17 @@ $mount(App, "#app"); One of SigPro's core strengths is its **Global API**, which eliminates "Import Hell" while remaining ESM-compatible. -* **The "Zero-Config" Import:** By simply adding `import SigPro from "sigpro"`, the framework automatically "hydrates" the global `window` object. - * **Core Functions:** You get immediate access to `$`, `$watch`, `$html`, `$if`, `$for`, and `$router` anywhere in your scripts without using the `SigPro.` prefix. - * **Auto-Installation:** This happens instantly upon import thanks to its built-in `install()` routine, making it "Plug & Play" for both local projects and CDN usage. +- **The "Zero-Config" Import:** By simply adding `import SigPro from "sigpro"`, the framework automatically "hydrates" the global `window` object. + - **Core Functions:** You get immediate access to `$`, `$watch`, `$html`, `$if`, `$for`, and `$router` anywhere in your scripts without using the `SigPro.` prefix. + - **Auto-Installation:** This happens instantly upon import thanks to its built-in `install()` routine, making it "Plug & Play" for both local projects and CDN usage. -* **PascalCase Tag Helpers:** Standard HTML tags are pre-registered as global functions (`Div`, `Span`, `Button`, `Section`, etc.). - * **Clean UI Syntax:** This allows you to write UI structures that look like HTML but are pure, reactive JavaScript: `Div({ class: "card" }, [ H1("Title") ])`. +- **PascalCase Tag Helpers:** Standard HTML tags are pre-registered as global functions (`Div`, `Span`, `Button`, `Section`, etc.). + - **Clean UI Syntax:** This allows you to write UI structures that look like HTML but are pure, reactive JavaScript: `Div({ class: "card" }, [ H1("Title") ])`. -* **Hybrid Tree Shaking:** * For **Maximum Speed**, use `import SigPro from "sigpro"`. - * For **Maximum Optimization**, you can still use Named Imports: `import { $, $html } from "sigpro"`. This allows modern bundlers like Vite to prune unused code while keeping your core reactive. +- **Hybrid Tree Shaking:** \* For **Maximum Speed**, use `import SigPro from "sigpro"`. + - For **Maximum Optimization**, you can still use Named Imports: `import { $, $html } from "sigpro"`. This allows modern bundlers like Vite to prune unused code while keeping your core reactive. -* **Custom Components:** We recommend using **PascalCase** for your own components (e.g., `UserCard()`) to maintain visual consistency with the built-in Tag Helpers and distinguish them from standard logic. +- **Custom Components:** We recommend using **PascalCase** for your own components (e.g., `UserCard()`) to maintain visual consistency with the built-in Tag Helpers and distinguish them from standard logic. --- diff --git a/index.js b/index.js index 57a0649..7c1a028 100644 --- a/index.js +++ b/index.js @@ -1,2 +1,2 @@ // index.js -export * from './dist/sigpro.esm.js'; \ No newline at end of file +export * from './sigpro/index.js'; \ No newline at end of file diff --git a/sigpro/index.js b/sigpro/index.js index fa05d66..06d86eb 100644 --- a/sigpro/index.js +++ b/sigpro/index.js @@ -223,13 +223,13 @@ const $html = (tag, props = {}, content = []) => { if (props instanceof Node || Array.isArray(props) || typeof props !== "object") { content = props; props = {}; } - - const svgTags = ["svg","path","circle","rect","line","polyline","polygon","g","defs","text","tspan","use"]; + + const svgTags = ["svg", "path", "circle", "rect", "line", "polyline", "polygon", "g", "defs", "text", "tspan", "use"]; const isSVG = svgTags.includes(tag); - const el = isSVG + const el = isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tag) : document.createElement(tag); - + const _sanitize = (key, val) => (key === 'src' || key === 'href') && String(val).toLowerCase().includes('javascript:') ? '#' : val; el._cleanups = new Set(); @@ -312,12 +312,12 @@ const $if = (condition, thenVal, otherwiseVal = null, transition = null) => { const marker = document.createTextNode(""); const container = $html("div", { style: "display:contents" }, [marker]); let current = null, last = null; - + $watch(() => { const state = !!(typeof condition === "function" ? condition() : condition); if (state === last) return; last = state; - + if (current && !state && transition?.out) { transition.out(current.container, () => { current.destroy(); @@ -327,7 +327,7 @@ const $if = (condition, thenVal, otherwiseVal = null, transition = null) => { if (current) current.destroy(); current = null; } - + if (state || (!state && otherwiseVal)) { const branch = state ? thenVal : otherwiseVal; if (branch) { @@ -337,7 +337,7 @@ const $if = (condition, thenVal, otherwiseVal = null, transition = null) => { } } }); - + return container; }; @@ -443,7 +443,9 @@ const $mount = (component, target) => { return instance; }; -const SigProCore = { $, $watch, $html, $if, $for, $router, $mount }; +export const Fragment = ({ children }) => children; + +const SigProCore = { $, $watch, $html, $if, $for, $router, $mount, Fragment }; if (typeof window !== "undefined") { const install = (registry) => { @@ -458,7 +460,8 @@ if (typeof window !== "undefined") { window[helperName] = (props, content) => $html(tagName, props, content); } }); - + + window.Fragment = Fragment; window.SigPro = Object.freeze(registry); };