sigment
Version:
A lightweight reactive JavaScript framework built with signals and vanilla JS — no virtual DOM, no JSX, no transpilation.
12 lines (9 loc) • 15.9 kB
JavaScript
var Z=Object.defineProperty;var s=(e,t)=>Z(e,"name",{value:t,configurable:!0});var b={cleanHtml:N,cleanhtml:!0,setMaxCacheSize:X,maxCacheSize:10,setRoute:ee,route:null},E={funcname:[],dataMap:new Map},O=null,k={},M=new Map,x=new Map,_=new Map,K=null,A=null,F=new Map,S=null,V=window.location.href.replace(/^https?:\/\//,"").replace(/\/$/,""),a={innerHTMLElements:["div","p","span","h1","h2","h3","h4","h5","h6","a","ul","ol","li","table","tr","td","th","thead","tbody","tfoot","form","label","button","section","article","header","footer","nav","aside","main","figure","figcaption","blockquote","cite","code","pre","em","strong","i","b","u","s","small","mark","time","abbr","q","dl","dt","dd","fieldset","legend","textarea","output","progress","meter","fragment","details","summary","dialog","menu","slot","template"],valueElements:["input","textarea","select","button","option","progress","meter"],srcElements:["img","script","iframe","audio","video","source","track","embed","frame","input"],hrefElements:["a","link","area","base"],voidElements:["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr","frame"]};Object.values(a).flat().forEach(e=>{globalThis[e]=(...t)=>T(e,...t)});var H=new Set(a.valueElements),J=new Set(a.srcElements),U=new Set(a.hrefElements),P=new Set(a.voidElements);function fe(e,t){k[e]||(k[e]=le(t))}s(fe,"createGlobalSignal");function de(e){return k[e]}s(de,"getGlobalSignal");function B(e,t){E.dataMap.has(e)&&E.dataMap.delete(e),E.dataMap.set(e,t)}s(B,"addEntry");function L(e){C(L.name);let t=E.dataMap.get(e);return t?t.value:null}s(L,"gve");function pe(e,t,n){let l;if(t instanceof HTMLElement?l=t.outerHTML:typeof t=="object"?l=JSON.stringify(t):l=t.toString(),l.length>4096){console.error("Cookie size exceeds 4KB limit. Data not stored.");return}document.cookie=e+"="+l+"; max-age="+n+" ; path=/ ;",setTimeout(()=>{document.cookie="testCookie=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/;"},n*1e3)}s(pe,"setCookie");function he(e){let n=`; ${document.cookie}`.split(`; ${e}=`);if(n.length===2){let l=n.pop().split(";").shift();try{let o=JSON.parse(l);return typeof o=="object"&&o!==null&&"nodeType"in o&&o.nodeType===1,o}catch{return l}}return null}s(he,"getCookie");function me(e,t){let n;t instanceof HTMLElement?n=t.outerHTML:typeof t=="object"?n=JSON.stringify(t):n=t.toString(),localStorage.setItem(e,n)}s(me,"setStorage");function ye(e){let t=localStorage.getItem(e);if(t!==null)try{let n=JSON.parse(t);return typeof n=="object"&&n!==null&&"nodeType"in n&&n.nodeType===1,n}catch{return t}}s(ye,"getStorage");function R(e,t=void 0){C(R.name),E.createInstance=R.name;let n="";t===void 0?n=e():n=e(t)}s(R,"createInstance");function G(e,t){C(G.name),E.rpc=G.name;let n={};for(let[l,o]of Object.entries(t))e[l]?n[l]=e[l].apply(null,o):(console.error(`Function ${l} not found!`),n[l]=null);return n}s(G,"rpc");function W(e,t=!1,n){C(W.name),E.gvec=W.name;let l=Object.keys(e),o=l[0],c=l[1],i=l[2];var d=e[o];d=d.name;var f=e[c];let m=e[c];var p=L(c)===null;if(p||t===!1){var g=""+c;E.dataMap.delete(g),R(f,e[i])}f=L(c);var y=L(o);if(y===null)throw new Error(` source id '${o} is not found in source component `);if(f===null)throw new Error(` target id '${c} is not found in target component `);if(y.replaceWith(f),n!==void 0)for(let h in m){let w=h.toString();if(typeof n=="object"){for(var r in n)if(w===r){var u=n[r];typeof u=="object"?m[h].apply(null,u):m[h].apply(null,[])}}else if(n.indexOf(",">-1)){let D=n.split(",");for(let $=0;$<D.length;$++)w===D[$]&&m[h].apply(null,[])}else w===n&&m[h].apply(null,[])}}s(W,"gvec");async function ge(e,t={}){let{passRestriction:n=[]}=t,l=window.location.pathname.replace(/^\/|\/$/g,"").toLowerCase(),o=e.replace(/^\/|\/$/g,"").toLowerCase();if(!new RegExp("^"+o.replace(/:[^\/]+/g,"[^/]+")+"$").test(l))return!1;let i=Array.isArray(n)?n:[n];for(let d of i)try{let f=typeof d=="function"?d():d;if(f instanceof Promise){if(!await f)return!1}else if(!f)return!1}catch(f){return console.error("Route check failed:",f),!1}return!0}s(ge,"Route");function be(e){return e==null||e===""}s(be,"IsEmpty");function Q(e){let t=e.startsWith("/")?e:"/"+e;window.history.pushState({},"",t)}s(Q,"Navigate");function X(e){b.maxCacheSize=e}s(X,"setMaxCacheSize");function N(e){b.cleanhtml=e}s(N,"cleanHtml");function ee(e){b.route=e}s(ee,"setRoute");async function Ee(e,t){let n;t==="/"?n=t:n=t.replace(/\//g,"").toLowerCase();let l=Object.keys(e).find(o=>o.toLowerCase()===n.toLowerCase());if(!l){let o=Object.keys(e).join(", ");throw new Error(`Unknown component: "${t}".
Available components: ${o}
To add this component:
const loadAsyncComponents = {
...existingComponents,
"${t}": () => import('./${t}.js')
};`)}if(x.has(l))return x.get(l);try{let c=(await e[l]()).default;return x.set(l,c),c}catch(o){throw new Error(`Failed to load component "${l}": ${o.message}`)}}s(Ee,"loadFunc");async function we(e,t,n,l){debugger;let o=window.location.host+"/"+e;if(V===o)return;V=o;let c;typeof t=="boolean"||typeof t=="string"?(n=t,t=b.route):t===void 0&&(t=b.route,n=!1),Q(e);let{componentKey:i,params:d}=te(t),f=Object.keys(t);if(typeof n=="string")i=n,c=!!l;else if(typeof n=="boolean"){if(f.length===1)i=f[0];else if(f.includes(e))i=e;else throw new Error(`Ambiguous component map: multiple components exist and no matching key for path '${e}' found. Provide component key explicitly.`);c=n}else{if(f.length===1)i=f[0];else if(f.includes(e))i=e;else throw new Error(`Ambiguous component map: multiple components exist and no matching key for path '${e}' found. Provide component key explicitly.`);c=!1}let m=await ne(t,i,d,null,!1),p=F.get(e);if((!p||!c)&&(typeof m=="function"?(p=m(),F.set(e,p)):p=m),A&&A.isConnected){var g=A.contains(p);g||A.replaceWith(p)}else document.body.appendChild(p);A=p,K=e}s(we,"NavigateTo");function xe(e=S,t){let n=typeof e=="string"?document.getElementById(e):e;n.contains(t)||n.replaceChildren(t)}s(xe,"updateNodeIfNeeded");function ke(e,t){if(S=typeof e=="string"?document.getElementById(e):e,!S)throw new Error("Mount target not found: "+e);S.replaceChildren(t)}s(ke,"mount");function Ae(e){if(e){let t=e.toLowerCase(),n=!1;for(let l of x.keys())l.toLowerCase()===t&&(x.delete(l),n=!0);return n}else return x.clear(),!0}s(Ae,"clearComponentCache");function te(e){var d,f;let n=window.location.pathname.split("/").filter(Boolean),l=n[0]||"home",o={},c=(f=(d=e[l])==null?void 0:d.urlParam)==null?void 0:f.split("/");return c&&c.length&&c.forEach((m,p)=>{m=m.replace(/[{}]/g,""),n[p+1]&&(o[m]=n[p+1])}),new URL(window.location.href).searchParams.forEach((m,p)=>{o[p]=m}),{componentName:l,params:o}}s(te,"parsePath");function v(e){return new DOMParser().parseFromString(e,"text/html").body.firstChild}s(v,"parseHTML");async function ne(e,t,n=null,l=null,o=!0){let c=e[t.toLowerCase()];if(c||(typeof e.fallback=="string"?c=e[e.fallback]:c=e.fallback),!c)return v("<h1>404 - Component not found</h1>");let{loader:i,guard:d,cacheExpiration:f=null,...m}=c;if(l===null&&typeof c.logic=="function"&&(l=c.logic),typeof d=="function"&&!await d(n))return v("<h1>403 - Forbidden</h1><p>You do not have access to this page.</p>");for(let p in m){let g=m[p];if(typeof g=="function")try{await g()}catch(y){console.error(y)}}try{let p=Date.now(),g=x.get(t);g&&f!==null&&p-g.cachedAt>f&&(x.delete(t),g=null);let y;if(g)y=g.component,x.set(t,{component:y,cachedAt:p});else{if(y=(await i()).default,x.size>=b.maxCacheSize){let w=x.keys().next().value;x.delete(w)}x.set(t,{component:y,cachedAt:p})}if(typeof y!="function")return v("<h1>Invalid component</h1>");if(!o)return y;let r;Array.isArray(n)?r=y(...n):typeof n=="object"&&n!==null?r=y(n):r=y();let u="/";try{u=window.location.pathname.slice(1)+window.location.hash,u=u.endsWith("/")&&u!=="/"?u.slice(0,-1):u,u===""&&(u="/")}catch{u=t}return F.set(u,r),A=r,r}catch(p){return console.error(p),v("<h1>Error loading component</h1>")}}s(ne,"loadRunFunc");function z(e=""){var o,c;C(z.name),E.buildRoadMap=z.name;var t="";let n=(o=new Error().stack)==null?void 0:o.toString();navigator.userAgent.toLowerCase().indexOf("firefox")>0?n=n.split("@"):n=n.split(`
`);for(let i=0;i<n.length;i++){var l="";if(navigator.userAgent.indexOf("Firefox")>0){let d=n[i].lastIndexOf(`
`);if(d===-1)continue;l=n[i].slice(d+1),l===""?(d=n[i].lastIndexOf("/")+1,d>-1&&(l=n[i].substr(d),l=l.substr(0,l.indexOf(".")))):l.indexOf("/")>-1&&(l=l.substr(0,l.indexOf("/")))}else l=(c=n[i])==null?void 0:c.trim().split(" ")[1];if(!E.funcname.includes(l)&&!(l===void 0||l==="")&&!(l.indexOf("http://")>-1||l.indexOf("https://")>-1)){if(E.gvec!==void 0&&l.indexOf(E.gvec)>-1)break;t.indexOf("|"+l)>-1||(t+="|"+l.replace(".","|"))}}return e+t}s(z,"buildRoadMap");function C(e){!E.funcname.includes(e)&&E.funcname.push(e)}s(C,"setFuncName");function le(e){let t=e,n=new Set;function l(){return O&&n.add(O),t}s(l,"get");function o(c,i=!1){(i||t!==c)&&(t=c,n.forEach(d=>d()))}return s(o,"set"),[l,o]}s(le,"createSignal");function j(e){function t(){O=t,e(),O=null}s(t,"wrapped"),t()}s(j,"createEffect");function ie(e){e=e.toLowerCase(),a.innerHTMLElements.includes(e)||(a.innerHTMLElements.push(e),globalThis[e]=(...t)=>T(e,...t))}s(ie,"createTypeElement");function q(e){return e.replace(/-+/g,"-").replace(/-([a-z])/g,(t,n)=>n.toUpperCase())}s(q,"dashToCamel");function Ce(e,t=null){Y(e,t)}s(Ce,"createSigment");function ve(e,t=null){Y(e,t)}s(ve,"addSigment");function Se(e,...t){if(ie(e),t.length!==0)return globalThis[e](...t)}s(Se,"createElement");function re(e){let t=document.createTextNode("");return j(()=>{if(typeof k!="object"||k===null){t.nodeValue=e;return}let n=e.replace(/{{(.*?)}}/g,(l,o)=>{let c=o.trim();if(k.hasOwnProperty(c)){let i=k[c];if(i&&typeof i[0]=="function")return i[0]()??""}return""});t.nodeValue=n}),t}s(re,"interpolateReactiveText");function Le(e,t=5e3,n={}){let l=JSON.stringify([e,n,t]);if(!M.has(l)){let o=se(async()=>{let c=await fetch(e,n);if(!c.ok)throw new Error(`Fetch failed: ${c.status}`);return c.json()},t);M.set(l,o)}return M.get(l)()}s(Le,"fetchCache");function I(e){if(Array.isArray(e))return e.map(I);if(e&&typeof e=="object"){let t={};return Object.keys(e).sort().forEach(n=>{t[n]=I(e[n])}),t}return e}s(I,"sortObjectDeep");function oe(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t={};return Object.keys(e).sort().forEach(n=>{t[n]=e[n]}),t}return e}s(oe,"sortObjectShallow");function se(e,t=null,n={}){debugger;let l=new Map,o=s((...c)=>{let{deepSort:i}=n,d;i===!0?d=c.map(r=>r&&typeof r=="object"?I(r):r):i===!1?d=c.map(r=>r&&typeof r=="object"?oe(r):r):d=c;let f=JSON.stringify(d),m=Date.now();f.length===2&&(f=e.name);let g=l.get(f);if(g&&(t===null||m-g.timestamp<t))return g.value;let y=e(...c);return l.set(f,{value:y,timestamp:m}),y instanceof Promise&&y.catch(()=>l.delete(f)),y},"wrapped");return o.clear=()=>l.clear(),o}s(se,"memoizeFunc");function T(e,...t){let n={},l=[];C(T.name);var o="";o=z();var c=o.split("|");if(c.includes(E.rpc))return;t[0]&&typeof t[0]=="object"&&!Array.isArray(t[0])&&!(t[0]instanceof Node)?(n=t[0],l=t.slice(1)):l=t;let i=null,d=e.toLowerCase()==="fragment";if(d)i=document.createDocumentFragment();else{var f;let r=_.get(e);r&&(f=r.tagName,r.nativeTag!==null&&(f=r.nativeTag)),f!==void 0&&(e=f),i=document.createElement(e)}let m=P.has(e),p=H.has(q(e)),g=e==="input"||e==="option",y=e==="option";if(!d)for(let r in n){let u=n[r];r.startsWith("on")&&typeof u=="function"?i.addEventListener(r.slice(2).toLowerCase(),u):typeof u=="function"&&r!=="children"?j(()=>{let h=u();h==null||h===!1?(i.removeAttribute(r),r==="value"&&p&&(i.value="",b.cleanhtml||i.removeAttribute("value")),r==="checked"&&g&&(i.checked=!1,b.cleanhtml||i.removeAttribute("checked")),r==="selected"&&y&&(i.selected=!1,b.cleanhtml||i.removeAttribute("selected")),r==="id"&&(i.iid="",b.cleanhtml||i.removeAttribute("id"))):r==="id"?(i.iid=h,b.cleanhtml?i.removeAttribute("id"):i.setAttribute("id",h),B(h,{name:h,caller:h+o,value:i})):r==="value"&&p?(i.value=h,b.cleanhtml?i.removeAttribute("value"):i.setAttribute("value",h)):r==="checked"&&g?(i.checked=h,b.cleanhtml?i.removeAttribute("checked"):h?i.setAttribute("checked",""):i.removeAttribute("checked")):r==="selected"&&y?(i.selected=h,b.cleanhtml?i.removeAttribute("selected"):h?i.setAttribute("selected",""):i.removeAttribute("selected")):i.setAttribute(r,h)}):u!=null&&u!==!1&&(r==="id"?(i.iid=u,b.cleanhtml?i.removeAttribute("id"):i.setAttribute("id",u),B(u,{name:u,caller:u+o,value:i})):r==="value"&&p?(i.value=u,b.cleanhtml?i.removeAttribute("value"):i.setAttribute("value",u)):r==="checked"&&g?(i.checked=u,b.cleanhtml?i.removeAttribute("checked"):i.setAttribute("checked","")):r==="selected"&&y?(i.selected=u,b.cleanhtml?i.removeAttribute("selected"):i.setAttribute("selected","")):i.setAttribute(r,u))}return m?l.length===1&&(typeof l[0]=="string"||typeof l[0]=="number")?p&&(i.value=l[0],b.cleanhtml?i.removeAttribute("value"):i.setAttribute("value",l[0])):l.length>0&&console.warn(`Void element <${e}> should not have children.`):l.flat().forEach(r=>{if(typeof r=="function"){let u=document.createTextNode("");i.appendChild(u),j(()=>{let h=r();if(h instanceof Node){let w=u.parentNode;if(!w)return;w.nodeType===Node.DOCUMENT_FRAGMENT_NODE?w.replaceChildren(h):w.replaceChild(h,u),u=h}else{let w=h==null?"":String(h);u.nodeValue!==w&&(u.nodeValue=w)}})}else if(typeof r=="string"&&r.includes("{{")&&!r.includes("function"))i.appendChild(re(r));else if(typeof r=="string"||typeof r=="number"){if(r.includes("function get(")||r.includes("function (")||r.includes("[native code]"))throw new Error("Detected reactive getter function used inside a template string. Use a function instead like: div(() => `Your text is: ${someState()}`)");i.appendChild(document.createTextNode(r))}else(r instanceof DocumentFragment||r instanceof Node)&&i.appendChild(r)}),i}s(T,"h");function ce(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/-+/g,"-").toLowerCase()}s(ce,"camelToDash");function Y(e,t=null){if(a.innerHTMLElements.includes(e)||a.valueElements.includes(e)||a.srcElements.includes(e)||a.hrefElements.includes(e)||a.voidElements.includes(e))return;let l=/[A-Z]/.test(e)?ce(e):e.toLowerCase();l.includes("-")||(l="s-"+l),e.includes("-")&&(l=e,e=q(e)),_.set(e,{tagName:l,nativeTag:t}),!a.innerHTMLElements.includes(e)&&t===null?a.innerHTMLElements.push(e):!a.innerHTMLElements.includes(e)&&t!==null&&(a.innerHTMLElements.includes(t)||a.innerHTMLElements.push(e)),!a.valueElements.includes(e)&&t===null?(a.valueElements.push(e),H.add(e)):!a.valueElements.includes(e)&&t!==null&&(a.valueElements.includes(t)||(a.valueElements.push(e),H.add(e))),!a.srcElements.includes(e)&&t===null?(a.srcElements.push(e),J.add(e)):!a.srcElements.includes(e)&&t!==null&&(a.srcElements.includes(t)||(a.srcElements.push(e),J.add(e))),!a.hrefElements.includes(e)&&t===null?(a.hrefElements.push(e),U.add(e)):!a.hrefElements.includes(e)&&t!==null&&(a.hrefElements.includes(t)||(a.hrefElements.push(e),U.add(e))),!a.voidElements.includes(e)&&t===null?(a.voidElements.push(e),P.add(e)):!a.voidElements.includes(e)&&t!==null&&(a.voidElements.includes(t)||(a.voidElements.push(e),P.add(e))),globalThis[e]=(...o)=>T(e,...o)}s(Y,"defineElement");function ue(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}s(ue,"onPaint");function Oe(e){let t=!1;ue(()=>{t||(t=!0,e())})}s(Oe,"paintFinish");export{be as IsEmpty,b as MyApp,Q as Navigate,we as NavigateTo,ge as Route,ve as addSigment,Ae as clearComponentCache,j as createEffect,Se as createElement,fe as createGlobalSignal,Ce as createSigment,le as createSignal,Le as fetchCache,he as getCookie,de as getGlobalSignal,ye as getStorage,L as getVirtualElementById,fe as globalSignal,L as gve,W as gvec,T as h,Ee as loadFunc,ne as loadRunFunc,se as memoizeFunc,ke as mount,ue as onPaint,Oe as paintFinish,te as parsePath,G as rpc,pe as setCookie,me as setStorage,le as signal,xe as updateNodeIfNeeded,de as useGlobalSignal};