vaderjs 1.6.9 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.MD CHANGED
@@ -20,10 +20,10 @@ export default function(){
20
20
  return(
21
21
  <div>
22
22
  <Switch>
23
- <Match when={count() > 10}>
23
+ <Match when={count > 10}>
24
24
  <h1>Count is greater than 10 </h1>
25
25
  </Match>
26
- <Match when={count() < 10}>
26
+ <Match when={count < 10}>
27
27
  <h1>Count is less than 10 </h1>
28
28
  </Match>
29
29
  </Switch>
package/bundler/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
- Component,
3
- e,
4
- useState,
5
- useEffect,
6
- useFetch,
7
- useAsyncState,
8
- Fragment,
2
+ Component,
3
+ e,
4
+ useState,
5
+ useEffect,
6
+ useFetch,
7
+ useAsyncState,
8
+ Fragment,
9
9
  } from "vaderjs";
10
10
  import { document } from "vaderjs/document";
11
11
  import fs from "fs";
@@ -14,10 +14,10 @@ import path from "path";
14
14
  let path2 = require("path");
15
15
  globalThis.Fragment = Fragment;
16
16
  globalThis.window = {
17
- location: {
18
- hash: "",
19
- host: "",
20
- },
17
+ location: {
18
+ hash: "",
19
+ host: "",
20
+ },
21
21
  };
22
22
  globalThis.Component = Component;
23
23
  globalThis.e = e;
@@ -26,87 +26,99 @@ globalThis.useEffect = useEffect;
26
26
  globalThis.useAsyncState = useAsyncState;
27
27
  globalThis.useState = useState;
28
28
  globalThis.genKey = () => {
29
- return crypto.randomUUID();
29
+ return crypto.randomUUID();
30
30
  };
31
31
  globalThis.document = {
32
- createElement: (tag) => { },
33
- getElementById: (id) => { },
34
- querySelector: (query) => { },
32
+ createElement: (tag) => {},
33
+ getElementById: (id) => {},
34
+ querySelector: (query) => {},
35
35
  };
36
36
  await Bun.build({
37
- entrypoints: [process.env.ENTRYPOINT],
38
- minify: false,
39
- root: process.cwd() + "/dist/",
40
- outdir: process.cwd() + "/dist/",
41
-
42
- format: "esm",
43
- ...(process.env.DEV ? { sourcemap: "inline" } : {}),
44
- external:['*.jsx', '*.js', '*.ts']
37
+ entrypoints: [process.env.ENTRYPOINT],
38
+ minify: false,
39
+ root: process.cwd() + "/dist/",
40
+ outdir: process.cwd() + "/dist/",
41
+
42
+ format: "esm",
43
+ ...(process.env.DEV ? { sourcemap: "inline" } : {}),
44
+ external: ["*.jsx", "*.js", "*.ts"],
45
45
  });
46
46
 
47
- let builtCode = fs.readFileSync(path.join(process.cwd(), 'dist', process.env.filePath), 'utf-8')
48
-
47
+ let builtCode = fs.readFileSync(
48
+ path.join(process.cwd(), "dist", process.env.filePath),
49
+ "utf-8",
50
+ );
51
+
49
52
  function handleReplacements(code) {
50
- let lines = code.split("\n");
51
- let newLines = [];
52
- for (let line of lines) {
53
- let hasImport = line.includes('import')
54
- if(hasImport && line.includes('from') && !newLines.includes(line)){
55
- try {
56
- let url = line.includes("'") ? line.split("'")[1] : line.split('"')[1]
57
- line = line.replace(url, url.replace('.jsx', '.js').replace('.tsx', '.js'))
58
- line = line.replace(url, url.replace('.ts', '.js').replace('.tsx', '.js'))
59
- newLines.push(line)
60
- } catch (error) {
61
- continue;
62
- }
63
- }else{
64
- newLines.push(line)
65
- }
53
+ let lines = code.split("\n");
54
+ let newLines = [];
55
+ for (let line of lines) {
56
+ let hasImport = line.includes("import");
57
+ if (hasImport && line.includes("from") && !newLines.includes(line)) {
58
+ try {
59
+ let url = line.includes("'") ? line.split("'")[1] : line.split('"')[1];
60
+ line = line.replace(
61
+ url,
62
+ url.replace(".jsx", ".js").replace(".tsx", ".js"),
63
+ );
64
+ line = line.replace(
65
+ url,
66
+ url.replace(".ts", ".js").replace(".tsx", ".js"),
67
+ );
68
+ newLines.push(line);
69
+ } catch (error) {
70
+ continue;
71
+ }
72
+ } else {
73
+ newLines.push(line);
66
74
  }
67
- return newLines.join("\n");
75
+ }
76
+ return newLines.join("\n");
68
77
  }
69
- builtCode = handleReplacements(builtCode)
70
- fs.writeFileSync(path.join(process.cwd(), 'dist', process.env.filePath), builtCode)
78
+ builtCode = handleReplacements(builtCode);
79
+ fs.writeFileSync(
80
+ path.join(process.cwd(), "dist", process.env.filePath),
81
+ builtCode,
82
+ );
71
83
 
72
84
  let isClass = function (element) {
73
- return element.toString().startsWith("class");
85
+ return element.toString().startsWith("class");
74
86
  };
75
87
  const generatePage = async (
76
- data = { path: process.env.INPUT, route: process.env.OUT }
88
+ data = { path: process.env.INPUT, route: process.env.OUT },
77
89
  ) => {
78
- const { path, route } = data;
79
- if (path.includes("root.js")) return;
80
- let html = await import(path).then((m) => m.default);
81
- let { head } = await import(path).then((m) => m);
82
- let isFunction = false;
83
- globalThis.isServer = true;
84
- if (isClass(html)) {
85
- html = new html();
86
- html.Mounted = true;
87
- html = html.render();
88
- } else {
89
- isFunction = true;
90
- let instance = new Component();
91
- html = html.bind(instance);
92
- instance.render = html;
93
- html = instance.render();
94
- }
90
+ const { path, route } = data;
91
+ if (path.includes("root.js")) return;
92
+ let html = await import(path).then((m) => m.default);
93
+ let { head } = await import(path).then((m) => m);
94
+ let isFunction = false;
95
+ globalThis.isServer = true;
96
+ if (isClass(html)) {
97
+ html = new html();
98
+ html.Mounted = true;
99
+ html = html.render();
100
+ } else {
101
+ isFunction = true;
102
+ let instance = new Component();
103
+ html = html.bind(instance);
104
+ instance.render = html;
105
+ html = instance.render();
106
+ }
95
107
 
96
- let h = document(html);
97
- if (!fs.existsSync(process.cwd() + "/dist" + path2.dirname(route))) {
98
- fs.mkdirSync(process.cwd() + "/dist" + path2.dirname(route), {
99
- recursive: true,
100
- });
101
- }
102
- let headHtml = "";
103
- if (head) {
104
- headHtml = document(head());
105
- }
106
-
107
- await Bun.write(
108
- process.cwd() + "/dist/" + route + "/index.html",
109
- `<!DOCTYPE html>
108
+ let h = document(html);
109
+ if (!fs.existsSync(process.cwd() + "/dist" + path2.dirname(route))) {
110
+ fs.mkdirSync(process.cwd() + "/dist" + path2.dirname(route), {
111
+ recursive: true,
112
+ });
113
+ }
114
+ let headHtml = "";
115
+ if (head) {
116
+ headHtml = document(head());
117
+ }
118
+
119
+ await Bun.write(
120
+ process.cwd() + "/dist/" + route + "/index.html",
121
+ `<!DOCTYPE html>
110
122
  <head>
111
123
  ${headHtml}
112
124
  ${process.env.bindes}
@@ -114,29 +126,29 @@ const generatePage = async (
114
126
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
115
127
  </head>
116
128
  ${h}
117
- <script type="module">
129
+ <script type="module">
118
130
  import c from '${process.env.filePath}'
119
131
  import {render, e} from '/src/vader/index.js'
120
132
  window.e = e
121
133
  render(c, document.body.firstChild)
122
134
  </script>
123
- `
124
- );
125
- console.log(
126
- ansiColors.blue(
127
- `${process.env.filePath.replace(".js", ".jsx")} - ${parseInt(
128
- process.env.size
129
- ).toFixed(2)}kb`
130
- )
131
- );
132
- process.exit(0);
135
+ `,
136
+ );
137
+ console.log(
138
+ ansiColors.blue(
139
+ `${process.env.filePath.replace(".ts", ".js")} - ${parseInt(
140
+ process.env.size,
141
+ ).toFixed(2)}kb`,
142
+ ),
143
+ );
144
+ process.exit(0);
133
145
  };
134
- try {
135
- if(process.env.isTs == undefined && process.env.isImport) {
136
- generatePage({ path: process.env.INPUT, route: process.env.OUT })
137
- }else if(process.env.isTs == undefined){
138
- generatePage({ path: process.env.INPUT, route: process.env.OUT })
139
- }
140
- } catch (error) {
141
- console.log(ansiColors.red(error))
142
- }
146
+ try {
147
+ if (process.env.isTs == undefined && process.env.isImport) {
148
+ generatePage({ path: process.env.INPUT, route: process.env.OUT });
149
+ } else if (process.env.isTs == undefined) {
150
+ generatePage({ path: process.env.INPUT, route: process.env.OUT });
151
+ }
152
+ } catch (error) {
153
+ console.log(ansiColors.red(error));
154
+ }
package/index.ts CHANGED
@@ -63,8 +63,8 @@ export const useFetch = (url: string, options: any) => {
63
63
  export const useAsyncState = (promise: Promise<any>) => {
64
64
  return [null, () => {}];
65
65
  }
66
- export const useEffect = (callback:any, dependencies: any[]) => {
67
- dependencies = dependencies.map((dep) => dep.toString());
66
+ export const useEffect = (callback:any, dependencies: any[] = []) => {
67
+ dependencies = dependencies.map((dep) => JSON.stringify(dep));
68
68
  if (dependencies.length === 0) {
69
69
  callback();
70
70
  }
@@ -138,9 +138,12 @@ export const e = (element, props, ...children) => {
138
138
  instance.Mounted = true;
139
139
  let firstEl = instance.render({key: instance.key, children: children, ...props}, children);
140
140
  instance.children = children;
141
- if (!firstEl) firstEl = {type: "div", props: {key: instance.key, ...props}, children: children};
141
+ if (!firstEl) {
142
+ return {type: "div", props: {key: instance.key, ...props}, children: children};
143
+ }
144
+
142
145
  firstEl.props = { key: instance.key, ...firstEl.props, ...props };
143
- return firstEl;
146
+ return { type: "ghost", props:{}, children: [firstEl]}
144
147
  default:
145
148
  return { type: element, props: props || {}, children: children || [] };
146
149
  }
@@ -177,20 +180,15 @@ export function Match({ when, children }) {
177
180
  * @param key
178
181
  * @param initialState
179
182
  * @param persist - persist state on reload
180
- * @returns {()=> T, (newState: any, Element: string) => void, key}
183
+ * @returns {T, (newState: any, Element: string) => void, key}
181
184
  */
182
185
  export const useState = <T>(initialState: T, persist: false) => {
183
186
  const setState = (newState: T) => {
184
187
  initialState = newState;
185
188
  }
186
- /**
187
- * @returns {T}
188
- */
189
- const getVal = () => {
190
- return initialState as T;
191
- }
192
189
 
193
- return [getVal, setState];
190
+
191
+ return [initialState, setState];
194
192
  }
195
193
 
196
194
  if (!isServer) {
@@ -215,6 +213,19 @@ if (!isServer) {
215
213
  *
216
214
  * render(<App name="John" />, document.getElementById("root"));
217
215
  */
216
+
217
+ // create a hidden object on window
218
+ //
219
+ if(!isServer){
220
+ Object.defineProperty(window, "state", {
221
+ value: [],
222
+ writable: true,
223
+ enumerable: true,
224
+ })
225
+
226
+ }else{
227
+ globalThis.state = []
228
+ }
218
229
  export class Component {
219
230
  props;
220
231
  state;
@@ -225,17 +236,27 @@ export class Component {
225
236
  effectCalls: any[]
226
237
  eventRegistry: any
227
238
  prevState;
239
+ refs: HTMLElement[] | any[]
240
+ state: any[] = []
228
241
  constructor() {
229
242
  this.key = crypto.randomUUID();
230
243
  this.props = {};
231
- this.state = {};
232
244
  this.effect = [];
233
245
  this.Mounted = false;
246
+ this.state = [];
234
247
  this.element = null;
235
248
  this.effectCalls = []
236
249
  this.errorThreshold = 1000
237
250
  this.maxIntervalCalls = 10
238
- this.eventRegistry = new Map();
251
+ this.eventRegistry = new WeakMap();
252
+ this.refs = []
253
+ }
254
+ useRef = (key, value) => {
255
+ if(!this.refs.find((r)=> r.key == key)){
256
+ this.refs.push({key, value});
257
+ }
258
+
259
+ return this.refs.find((r)=> r.key == key).value;
239
260
  }
240
261
  useEffect(callback, dependencies = []) {
241
262
  const callbackId = callback.toString();
@@ -263,7 +284,10 @@ export class Component {
263
284
 
264
285
  setTimeout(() => {
265
286
  try {
266
- callback();
287
+
288
+ effects.push(callbackId);
289
+
290
+ callback()
267
291
  } catch (error) {
268
292
  console.error(error);
269
293
  }
@@ -273,7 +297,6 @@ export class Component {
273
297
  if (dependencies.length === 0 && this.Mounted && this.effect.length === 0 && !effects.includes(callbackId)){
274
298
  executeCallback();
275
299
  this.effect.push(callbackId);
276
- effects.push(callbackId);
277
300
  } else {
278
301
  // Check if dependencies have changed
279
302
  let dependenciesChanged = false;
@@ -295,53 +318,96 @@ export class Component {
295
318
  }
296
319
  }
297
320
  useState(key, defaultValue, persist = false) {
321
+
298
322
  if (typeof window === "undefined")
299
323
  return [defaultValue, () => {
300
324
  }];
301
- let value = sessionStorage.getItem("state_" + key) ? JSON.parse(sessionStorage.getItem("state_" + key)).value : defaultValue;
302
325
 
326
+ let value = this.state.find((v) => v.key == key) ? this.state.find((v) => v.key == key).value : defaultValue;
327
+
328
+ if(!this.state.find(i => i.key === key)){
329
+ this.state.push({key: key, value: defaultValue})
330
+ }
303
331
  if (typeof value === "string") {
304
332
  try {
305
333
  value = JSON.parse(value);
306
334
  } catch (error) {
307
335
  }
308
336
  }
309
- if (!window["listener" + key] && !isServer) {
310
- window["listener" + key] = true;
311
- window.addEventListener("beforeunload", () => {
312
- !persist && sessionStorage.removeItem("state_" + key);
313
- });
337
+
338
+ const clear = () =>{
339
+ this.state = this.state.filter((v) => v.key !== key);
314
340
  }
315
341
  const setValue = (newValue) => {
342
+ // If newValue is a function, call it with the current value
316
343
  if (typeof newValue === "function") {
317
- newValue = newValue(value);
344
+ const item = this.state.find(i => i.key === key);
345
+ newValue = item ? newValue(item.value) : newValue;
346
+ }
347
+
348
+
349
+ let itemIndex = this.state.findIndex(i => i.key === key);
350
+
351
+ if (itemIndex !== -1) {
352
+ this.state[itemIndex].value = newValue;
353
+ } else {
354
+ this.state.push({ key: key, value: newValue });
318
355
  }
319
- sessionStorage.setItem("state_" + key, JSON.stringify({ value: newValue }));
356
+
320
357
  this.forceUpdate(this.key);
321
358
  };
322
- const getVal = () => {
323
- return sessionStorage.getItem("state_" + key) ? JSON.parse(sessionStorage.getItem("state_" + key)).value : defaultValue;
324
- }
325
- return [getVal, setValue];
359
+
360
+
361
+ return [value, setValue, clear];
326
362
  }
327
363
  useFetch(url, options) {
328
364
  const loadingKey = "loading_" + url;
329
365
  const errorKey = "error" + url;
330
366
  const dataKey = "_data" + url;
331
- let [loading, setLoading] = this.useState(loadingKey, true);
332
- let [error, setError] = this.useState(errorKey, null);
333
- let [data, setData] = this.useState(dataKey, null);
334
- if (loading && !error && !data) {
367
+ let [loading, setLoading, _clear1] = this.useState(loadingKey, true);
368
+ let [error, setError, _clear2] = this.useState(errorKey, null);
369
+ let [data, setData, clear] = this.useState(dataKey, null);
370
+ if (loading() && !error() && !data()) {
335
371
  fetch(url, options).then((res) => res.json()).then((data2) => {
336
372
  setLoading(false);
337
373
  setData(data2);
338
374
  this.forceUpdate(this.key);
375
+ setTimeout(()=> {
376
+ _clear1()
377
+ _clear2()
378
+ clear()
379
+ }, 1500)
339
380
  }).catch((err) => {
340
381
  setError(err);
341
382
  this.forceUpdate(this.key);
342
383
  });
343
384
  }
344
- return [data, loading, error];
385
+ return { loading, error, data };
386
+ }
387
+ addEventListener(element, event, handler) {
388
+ // Ensure element is tracked
389
+ if (!this.eventRegistry.has(element)) {
390
+ this.eventRegistry.set(element, []);
391
+ }
392
+
393
+ // Check for duplicates
394
+ const registeredEvents = this.eventRegistry.get(element);
395
+ const isDuplicate = registeredEvents.some(
396
+ (e) => e.type === event && e.handler === handler
397
+ );
398
+ if (!isDuplicate) {
399
+ element.addEventListener(event, handler);
400
+ registeredEvents.push({ type: event, handler });
401
+ this.eventRegistry.set(element, registeredEvents);
402
+ }
403
+ }
404
+ removeEventListeners(element) {
405
+ // Unregister and remove all events for the element
406
+ const registeredEvents = this.eventRegistry.get(element) || [];
407
+ registeredEvents.forEach(({ type, handler }) => {
408
+ element.removeEventListener(type, handler);
409
+ });
410
+ this.eventRegistry.delete(element);
345
411
  }
346
412
  forceUpdate(key) {
347
413
  let el = Array.from(document.querySelectorAll("*")).filter((el2) => {
@@ -354,50 +420,92 @@ export class Component {
354
420
  this.Reconciler.update(el, newl);
355
421
  }
356
422
  Reconciler = {
357
- update: (oldElement, newElement) => {
423
+ update:(oldElement, newElement) => {
358
424
  if (!oldElement || !newElement) return;
359
-
360
- // Store and re-attach events before updating
361
- const events = this.eventRegistry.get(oldElement) || [];
362
-
425
+
426
+ // If nodes are the same type and can be updated
363
427
  if (this.Reconciler.shouldUpdate(oldElement, newElement)) {
364
- let part = this.Reconciler.shouldUpdate(oldElement, newElement, true);
365
- if (part === true) {
366
- if (oldElement.nodeType === 3) {
367
- oldElement.nodeValue = newElement.nodeValue;
428
+ // Update attributes of the parent
429
+ Array.from(oldElement.attributes).forEach(({ name }) => {
430
+ if (!newElement.hasAttribute(name)) {
431
+ oldElement.removeAttribute(name);
432
+ }
433
+ });
434
+
435
+ Array.from(newElement.attributes).forEach(({ name, value }) => {
436
+ if (oldElement.getAttribute(name) !== value) {
437
+ oldElement.setAttribute(name, value);
438
+ }
439
+ });
440
+
441
+ // Update the parent content (if text content differs)
442
+ if (oldElement.childNodes.length === 1 && oldElement.firstChild.nodeType === Node.TEXT_NODE) {
443
+ if (oldElement.textContent !== newElement.textContent) {
444
+ oldElement.textContent = newElement.textContent;
445
+ }
446
+ return; // No children to reconcile if it's a text node
447
+ }
448
+
449
+ // Reconcile child nodes
450
+ const oldChildren = Array.from(oldElement.childNodes);
451
+ const newChildren = Array.from(newElement.childNodes);
452
+
453
+ const maxLength = Math.max(oldChildren.length, newChildren.length);
454
+ for (let i = 0; i < maxLength; i++) {
455
+ if (i >= oldChildren.length) {
456
+ // Add new children
457
+ const newChildClone = newChildren[i].cloneNode(true);
458
+ oldElement.appendChild(newChildClone);
459
+
460
+ // Transfer events for the new child
461
+ const newChildEvents = this.eventRegistry.get(newChildren[i]) || [];
462
+ newChildEvents.forEach(({ type, handler }) => {
463
+ this.addEventListener(newChildClone, type, handler);
464
+ });
465
+ } else if (i >= newChildren.length) {
466
+ // Remove extra old children
467
+ oldElement.removeChild(oldChildren[i]);
368
468
  } else {
369
- oldElement.innerHTML = newElement.innerHTML;
370
-
371
- // Swap attributes
372
- for (let i = 0; i < newElement.attributes.length; i++) {
373
- let attr = newElement.attributes[i];
374
- oldElement.setAttribute(attr.name, attr.value);
375
- }
376
-
377
- // Re-attach events
378
- for (const { event, handler } of events) {
379
- oldElement.addEventListener(event, handler);
380
- }
381
-
382
- // Update children recursively
383
- for (let i = 0; i < newElement.childNodes.length; i++) {
384
- this.Reconciler.update(oldElement.childNodes[i], newElement.childNodes[i], true);
385
- }
469
+ // Update existing children recursively
470
+ this.Reconciler.update(oldChildren[i], newChildren[i]);
386
471
  }
387
- } else if (part.type === "attribute") {
388
- oldElement.setAttribute(part.name, part.value);
389
472
  }
473
+
474
+ // Reapply events to the parent
475
+ const parentEvents = this.eventRegistry.get(newElement) || [];
476
+ parentEvents.forEach(({ type, handler }) => {
477
+ this.addEventListener(oldElement, type, handler);
478
+ });
390
479
  } else {
391
- // Update children recursively
392
- for (let i = 0; i < newElement.childNodes.length; i++) {
393
- this.Reconciler.update(oldElement.childNodes[i], newElement.childNodes[i], true);
480
+ const oldChildren = Array.from(oldElement.childNodes);
481
+ const newChildren = Array.from(newElement.childNodes);
482
+
483
+ const maxLength = Math.max(oldChildren.length, newChildren.length);
484
+ for (let i = 0; i < maxLength; i++) {
485
+ if (i >= oldChildren.length) {
486
+ // Add new children
487
+ const newChildClone = newChildren[i].cloneNode(true);
488
+ oldElement.appendChild(newChildClone);
489
+
490
+ // Transfer events for the new child
491
+ const newChildEvents = this.eventRegistry.get(newChildren[i]) || [];
492
+ newChildEvents.forEach(({ type, handler }) => {
493
+ this.addEventListener(newChildClone, type, handler);
494
+ });
495
+ } else if (i >= newChildren.length) {
496
+ // Remove extra old children
497
+ oldElement.removeChild(oldChildren[i]);
498
+ } else {
499
+ // Update existing children recursively
500
+ this.Reconciler.update(oldChildren[i], newChildren[i]);
501
+ }
394
502
  }
395
503
  }
396
504
  },
397
-
505
+
398
506
  shouldUpdate: (oldElement, newElement, isChild = false) => {
399
507
  if (oldElement.nodeType !== newElement.nodeType) {
400
- return oldElement.innerHTML !== newElement.innerHTML ? { type: 'innerHTML' } : true;
508
+ return oldElement.innerHTML !== newElement.innerHTML ? { type: "innerHTML" } : true;
401
509
  }
402
510
  if (oldElement.nodeType === 3 && newElement.nodeType === 3) {
403
511
  if (oldElement.nodeValue !== newElement.nodeValue) {
@@ -411,7 +519,7 @@ export class Component {
411
519
  return true;
412
520
  }
413
521
  if (newElement.attributes) {
414
- for (let i = 0; i < newElement.attributes.length; i++) {
522
+ for (let i = 0;i < newElement.attributes.length; i++) {
415
523
  let attr = newElement.attributes[i];
416
524
  if (oldElement.getAttribute(attr.name) !== attr.value) {
417
525
  return { type: "attribute", name: attr.name, value: attr.value };
@@ -428,7 +536,7 @@ export class Component {
428
536
  let svg = ["svg", "path", "circle", "rect", "line", "polyline", "polygon", "ellipse", "g"];
429
537
  let el = svg.includes(element.type) ? document.createElementNS("http://www.w3.org/2000/svg", element.type) : document.createElement(element.type);
430
538
  let isText = typeof element === "string" || typeof element === "number" || typeof element === "boolean";
431
- if (isText) {
539
+ if (isText && element){
432
540
  el.innerHTML = element;
433
541
  } else {
434
542
  let attributes = element.props;
@@ -439,7 +547,7 @@ export class Component {
439
547
  continue;
440
548
  }
441
549
  if (key === "className") {
442
- el.className = attributes[key];
550
+ el.setAttribute("class", attributes[key]);
443
551
  continue;
444
552
  }
445
553
  if (key === "style") {
@@ -454,7 +562,8 @@ export class Component {
454
562
  }
455
563
  if (key.startsWith("on")) {
456
564
  el.addEventListener(key.substring(2).toLowerCase(), attributes[key]);
457
- this.eventRegistry.set(el, [...(this.eventRegistry.get(el) || []), { event: key.substring(2).toLowerCase(), handler: attributes[key] }]);
565
+ this.eventRegistry.set(el, [...this.eventRegistry.get(el) || [], { event: key.substring(2).toLowerCase(), handler: attributes[key] }]);
566
+ this.addEventListener(el,key.substring(2).toLowerCase(), attributes[key])
458
567
  continue;
459
568
  }
460
569
  el.setAttribute(key, attributes[key]);
@@ -468,8 +577,7 @@ export class Component {
468
577
  el.appendChild(this.parseToElement(c));
469
578
  });
470
579
  }
471
- if (typeof child === "function") {
472
- console.log("child is function");
580
+ if (typeof child === "function") {
473
581
  let comp = memoizeClassComponent(Component);
474
582
  comp.Mounted = true;
475
583
  comp.render = child;
@@ -478,7 +586,7 @@ export class Component {
478
586
  el.appendChild(el2);
479
587
  } else if (typeof child === "object") {
480
588
  el.appendChild(this.parseToElement(child));
481
- } else {
589
+ } else if(child){
482
590
  let span = document.createTextNode(child)
483
591
  el.appendChild(span);
484
592
  }
package/main.js CHANGED
@@ -110,7 +110,9 @@ const vader = {
110
110
  const handleReplacements = (code) => {
111
111
  let lines = code.split('\n')
112
112
  let newLines = []
113
+ let isDefault
113
114
  for (let line of lines) {
115
+
114
116
  let hasImport = line.includes('import')
115
117
 
116
118
  if (hasImport && line.includes('.css')) {
@@ -300,7 +302,6 @@ async function generateApp() {
300
302
  function handleFiles() {
301
303
  return new Promise(async (resolve, reject) => {
302
304
  try {
303
- console.log(Glob)
304
305
  let glob = new Glob('public/**/*')
305
306
  for await (var i of glob.scan()) {
306
307
  let file = i
@@ -311,42 +312,42 @@ function handleFiles() {
311
312
  fs.copyFileSync(file, path.join(process.cwd() + '/dist', file))
312
313
  }
313
314
  let glob2 = new Glob('src/**/*')
314
- for await (var i of glob2.scan()) {
315
- var file = i
316
- fs.mkdirSync(path.join(process.cwd() + '/dist', path.dirname(file)), { recursive: true })
317
- // turn jsx to js
318
- if (file.includes('.jsx') || file.includes('.tsx')) {
319
- let code = await Bun.file(file).text()
320
-
321
- code = handleReplacements(code)
322
-
323
- file = file.replace('.jsx', '.js').replace('.tsx', '.js')
324
- fs.writeFileSync(path.join(process.cwd() + '/dist', file.replace('.jsx', '.js').replace('.tsx', '.js')), code)
325
- await Bun.spawn({
326
- cmd: ['bun', 'run', './dev/bundler.js'],
327
- cwd: process.cwd(),
328
- stdout: 'inherit',
329
- env: {
330
- ENTRYPOINT: path.join(process.cwd() + '/dist/' + file.replace('.jsx', '.js').replace('.tsx', '.js')),
331
- ROOT: process.cwd() + '/app/',
332
- OUT: path.dirname(file),
333
- shouldReplace: true,
334
- file: process.cwd() + '/dist/' + file.replace('.jsx', '.js').replace('.tsx', '.js'),
335
- DEV: mode === 'development',
336
- size: code.length / 1024,
337
- filePath: file.replace('.jsx', '.js'),
338
- isTs: file.includes('.tsx'),
339
- INPUT: path.join(process.cwd(), file.replace('.js', '.jsx').replace('.tsx', '.js')),
340
- },
341
- onExit({ exitCode: code }) {
342
- if (code === 0) {
343
- resolve()
344
- } else {
345
- reject()
346
- }
347
- }
348
- })
349
- } else if (file.includes('.ts')) {
315
+ for await (var i of glob2.scan()) {
316
+ var file = i
317
+ fs.mkdirSync(path.join(process.cwd() + '/dist', path.dirname(file)), { recursive: true })
318
+ // turn jsx to js
319
+ if (file.includes('.jsx') || file.includes('.tsx')) {
320
+ let code = await Bun.file(file).text()
321
+
322
+ code = handleReplacements(code)
323
+
324
+ file = file.replace('.jsx', '.js').replace('.tsx', '.js')
325
+ fs.writeFileSync(path.join(process.cwd() + '/dist', file.replace('.jsx', '.js').replace('.tsx', '.js')), code)
326
+ await Bun.spawn({
327
+ cmd: ['bun', 'run', './dev/bundler.js'],
328
+ cwd: process.cwd(),
329
+ stdout: 'inherit',
330
+ env: {
331
+ ENTRYPOINT: path.join(process.cwd() + '/dist/' + file.replace('.jsx', '.js').replace('.tsx', '.js')),
332
+ ROOT: process.cwd() + '/app/',
333
+ OUT: path.dirname(file),
334
+ shouldReplace: true,
335
+ file: process.cwd() + '/dist/' + file.replace('.jsx', '.js').replace('.tsx', '.js'),
336
+ DEV: mode === 'development',
337
+ size: code.length / 1024,
338
+ filePath: file.replace('.jsx', '.js'),
339
+ isTs: false,
340
+ INPUT: path.join(process.cwd(), file.replace('.js', '.jsx').replace('.tsx', '.js')),
341
+ },
342
+ onExit({ exitCode: code }) {
343
+ if (code === 0) {
344
+ resolve()
345
+ } else {
346
+ reject()
347
+ }
348
+ }
349
+ })
350
+ } else if (file.includes('.ts') || file.includes('.js')) {
350
351
  let code = await Bun.file(file).text()
351
352
  code = handleReplacements(code)
352
353
  file = file.replace('.ts', '.js')
@@ -361,10 +362,10 @@ function handleFiles() {
361
362
  OUT: path.dirname(file),
362
363
  file: process.cwd() + '/dist/' + file.replace('.ts', '.js'),
363
364
  DEV: mode === 'development',
364
- isTS: true,
365
+ isTs: true,
365
366
  size: code.length / 1024,
366
367
  filePath: file.replace('.ts', '.js'),
367
- INPUT: path.join(process.cwd(), file.replace('.js', '.jsx')),
368
+ INPUT: path.join(process.cwd(), file.replace('.ts', '.js')),
368
369
  },
369
370
  onExit({ exitCode: code }) {
370
371
  if (code === 0) {
@@ -399,6 +400,7 @@ if (mode === 'development') {
399
400
  const handleFileChangeDebounced = async (change, file) => {
400
401
  if (file.endsWith('.tsx') || file.endsWith('.jsx') || file.endsWith('.css') || file.endsWith('.ts')
401
402
  && !file.includes('node_module')
403
+ || file.endsWith('.js') && !file.includes('dist')
402
404
  ) {
403
405
  // delete files cache
404
406
  if (file.endsWith('vader.config.ts')){
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vaderjs",
3
- "version": "1.6.9",
3
+ "version": "1.7.0",
4
4
  "description": "A simple and powerful JavaScript library for building modern web applications.",
5
5
  "bin": {
6
6
  "vaderjs": "./main.js"