vaderjs 1.3.3-7bn27417d42e1 → 1.3.3-7u27417d42e1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -81,7 +81,7 @@ export default function(req, res){
81
81
 
82
82
  return <>
83
83
  <h1>${count}</h1>
84
- <button onClick={(event)=>{setCount(++count)}}>
84
+ <button onClick={(event)=>{setCount(count + 1)}}>
85
85
  </>
86
86
  }
87
87
 
@@ -130,7 +130,7 @@ export function Layout({title, keywords, description, children}){
130
130
 
131
131
  export default function (req, res){
132
132
  return <>
133
- <Layout ${{title:'home', description:'home page', keywords:'vader.js', logo:''}}>
133
+ <Layout $={{title:'home', description:'home page', keywords:'vader.js', logo:''}}>
134
134
  <h1> Hello World</h1>
135
135
  </Layout>
136
136
  </>
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "vaderjs",
3
3
  "description": "A Reactive library aimed to helping you build reactive applications inspired by react.js",
4
4
  "module": "vader.js",
5
- "version": "1.3.3-7bn27417d42e1",
5
+ "version": "1.3.3-7u27417d42e1",
6
6
  "bin": {
7
7
  "vader": "./vader.js"
8
8
  },
package/runtime/vader.js CHANGED
@@ -1 +1 @@
1
- window.Vader={version:"1.3.3"},window.componentRegistry={};let errors={"SyntaxError: Unexpected token '<'":"You forgot to enclose tags in a fragment <></>"},mounts=[],lastRoute=null,hasRan=[];export const strictMount=(e,t)=>{let s=setInterval((()=>{document.querySelector(`[key="${e}"]`)&&!hasRan.includes(e)&&(clearInterval(s),t(),hasRan.push(e))}),120)};export class Component{constructor(e={}){this.$_vaderElement=!0,this.state={},this.key=null,this.components={},this.mounted=!1,this.checkIFMounted(),this.memoizes=[],this.functions=[],this.props={children:"",$:{},...e},this.children=[],this.noKey=!1,this.parentNode={},this.request={headers:{},method:"GET",params:{},path:"",query:{}},this.response={json:e=>{},send:e=>{},redirect:e=>{},render:async e=>{},log:e=>{},setQuery:e=>{}},this.router={use:e=>{}}}createComponent(e,t,s){function r(e){return"function"==typeof e&&/^class\s/.test(Function.prototype.toString.call(e))}let n=r(e)?new e(t):null;if(!e)throw new Error("Component must be defined");let i=[],o=new Component(t);if(r(e))n.props=t||{},n.props.children=s.join("")||[],n.props.children=s.join(""),n.parentNode=this,n.type="class ",n.request=this.request,n.response=this.response,n.key=n.props.key?n.props.key:Math.random(),o=n;else{e.toString();o.key=e.toString().split('key="')[1]?e.toString().split('key="')[1].split('"')[0]:null,t=t?{...t,...i.reduce(((e,t)=>({...e,...t})),{}),children:s.join("")||[]}:{children:s.join("")||[]};let r={key:o.key?o.key:Math.random(),isUnique:!!o.key,render:()=>e.apply(o,[t]),request:this.request,isChild:!0,response:this.response,params:this.request.params,queryParams:this.request.query,reset:o.reset.bind(o),onMount:o.onMount.bind(o),useState:null,router:{use:o.router.use.bind(o)},bindMount:o.bindMount.bind(o),memoize:o.memoize.bind(o),createComponent:o.createComponent.bind(o),isChild:!1,useState:o.useState.bind(o),parseStyle:o.parseStyle.bind(o),bind:o.bind.bind(o),useRef:o.useRef.bind(o),request:this.request,response:this.response,useReducer:o.useReducer.bind(o),hydrate:o.hydrate.bind(o),onUnmount:o.onUnmount.bind(o),type:"function",parentNoe:this,props:{...t,children:s.join("")||[]}};o.render=r.render,o=r,o.props.children=s.join("")||[]}return this.components[o.key]||(this.components[o.key]=o),!this.children.includes(o)&&this.children.push(o),this.components[o.key]}reset(){Object.keys(this.components).forEach((e=>{this.components[e].onUnmount(),delete this.components[e]})),this.state={},this.children=[]}memoize(e){if(!0==!this.memoizes.includes(e.key))this.memoizes.push(e.key),this.components[e.key]=e;let t=this.components[e.key];"class"!==t.type||t.$_vaderElement||console.error(`class ${t.constructor.name} must extend Component`),t.bindMount(),t.parentNode=this,t.props=e.props,t.request=this.request,t.response=this.response,t.onMount=e.onMount.bind(e),t.onUnmount=e.onUnmount.bind(e);let s=t.render();return s&&s.split(">,").length>1&&(s=s.replaceAll(">,",">")),t.nokey||t.noKey?s:`<div key="${t.key}">${s}</div>`}parseStyle(e){let t="";return Object.keys(e).forEach((s=>{let r=e[s];s=s.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g,"$1-$2").toLowerCase(),t+=`${s}:${r};`})),t}bindMount(){mounts.push(this)}domDifference(e,t){let s=[];for(let r=0;r<e.length;r++){let n=e[r],i=t[r];if(n&&i&&n.childNodes.length>0&&i.childNodes.length>0){switch(!0){case n.attributes&&i.attributes&&n.attributes.length!==i.attributes.length:s.push({type:"attributeSwap",old:n,new:i});break;case!n.isEqualNode(i)&&n.nodeName===i.nodeName&&n.textContent!==i.textContent:s.push({type:"replace",old:n,new:i})}let e=this.domDifference(Array.from(n.childNodes),Array.from(i.childNodes));return s.push(...e),s}n.isEqualNode(i)||n.nodeName!==i.nodeName||n.textContent===i.textContent?!n&&i&&s.push({type:"add",old:n,new:i}):s.push({type:"replace",old:n,new:i})}return s}updateChangedElements(e){e.forEach((e=>{if(e)switch(e.type){case"replace":if(e.old.panrntNode&&"BODY"===e.old.parentNode.nodeName)return;e.old.replaceWith(e.new.cloneNode(!0));break;case"remove":e.old.remove();break;case"attributeSwap":let t=Array.from(e.old.attributes),s=Array.from(e.new.attributes);t.forEach((t=>{e.old.removeAttribute(t.name)})),s.forEach((t=>{e.old.setAttribute(t.name,t.value)}));break;case"add":e.old.appendChild(e.new.cloneNode(!0))}}))}hydrate(e){if(e){let t=(new DOMParser).parseFromString(this.render(),"text/html").body.querySelectorAll(`[ref="${e.bind?e.bind:e}"]`),s=document.querySelectorAll(`[ref="${e?e.bind:e}"]`);t.forEach((e=>{let t=Array.from(s).find((t=>t.getAttribute("ref")===e.getAttribute("ref")));if(t){let s=this.domDifference(Array.from(t.childNodes),Array.from(e.childNodes));this.updateChangedElements([s])}}))}else{let e=this.key?document.querySelector(`[key="${this.key}"]`):null;if(e){let t=(new DOMParser).parseFromString(this.render(),"text/html").body.querySelector(`[key="${this.key}"]`),s=e,r=this.domDifference([s],[t]);this.updateChangedElements(r)}}}patch(e,t){const s=this.domDifference(e,t);this.updateChangedElements(s)}handleObject(obj){try{obj=JSON.parse(obj)}catch(e){}return eval(obj)}bind(e,t,s,r,...n){return s+=this.key,window["callFunctions"+this.key]=(e,t)=>{let s=this.functions.find((t=>t.ref===e));s&&s.func(t)},this.functions.find((e=>e.ref===s))||this.functions.push({ref:s,func:e}),t?e:`((event)=>{callFunctions${this.key} ? callFunctions${this.key}('${s}', event) : null})(event)`}setState(e,t){this.state=e,this.hydrate(t)}useState(e,t){this.state.hasOwnProperty(e)||(this.state[e]=t);return[(()=>this.state[e])(),(t,s)=>{this.state[e]=t,this.hydrate(s)}]}useRef(e=null,t){this.state[e]||(this.state[e]=t);return{bind:e+this.key,current:(()=>document.querySelector(`[ref="${e+this.key}"]`)||t)()}}useReducer(e=null,t,s=null){this.state[e]||(this.state[e]=t);const r=()=>this.state[e];let n=r();return[r(),(t,i)=>{const o=s(n,t)??t;this.state[e]=o,this.hydrate(i),n=r()}]}render(){}checkIFMounted(){new MutationObserver((e=>{e.forEach((e=>{e.target.querySelector(`[key="${this.key}"]`)&&!this.mounted&&(this.onMount(),this.mounted=!0),Array.from(e.removedNodes).find((e=>e.attributes&&e.attributes.key&&e.attributes.key.value===this.key))&&(this.onUnmount(),this.reset())}))})).observe(document.body,{childList:!0,subtree:!0})}onMount(){}onUnmount(){}}export const useState=(e,t)=>{this.state[e]||(this.state[e]=t);return[states[e],(t,s)=>{states[e]=t,this.hydrate(s)}]};export const useReducer=(e,t)=>[e,e=>{}];export const useRef=e=>({current:e,bind:""});export class Link extends Component{constructor(e){super(e),this.props=e,this.link=document.createElement("a"),this.key=e.href+Math.random(),this.nokey=!0}render(){return this.link.innerHTML=this.props.children,this.link.setAttribute("id",this.props?.href),this.link.style=this.props?.style,this.link.setAttribute("class",this.props?.class||this.props?.className),this.link.setAttribute("onclick",this.props?.href?.includes("https")||this.props?.href?.includes("http")?`window.open('${this.props.href}', '${this.props.action||"_blank"}').focus()`:`window.history.pushState({}, '', '${this.props?.href}'); window.dispatchEvent(new Event('popstate'));`),this.link.outerHTML}}export class Image extends Component{constructor(e){super(e),this.props={src:e.src,class:e.class,style:e.style,blur:e.blur,width:e.width,height:e.height,optimize:e.optimize||!0,loader:e.loader||!0,alt:e.alt||"image",ref:e.ref||null},this.key=e.src+Math.random(),this.img=document.createElement("img"),this.placeholder=document.createElement("div")}render(){if(window.isServer)return"";let[e,t]=this.useState("loaded",!1),s=this.useRef("hookref",null),r=this.props.width?this.props.width:window.innerWidth/2,n=this.props.height?this.props.height:window.innerHeight/2;if(!this.props.src)throw new Error("Image src is required");return this.img.setAttribute("src",this.props.src),this.img.setAttribute("class",this.props.class),this.img.setAttribute("style",this.props.style?this.props.style:""),this.img.setAttribute("width",r),this.img.setAttribute("ref",s.bind),this.img.referrerPolicy="no-referrer",this.img.setAttribute("height",n),this.img.setAttribute("loading","lazy"),this.img.setAttribute("alt",this.props.alt),this.props.blur&&this.img.setAttribute("style",`filter: blur(${this.props.blur}px);`),this.props.optimize&&this.img.setAttribute("style",`image-rendering: -webkit-optimize-contrast; object-fit: cover; object-position: center; ${this.props.style?this.props.style:""}`),!this.props.loader||e||window.isServer||(this.placeholder.setAttribute("style",`width: ${r}px; height: ${n}px; background: #eee;`),this.placeholder.setAttribute("class","vader-image-placeholder"),this.placeholder.innerHTML=this.props.loader,window.isServer)?void 0:(this.img.onload=()=>{t(!0,s.bind)},`<span ref="${s.bind}">${e?this.img.outerHTML:this.placeholder.outerHTML}</span>`)}}export class Html extends Component{constructor(e){super(e),this.props={children:e.children,lang:e.lang||"en",attributes:e.attributes||{}},this.key="html",this.html=document.createElement("div")}render(){return this.html.setAttribute("lang",this.props.lang?this.props.lang:"en"),window.isServer?(this.html.innerHTML=this.props.children,this.props.attributes&&Object.keys(this.props.attributes).forEach((e=>{this.html.setAttribute(e,this.props.attributes[e])})),this.html.innerHTML):this.props.children}onMount(){console.log("Document Has Been Mounted")}}export class Head extends Component{constructor(e){super(e),this.props=e,this.key="head",this.head=document.createElement("head"),this.eagerScripts=document.querySelectorAll("script[eager]")}render(){if(!window.isServer&&this.props?.updateOnReload){this.props.children=(new DOMParser).parseFromString(this.props.children,"text/html").head;let e=this.props.children.querySelector("title");e&&e.textContent&&(console.log("title",e.textContent),document.querySelector("title").textContent=e.textContent),this.props.children.querySelectorAll("meta").forEach((e=>{let t=e.getAttribute("name"),s=e.getAttribute("content");t&&s&&document.querySelector(`meta[name="${t}"]`).setAttribute("content",s)})),this.props.children.querySelectorAll("link").forEach((e=>{let t=e.getAttribute("rel"),s=e.getAttribute("href");t&&s&&document.querySelector(`link[rel="${t}"]`).setAttribute("href",s)}))}return""}onMount(){if(!this.state.hasMounted&&window.isServer){document.head.innerHTML=this.props.children+document.head.innerHTML,document.querySelectorAll("script[eager]").forEach((async e=>{if(!e.getAttribute("src"))throw new Error("Eager scripts must be external");e.remove();let t=e.getAttribute("src"),s=document.createElement("script"),r=null;await fetch(t).then((e=>{if(404===e.status)throw document.documentElement.setAttribute("error",JSON.stringify({error:`File ${t} not found`,status:404})),new Error(`File ${t} not found`);return e.text()})).then((e=>{r=e})).catch((e=>{throw e})),s.innerHTML=r,s.setAttribute("srcid",t),document.querySelector(`[srcid="${t}"]`)||document.head.prepend(s)})),this.state.hasMounted=!0}}}export class Script extends Component{constructor(e){super(e),this.props={children:e.children},this.key="script",this.script=document.createElement("script")}render(){return this.script.innerHTML=this.props.children.split("\n").join(";\n"),this.script.outerHTML}onMount(){document.head.appendChild(this.script),document.body.querySelector(`[key="${this.key}"]`).remove()}}export default{Component:Component,useRef:useRef,useReducer:useReducer,useState:useState,strictMount:strictMount,Link:Link,Image:Image,Head:Head,Script:Script,Html:Html};
1
+ window.Vader={version:"1.3.3"},window.componentRegistry={};let errors={"SyntaxError: Unexpected token '<'":"You forgot to enclose tags in a fragment <></>"},mounts=[],lastRoute=null,hasRan=[];export const strictMount=(e,t)=>{let s=setInterval((()=>{document.querySelector(`[key="${e}"]`)&&!hasRan.includes(e)&&(clearInterval(s),t(),hasRan.push(e))}),120)};export class Component{constructor(e={}){this.$_vaderElement=!0,this.state={},this.key=null,this.components={},this.mounted=!1,this.checkIFMounted(),this.memoizes=[],this.functions=[],this.props={children:"",$:{},...e},this.children=[],this.noKey=!1,this.parentNode={},this.request={headers:{},method:"GET",params:{},path:"",query:{}},this.response={json:e=>{},send:e=>{},redirect:e=>{},render:async e=>{},log:e=>{},setQuery:e=>{}},this.router={use:e=>{}}}createComponent(e,t,s){function isClass(e){return"function"==typeof e&&/^class\s/.test(Function.prototype.toString.call(e))}let r=isClass(e)?new e(t):null;if(!e)throw new Error("Component must be defined");let n=[],i=new Component(t);if(isClass(e))r.props=t||{},r.props.children=s.join("")||[],r.props.children=s.join(""),r.parentNode=this,r.type="class ",r.request=this.request,r.response=this.response,r.key=r.props.key?r.props.key:Math.random(),i=r;else{e.toString();i.key=e.toString().split('key="')[1]?e.toString().split('key="')[1].split('"')[0]:null,t=t?{...t,...n.reduce(((e,t)=>({...e,...t})),{}),children:s.join("")||[]}:{children:s.join("")||[]};let r={key:i.key?i.key:Math.random(),isUnique:!!i.key,render:()=>e.apply(i,[t]),request:this.request,isChild:!0,response:this.response,params:this.request.params,queryParams:this.request.query,reset:i.reset.bind(i),onMount:i.onMount.bind(i),useState:null,router:{use:i.router.use.bind(i)},bindMount:i.bindMount.bind(i),memoize:i.memoize.bind(i),createComponent:i.createComponent.bind(i),isChild:!1,useState:i.useState.bind(i),parseStyle:i.parseStyle.bind(i),bind:i.bind.bind(i),useRef:i.useRef.bind(i),request:this.request,response:this.response,useReducer:i.useReducer.bind(i),hydrate:i.hydrate.bind(i),onUnmount:i.onUnmount.bind(i),type:"function",parentNoe:this,props:{...t,children:s.join("")||[]}};i.render=r.render,i=r,i.props.children=s.join("")||[]}return this.components[i.key]||(this.components[i.key]=i),!this.children.includes(i)&&this.children.push(i),this.components[i.key]}reset(){Object.keys(this.components).forEach((e=>{this.components[e].onUnmount(),delete this.components[e]})),this.state={},this.children=[]}memoize(e){if(!0==!this.memoizes.includes(e.key))this.memoizes.push(e.key),this.components[e.key]=e;let t=this.components[e.key];"class"!==t.type||t.$_vaderElement||console.error(`class ${t.constructor.name} must extend Component`),t.bindMount(),t.parentNode=this,t.props=e.props,t.request=this.request,t.response=this.response,t.onMount=e.onMount.bind(e),t.onUnmount=e.onUnmount.bind(e);let s=t.render();return s&&s.split(">,").length>1&&(s=s.replaceAll(">,",">")),t.nokey||t.noKey?s:`<div key="${t.key}">${s}</div>`}parseStyle(e){let t="";return Object.keys(e).forEach((s=>{let r=e[s];s=s.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g,"$1-$2").toLowerCase(),t+=`${s}:${r};`})),t}bindMount(){mounts.push(this)}domDifference(e,t){let s=[];for(let r=0;r<e.length;r++){let n=e[r],i=t[r];if(n&&i&&n.childNodes.length>0&&i.childNodes.length>0){switch(!0){case n.attributes&&i.attributes&&n.attributes.length!==i.attributes.length:s.push({type:"attributeSwap",old:n,new:i});break;case!n.isEqualNode(i)&&n.nodeName===i.nodeName&&n.textContent!==i.textContent:s.push({type:"replace",old:n,new:i})}let e=this.domDifference(Array.from(n.childNodes),Array.from(i.childNodes));return s.push(...e),s}n.isEqualNode(i)||n.nodeName!==i.nodeName||n.textContent===i.textContent?!n&&i&&s.push({type:"add",old:n,new:i}):s.push({type:"replace",old:n,new:i})}return s}updateChangedElements(e){e.forEach((e=>{if(e)switch(e.type){case"replace":if(e.old.panrntNode&&"BODY"===e.old.parentNode.nodeName)return;e.old.replaceWith(e.new.cloneNode(!0));break;case"remove":e.old.remove();break;case"attributeSwap":let t=Array.from(e.old.attributes),s=Array.from(e.new.attributes);t.forEach((t=>{e.old.removeAttribute(t.name)})),s.forEach((t=>{e.old.setAttribute(t.name,t.value)}));break;case"add":e.old.appendChild(e.new.cloneNode(!0))}}))}hydrate(e){if(e){let t=(new DOMParser).parseFromString(this.render(),"text/html").body.querySelectorAll(`[ref="${e.bind?e.bind:e}"]`),s=document.querySelectorAll(`[ref="${e?e.bind:e}"]`);t.forEach((e=>{let t=Array.from(s).find((t=>t.getAttribute("ref")===e.getAttribute("ref")));if(t){let s=this.domDifference(Array.from(t.childNodes),Array.from(e.childNodes));this.updateChangedElements([s])}}))}else{let e=this.key?document.querySelector(`[key="${this.key}"]`):null;if(e){let t=(new DOMParser).parseFromString(this.render(),"text/html").body.querySelector(`[key="${this.key}"]`),s=e,r=this.domDifference([s],[t]);this.updateChangedElements(r)}}}patch(e,t){const s=this.domDifference(e,t);this.updateChangedElements(s)}handleObject(obj){try{obj=JSON.parse(obj)}catch(e){}return eval(obj)}bind(e,t,s,r,...n){return s+=this.key,window["callFunctions"+this.key]=(e,t)=>{let s=this.functions.find((t=>t.ref===e));s&&s.func(t)},this.functions.find((e=>e.ref===s))||this.functions.push({ref:s,func:e}),t?e:`((event)=>{callFunctions${this.key} ? callFunctions${this.key}('${s}', event) : null})(event)`}setState(e,t){this.state=e,this.hydrate(t)}useState(e,t){this.state.hasOwnProperty(e)||(this.state[e]=t);return[(()=>this.state[e])(),(t,s)=>{this.state[e]=t,this.hydrate(s)}]}useRef(e=null,t){this.state[e]||(this.state[e]=t);return{bind:e+this.key,current:(()=>document.querySelector(`[ref="${e+this.key}"]`)||t)()}}useReducer(e=null,t,s=null){this.state[e]||(this.state[e]=t);const getValue=()=>this.state[e];let r=getValue();return[getValue(),(t,n)=>{const i=s(r,t)??t;this.state[e]=i,this.hydrate(n),r=getValue()}]}render(){}checkIFMounted(){new MutationObserver((e=>{e.forEach((e=>{e.target.querySelector(`[key="${this.key}"]`)&&!this.mounted&&(this.onMount(),this.mounted=!0),Array.from(e.removedNodes).find((e=>e.attributes&&e.attributes.key&&e.attributes.key.value===this.key))&&(this.onUnmount(),this.reset())}))})).observe(document.body,{childList:!0,subtree:!0})}onMount(){}onUnmount(){}}export const useState=(e,t)=>{this.state[e]||(this.state[e]=t);return[states[e],(t,s)=>{states[e]=t,this.hydrate(s)}]};export const useReducer=(e,t)=>[e,e=>{}];export const useRef=e=>({current:e,bind:""});export class Link extends Component{constructor(e){super(e),this.props=e,this.link=document.createElement("a"),this.key=e.href+Math.random(),this.nokey=!0}render(){return this.link.innerHTML=this.props.children,this.link.setAttribute("id",this.props?.href),this.link.style=this.props?.style,this.link.setAttribute("class",this.props?.class||this.props?.className),this.link.setAttribute("onclick",this.props?.href?.includes("https")||this.props?.href?.includes("http")?`window.open('${this.props.href}', ${this.props.action||"_blank"}).focus()`:`window.history.pushState({}, '', '${this.props?.href}'); window.dispatchEvent(new Event('popstate'));`),this.link.outerHTML}}export class Image extends Component{constructor(e){super(e),this.props={src:e.src,class:e.class,style:e.style,blur:e.blur,width:e.width,height:e.height,optimize:e.optimize||!0,loader:e.loader||!0,alt:e.alt||"image",ref:e.ref||null},this.key=e.src+Math.random(),this.img=document.createElement("img"),this.placeholder=document.createElement("div")}render(){if(window.isServer)return"";let[e,t]=this.useState("loaded",!1),s=this.useRef("hookref",null),r=this.props.width?this.props.width:window.innerWidth/2,n=this.props.height?this.props.height:window.innerHeight/2;if(!this.props.src)throw new Error("Image src is required");return this.img.setAttribute("src",this.props.src),this.img.setAttribute("class",this.props.class),this.img.setAttribute("style",this.props.style?this.props.style:""),this.img.setAttribute("width",r),this.img.setAttribute("ref",s.bind),this.img.referrerPolicy="no-referrer",this.img.setAttribute("height",n),this.img.setAttribute("loading","lazy"),this.img.setAttribute("alt",this.props.alt),this.props.blur&&this.img.setAttribute("style",`filter: blur(${this.props.blur}px);`),this.props.optimize&&this.img.setAttribute("style",`image-rendering: -webkit-optimize-contrast; object-fit: cover; object-position: center; ${this.props.style?this.props.style:""}`),!this.props.loader||e||window.isServer||(this.placeholder.setAttribute("style",`width: ${r}px; height: ${n}px; background: #eee;`),this.placeholder.setAttribute("class","vader-image-placeholder"),this.placeholder.innerHTML=this.props.loader,window.isServer)?void 0:(this.img.onload=()=>{t(!0,s.bind)},`<span ref="${s.bind}">${e?this.img.outerHTML:this.placeholder.outerHTML}</span>`)}}export class Html extends Component{constructor(e){super(e),this.props={children:e.children,lang:e.lang||"en",attributes:e.attributes||{}},this.key="html",this.html=document.createElement("div")}render(){return window.isServer?(this.html.innerHTML=this.props.children,this.html.setAttribute("lang",this.props.lang?this.props.lang:"en"),this.props.attributes&&Object.keys(this.props.attributes).forEach((e=>{this.html.setAttribute(e,this.props.attributes[e])})),this.html.innerHTML):this.props.children}onMount(){console.log("Document Has Been Mounted")}}export class Head extends Component{constructor(e){super(e),this.props=e,this.key="head",this.head=document.createElement("head")}render(){return""}onMount(){if(!this.state.hasMounted&&window.isServer){document.head.innerHTML=this.props.children+document.head.innerHTML,document.querySelectorAll("script[eager]").forEach((async e=>{if(!e.getAttribute("src"))throw new Error("Eager scripts must be external");e.remove();let t=e.getAttribute("src"),s=document.createElement("script"),r=null;await fetch(t).then((e=>{if(404===e.status)throw document.documentElement.setAttribute("error",JSON.stringify({error:`File ${t} not found`,status:404})),new Error(`File ${t} not found`);return e.text()})).then((e=>{r=e})).catch((e=>{throw e})),s.innerHTML=r,s.setAttribute("srcid",t),document.querySelector(`[srcid="${t}"]`)||document.head.prepend(s)})),this.state.hasMounted=!0}}}export class Script extends Component{constructor(e){super(e),this.props={children:e.children},this.key="script",this.script=document.createElement("script")}render(){return this.script.innerHTML=this.props.children.split("\n").join(";\n"),this.script.outerHTML}onMount(){document.head.appendChild(this.script),document.body.querySelector(`[key="${this.key}"]`).remove()}}export default{Component:Component,useRef:useRef,useReducer:useReducer,useState:useState,strictMount:strictMount,Link:Link,Image:Image,Head:Head,Script:Script,Html:Html};
package/vader.js CHANGED
@@ -117,7 +117,7 @@ function Compiler(func, file) {
117
117
  let functionAttributes = [];
118
118
  let spreadFunctions = [];
119
119
  let functionMatch;
120
-
120
+
121
121
  /**
122
122
  * @search - handle attributes for html elements
123
123
  * @keywords - attributes, props, html attributes
@@ -139,7 +139,59 @@ function Compiler(func, file) {
139
139
  attributesList.push({ element, attributes: elementAttributes });
140
140
  }
141
141
 
142
+ let spreadMatch;
143
+ while ((spreadMatch = spreadAttributeRegex.exec(code)) !== null) {
144
+ let [, element, spread] = spreadMatch;
145
+ let isJSXComponent = element.match(/^[A-Z]/) ? true : false;
146
+ if (isJSXComponent) {
147
+ continue;
148
+ }
149
+ let old = spread;
150
+ spread = spread.trim().replace(/\s+/g, " ");
151
+ // re,pve $={ and }
152
+ spread = spread.replace(/\s*\$\s*=\s*{\s*{/gs, '')
153
+
154
+ // replace trailing }
155
+ spread = spread.replace(/}}\s*$/, '').replace(/}\s*}$/, '')
156
+ let splitByCommas = spread.split(/,(?![^{}]*})/gs)
157
+ // remove empty strings
158
+ splitByCommas = splitByCommas.filter((e) => e.split(':')[0].trim().length > 0)
159
+ splitByCommas = splitByCommas.map((e, index) => {
160
+ let key = e.split(':')[0].trim()
161
+ switch (true) {
162
+ case e.includes('function') && !e.includes('this.bind') || e && e.includes('=>') && !e.includes('this.bind'):
163
+ let value = e.split(':')[1].trim()
164
+ let ref = Math.random().toString(36).substring(2).split('').filter((e) => !Number(e)).join('');
165
+ value = `this.bind(${value}, false, "${ref}", "")`
166
+ e = `${key}="\${${value}}"`
167
+ break;
168
+ case e.includes('style:'):
169
+ let v2 = e.split('style:')[1].trim().replace(/,$/, '')
170
+ v2 = v2.replace(/,$/, '')
171
+ e = `${key}="\${this.parseStyle(${v2})}"`
172
+ break;
173
+
174
+ default:
175
+ let v = e.split(':')
176
+ key = v[0].trim()
177
+ // remove key from v
178
+ v.shift()
179
+ v = v.join(' ')
180
+ e = `${key}="\${${v}}"`
181
+
182
+ break;
183
+ }
184
+
185
+
186
+ return e;
187
+ });
188
+
142
189
 
190
+ let newSpread = splitByCommas.join(' ').trim().replace(/,$/, '');
191
+
192
+ // remove trailing }
193
+ string = string.replace(old, newSpread);
194
+ }
143
195
 
144
196
  while ((functionMatch = functionAttributeRegex.exec(code)) !== null) {
145
197
 
@@ -164,17 +216,17 @@ function Compiler(func, file) {
164
216
  .split("<")[1]
165
217
  .split(">")[0]
166
218
  .split(" ")[0];
167
- isJSXComponent = elementTag.match(/^[A-Z]/) ? true : false;
219
+ isJSXComponent = elementTag.match(/^[A-Z]/) ? true : false;
168
220
  }
169
221
  });
170
- if (isJSXComponent) {
222
+ if (isJSXComponent) {
171
223
  continue
172
224
  }
173
225
  // add ; after newlines
174
226
 
175
227
 
176
228
  let newvalue = attributeValue.includes('=>') ? attributeValue.split("=>").slice(1).join("=>").trim() : attributeValue.split("function").slice(1).join("function").trim()
177
-
229
+
178
230
  // add ; after newlines
179
231
 
180
232
 
@@ -226,14 +278,14 @@ function Compiler(func, file) {
226
278
  newvalue = newvalue.replace(/\(\s*=>/gs, '=>').replace(/\function\s*\([^\)]*\)\s*\{/gs, '{')
227
279
  newvalue = newvalue + `\n /**@id=${ref}**/ \n`
228
280
 
229
- let bind = !isJSXComponent && `${attributeName}="\$\{this.bind(function(){${newvalue}}.bind(this), ${isJSXComponent}, "${ref}", "${paramnames ? paramnames.map((e, index) => {
281
+ let bind = !isJSXComponent && `${attributeName}="\$\{this.bind(function(){${newvalue}}.bind(this), ${isJSXComponent}, "${ref}", "${paramnames ? paramnames.map((e, index) => {
230
282
  if (e.length < 1) return ''
231
283
  if (e.length > 0) {
232
284
  index == 0 ? e : ',' + e
233
285
  }
234
286
  return e
235
287
  }) : ''}" ${params ? params.split(',').map((e) => e.trim()).filter(Boolean).map((e) => `,${e}`).join('') : ''})}"`
236
-
288
+
237
289
  string = string.replace(old, bind)
238
290
  }
239
291
  }
@@ -360,15 +412,9 @@ function Compiler(func, file) {
360
412
  switch (true) {
361
413
  case line.includes("useState") && !line.includes("import"):
362
414
  let varType = line.split("[")[0]
363
- if (!line.split("=")[0].split(",")[1]) {
364
- throw new Error('You forgot to value selector (useState) ' + ' at ' + `${file}:${string.split(line)[0].split('\n').length}`)
365
- }
366
415
  let key = line.split("=")[0].split(",")[0].trim().split('[')[1];
367
416
 
368
- if (!line.split("=")[0].split(",")[1]) {
369
- throw new Error('You forgot to add a setter (useState) ' + ' at ' + `${file}:${string.split(line)[0].split('\n').length}`)
370
- }
371
- let setKey = line.split("=")[0].split(",")[1].trim().replace("]", "");
417
+ let setKey = line.split("=")[0].trim().split(",")[1].trim().replace("]", "");
372
418
  key = key.replace("[", "").replace(",", "");
373
419
  let valuestate = line.split("=")[1].split("useState(")[1];
374
420
 
@@ -437,71 +483,37 @@ function Compiler(func, file) {
437
483
  let myChildrens = [];
438
484
 
439
485
  let name = component.split("<")[1].split(">")[0].split(" ")[0].replace("/", "");
440
- let componentAttributes = component.split("<")[1].split(">")[0].split(" ").join(" ").replace(name, "").trim();
441
- let props = component.includes('/>') ? component.split(`<`)[1].split('/>')[0] : component.split(`<`)[1].split(`>`)[0]
442
- props = props.replaceAll(/\s+/g, " ").trim()
486
+ let componentAttributes = component.split("<")[1].split(">")[0].split(" ").join(" ").replace(name, "").trim();
487
+ let props = component.includes('/>')? component.split(`<`)[1].split('/>')[0] : component.split(`<`)[1].split(`>`)[0]
488
+ props = props.replaceAll(/\s+/g, " ").trim()
443
489
  props = props.replace(name, '').trim()
444
490
  component = component.replace(componentAttributes, '')
445
- // or spread attributes {...{}, ...{}}
446
- const dynamicAttributesRegex = /([a-zA-Z0-9_-]+)\s*=\s*("(?:[^"\\]*(?:\\.[^"\\]*)*)"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'|\{(?:[^{}]|(?:\{(?:[^{}]|(?:\{(.*.*?)\})*)*\})*)*\}|(?:\([^)]*\)|()\s*=>\s*(?:\{.*.*\})?|\{.*\})|\[[^\]]*\])|\${\{.*\}}/gs;
491
+ const dynamicAttributesRegex = /([a-zA-Z0-9_-]+)\s*=\s*("(?:[^"\\]*(?:\\.[^"\\]*)*)"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'|\{(?:[^{}]|(?:\{(?:[^{}]|(?:\{(.*.*?)\})*)*\})*)*\}|(?:\([^)]*\)|()\s*=>\s*(?:\{.*.*\})?|\{.*\})|\[[^\]]*\])/gs;
447
492
 
448
493
  const attributeObject = {};
449
- let propstring = ''
494
+
450
495
  let $_ternaryprops = []
451
- let spreadRegex = /\$\{.*\}/gs;
452
- let spreadMatch;
453
- let hasSpread = false;
454
- while ((spreadMatch = spreadRegex.exec(props)) !== null) {
455
- let spread = spreadMatch[0].trim().replace(/\s+/g, " ");
456
- if (!spread.includes('...')) {
457
- continue
458
- }
459
- let old = spread;
460
- spread = spread.trim().replace(/\s+/g, " ");
461
- //${...( loaded ? { title: "Malik Whitten - Blog" } : { title: "Loading" } )} -> ...( loaded ? { title: "Malik Whitten - Blog" } : { title: "Loading" } )
462
-
463
- let spreadContent = spread.match(/\$\{.*\}/gs) ? spread.match(/\$\{.*.*\}/gs)[0] : null
464
- spreadContent = spread.split('${')[1]
465
-
466
- spreadContent = spread.replace(/\${/, '')
467
- spreadContent = spreadContent.replaceAll(/\s+/g, " ").trim()
468
- spreadContent = spreadContent.replace(')}', ')').replace('}}', '}')
469
-
470
- propstring += spreadContent + ','
471
- hasSpread = true
472
-
473
- }
474
496
 
475
497
  let match;
476
-
498
+ let propstring = ''
477
499
  // props right now is just a string with all of them on one line and a space between each
478
500
  while ((match = dynamicAttributesRegex.exec(props)) !== null) {
479
501
  let str = match[0].trim().replace(/\s+/g, " ");
480
502
  if (!str.includes('=')) {
481
503
  continue
482
- }
483
-
484
- if (hasSpread) {
485
-
486
- console.log('\x1b[33m', '🚨 Code confliction detected', '\x1b[0m')
487
- let line = string.split(match[0])[0].split('\n').length
488
- try {
489
- throw new Error('You cannot use spread props and named props\n on the same component at ' + match[0] + ' at ' + `${file}:${line}`)
490
- } catch (error) {
491
- console.error(error)
492
- process.exit(1)
493
- }
494
- }
495
-
496
- str = str.replaceAll(/\s+/g, " ")
504
+ }
505
+
506
+
507
+ str = str.replaceAll(/\s+/g, " ")
497
508
  str = str.split('=')
498
- let key = str[0].trim()
509
+ let key = str[0].trim()
499
510
  let value = str.slice(1).join('=').trim().match(/\{.*\}/gs) ? str.slice(1).join('=').trim().match(/\{.*\}/gs)[0] : str.slice(1).join('=').trim();
500
-
501
-
511
+
512
+
513
+
502
514
  let isObject = value.startsWith('{{') && value.endsWith('}}')
503
- if (isObject) {
504
- value = value.split('{{')[1].split('}}')[0].trim()
515
+ if (isObject) {
516
+ value = value.split('{{')[1].split('}}')[0].trim()
505
517
  value = `{${value}}`
506
518
  propstring += `${key}:${value},`
507
519
  } else {
@@ -510,8 +522,8 @@ function Compiler(func, file) {
510
522
  propstring += `${key}:${value},`
511
523
  }
512
524
  propstring = propstring.replaceAll(/\s+/g, " ").trim()
513
-
514
- }
525
+
526
+ }
515
527
  component = component.replaceAll(/\s+/g, " ");
516
528
 
517
529
  component = component.replace(componentAttributes, '')
@@ -578,7 +590,7 @@ function Compiler(func, file) {
578
590
  let replaceMents = [];
579
591
 
580
592
 
581
- if (imports) {
593
+ if(imports){
582
594
  for (let match of imports) {
583
595
  let path = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
584
596
  switch (true) {
@@ -588,11 +600,11 @@ function Compiler(func, file) {
588
600
  if (!fs.existsSync(process.cwd() + componentFolder)) {
589
601
  throw new Error('Could not find ' + path + ' at ' + match + ' in file ' + file)
590
602
  }
591
-
603
+
592
604
  if (!fs.existsSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'))) {
593
605
  fs.mkdirSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'), { recursive: true })
594
606
  }
595
-
607
+
596
608
  let baseFolder = componentFolder.split('node_modules')[1].split('/')[1]
597
609
  let glp = globSync('**/**/**/**.{jsx,js}', {
598
610
  cwd: process.cwd() + '/node_modules/' + baseFolder + '/',
@@ -603,7 +615,7 @@ function Compiler(func, file) {
603
615
  let text = fs.readFileSync(file, "utf8");
604
616
  if (!file.endsWith('.js') && file.endsWith('.jsx')) {
605
617
  text = Compiler(text, file);
606
-
618
+
607
619
  }
608
620
  let dest = file.split('node_modules')[1]
609
621
  dest = dest.split(baseFolder)[1]
@@ -615,8 +627,8 @@ function Compiler(func, file) {
615
627
  replaceMents.push({ match: oldImportstring, replace: newImport })
616
628
  console.log(`📦 imported Node Package ${baseFolder} `)
617
629
  }
618
-
619
-
630
+
631
+
620
632
  break;
621
633
  default:
622
634
  break;
@@ -641,7 +653,7 @@ function Compiler(func, file) {
641
653
  string = string.replaceAll(/\$\{\/\*.*\*\/\}/gs, "");
642
654
  string = string.replaceAll("<>", "`").replaceAll("</>", "`");
643
655
  string = string.replaceAll(".jsx", ".js");
644
-
656
+
645
657
 
646
658
  string = string
647
659
  .replaceAll("className", "class")
@@ -893,7 +905,7 @@ async function Build() {
893
905
  page.on('crash', () => {
894
906
  console.error(`Render process crashed for ${route.url}`)
895
907
  });
896
-
908
+
897
909
  await page.goto(`http://localhost:${port}${route.url}`, { waitUntil: 'networkidle2' });
898
910
 
899
911
  page.evaluate(() => {
@@ -937,8 +949,8 @@ async function Build() {
937
949
  browser.close()
938
950
  })
939
951
  hasRendered = []
940
- globalThis.isBuilding = false
941
-
952
+ globalThis.isBuilding = false
953
+
942
954
  }
943
955
 
944
956
  if (hasRendered.length === routes.length) {
@@ -954,7 +966,6 @@ async function Build() {
954
966
  }
955
967
  }
956
968
  globalThis.routes = []
957
- globalThis.paramRoutes = []
958
969
 
959
970
  for await (let file of glb) {
960
971
  // Normalize file paths
@@ -1053,10 +1064,7 @@ async function Build() {
1053
1064
  }
1054
1065
 
1055
1066
 
1056
- if (obj.url.includes(':') && !paramRoutes.includes(obj.url)) {
1057
- globalThis.paramRoutes.push({ fileName: fileName, url: obj.url, html: '/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html') })
1058
- } else {
1059
-
1067
+ if (!obj.url.includes(':')) {
1060
1068
  globalThis.routes.push({ fileName: fileName, url: obj.url, html: '/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html') })
1061
1069
  }
1062
1070
 
@@ -1077,8 +1085,7 @@ async function Build() {
1077
1085
 
1078
1086
  globalThis.routeDocuments = []
1079
1087
  globalThis.routes.map((route) => {
1080
- let equalparamroute = globalThis.paramRoutes.map((e) => {
1081
- console
1088
+ let equalparamroute = globalThis.routes.map((e) => {
1082
1089
  if (e.url.includes(':')) {
1083
1090
  let url = e.url.split('/:')[0]
1084
1091
  if (url && route.url === url) {
@@ -1153,13 +1160,13 @@ async function Build() {
1153
1160
  `;
1154
1161
  globalThis.routeDocuments.push({ url: route.url, document: document })
1155
1162
  })
1156
-
1157
- if (globalThis.devMode && !globalThis.oneAndDone) {
1163
+
1164
+ if(globalThis.devMode && !globalThis.oneAndDone){
1158
1165
  ssg(globalThis.routes)
1159
1166
  globalThis.oneAndDone = true
1160
1167
  console.log(`In Development Mode, Prerendering ${globalThis.routes.length} pages... Once`)
1161
- }
1162
- else if (globalThis.isProduction) {
1168
+ }
1169
+ else if(globalThis.isProduction){
1163
1170
  ssg(globalThis.routes)
1164
1171
  }
1165
1172
 
@@ -1244,7 +1251,7 @@ async function Build() {
1244
1251
  let data = await reader(process.cwd() + "/node_modules/vaderjs/runtime/" + file)
1245
1252
  await writer(process.cwd() + "/dist/" + file, data);
1246
1253
  });
1247
-
1254
+
1248
1255
 
1249
1256
  }
1250
1257
 
@@ -1340,7 +1347,7 @@ const s = (port) => {
1340
1347
  return 'application/octet-stream';
1341
1348
  }
1342
1349
  }
1343
-
1350
+
1344
1351
  server.listen(port, () => {
1345
1352
  console.log(`Server is running on port ${port}`);
1346
1353
  globalThis.ws = ws
@@ -1355,7 +1362,7 @@ switch (true) {
1355
1362
 
1356
1363
  globalThis.devMode = true
1357
1364
  globalThis.isProduction = false
1358
-
1365
+
1359
1366
  let p = process.env.PORT || config.port || process.argv.includes('-p') ? process.argv[process.argv.indexOf('-p') + 1] : 3000
1360
1367
  globalThis.oneAndDone = false
1361
1368
  console.log(`
@@ -1387,7 +1394,7 @@ Vader.js v${fs.readFileSync(process.cwd() + '/node_modules/vaderjs/package.json'
1387
1394
  Build()
1388
1395
  }
1389
1396
  }).on('error', (err) => console.log(err))
1390
- })
1397
+ })
1391
1398
  s(p)
1392
1399
 
1393
1400
  globalThis.listen = true;