vaderjs 1.4.2-jpiml56 → 1.4.2-kml56

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/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "vaderjs",
3
3
  "description": "A reactive framework for building fast and scalable web applications",
4
- "version": "1.4.2-jpiml56",
4
+ "version": "1.4.2-kml56",
5
+ "main": "vader.js",
5
6
  "author": {
6
7
  "name": "Malikwhitten67",
7
8
  "email": "malikwhitterb@gmail.com"
@@ -13,7 +14,7 @@
13
14
  },
14
15
  "type": "module",
15
16
  "bin":{
16
- "vader":"./vader_dev.js"
17
+ "vader":"./vader.js"
17
18
  },
18
19
  "dependencies": {
19
20
  "ws": "latest"
@@ -8,10 +8,6 @@ const glob = new Glob("/**/*.{ts,tsx,js,jsx}", {
8
8
  */
9
9
  async function generate(){
10
10
  let config = await import(process.cwd() + '/vader.config.js').then((config) => { return config.default })
11
- if(!config?.env || !config?.env.SSR){
12
- console.error('\x1b[31m[CloudFlare Functions] \x1b[0m - Please add an SSR environment variable to your vader.config.js file')
13
- return
14
- }
15
11
  let start = Date.now()
16
12
  for(var i of glob.scanSync({cwd: process.cwd() + '/routes', absolute: true})){
17
13
  let data = await Bun.file(i).text()
@@ -10,40 +10,10 @@ export class DOMParser {
10
10
  */
11
11
  parseFromString(html) {
12
12
  let doc = new Document();
13
- let t = new Bun.Transpiler({
14
- loader: "tsx", // "js | "jsx" | "ts" | "tsx",
15
- target: "browser",
16
- define: {
17
- "jsxDEV": "Element",
18
- "jsx": "Element"
19
- }
20
- });
21
-
22
- let el = t.transformSync(`
23
-
24
- const html = ${html}
25
- function Doc() {
26
- return (
27
- <html>
28
- <body>${html}</body>
29
- </html>
30
- )
31
- }
32
- return Doc()
33
- ` )
34
- el = el.replaceAll(`jsxDEV`, `Element`)
35
- let evaluated = eval(`(function(){${el}})()`)
36
- evaluated.children.forEach((child) => {
37
- child.outerHTML = child.toString()
38
- })
39
- doc.tree = evaluated.children
40
- doc.body = evaluated.children[0]
41
- doc.body.outerHTML = evaluated.children[0].toString()
42
- doc.body.firstChild = evaluated.children[0].children[0]
43
- doc.documentElement = evaluated
44
- doc.documentElement.outerHTML = evaluated.children[0].toString()
45
- this.tree = evaluated.children
46
- return doc
13
+ return {
14
+ error: "Not implemented",
15
+ }
16
+
47
17
  }
48
18
  /**
49
19
  * @description - Returns a string containing the HTML serialization of the element's descendants.
@@ -67,7 +37,7 @@ export class HTMLTextNode {
67
37
  }
68
38
 
69
39
  insertBefore(node) {
70
- this.nodeValue = `${node.nodeValue}${this.nodeValue}`;
40
+ this.nodeValue = `${node.toString()}${this.nodeValue}`;
71
41
  return this;
72
42
  }
73
43
  }
@@ -111,7 +81,7 @@ export class HTMLElement {
111
81
  if (key !== 'style' && key !== 'ref' && !key.startsWith('on')) {
112
82
  props += `${key}="${this.props[key]}" `
113
83
  }
114
- }
84
+ }
115
85
  let children = this.children
116
86
  .map((child) => {
117
87
  return child.toString();
@@ -153,9 +123,7 @@ export class HTMLElement {
153
123
  }
154
124
  })
155
125
  .join("");
156
- return string;
157
-
158
-
126
+ return string;
159
127
  default:
160
128
  break;
161
129
  }
@@ -182,8 +150,8 @@ export class HTMLElement {
182
150
  * @returns {HTMLElement}
183
151
  */
184
152
  setContent(content) {
185
- let textNode = new HTMLTextNode(content)
186
- this.children = [textNode];
153
+ let textNode = new HTMLTextNode(content);
154
+ this.children = [textNode];
187
155
  this.outerHTML = this.toString("outerHTML");
188
156
  this.innerHTML = this.toString("innerHTML");
189
157
  return this;
@@ -351,7 +319,7 @@ export class HTMLElement {
351
319
  this.textContent = this.toString("innerText");
352
320
  this.children.forEach((c) => {
353
321
  if (c.children) {
354
- child = c.children.find((child) => {
322
+ child = c.children.find((child) => {
355
323
  child.outerHTML = child.toString("outerHTML");
356
324
  child.innerHTML = child.toString("innerHTML");
357
325
  return child.tagName === selector;
@@ -439,9 +407,6 @@ export class Document {
439
407
  * @returns {HTMLElement}
440
408
  */
441
409
  createElement(nodeData) {
442
- if(!nodeData){
443
- return new HTMLElement("div", {}, [])
444
- }
445
410
  if (typeof nodeData === 'string') {
446
411
  return new HTMLElement(nodeData, {}, [])
447
412
  }
@@ -561,17 +526,7 @@ function handleStyles(styles, nodeEl) {
561
526
  */
562
527
  export function Element(tag, props = {}, ...children) {
563
528
  if(typeof tag === 'function'){
564
- let childObj = children.map((child) => {
565
- if (child.tagName === "TEXT_ELEMENT") {
566
- return new HTMLTextNode(child);
567
- }
568
- if (child instanceof HTMLElement) {
569
- return child;
570
- }
571
- return new HTMLElement(child.tagName, child.props, child.children);
572
- })
573
- childObj = childObj[0]
574
- let el = tag({...props, children: childObj})
529
+ let el = tag(props, children)
575
530
  return el
576
531
  }
577
532
  if(props === null){
@@ -637,12 +592,9 @@ export function Element(tag, props = {}, ...children) {
637
592
 
638
593
  node.children = children
639
594
  delete props.children
640
- }
595
+ }
596
+
641
597
  for (var i = 0; i < children.length; i++) {
642
- if(typeof children[i] === 'undefined'){
643
- delete children[i]
644
- continue;
645
- }
646
598
  if (typeof children[i] === "string" || typeof children[i] === "number") {
647
599
  children[i] = {
648
600
  tagName: "TEXT_ELEMENT",
@@ -655,7 +607,7 @@ export function Element(tag, props = {}, ...children) {
655
607
  } else {
656
608
  if (children[i]) {
657
609
  children[i].parentNode = { tagName: tag, props: props, children: children };
658
- }
610
+ }
659
611
 
660
612
  children[i] = new HTMLElement(children[i].tagName, children[i].props, children[i].children)
661
613
  }
@@ -1 +1,432 @@
1
- window.vader={version:"1.0.0"},globalThis.isServer=!1,globalThis.preRender=!1,window.hasRan=[],globalThis.memoizedFunctions=[];const memoizedRefs=[];function calculateDiff(e,t){if(void 0===e||void 0===t)return[];let n=[];if(e?.children.length>0){for(var r=0;r<e.children.length;r++)n.push(...calculateDiff(e.children[r],t.children[r]));return n}if(!e?._isRoot)if(3===e.nodeType&&e.nodeValue!==t.nodeValue)n.push({type:"REPLACE",oldNode:e,newNode:t});else if(1===e.nodeType&&e.innerHTML!==t.innerHTML)n.push({type:"REPLACE",oldNode:e,newNode:t});else if(1===e.nodeType&&e.tagName===t.tagName)for(r=0;r<e.attributes.length;r++)e.attributes[r].value!==t.attributes[r].value&&n.push({type:"PROPS",oldNode:e,newNode:t});return n}function generateJSX(e,t,...n){let r={state:{},mainFunction:e,_key:e.name||Math.random().toString(36).substring(7),$$typeof:"JSX_CHILD",firstChild:null,children:n,_name:e.name},o=new Component({$$key:r._key});return e=e.bind(o),o.render=()=>{let r=(n=n.flat(1/0)).map((e=>"function"==typeof e?generateJSX(e,t,e.props.children):e));return e({...t,children:r[0]||r})},r.firstChild=o.render(),r.firstChild.htmlNode._key=r._key,r.firstChild.htmlRoot=r,r.firstChild.htmlNode._isRoot=!0,r.firstChild.props=t||{},r.firstChild._isRoot=!0,r.firstChild._key=r._key,r.firstChild.props.key=r._key,r.firstChild}function handleStyles(e,t){for(let n in e)"object"==typeof e[n]&&handleStyles(e[n],t),t.style[n]=e[n]}let hasBeenCalled=[];function Element(e,t,...n){if(!t&&(t={}),t?.$$key||(t.$$key=e.name||Math.random().toString(36).substring(7)),"function"==typeof e)return generateJSX(e,t,n);let r={tag:e,props:t,children:n,_key:t.$$key,events:[],staticEl:document.createElement(e),parentNode:null};for(var o=0;o<n.length;o++)"string"==typeof n[o]||"number"==typeof n[o]?n[o]={tag:"TEXT_ELEMENT",props:{nodeValue:n[o]},_key:t.$$key,parentNode:{tag:e,props:t,children:n,_key:t.$$key},children:[]}:n[o]&&(n[o].parentNode={tag:e,props:t,children:n});let i="TEXT_ELEMENT"===r.tag?document.createTextNode(""):document.createElement(r.tag);for(var s in r.staticEl=i,t)s.toLowerCase().startsWith("on")?(i.addEventListener(s.substring(2).toLowerCase(),t[s]),r.events.push({type:s.substring(2).toLowerCase(),listener:t[s]})):"$$key"!==s||i._key||1!==i.nodeType?i&&1===i.nodeType&&i.setAttribute(s,t[s]):Object.defineProperty(i,"_key",{value:t[s],writable:!0});if(t.style&&handleStyles(t.style,i),t.id&&(i.id=t.id),t.ref)switch(!0){case Array.isArray(t.ref.current):t.ref.current.find((e=>e===i))||t.ref.current.push(i);break;case t.ref.current===HTMLElement:case null===t.ref.current:t.ref.current=i;break;case"function"==typeof t.ref&&!window.hasRan.includes(t.ref):window.hasRan.push(t.ref),t.ref(i),setTimeout((()=>{window.hasRan.filter((e=>e!==t.ref))}),0);break;default:t.ref.current=i}if(r.htmlNode=i,1===i.nodeType)for(o=0;o<n.length;o++)n[o]&&("TEXT_ELEMENT"===n[o].tag&&i.appendChild(document.createTextNode(n[o].props.nodeValue)),i.appendChild(Element(n[o].tag,n[o].props,...n[o].children).htmlNode));return r}function handleDiff(e){for(var t=0;t<e.length;t++)switch(!0){case"REPLACE"===e[t].type&&!e[t].oldNode._isRoot:e[t].oldNode.parentNode;e[t].oldNode.parentNode.replaceChild(e[t].newNode,e[t].oldNode);case"PROPS"===e[t].type:}}let states={};export const useState=(e,t)=>{};export function useRef(e,t){let n=t;memoizedRefs.find((t=>t.name===e))||memoizedRefs.push({name:e,ref:n});return{current:memoizedRefs.find((t=>t.name===e)).ref,name:e}}export function Mounted(e,t){Array.from(document.querySelectorAll("*")).find((e=>e._key===memoizedFunctions.find((e=>e.mainFunction===t))._key))&&!hasBeenCalled.find((e=>e===t))?(e(),hasBeenCalled.push(t)):setTimeout((()=>{Mounted(e,t)}),0)}let effects=[];export function useEffect(e,t){if(effects.find((t=>t.fn.toString()===e.toString()))){let n=effects.find((t=>t.fn.toString()===e.toString()));n.deps.toString()!==t.toString()&&(n.deps=t,n.fn())}else effects.push({fn:e,deps:t});return()=>{effects=effects.filter((t=>t.fn!==e))}}export function useReducer(e,t,n,r){let[o,i]=void 0;return[o,e=>{let n=t(o,e);i(n)}]}class Component{constructor(e){this.props=e,this._key=e.$$key||Math.random().toString(36).substring(7),this.state={},this.htmlNode=null,this.firstChild=null,this.Element=Element,this.passiveProps={}}setState(e){this.state=e}handleDiff(e){for(var t=0;t<e.length;t++)switch(!0){case"REPLACE"===e[t].type&&!e[t].oldNode._isRoot:e[t].oldNode.parentNode;e[t].oldNode.parentNode.replaceChild(e[t].newNode,e[t].oldNode);case"PROPS"===e[t].type:}}calculateDiff(e,t){if(void 0===e||void 0===t)return[];let n=[];if(e?.children.length>0){for(var r=0;r<e.children.length;r++)n.push(...this.calculateDiff(e.children[r],t.children[r]));return n}if(!e?._isRoot)if(3===e.nodeType&&e.nodeValue!==t.nodeValue)n.push({type:"REPLACE",oldNode:e,newNode:t});else if(1===e.nodeType&&e.innerHTML!==t.innerHTML)n.push({type:"REPLACE",oldNode:e,newNode:t});else if(1===e.nodeType&&e.tagName===t.tagName)for(r=0;r<e.attributes.length;r++)e.attributes[r].value!==t.attributes[r].value&&n.push({type:"PROPS",oldNode:e,newNode:t});return n}useState(e,t){this.state[e]||(this.state[e]=t);return[()=>this.state[e],t=>{let n=this.firstChild.htmlNode;"HTML"===n.tagName&&(n=n.querySelector("body"),n.firstChild._key=this._key),this.state[e]=t,handleDiff(calculateDiff(Array.from(document.querySelectorAll("*")).find((e=>e._key===n._key)),"HTML"===this.render(this.passiveProps).htmlNode.tagName?this.render(this.passiveProps).htmlNode.querySelector("body"):this.render(this.passiveProps).htmlNode))}]}useEffect=useEffect;useReducer(e,t,n){let[r,o]=this.useState(e,n);return[r,e=>{let n=t(r(),e);o(n)}]}render(){return null}}export async function render(e,t,...n){if(!e)throw new Error("No vnode was provided");let r=new Component({$$key:e.name||Math.random().toString(36).substring(7)});e=e.bind(r),n.length>0&&(n={req:n[0],res:n[1]},r.passiveProps=n),r.render=()=>e(r.passiveProps),r.firstChild=r.render(),t.innerHTML="",t.replaceWith(r.firstChild.htmlNode)}export default Element;
1
+ window.vader = {
2
+ version: '1.0.0'
3
+ }
4
+ globalThis.isServer = false
5
+ window.hasRan = []
6
+ globalThis.memoizedFunctions = []
7
+ const memoizedRefs = []
8
+ /**
9
+ * @description This function is used to calculate the difference between two nodes - and return the elements in which the difference is found
10
+ * @param {HTMLElement} oldNode
11
+ * @param {HTMLElement} newNode
12
+ * @returns
13
+ */
14
+ function calculateDiff(oldNode, newNode){
15
+ if(oldNode === undefined || newNode === undefined){
16
+ return []
17
+ }
18
+ let diff = []
19
+ if(oldNode?.children.length > 0){
20
+ for(var i = 0; i < oldNode.children.length; i++){
21
+ diff.push(...calculateDiff(oldNode.children[i], newNode.children[i]))
22
+
23
+ }
24
+ return diff
25
+ }
26
+ if(!oldNode?._isRoot){
27
+ if(oldNode.nodeType === 3 && oldNode.nodeValue !== newNode.nodeValue){
28
+ diff.push({type: 'REPLACE', oldNode, newNode})
29
+ }
30
+ else if(oldNode.nodeType === 1 && oldNode.innerHTML !== newNode.innerHTML
31
+ ){
32
+ diff.push({type: 'REPLACE', oldNode, newNode})
33
+ }
34
+ else if(oldNode.nodeType === 1 && oldNode.tagName === newNode.tagName){
35
+ for(var i = 0; i < oldNode.attributes.length; i++){
36
+ if(oldNode.attributes[i].value !== newNode.attributes[i].value){
37
+ diff.push({type: 'PROPS', oldNode, newNode})
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+
44
+
45
+ return diff
46
+ }
47
+
48
+ /**
49
+ * @description This function is used to generate functonal components
50
+ * @param {Function} tag
51
+ * @param {Object} props
52
+ * @param {...any} children
53
+ * @returns {Object} - The first child of the functional component
54
+ */
55
+ function generateJSX(tag, props, ...children){
56
+ let node = {
57
+ state: {},
58
+ mainFunction: tag,
59
+ _key: tag.name || Math.random().toString(36).substring(7),
60
+ $$typeof: 'JSX_CHILD',
61
+ firstChild:null,
62
+ children: children,
63
+ _name: tag.name,
64
+ }
65
+
66
+ node.firstChild = tag()
67
+ node.firstChild.htmlNode._key = node._key
68
+ node.firstChild.htmlRoot = node
69
+ node.firstChild.htmlNode._isRoot = true
70
+ node.firstChild.props = props || {}
71
+ node.firstChild._isRoot = true
72
+ node.firstChild._key = node._key
73
+ node.firstChild.props['key'] = node._key
74
+ return node.firstChild
75
+
76
+
77
+ }
78
+ function handleStyles(styles, nodeEl) {
79
+
80
+ for (let key in styles) {
81
+ if(typeof styles[key] === 'object'){
82
+ handleStyles(styles[key], nodeEl)
83
+ }
84
+ nodeEl.style[key] = styles[key];
85
+ }
86
+
87
+ }
88
+
89
+
90
+ let hasBeenCalled = []
91
+ /**
92
+ * @description Create a virtual DOM element
93
+ * @param {string | Function} tag
94
+ * @param {Object} props
95
+ * @param {...any} children
96
+ * @returns {Object} - The virtual DOM element
97
+ */
98
+ function Element(tag, props, ...children){
99
+ !props ? props = {} : null
100
+ if(!props?.['$$key']){
101
+ props['$$key'] = tag.name || Math.random().toString(36).substring(7)
102
+ }
103
+
104
+ if(typeof tag === 'function'){
105
+ return generateJSX(tag, props, children)
106
+ }
107
+ let node = {
108
+ tag: tag,
109
+ props: props,
110
+ children: children,
111
+ _key: props['$$key'],
112
+ events: [],
113
+ staticEl: document.createElement(tag),
114
+ parentNode: null
115
+ }
116
+ for(var i = 0; i < children.length; i++){
117
+ if(typeof children[i] === 'string' || typeof children[i] === 'number'){
118
+ children[i] = {
119
+ tag: 'TEXT_ELEMENT',
120
+ props: {nodeValue: children[i]},
121
+ _key: props['$$key'],
122
+ parentNode: {tag: tag, props: props, children: children, _key: props['$$key']},
123
+ children: []
124
+ }
125
+ }else{
126
+ if(children[i]){
127
+ children[i].parentNode = {tag: tag, props: props, children: children}
128
+ }
129
+ }
130
+ }
131
+ let nodeEl = node.tag === 'TEXT_ELEMENT' ? document.createTextNode('') : document.createElement(node.tag)
132
+ node.staticEl = nodeEl
133
+
134
+ for(var key in props){
135
+ if(key.toLowerCase().startsWith('on')){
136
+ nodeEl.addEventListener(key.substring(2).toLowerCase(), props[key])
137
+ node.events.push({type: key.substring(2).toLowerCase(), listener: props[key]})
138
+ continue
139
+ }
140
+ if(key === '$$key' && !nodeEl._key && nodeEl.nodeType === 1
141
+ ){
142
+ Object.defineProperty(nodeEl, '_key', {
143
+ value: props[key],
144
+ writable: true
145
+ })
146
+ continue
147
+ }
148
+
149
+ if(nodeEl && nodeEl.nodeType === 1){
150
+ nodeEl.setAttribute(key, props[key])
151
+ }
152
+
153
+ }
154
+ if(props.style){
155
+ handleStyles(props.style, nodeEl)
156
+ }
157
+
158
+ if(props.id){
159
+ nodeEl.id = props.id
160
+ }
161
+ if(props.ref){
162
+ switch(true){
163
+ case Array.isArray(props.ref.current):
164
+ if(!props.ref.current.find((el) => el === nodeEl)){
165
+ props.ref.current.push(nodeEl)
166
+ }
167
+ break;
168
+ case props.ref.current === HTMLElement:
169
+ props.ref.current = nodeEl
170
+ break;
171
+ case props.ref.current === null:
172
+ props.ref.current = nodeEl
173
+ break;
174
+ case typeof props.ref === 'function' && !window.hasRan.includes(props.ref):
175
+ window.hasRan.push(props.ref)
176
+ props.ref(nodeEl)
177
+ setTimeout(() => {
178
+ window.hasRan.filter((el) => el !== props.ref)
179
+ }, 0)
180
+ break;
181
+ default:
182
+ props.ref.current = nodeEl
183
+ break;
184
+
185
+ }
186
+ }
187
+ node['htmlNode'] = nodeEl
188
+
189
+
190
+ if(nodeEl.nodeType === 1){
191
+ for(var i = 0; i < children.length; i++){
192
+ if(children[i]){
193
+ if(children[i].tag === 'TEXT_ELEMENT'){
194
+ nodeEl.appendChild(document.createTextNode(children[i].props.nodeValue))
195
+ }
196
+ nodeEl.appendChild(Element(children[i].tag, children[i].props, ...children[i].children).htmlNode)
197
+ }
198
+ }
199
+
200
+ }
201
+
202
+ return node;
203
+ }
204
+
205
+
206
+ function handleDiff(diff){
207
+ for(var i = 0; i < diff.length; i++){
208
+ switch(true){
209
+ case diff[i].type === 'REPLACE' && !diff[i].oldNode._isRoot:
210
+ let parent = diff[i].oldNode.parentNode
211
+ diff[i].oldNode.parentNode.replaceChild(diff[i].newNode, diff[i].oldNode)
212
+ break;
213
+ case diff[i].type === 'PROPS':
214
+ break;
215
+ }
216
+ }
217
+
218
+ }
219
+ let states = {}
220
+ export const useState = (name, initialValue) => {}
221
+ export function useRef(name, initialValue){
222
+ let ref = initialValue
223
+ if(!memoizedRefs.find((el) => el.name === name)){
224
+ memoizedRefs.push({name, ref})
225
+ }
226
+ let getRef = () => memoizedRefs.find((el) => el.name === name).ref
227
+ let setRef = (newValue) => {
228
+ memoizedRefs.find((el) => el.name === name).ref = newValue
229
+ }
230
+ return {
231
+ current: getRef(),
232
+ name,
233
+ }
234
+ }
235
+ export function Mounted(fn, node){
236
+ let el = Array.from(document.querySelectorAll('*')).find((el) => el._key === memoizedFunctions.find((el) => el.mainFunction === node)._key)
237
+ if(el && !hasBeenCalled.find((el) => el === node)){
238
+ fn()
239
+ hasBeenCalled.push(node)
240
+ }
241
+ else{
242
+ setTimeout(() => {
243
+ Mounted(fn, node)
244
+ }, 0)
245
+ }
246
+ }
247
+
248
+
249
+ let effects = [];
250
+
251
+ export function useEffect(fn, deps){
252
+ if(!effects.find((el) => el.fn.toString() === fn.toString())){
253
+ effects.push({fn, deps})
254
+ }
255
+ else{
256
+ let effect = effects.find((el) => el.fn.toString() === fn.toString())
257
+ if(effect.deps.toString() !== deps.toString()){
258
+ effect.deps = deps
259
+ effect.fn()
260
+ }
261
+ }
262
+ return () => {
263
+ effects = effects.filter((el) => el.fn !== fn)
264
+ }
265
+
266
+ }
267
+ export function useReducer(name, reducer, vnode, initialState){
268
+ let [state, setState] = useState(name, vnode, initialState)
269
+ let dispatch = (action) => {
270
+ let newState = reducer(state, action)
271
+ setState(newState)
272
+ }
273
+
274
+ return [state, dispatch]
275
+
276
+ }
277
+
278
+ class Component {
279
+ constructor(props){
280
+ this.props = props
281
+ this._key = props['$$key'] || Math.random().toString(36).substring(7)
282
+ this.state = {}
283
+ this.htmlNode = null
284
+ this.firstChild = null
285
+ this.Element = Element
286
+ this.effects = []
287
+ }
288
+
289
+
290
+ setState(newState){
291
+ this.state = newState
292
+ }
293
+
294
+ handleDiff(diff){
295
+ for(var i = 0; i < diff.length; i++){
296
+ switch(true){
297
+ case diff[i].type === 'REPLACE' && !diff[i].oldNode._isRoot:
298
+ let parent = diff[i].oldNode.parentNode
299
+ diff[i].oldNode.parentNode.replaceChild(diff[i].newNode, diff[i].oldNode)
300
+ break;
301
+ case diff[i].type === 'PROPS':
302
+ break;
303
+ }
304
+ }
305
+ }
306
+ calculateDiff(oldNode, newNode){
307
+ if(oldNode === undefined || newNode === undefined){
308
+ return []
309
+ }
310
+ let diff = []
311
+ if(oldNode?.children.length > 0){
312
+ for(var i = 0; i < oldNode.children.length; i++){
313
+ diff.push(...this.calculateDiff(oldNode.children[i], newNode.children[i]))
314
+
315
+ }
316
+ return diff
317
+ }
318
+ if(!oldNode?._isRoot){
319
+ if(oldNode.nodeType === 3 && oldNode.nodeValue !== newNode.nodeValue){
320
+ diff.push({type: 'REPLACE', oldNode, newNode})
321
+ }
322
+ else if(oldNode.nodeType === 1 && oldNode.innerHTML !== newNode.innerHTML
323
+ ){
324
+ diff.push({type: 'REPLACE', oldNode, newNode})
325
+ }
326
+ else if(oldNode.nodeType === 1 && oldNode.tagName === newNode.tagName){
327
+ for(var i = 0; i < oldNode.attributes.length; i++){
328
+ if(oldNode.attributes[i].value !== newNode.attributes[i].value){
329
+ diff.push({type: 'PROPS', oldNode, newNode})
330
+ }
331
+ }
332
+ }
333
+ }
334
+
335
+
336
+
337
+ return diff
338
+ }
339
+ useEffect(fn, deps){
340
+ if(!this.effects.find((el) => el.fn.toString() === fn.toString())){
341
+ this.effects.push({fn, deps})
342
+ }
343
+ else{
344
+ let effect = this.effects.find((el) => el.fn.toString() === fn.toString())
345
+ if(effect.deps.toString() !== deps.toString()){
346
+ effect.deps = deps
347
+ effect.fn()
348
+ }
349
+ }
350
+ return () => {
351
+ this.effects = this.effects.filter((el) => el.fn !== fn)
352
+ }
353
+ }
354
+ useState(name, initialValue){
355
+ if(!this.state[name]){
356
+ this.state[name] = initialValue
357
+ }
358
+
359
+ let getState = () => this.state[name]
360
+ let setState = (newValue) => {
361
+ let dEl = this.firstChild.htmlNode
362
+ if(dEl.tagName === 'HTML'){
363
+ let firstChild = dEl.querySelector('body').firstChild
364
+ dEl = firstChild
365
+ }
366
+ this.state[name] = newValue
367
+ let el = Array.from(document.querySelectorAll('*')).find((el) =>{
368
+ return el._key === dEl._key
369
+ })
370
+ let diff = calculateDiff(el, this.render().htmlNode.tagName === 'HTML' ? this.render().htmlNode.querySelector('body').firstChild : this.render().htmlNode)
371
+ handleDiff(diff)
372
+
373
+ }
374
+ return [getState, setState]
375
+
376
+ }
377
+ useReducer(name, reducer, initialState){
378
+ let [state, setState] = this.useState(name, initialState)
379
+ let dispatch = (action) => {
380
+ let newState = reducer(state(), action)
381
+ setState(newState)
382
+ }
383
+
384
+ return [state, dispatch]
385
+ }
386
+
387
+ render(){
388
+ return null
389
+ }
390
+
391
+ }
392
+
393
+ export async function render(vnode, container, ...passProps){
394
+
395
+ if(!vnode){
396
+ throw new Error('No vnode was provided')
397
+ }
398
+ // create an object for the node then bind to firstChild
399
+ let comp = new Component({$$key: vnode.name || Math.random().toString(36).substring(7)})
400
+ vnode = vnode.bind(comp)
401
+ comp.render = () => {
402
+ return vnode(...passProps)
403
+ }
404
+
405
+ comp.firstChild = comp.render()
406
+
407
+ if(comp.firstChild.htmlNode.tagName === 'HTML'){
408
+ let hasHead = comp.firstChild.htmlNode.querySelector('head') ? true : false
409
+ let hasBody = comp.firstChild.htmlNode.querySelector('body') ? true : false
410
+
411
+ if(hasHead){
412
+ document.head.innerHTML = comp.firstChild.htmlNode.querySelector('head').innerHTML
413
+ comp.firstChild.children = comp.firstChild.children.filter((el) =>{
414
+ return el.htmlNode.tagName !== 'HEAD'
415
+ })
416
+ }
417
+ if(hasBody){
418
+ comp.firstChild.children = comp.firstChild.children.filter((el) =>{
419
+ if(el.htmlNode.tagName == 'BODY'){
420
+ comp.firstChild = el.children[0]
421
+ }
422
+ })
423
+ }
424
+ }
425
+ container.innerHTML = ''
426
+
427
+ container.appendChild(comp.firstChild.htmlNode)
428
+
429
+
430
+ }
431
+
432
+ export default Element