vaderjs 1.7.3 → 1.7.5
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/bundler/index.js +87 -91
- package/index.ts +184 -126
- package/main.js +43 -33
- package/package.json +1 -1
package/bundler/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
useAsyncState,
|
|
8
8
|
Fragment,
|
|
9
9
|
} from "vaderjs";
|
|
10
|
-
import { document } from "vaderjs/document";
|
|
10
|
+
import { document } from "vaderjs/document/index.ts";
|
|
11
11
|
import fs from "fs";
|
|
12
12
|
import ansiColors from "ansi-colors";
|
|
13
13
|
import path from "path";
|
|
@@ -15,8 +15,8 @@ let path2 = require("path");
|
|
|
15
15
|
globalThis.Fragment = Fragment;
|
|
16
16
|
globalThis.window = {
|
|
17
17
|
location: {
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
hash: "",
|
|
19
|
+
host: "",
|
|
20
20
|
},
|
|
21
21
|
};
|
|
22
22
|
globalThis.Component = Component;
|
|
@@ -29,126 +29,122 @@ globalThis.genKey = () => {
|
|
|
29
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
36
|
+
try {
|
|
37
|
+
await Bun.build({
|
|
38
|
+
entrypoints: [process.env.ENTRYPOINT],
|
|
39
|
+
minify: false,
|
|
40
|
+
root: process.cwd() + "/dist/",
|
|
41
|
+
outdir: process.cwd() + "/dist/",
|
|
42
|
+
format: "esm",
|
|
43
|
+
...(process.env.DEV ? { sourcemap: "inline" } : {}),
|
|
44
|
+
packages: "bundle",
|
|
45
|
+
external: ['*.jsx', '*.js', '*.ts']
|
|
46
|
+
});
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error(error)
|
|
49
|
+
}
|
|
46
50
|
|
|
47
|
-
let builtCode = fs.readFileSync(
|
|
48
|
-
path.join(process.cwd(), "dist", process.env.filePath),
|
|
49
|
-
"utf-8",
|
|
50
|
-
);
|
|
51
|
+
let builtCode = fs.readFileSync(path.join(process.cwd(), 'dist', process.env.filePath), 'utf-8')
|
|
51
52
|
|
|
52
53
|
function handleReplacements(code) {
|
|
53
54
|
let lines = code.split("\n");
|
|
54
55
|
let newLines = [];
|
|
55
56
|
for (let line of lines) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
newLines.push(line);
|
|
69
|
-
} catch (error) {
|
|
70
|
-
continue;
|
|
57
|
+
let hasImport = line.includes('import')
|
|
58
|
+
if (hasImport && line.includes('from') && !newLines.includes(line)) {
|
|
59
|
+
try {
|
|
60
|
+
let url = line.includes("'") ? line.split("'")[1] : line.split('"')[1]
|
|
61
|
+
line = line.replace(url, url.replace('.jsx', '.js').replace('.tsx', '.js'))
|
|
62
|
+
line = line.replace(url, url.replace('.ts', '.js').replace('.tsx', '.js'))
|
|
63
|
+
newLines.push(line)
|
|
64
|
+
} catch (error) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
newLines.push(line)
|
|
71
69
|
}
|
|
72
|
-
} else {
|
|
73
|
-
newLines.push(line);
|
|
74
|
-
}
|
|
75
70
|
}
|
|
76
71
|
return newLines.join("\n");
|
|
77
|
-
}
|
|
78
|
-
builtCode = handleReplacements(builtCode)
|
|
79
|
-
fs.writeFileSync(
|
|
80
|
-
path.join(process.cwd(), "dist", process.env.filePath),
|
|
81
|
-
builtCode,
|
|
82
|
-
);
|
|
72
|
+
}
|
|
73
|
+
builtCode = handleReplacements(builtCode)
|
|
74
|
+
fs.writeFileSync(path.join(process.cwd(), 'dist', process.env.filePath), builtCode)
|
|
83
75
|
|
|
84
|
-
let isClass = function (element) {
|
|
85
|
-
return element.toString().startsWith("class");
|
|
76
|
+
let isClass = function (element) {
|
|
77
|
+
return element && element.toString().startsWith("class");
|
|
86
78
|
};
|
|
87
79
|
const generatePage = async (
|
|
88
|
-
data = { path: process.env.INPUT, route: process.env.OUT }
|
|
80
|
+
data = { path: process.env.INPUT, route: process.env.OUT }
|
|
89
81
|
) => {
|
|
90
82
|
const { path, route } = data;
|
|
91
|
-
if (path.includes("root.js")) return;
|
|
83
|
+
if (path.includes("root.js")) return;
|
|
92
84
|
let html = await import(path).then((m) => m.default);
|
|
85
|
+
|
|
93
86
|
let { head } = await import(path).then((m) => m);
|
|
94
87
|
let isFunction = false;
|
|
95
|
-
globalThis.isServer = true;
|
|
96
|
-
if
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
88
|
+
globalThis.isServer = true;
|
|
89
|
+
if(!html){
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
if (isClass(html) ) {
|
|
93
|
+
html = new html();
|
|
94
|
+
html.Mounted = true;
|
|
95
|
+
html = html.render();
|
|
100
96
|
} else {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
97
|
+
isFunction = true;
|
|
98
|
+
let instance = new Component();
|
|
99
|
+
html = html.bind(instance);
|
|
100
|
+
instance.render = html;
|
|
101
|
+
html = instance.render();
|
|
106
102
|
}
|
|
107
103
|
|
|
108
104
|
let h = document(html);
|
|
109
105
|
if (!fs.existsSync(process.cwd() + "/dist" + path2.dirname(route))) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
106
|
+
fs.mkdirSync(process.cwd() + "/dist" + path2.dirname(route), {
|
|
107
|
+
recursive: true,
|
|
108
|
+
});
|
|
113
109
|
}
|
|
114
110
|
let headHtml = "";
|
|
115
111
|
if (head) {
|
|
116
|
-
|
|
112
|
+
headHtml = document(head());
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
if (h.includes("<head>")) {
|
|
118
|
+
h = h.replace("<head>", `<head>${process.env.bindes}`)
|
|
119
|
+
}else{
|
|
120
|
+
h += process.env.bindes
|
|
117
121
|
}
|
|
118
122
|
|
|
119
123
|
await Bun.write(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
import c from '${process.env.filePath}'
|
|
131
|
-
import {render, e} from '/src/vader/index.js'
|
|
132
|
-
window.e = e
|
|
133
|
-
render(c, document.body.firstChild)
|
|
134
|
-
</script>
|
|
135
|
-
`,
|
|
124
|
+
process.cwd() + "/dist/" + route + "/index.html",
|
|
125
|
+
`<!DOCTYPE html>
|
|
126
|
+
${h}
|
|
127
|
+
<script type="module">
|
|
128
|
+
import c from '${process.env.filePath}'
|
|
129
|
+
import {render, e} from '/src/vader/index.js'
|
|
130
|
+
window.e = e
|
|
131
|
+
render(c, document.body.firstChild)
|
|
132
|
+
</script>
|
|
133
|
+
`
|
|
136
134
|
);
|
|
137
135
|
console.log(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
136
|
+
ansiColors.blue(
|
|
137
|
+
`${process.env.filePath.replace(".js", ".jsx")} - ${parseInt(
|
|
138
|
+
process.env.size
|
|
139
|
+
).toFixed(2)}kb`
|
|
140
|
+
)
|
|
143
141
|
);
|
|
144
142
|
process.exit(0);
|
|
145
|
-
};
|
|
146
|
-
try {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
} else if (process.env.isTs == undefined) {
|
|
150
|
-
generatePage({ path: process.env.INPUT, route: process.env.OUT });
|
|
143
|
+
};
|
|
144
|
+
try {
|
|
145
|
+
if (process.env.isJsx == "true" && process.env.isAppFile == "true" ) {
|
|
146
|
+
generatePage({ path: process.env.INPUT, route: process.env.OUT })
|
|
151
147
|
}
|
|
152
148
|
} catch (error) {
|
|
153
|
-
console.log(ansiColors.red(error))
|
|
154
|
-
}
|
|
149
|
+
console.log(ansiColors.red(error))
|
|
150
|
+
}
|
package/index.ts
CHANGED
|
@@ -124,6 +124,8 @@ globalThis.Fragment = Fragment;
|
|
|
124
124
|
* @returns
|
|
125
125
|
*/
|
|
126
126
|
export const e = (element, props, ...children) => {
|
|
127
|
+
if (!element)
|
|
128
|
+
return "";
|
|
127
129
|
let instance;
|
|
128
130
|
switch (true) {
|
|
129
131
|
case isClassComponent(element):
|
|
@@ -135,6 +137,10 @@ export const e = (element, props, ...children) => {
|
|
|
135
137
|
case typeof element === "function":
|
|
136
138
|
instance = new Component;
|
|
137
139
|
instance.render = element;
|
|
140
|
+
if(element.name.toLowerCase() == "default"){
|
|
141
|
+
throw new Error("Function name must be unique")
|
|
142
|
+
}
|
|
143
|
+
instance.key = element.name
|
|
138
144
|
instance.Mounted = true;
|
|
139
145
|
let firstEl = instance.render({ key: instance.key, children, ...props }, children);
|
|
140
146
|
instance.children = children;
|
|
@@ -404,165 +410,213 @@ export class Component {
|
|
|
404
410
|
}
|
|
405
411
|
this.Reconciler.update(el, newl);
|
|
406
412
|
}
|
|
413
|
+
attachEventsRecursively = (element, source) => {
|
|
414
|
+
// Rebind events for the current element
|
|
415
|
+
const events = this.eventRegistry.get(source) || [];
|
|
416
|
+
events.forEach(({ event, handler }) => {
|
|
417
|
+
this.addEventListener(element, event, handler);
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
// Traverse children recursively
|
|
421
|
+
const children = Array.from(source.childNodes || []);
|
|
422
|
+
const elementChildren = Array.from(element.childNodes || []);
|
|
423
|
+
|
|
424
|
+
children.forEach((child, index) => {
|
|
425
|
+
if (elementChildren[index]) {
|
|
426
|
+
this.attachEventsRecursively(elementChildren[index], child);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
|
|
407
432
|
Reconciler = {
|
|
408
|
-
update: (oldElement, newElement) => {
|
|
409
|
-
if (!oldElement || !newElement)
|
|
410
|
-
|
|
433
|
+
update: (oldElement, newElement) => {
|
|
434
|
+
if (!oldElement || !newElement) return;
|
|
435
|
+
|
|
436
|
+
// Check if the current element needs an update
|
|
411
437
|
if (this.Reconciler.shouldUpdate(oldElement, newElement)) {
|
|
412
|
-
|
|
413
|
-
if (oldElement.attributes && Object.keys(oldElement.attributes).length > 0)
|
|
414
|
-
Array.from(oldElement.attributes).forEach(({ name }) => {
|
|
415
|
-
if (!newElement.hasAttribute(name)) {
|
|
416
|
-
oldElement.removeAttribute(name);
|
|
417
|
-
}
|
|
418
|
-
});
|
|
419
|
-
if (newElement.attributes && Object.keys(newElement.attributes).length > 0)
|
|
420
|
-
Array.from(newElement.attributes).forEach(({ name, value }) => {
|
|
421
|
-
if (oldElement.getAttribute(name) !== value) {
|
|
422
|
-
oldElement.setAttribute(name, value);
|
|
423
|
-
}
|
|
424
|
-
});
|
|
425
|
-
if (oldElement.childNodes.length === 1 && oldElement.firstChild.nodeType === Node.TEXT_NODE) {
|
|
426
|
-
if (oldElement.textContent !== newElement.textContent) {
|
|
427
|
-
oldElement.textContent = newElement.textContent;
|
|
428
|
-
}
|
|
429
|
-
return;
|
|
430
|
-
}else if(oldElement.nodeType === Node.TEXT_NODE){
|
|
431
|
-
if (oldElement.textContent !== newElement.textContent) {
|
|
432
|
-
oldElement.textContent = newElement.textContent;
|
|
433
|
-
}
|
|
434
|
-
return;
|
|
435
|
-
}
|
|
438
|
+
// Update attributes
|
|
436
439
|
const oldChildren = Array.from(oldElement.childNodes);
|
|
437
440
|
const newChildren = Array.from(newElement.childNodes);
|
|
441
|
+
|
|
438
442
|
const maxLength = Math.max(oldChildren.length, newChildren.length);
|
|
439
|
-
for (let i = 0;i < maxLength; i++) {
|
|
443
|
+
for (let i = 0; i < maxLength; i++) {
|
|
440
444
|
if (i >= oldChildren.length) {
|
|
441
445
|
const newChildClone = newChildren[i].cloneNode(true);
|
|
442
446
|
oldElement.appendChild(newChildClone);
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
});
|
|
447
|
+
|
|
448
|
+
// Rebind events to the new child (and its children recursively)
|
|
449
|
+
this.attachEventsRecursively(newChildClone, newChildren[i]);
|
|
447
450
|
} else if (i >= newChildren.length) {
|
|
448
451
|
oldElement.removeChild(oldChildren[i]);
|
|
449
452
|
} else {
|
|
450
453
|
this.Reconciler.update(oldChildren[i], newChildren[i]);
|
|
451
454
|
}
|
|
452
455
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
+
|
|
457
|
+
Array.from(oldElement.attributes || []).forEach(({ name }) => {
|
|
458
|
+
if (!newElement.hasAttribute(name)) {
|
|
459
|
+
oldElement.removeAttribute(name);
|
|
460
|
+
}
|
|
456
461
|
});
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
});
|
|
469
|
-
} else if (i >= newChildren.length) {
|
|
470
|
-
oldElement.removeChild(oldChildren[i]);
|
|
471
|
-
} else {
|
|
472
|
-
this.Reconciler.update(oldChildren[i], newChildren[i]);
|
|
462
|
+
|
|
463
|
+
Array.from(newElement.attributes || []).forEach(({ name, value }) => {
|
|
464
|
+
if (oldElement.getAttribute(name) !== value) {
|
|
465
|
+
oldElement.setAttribute(name, value);
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
// Handle text node updates
|
|
470
|
+
if (oldElement.nodeType === Node.TEXT_NODE) {
|
|
471
|
+
if (oldElement.textContent !== newElement.textContent) {
|
|
472
|
+
oldElement.textContent = newElement.textContent;
|
|
473
473
|
}
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// If the element has a single text node, update text directly
|
|
478
|
+
if (
|
|
479
|
+
oldElement.childNodes.length === 1 &&
|
|
480
|
+
oldElement.firstChild.nodeType === Node.TEXT_NODE
|
|
481
|
+
) {
|
|
482
|
+
if (oldElement.textContent !== newElement.textContent) {
|
|
483
|
+
oldElement.textContent = newElement.textContent;
|
|
484
|
+
}
|
|
485
|
+
return;
|
|
474
486
|
}
|
|
475
487
|
}
|
|
488
|
+
|
|
489
|
+
// Process children recursively
|
|
490
|
+
const oldChildren = Array.from(oldElement.childNodes);
|
|
491
|
+
const newChildren = Array.from(newElement.childNodes);
|
|
492
|
+
|
|
493
|
+
const maxLength = Math.max(oldChildren.length, newChildren.length);
|
|
494
|
+
|
|
495
|
+
for (let i = 0; i < maxLength; i++) {
|
|
496
|
+
if (i >= oldChildren.length) {
|
|
497
|
+
// Add new child if it exists in newChildren but not in oldChildren
|
|
498
|
+
const newChildClone = newChildren[i].cloneNode(true);
|
|
499
|
+
oldElement.appendChild(newChildClone);
|
|
500
|
+
|
|
501
|
+
// Attach any event listeners
|
|
502
|
+
const newChildEvents = this.eventRegistry.get(newChildren[i]) || [];
|
|
503
|
+
newChildEvents.forEach(({ type, handler }) => {
|
|
504
|
+
this.addEventListener(newChildClone, type, handler);
|
|
505
|
+
});
|
|
506
|
+
} else if (i >= newChildren.length) {
|
|
507
|
+
// Remove child if it exists in oldChildren but not in newChildren
|
|
508
|
+
oldElement.removeChild(oldChildren[i]);
|
|
509
|
+
} else {
|
|
510
|
+
this.Reconciler.update(oldChildren[i], newChildren[i]);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Reapply events for the current element
|
|
515
|
+
const parentEvents = this.eventRegistry.get(newElement) || [];
|
|
516
|
+
parentEvents.forEach(({ type, handler }) => {
|
|
517
|
+
this.addEventListener(oldElement, type, handler);
|
|
518
|
+
});
|
|
519
|
+
|
|
476
520
|
},
|
|
477
|
-
shouldUpdate: (oldElement, newElement
|
|
521
|
+
shouldUpdate: (oldElement, newElement) => {
|
|
522
|
+
// Check if node types differ
|
|
478
523
|
if (oldElement.nodeType !== newElement.nodeType) {
|
|
479
|
-
return
|
|
524
|
+
return true;
|
|
480
525
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
526
|
+
|
|
527
|
+
// Check if text content differs
|
|
528
|
+
if (oldElement.nodeType === Node.TEXT_NODE) {
|
|
529
|
+
return oldElement.textContent !== newElement.textContent;
|
|
485
530
|
}
|
|
531
|
+
|
|
532
|
+
// Check if node names differ
|
|
486
533
|
if (oldElement.nodeName !== newElement.nodeName) {
|
|
487
534
|
return true;
|
|
488
535
|
}
|
|
536
|
+
|
|
537
|
+
// Check if child counts differ
|
|
489
538
|
if (oldElement.childNodes.length !== newElement.childNodes.length) {
|
|
490
539
|
return true;
|
|
491
540
|
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
541
|
+
|
|
542
|
+
// Check if attributes differ
|
|
543
|
+
const newAttributes = Array.from(newElement.attributes || []);
|
|
544
|
+
for (let { name, value } of newAttributes) {
|
|
545
|
+
if (oldElement.getAttribute(name) !== value) {
|
|
546
|
+
return true;
|
|
498
547
|
}
|
|
499
548
|
}
|
|
549
|
+
|
|
550
|
+
// If no differences found, no update needed
|
|
500
551
|
return false;
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
|
|
552
|
+
},
|
|
553
|
+
}
|
|
554
|
+
|
|
504
555
|
parseToElement = (element) => {
|
|
505
|
-
if (!element) return
|
|
506
|
-
|
|
507
|
-
let
|
|
508
|
-
let
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
556
|
+
if (!element || element.nodeType) return ""
|
|
557
|
+
|
|
558
|
+
let svgTags = ["svg", "path", "circle", "rect", "line", "polyline", "polygon", "ellipse", "g"];
|
|
559
|
+
let isSvg = svgTags.includes(element.type);
|
|
560
|
+
|
|
561
|
+
// Create the element, using proper namespace for SVG
|
|
562
|
+
let el = isSvg
|
|
563
|
+
? document.createElementNS("http://www.w3.org/2000/svg", element.type)
|
|
564
|
+
: document.createElement(element.type);
|
|
565
|
+
|
|
566
|
+
// Handle text nodes
|
|
567
|
+
if (typeof element === "string" || typeof element === "number" || typeof element === "boolean") {
|
|
568
|
+
el.textContent = element; // Safer alternative to innerHTML
|
|
569
|
+
return el;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// Set attributes
|
|
573
|
+
let attributes = element.props || {};
|
|
574
|
+
for (let key in attributes) {
|
|
575
|
+
if (key === "key") {
|
|
576
|
+
el.key = attributes[key];
|
|
577
|
+
} else if (key === "className") {
|
|
578
|
+
el.setAttribute("class", attributes[key]);
|
|
579
|
+
} else if (key === "style") {
|
|
580
|
+
let styleObject = attributes[key];
|
|
581
|
+
if (typeof styleObject === "object") {
|
|
582
|
+
for (let styleKey in styleObject) {
|
|
583
|
+
el.style[styleKey] = styleObject[styleKey];
|
|
531
584
|
}
|
|
532
|
-
continue;
|
|
533
|
-
}
|
|
534
|
-
if (key.startsWith("on")) {
|
|
535
|
-
el.addEventListener(key.substring(2).toLowerCase(), attributes[key]);
|
|
536
|
-
this.eventRegistry.set(el, [...this.eventRegistry.get(el) || [], { event: key.substring(2).toLowerCase(), handler: attributes[key] }]);
|
|
537
|
-
this.addEventListener(el, key.substring(2).toLowerCase(), attributes[key])
|
|
538
|
-
continue;
|
|
539
585
|
}
|
|
586
|
+
} else if (key.startsWith("on")) {
|
|
587
|
+
// Event listeners
|
|
588
|
+
const eventType = key.substring(2).toLowerCase();
|
|
589
|
+
const handler = attributes[key];
|
|
590
|
+
this.eventRegistry.set(el, [...(this.eventRegistry.get(el) || []), { event: eventType, handler }]);
|
|
591
|
+
this.addEventListener(el, eventType, handler);
|
|
592
|
+
} else if (attributes[key] !== null && attributes[key] !== undefined) {
|
|
593
|
+
// General attributes
|
|
540
594
|
el.setAttribute(key, attributes[key]);
|
|
541
595
|
}
|
|
542
|
-
if (children === undefined)
|
|
543
|
-
return el;
|
|
544
|
-
for (let i = 0; i < children.length; i++) {
|
|
545
|
-
let child = children[i];
|
|
546
|
-
if (Array.isArray(child)) {
|
|
547
|
-
child.forEach((c) => {
|
|
548
|
-
el.appendChild(this.parseToElement(c));
|
|
549
|
-
});
|
|
550
|
-
}
|
|
551
|
-
if (typeof child === "function") {
|
|
552
|
-
let comp = memoizeClassComponent(Component);
|
|
553
|
-
comp.Mounted = true;
|
|
554
|
-
comp.render = child;
|
|
555
|
-
let el2 = comp.toElement();
|
|
556
|
-
el2.key = comp.key;
|
|
557
|
-
el.appendChild(el2);
|
|
558
|
-
} else if (typeof child === "object") {
|
|
559
|
-
el.appendChild(this.parseToElement(child));
|
|
560
|
-
} else if (child) {
|
|
561
|
-
let span = document.createTextNode(child)
|
|
562
|
-
el.appendChild(span);
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
596
|
}
|
|
597
|
+
|
|
598
|
+
// Handle children
|
|
599
|
+
let children = element.children || [];
|
|
600
|
+
children.forEach((child) => {
|
|
601
|
+
if (Array.isArray(child)) {
|
|
602
|
+
// Recursively process nested arrays
|
|
603
|
+
child.forEach((nestedChild) => el.appendChild(this.parseToElement(nestedChild)));
|
|
604
|
+
} else if (typeof child === "function") {
|
|
605
|
+
// Handle functional components
|
|
606
|
+
let component = memoizeClassComponent(Component);
|
|
607
|
+
component.Mounted = true;
|
|
608
|
+
component.render = child;
|
|
609
|
+
let componentElement = component.toElement();
|
|
610
|
+
el.appendChild(componentElement);
|
|
611
|
+
} else if (typeof child === "object") {
|
|
612
|
+
// Nested object children
|
|
613
|
+
el.appendChild(this.parseToElement(child));
|
|
614
|
+
} else if (child !== null && child !== undefined) {
|
|
615
|
+
// Text nodes
|
|
616
|
+
el.appendChild(document.createTextNode(child));
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
|
|
566
620
|
return el;
|
|
567
621
|
};
|
|
568
622
|
e(element, props, ...children) {
|
|
@@ -609,10 +663,14 @@ export function render(element, container) {
|
|
|
609
663
|
} else {
|
|
610
664
|
let memoizedInstance = memoizeClassComponent(Component);
|
|
611
665
|
memoizedInstance.Mounted = true;
|
|
612
|
-
memoizedInstance.render = element.bind(memoizedInstance);
|
|
613
|
-
|
|
614
|
-
|
|
666
|
+
memoizedInstance.render = element.bind(memoizedInstance);
|
|
667
|
+
if(element.name == "default"){
|
|
668
|
+
throw new Error("Function name Must be a unique function name as it is used for a element key")
|
|
669
|
+
}
|
|
670
|
+
memoizedInstance.key = element.name
|
|
671
|
+
let el = memoizedInstance.toElement();
|
|
672
|
+
el.key = element.name
|
|
615
673
|
container.innerHTML = "";
|
|
616
674
|
container.replaceWith(el);
|
|
617
675
|
}
|
|
618
|
-
}
|
|
676
|
+
}
|
package/main.js
CHANGED
|
@@ -204,6 +204,7 @@ async function generateApp() {
|
|
|
204
204
|
code = handleReplacements(code)
|
|
205
205
|
let size = code.length / 1024
|
|
206
206
|
r = r.replace(process.cwd().replace(/\\/g, '/') + '/app', '')
|
|
207
|
+
var beforeR = r
|
|
207
208
|
r = r.replace('.jsx', '.js').replace('.tsx', '.js')
|
|
208
209
|
fs.mkdirSync(path.join(process.cwd() + '/dist', path.dirname(r)), { recursive: true })
|
|
209
210
|
fs.writeFileSync(process.cwd() + '/dist/' + path.dirname(r) + '/' + path.basename(r), `
|
|
@@ -227,31 +228,40 @@ async function generateApp() {
|
|
|
227
228
|
fs.writeFileSync(process.cwd() + '/dist/src/vader/index.js', await new Bun.Transpiler({
|
|
228
229
|
loader: 'ts',
|
|
229
230
|
}).transformSync(await Bun.file(require.resolve('vaderjs')).text()))
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
|
|
231
|
+
|
|
232
|
+
try {
|
|
233
|
+
Bun.spawn({
|
|
234
|
+
cmd: ['bun', 'run', './dev/bundler.js'],
|
|
235
|
+
cwd: process.cwd(),
|
|
236
|
+
stdout: 'inherit',
|
|
237
|
+
env: {
|
|
238
|
+
ENTRYPOINT: path.join(process.cwd() + '/dist/' + path.dirname(r) + '/' + path.basename(r)),
|
|
239
|
+
ROOT: process.cwd() + '/app/',
|
|
240
|
+
OUT: path.dirname(r),
|
|
241
|
+
file: process.cwd() + '/dist/' + path.dirname(r) + '/' + path.basename(r),
|
|
242
|
+
DEV: mode === 'development',
|
|
243
|
+
size,
|
|
244
|
+
bindes: bindes.join('\n'),
|
|
245
|
+
isTs: beforeR.endsWith(".tsx"),
|
|
246
|
+
filePath: r,
|
|
247
|
+
|
|
248
|
+
isJsx: beforeR.endsWith('.tsx') || beforeR.endsWith(".jsx") ,
|
|
249
|
+
isAppFile: true,
|
|
250
|
+
INPUT: `../app/${beforeR}`,
|
|
251
|
+
},
|
|
252
|
+
onExit({ exitCode: code }) {
|
|
253
|
+
if (code === 0) {
|
|
254
|
+
bindes = []
|
|
255
|
+
console.log(`Built ${r} in ${Date.now() - start}ms`)
|
|
256
|
+
resolve()
|
|
257
|
+
} else {
|
|
258
|
+
reject()
|
|
259
|
+
}
|
|
252
260
|
}
|
|
253
|
-
}
|
|
254
|
-
})
|
|
261
|
+
})
|
|
262
|
+
} catch (error) {
|
|
263
|
+
|
|
264
|
+
}
|
|
255
265
|
|
|
256
266
|
})
|
|
257
267
|
|
|
@@ -299,8 +309,7 @@ async function generateApp() {
|
|
|
299
309
|
|
|
300
310
|
function handleFiles() {
|
|
301
311
|
return new Promise(async (resolve, reject) => {
|
|
302
|
-
try {
|
|
303
|
-
console.log(Glob)
|
|
312
|
+
try {
|
|
304
313
|
let glob = new Glob('public/**/*')
|
|
305
314
|
for await (var i of glob.scan()) {
|
|
306
315
|
let file = i
|
|
@@ -315,13 +324,13 @@ function handleFiles() {
|
|
|
315
324
|
var file = i
|
|
316
325
|
fs.mkdirSync(path.join(process.cwd() + '/dist', path.dirname(file)), { recursive: true })
|
|
317
326
|
// turn jsx to js
|
|
318
|
-
if (file.
|
|
327
|
+
if (file.endsWith('.jsx') || file.endsWith('.tsx')) {
|
|
319
328
|
let code = await Bun.file(file).text()
|
|
320
329
|
|
|
321
330
|
code = handleReplacements(code)
|
|
322
|
-
|
|
331
|
+
var url = file
|
|
323
332
|
file = file.replace('.jsx', '.js').replace('.tsx', '.js')
|
|
324
|
-
fs.writeFileSync(path.join(process.cwd() + '/dist', file.replace('.jsx', '.js').replace('.tsx', '.js')), code)
|
|
333
|
+
fs.writeFileSync(path.join(process.cwd() + '/dist', file.replace('.jsx', '.js').replace('.tsx', '.js')), code)
|
|
325
334
|
await Bun.spawn({
|
|
326
335
|
cmd: ['bun', 'run', './dev/bundler.js'],
|
|
327
336
|
cwd: process.cwd(),
|
|
@@ -335,8 +344,9 @@ function handleFiles() {
|
|
|
335
344
|
DEV: mode === 'development',
|
|
336
345
|
size: code.length / 1024,
|
|
337
346
|
filePath: file.replace('.jsx', '.js'),
|
|
338
|
-
|
|
339
|
-
|
|
347
|
+
isJsx: url.endsWith('.tsx') || url.endsWith(".jsx") ,
|
|
348
|
+
isAppFile: false,
|
|
349
|
+
INPUT: path.join(process.cwd(), url),
|
|
340
350
|
},
|
|
341
351
|
onExit({ exitCode: code }) {
|
|
342
352
|
if (code === 0) {
|
|
@@ -346,7 +356,7 @@ function handleFiles() {
|
|
|
346
356
|
}
|
|
347
357
|
}
|
|
348
358
|
})
|
|
349
|
-
} else if (file.
|
|
359
|
+
} else if (file.endsWith('.ts')) {
|
|
350
360
|
let code = await Bun.file(file).text()
|
|
351
361
|
code = handleReplacements(code)
|
|
352
362
|
file = file.replace('.ts', '.js')
|
|
@@ -528,4 +538,4 @@ if (mode == 'development' || mode == 'serve') {
|
|
|
528
538
|
})
|
|
529
539
|
|
|
530
540
|
console.log(ansiColors.green('Server started at http://localhost:' + port || 8080))
|
|
531
|
-
}
|
|
541
|
+
}
|