vaderjs 1.3.3-alpha-1 → 1.3.3-alpha-3
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 +2 -2
- package/vader.js +777 -0
- package/vader +0 -0
package/package.json
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
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-alpha-
|
|
5
|
+
"version": "1.3.3-alpha-3",
|
|
6
6
|
"bin": {
|
|
7
|
-
"vader": "./vader"
|
|
7
|
+
"vader": "./vader.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "bunx vader --build",
|
package/vader.js
ADDED
|
@@ -0,0 +1,777 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import fs, { watchFile } from "fs";
|
|
4
|
+
|
|
5
|
+
import { Glob } from "bun";
|
|
6
|
+
let bundleSize = 0;
|
|
7
|
+
switch (true) {
|
|
8
|
+
case !fs.existsSync(process.cwd() + "/pages"):
|
|
9
|
+
fs.mkdirSync(process.cwd() + "/pages");
|
|
10
|
+
break;
|
|
11
|
+
case !fs.existsSync(process.cwd() + "/dist"):
|
|
12
|
+
fs.mkdirSync(process.cwd() + "/dist");
|
|
13
|
+
console.log("Created dist folder");
|
|
14
|
+
case !fs.existsSync(process.cwd() + "/public"):
|
|
15
|
+
fs.mkdirSync(process.cwd() + "/public");
|
|
16
|
+
break;
|
|
17
|
+
case !fs.existsSync(process.cwd() + "/src"):
|
|
18
|
+
fs.mkdirSync(process.cwd() + "/src");
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function Compiler(func) {
|
|
23
|
+
let string = func;
|
|
24
|
+
let comments = string
|
|
25
|
+
|
|
26
|
+
.match(/\{\s*\/\*.*\*\/\s*}/gs)
|
|
27
|
+
?.map((comment) => comment.trim());
|
|
28
|
+
|
|
29
|
+
let savedfuncnames = [];
|
|
30
|
+
let functions = string
|
|
31
|
+
.match(
|
|
32
|
+
/(?:const|let)\s*([a-zA-Z0-9_-]+)\s*=\s*function\s*\(([^)]*)\)|function\s*([a-zA-Z0-9_-]+)\s*\(([^)]*)\)/gs
|
|
33
|
+
)
|
|
34
|
+
?.map((match) => match.trim());
|
|
35
|
+
|
|
36
|
+
let functionNames = [];
|
|
37
|
+
|
|
38
|
+
if (functions) {
|
|
39
|
+
functions.forEach((func) => {
|
|
40
|
+
if (
|
|
41
|
+
!func.match(
|
|
42
|
+
/(?:const|let)\s*([a-zA-Z0-9_-]+)\s*=\s*function\s*\(([^)]*)\)|function\s*([a-zA-Z0-9_-]+)\s*\(([^)]*)\)/gs
|
|
43
|
+
)
|
|
44
|
+
) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
let code = string;
|
|
48
|
+
|
|
49
|
+
let name = func.split(" ")[1].split("(")[0].trim();
|
|
50
|
+
|
|
51
|
+
let lines = string.match(/return\s*\<>.*\<\/>/gs);
|
|
52
|
+
|
|
53
|
+
if (lines) {
|
|
54
|
+
for (let i = 0; i < lines.length; i++) {
|
|
55
|
+
let line = lines[i];
|
|
56
|
+
|
|
57
|
+
if (!functionNames.includes(name)) {
|
|
58
|
+
functionNames.push(name);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// get all Obj({}) and parse to JSON.stringify
|
|
65
|
+
|
|
66
|
+
let objects = string.match(/Obj\({.*}\)/gs);
|
|
67
|
+
if (objects) {
|
|
68
|
+
objects.forEach((obj) => {
|
|
69
|
+
let key = obj.split("Obj")[1].split("(")[1].split(")")[0].trim();
|
|
70
|
+
let newobj = obj.replaceAll(`Obj(${key})`, `${key}`);
|
|
71
|
+
// let newobj = obj.replaceAll(`Obj(${key})`, `JSON.parse('${key}')`)
|
|
72
|
+
string = string.replaceAll(obj, `this.handleObject('${newobj}')`);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let childs = [];
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
function extractAttributes(code) {
|
|
80
|
+
// Match elements with opening tags
|
|
81
|
+
const elementRegex = /<([a-zA-Z0-9_-]+)([^>]*)>/gs;
|
|
82
|
+
|
|
83
|
+
// Match attributes in an opening tag, including those with ={}
|
|
84
|
+
// Match attributes in an opening tag, including those with ={...}
|
|
85
|
+
const attributeRegex =
|
|
86
|
+
/\s*([a-zA-Z0-9_-]+)(\s*=\s*("([^"\\]*(\\.[^"\\]*)*)"|'([^'\\]*(\\.[^'\\]*)*)'|\{(?:[^{}]|(?:\{(?:[^{}]|(?:\{[^{}]*\})*)*\})*)*\}|(?:\([^)]*\)|\{[^}]*\}|()=>\s*(?:\{[^}]*\})?)|\[[^\]]*\]))?/gs;
|
|
87
|
+
|
|
88
|
+
// only return elements with attribute {()=>{}} or if it also has parameters ex: onclick={(event)=>{console.log(event)}} also get muti line functions
|
|
89
|
+
const functionAttributeRegex =
|
|
90
|
+
/\s*([a-zA-Z0-9_-]+)(\s*=\s*{(?:[^{}]|(?:\{(?:[^{}]|(?:\{[^{}]*\})*)*\})*)*})/gs;
|
|
91
|
+
|
|
92
|
+
let attributesList = [];
|
|
93
|
+
|
|
94
|
+
// handle functions
|
|
95
|
+
let functionAttributes = [];
|
|
96
|
+
let functionMatch;
|
|
97
|
+
while ((functionMatch = functionAttributeRegex.exec(code)) !== null) {
|
|
98
|
+
let [, attributeName, attributeValue] = functionMatch;
|
|
99
|
+
let attribute = {};
|
|
100
|
+
|
|
101
|
+
if (attributeValue && attributeValue.includes("=>")) {
|
|
102
|
+
let ref = Math.random().toString(36).substring(2);
|
|
103
|
+
let old = `${attributeName}${attributeValue}`;
|
|
104
|
+
|
|
105
|
+
let newvalue =
|
|
106
|
+
attributeValue.split("=>")[1] || attributeValue.split("=>")[1].trim();
|
|
107
|
+
|
|
108
|
+
newvalue = newvalue.trim();
|
|
109
|
+
|
|
110
|
+
//remove starting {
|
|
111
|
+
newvalue = newvalue.replace("{", "");
|
|
112
|
+
|
|
113
|
+
let params = attributeValue
|
|
114
|
+
.split("=>")[0]
|
|
115
|
+
.split("(")[1]
|
|
116
|
+
.split(")")[0]
|
|
117
|
+
.trim();
|
|
118
|
+
let functionparams = [];
|
|
119
|
+
// split first {}
|
|
120
|
+
newvalue = newvalue.trim();
|
|
121
|
+
|
|
122
|
+
if (newvalue.startsWith("{")) {
|
|
123
|
+
newvalue = newvalue.split("{")[1];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
switch(true){
|
|
127
|
+
case newvalue.endsWith("}}"):
|
|
128
|
+
newvalue = newvalue.replace("}}", "");
|
|
129
|
+
break;
|
|
130
|
+
case newvalue.endsWith("}"):
|
|
131
|
+
newvalue = newvalue.replace("}", "");
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
if (functionNames.length > 0) {
|
|
138
|
+
functionNames.forEach((name) => {
|
|
139
|
+
string.split("\n").forEach((line) => {
|
|
140
|
+
if (line.includes(name) && line.includes("function")) {
|
|
141
|
+
line = line.trim();
|
|
142
|
+
line = line.replace(/\s+/g, " ");
|
|
143
|
+
|
|
144
|
+
let ps = line.split("(").slice(1).join("(").split(")")[0].trim();
|
|
145
|
+
|
|
146
|
+
// remove comments
|
|
147
|
+
ps = ps.match(/\/\*.*\*\//gs)
|
|
148
|
+
? ps.replace(ps.match(/\/\*.*\*\//gs)[0], "")
|
|
149
|
+
: ps;
|
|
150
|
+
|
|
151
|
+
functionparams.push({ ref: ref, name: name, params: ps });
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
newvalue = newvalue.trim();
|
|
155
|
+
let lines = newvalue.split("\n");
|
|
156
|
+
|
|
157
|
+
for (let i = 0; i < lines.length; i++) {
|
|
158
|
+
let line = lines[i];
|
|
159
|
+
|
|
160
|
+
if (line.includes(name) && !line.includes("useFunction")) {
|
|
161
|
+
let hasParams = line.includes("(") && line.includes(")");
|
|
162
|
+
let params = hasParams
|
|
163
|
+
? line.split("(")[1].split(")")[0].trim()
|
|
164
|
+
: null;
|
|
165
|
+
|
|
166
|
+
if (
|
|
167
|
+
functionparams.length > 0 &&
|
|
168
|
+
functionparams.find((p) => p.name == name)
|
|
169
|
+
) {
|
|
170
|
+
let params = functionparams.find((p) => p.name == name).params;
|
|
171
|
+
line.includes(params) ? (params = params) : (params = null);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
let elementMatch = string.match(/<([a-zA-Z0-9_-]+)([^>]*)>/gs);
|
|
175
|
+
let isJSXComponent = false;
|
|
176
|
+
elementMatch.forEach((element) => {
|
|
177
|
+
element = element.trim().replace(/\s+/g, " ");
|
|
178
|
+
if (element.includes(attributeName)) {
|
|
179
|
+
let elementTag = element
|
|
180
|
+
.split("<")[1]
|
|
181
|
+
.split(">")[0]
|
|
182
|
+
.split(" ")[0];
|
|
183
|
+
isJSXComponent = elementTag.match(/^[A-Z]/) ? true : false;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
let replacement = `this.useFunction(${name} ${isJSXComponent ? "" : ","
|
|
188
|
+
} ${params || null}${isJSXComponent ? "" : ","} true ${isJSXComponent ? "" : ","
|
|
189
|
+
} '${ref}')`;
|
|
190
|
+
|
|
191
|
+
newvalue = newvalue.replace(
|
|
192
|
+
hasParams ? `${name}(${params})` : name,
|
|
193
|
+
`this.callFunction(\${${replacement}}, ${isJSXComponent ? true : false
|
|
194
|
+
}, event,${params || null})`
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
params = params.match(/\/\*.*\*\//gs)
|
|
200
|
+
? params.replace(params.match(/\/\*.*\*\//gs)[0], "")
|
|
201
|
+
: params;
|
|
202
|
+
|
|
203
|
+
// get full element with function from string
|
|
204
|
+
let elementMatch = string.match(/<([a-zA-Z0-9_-]+)([^>]*)>/gs);
|
|
205
|
+
let isJSXComponent = false;
|
|
206
|
+
elementMatch.forEach((element) => {
|
|
207
|
+
element = element.trim().replace(/\s+/g, " ");
|
|
208
|
+
if (element.includes(attributeName)) {
|
|
209
|
+
let elementTag = element
|
|
210
|
+
.split("<")[1]
|
|
211
|
+
.split(">")[0]
|
|
212
|
+
.split(" ")[0];
|
|
213
|
+
isJSXComponent = elementTag.match(/^[A-Z]/) ? true : false;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
let otherdata = {};
|
|
221
|
+
params ? (otherdata["params"] = params) : null;
|
|
222
|
+
otherdata["jsx"] = isJSXComponent;
|
|
223
|
+
otherdata["ref"] = ref;
|
|
224
|
+
|
|
225
|
+
newvalue = newvalue.replaceAll(/\s+/g, "\n");
|
|
226
|
+
let newatribute = `${attributeName}="\${this.bind(\`${newvalue}\` ${isJSXComponent ? "" : ","
|
|
227
|
+
}${JSON.stringify(otherdata)} )}"`;
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
attribute[attributeName] = {
|
|
231
|
+
old: old,
|
|
232
|
+
new: newatribute,
|
|
233
|
+
attribute: attributeName,
|
|
234
|
+
};
|
|
235
|
+
attributesList.push({
|
|
236
|
+
element: attributeName,
|
|
237
|
+
attributes: attribute,
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
let elementMatch = string.match(/<([a-zA-Z0-9_-]+)([^>]*)>/gs);
|
|
243
|
+
let isJSXComponent = false;
|
|
244
|
+
elementMatch.forEach((element) => {
|
|
245
|
+
element = element.trim().replace(/\s+/g, " ");
|
|
246
|
+
if (element.includes(attributeName)) {
|
|
247
|
+
let elementTag = element
|
|
248
|
+
.split("<")[1]
|
|
249
|
+
.split(">")[0]
|
|
250
|
+
.split(" ")[0];
|
|
251
|
+
isJSXComponent = elementTag.match(/^[A-Z]/) ? true : false;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
let otherdata = {};
|
|
258
|
+
params ? (otherdata["params"] = params) : null;
|
|
259
|
+
otherdata["jsx"] = isJSXComponent;
|
|
260
|
+
otherdata["ref"] = ref;
|
|
261
|
+
newvalue = newvalue.replaceAll(/\s+/g, ";");
|
|
262
|
+
let newattribute = `${attributeName}="\${this.bind(\`${newvalue}\`, ${isJSXComponent ? "" : ","}${JSON.stringify(otherdata)} )}"`;
|
|
263
|
+
newattribute = newattribute.replace(/\s+/g, " ")
|
|
264
|
+
string = string.replace(old, newattribute);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
let match;
|
|
270
|
+
while ((match = elementRegex.exec(code)) !== null) {
|
|
271
|
+
let [, element, attributes] = match;
|
|
272
|
+
|
|
273
|
+
let attributesMatch;
|
|
274
|
+
let elementAttributes = {};
|
|
275
|
+
|
|
276
|
+
while ((attributesMatch = attributeRegex.exec(attributes)) !== null) {
|
|
277
|
+
let [, attributeName, attributeValue] = attributesMatch;
|
|
278
|
+
|
|
279
|
+
elementAttributes[attributeName] = attributeValue || null;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
attributesList.push({ element, attributes: elementAttributes });
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return attributesList;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function extractOuterReturn(code) {
|
|
289
|
+
// match return [...]
|
|
290
|
+
let returns = code.match(/return\s*\<>.*\<\/>/gs);
|
|
291
|
+
|
|
292
|
+
return returns || [];
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
let outerReturn = extractOuterReturn(string);
|
|
296
|
+
let contents = "";
|
|
297
|
+
let updatedContents = "";
|
|
298
|
+
outerReturn.forEach((returnStatement) => {
|
|
299
|
+
let lines = returnStatement.split("\n");
|
|
300
|
+
|
|
301
|
+
for (let i = 0; i < lines.length; i++) {
|
|
302
|
+
let line = lines[i];
|
|
303
|
+
if (line.match(/return\s*\<>/gs)) {
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
contents += line + "\n";
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Remove trailing ']'
|
|
310
|
+
contents = contents.trim().replace(/\]$/, "");
|
|
311
|
+
updatedContents = contents;
|
|
312
|
+
let attributes = extractAttributes(contents);
|
|
313
|
+
|
|
314
|
+
let newAttributes = [];
|
|
315
|
+
let oldAttributes = [];
|
|
316
|
+
attributes.forEach((attribute) => {
|
|
317
|
+
const { element, attributes } = attribute;
|
|
318
|
+
if (Object.keys(attributes).length === 0) return;
|
|
319
|
+
|
|
320
|
+
newAttributes.push(attribute);
|
|
321
|
+
for (let key in attributes) {
|
|
322
|
+
|
|
323
|
+
let value = attributes[key];
|
|
324
|
+
let oldvalue = value;
|
|
325
|
+
if (value && !value.new) {
|
|
326
|
+
if (value && value.includes("{")) {
|
|
327
|
+
value = value.replace("=", "");
|
|
328
|
+
value == "undefined" ? (value = '"') : (value = value);
|
|
329
|
+
key == 'style' ? value = `{this.parseStyle({${value.split('{{')[1].split('}}')[0]}})}` : null
|
|
330
|
+
|
|
331
|
+
value = `="\$${value}"`;
|
|
332
|
+
string = string.replace(oldvalue, value);
|
|
333
|
+
|
|
334
|
+
} else if (value && value.includes("`")) {
|
|
335
|
+
value = value.replace("=", "");
|
|
336
|
+
|
|
337
|
+
value = `"\$${value}"`;
|
|
338
|
+
string = string.replace(oldvalue, value);
|
|
339
|
+
|
|
340
|
+
}
|
|
341
|
+
} else if (value && value.new) {
|
|
342
|
+
let newvalue = value.new;
|
|
343
|
+
let old = value.old;
|
|
344
|
+
string = string.replace(old, newvalue);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
let retursnString = [];
|
|
351
|
+
let outerReturnString = extractOuterReturn(string);
|
|
352
|
+
|
|
353
|
+
outerReturnString.forEach((returnStatement) => {
|
|
354
|
+
let lines = returnStatement.split("\n");
|
|
355
|
+
let code = "";
|
|
356
|
+
for (let i = 0; i < lines.length; i++) {
|
|
357
|
+
let line = lines[i];
|
|
358
|
+
if (line.match(/return\s*\<>/gs)) {
|
|
359
|
+
}
|
|
360
|
+
code += line + "\n";
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
code = code.trim().replace(/\<\/\>$/, "");
|
|
364
|
+
retursnString.push(code);
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
retursnString.forEach((returnStatement, index) => {
|
|
368
|
+
let old = outerReturnString[index];
|
|
369
|
+
|
|
370
|
+
let newReturn = `${returnStatement}</>`;
|
|
371
|
+
string = string.replace(old, newReturn);
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
if (comments) {
|
|
375
|
+
comments.forEach((comment) => {
|
|
376
|
+
let before = comment.trim();
|
|
377
|
+
|
|
378
|
+
comment = comment.replaceAll(/\s+/g, " ");
|
|
379
|
+
comment = comment.trim();
|
|
380
|
+
string = string.replace(before, comment);
|
|
381
|
+
let to_remove = comment.split("{")[1].split("}")[0].trim();
|
|
382
|
+
let beforeComment = comment;
|
|
383
|
+
comment = comment.replaceAll(`{ ${to_remove} }`, "");
|
|
384
|
+
|
|
385
|
+
string = string.replace(beforeComment, comment);
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
let lines = string.split("\n");
|
|
389
|
+
lines.forEach((line) => {
|
|
390
|
+
if (
|
|
391
|
+
line.includes("let") ||
|
|
392
|
+
line.includes("const") ||
|
|
393
|
+
line.includes("var")
|
|
394
|
+
) {
|
|
395
|
+
if (line.includes("useState") && !line.includes("import")) {
|
|
396
|
+
line = line.trim();
|
|
397
|
+
// derive [key, value] from line
|
|
398
|
+
let type = line.split(" ")[0];
|
|
399
|
+
let key = line
|
|
400
|
+
.split("=")[0]
|
|
401
|
+
.split(" ")[1]
|
|
402
|
+
.trim()
|
|
403
|
+
.replace("[", "")
|
|
404
|
+
.replace(",", "");
|
|
405
|
+
let setKey = line.split("=")[0].split(",")[1].trim().replace("]", "");
|
|
406
|
+
|
|
407
|
+
key = key.replace("[", "").replace(",", "");
|
|
408
|
+
let value = line
|
|
409
|
+
.split("=")[1]
|
|
410
|
+
.split("useState")[1]
|
|
411
|
+
.split("(")[1]
|
|
412
|
+
.split(")")[0]
|
|
413
|
+
.trim();
|
|
414
|
+
let newState = `${type} [${key}, ${setKey}] = this.useState('${key}', ${value})
|
|
415
|
+
this.${key} = ${key}
|
|
416
|
+
this.${setKey} = ${setKey}
|
|
417
|
+
`;
|
|
418
|
+
|
|
419
|
+
// get setkey calls and replace with this.setKey
|
|
420
|
+
string.split("\n").forEach((line) => {
|
|
421
|
+
if (line.includes(setKey) && !line.includes("useState")) {
|
|
422
|
+
string = string.replace(line, line);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (line.includes(key)) {
|
|
426
|
+
line = line.replace(key, `this.states['${key}']`);
|
|
427
|
+
|
|
428
|
+
string = string.replace(line, line);
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
string = string.replace(line, newState);
|
|
432
|
+
} else if (line.includes("useRef")) {
|
|
433
|
+
line = line.trim();
|
|
434
|
+
// let ref = useRef(null)
|
|
435
|
+
let type = line.split(" ")[0];
|
|
436
|
+
let key = line.split("=")[0].split(" ")[1].trim();
|
|
437
|
+
let value = line
|
|
438
|
+
.split("=")[1]
|
|
439
|
+
.split("useRef")[1]
|
|
440
|
+
.split("(")[1]
|
|
441
|
+
.split(")")[0]
|
|
442
|
+
.trim();
|
|
443
|
+
let newState = `${type} ${key} = this.useRef('${key}', ${value})`;
|
|
444
|
+
|
|
445
|
+
string = string.replace(line, newState);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
// create a polyfill for Array.prototype.filter
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* @method Delete
|
|
454
|
+
* @param {*} item
|
|
455
|
+
* @returns {Array} array
|
|
456
|
+
* @description Delete an item from an array
|
|
457
|
+
*/
|
|
458
|
+
Array.prototype.delete = function (item) {
|
|
459
|
+
let array = this;
|
|
460
|
+
array.forEach((i, index) => {
|
|
461
|
+
switch (true) {
|
|
462
|
+
case typeof i === "object":
|
|
463
|
+
if (JSON.stringify(i) === JSON.stringify(item)) {
|
|
464
|
+
array.splice(index, 1);
|
|
465
|
+
}
|
|
466
|
+
break;
|
|
467
|
+
default:
|
|
468
|
+
if (i === item) {
|
|
469
|
+
array.splice(index, 1);
|
|
470
|
+
}
|
|
471
|
+
break;
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
return array;
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
// capture <Component />, <Component></Component>, and <Component>content</Component>
|
|
479
|
+
|
|
480
|
+
// Example usage
|
|
481
|
+
function parseComponents(body, isChild) {
|
|
482
|
+
let componentRegex =
|
|
483
|
+
/<([A-Z][a-zA-Z0-9_-]+)([^>]*)\/>|<([A-Z][a-zA-Z0-9_-]+)([^>]*)>(.*?)<\/\3>/gs;
|
|
484
|
+
|
|
485
|
+
let componentMatch = body.match(componentRegex);
|
|
486
|
+
let topComponent = "";
|
|
487
|
+
componentMatch?.forEach(async (component) => {
|
|
488
|
+
const rewriter = new HTMLRewriter();
|
|
489
|
+
let [, element, attributes] = component;
|
|
490
|
+
|
|
491
|
+
!isChild ? (topComponent = component) : null;
|
|
492
|
+
let before = component;
|
|
493
|
+
component = component.trim().replace(/\s+/g, " ");
|
|
494
|
+
|
|
495
|
+
let myChildrens = [];
|
|
496
|
+
|
|
497
|
+
let name = component.split("<")[1].split(">")[0].split(" ")[0].replace("/", "");
|
|
498
|
+
let props = component.split(`<${name}`)[1].split(">")[0].trim();
|
|
499
|
+
|
|
500
|
+
let savedname = name;
|
|
501
|
+
let children = props
|
|
502
|
+
? component
|
|
503
|
+
.split(`<${name}`)[1]
|
|
504
|
+
.split(`${props}`)[1]
|
|
505
|
+
.split(`</${name}>`)[0]
|
|
506
|
+
.trim()
|
|
507
|
+
.replace(">", "")
|
|
508
|
+
: component.split(`<${name}`)[1].split(`</${name}>`)[0].trim().replace(">", "");
|
|
509
|
+
name = name + Math.random().toString(36).substring(2);
|
|
510
|
+
if (children && children.match(componentRegex)) {
|
|
511
|
+
children = parseComponents(children, true);
|
|
512
|
+
childs.push({ parent: name, children: children });
|
|
513
|
+
} else {
|
|
514
|
+
|
|
515
|
+
children = `\`${children}\`,`;
|
|
516
|
+
children ? childs.push({ parent: name, children: children }) : null;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
childs.forEach((child) => {
|
|
520
|
+
if (child.parent == name) {
|
|
521
|
+
let html = child.children.match(
|
|
522
|
+
/<([a-zA-Z0-9_-]+)([^>]*)>(.*?)<\/\1>/gs
|
|
523
|
+
);
|
|
524
|
+
if (html) {
|
|
525
|
+
html = html.map((h) => h.trim().replace(/\s+/g, " ")).join(" ");
|
|
526
|
+
let before = child.children;
|
|
527
|
+
child.children = child.children.replaceAll(html, `${html}`);
|
|
528
|
+
// remove duplicate quotes
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
myChildrens.push(child.children);
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
props = props
|
|
536
|
+
.replaceAll("=", ":")
|
|
537
|
+
.replaceAll('"', "'")
|
|
538
|
+
.replaceAll(" ", ",")
|
|
539
|
+
.replaceAll(",,", ',')
|
|
540
|
+
.replaceAll("className", "class")
|
|
541
|
+
.replaceAll("classname", "class")
|
|
542
|
+
.replaceAll("'${", "")
|
|
543
|
+
.replaceAll("}'", "")
|
|
544
|
+
.split("$:")
|
|
545
|
+
.join("")
|
|
546
|
+
.replaceAll("-", "");
|
|
547
|
+
|
|
548
|
+
//remove trailing /
|
|
549
|
+
props = props.replace("/", "");
|
|
550
|
+
let replace = "";
|
|
551
|
+
replace = isChild
|
|
552
|
+
? `this.memoize(this.createComponent(${savedname.replaceAll('/', '')}, {${props}}, [${myChildrens.length > 0 ? myChildrens.join(",") : ""
|
|
553
|
+
}])),`
|
|
554
|
+
: `\${this.memoize(this.createComponent(${savedname.replaceAll('/', '')}, {${props}}, [${myChildrens.length > 0 ? myChildrens.join(",") : ""
|
|
555
|
+
}]))}`;
|
|
556
|
+
|
|
557
|
+
body = body.replace(before, replace);
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
return body;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
string = string.replaceAll("<>", "`").replaceAll("</>", "`");
|
|
566
|
+
string = parseComponents(string);
|
|
567
|
+
|
|
568
|
+
string = string
|
|
569
|
+
.replaceAll("className", "class")
|
|
570
|
+
.replaceAll("classname", "class");
|
|
571
|
+
|
|
572
|
+
string += `\n\n //wascompiled`;
|
|
573
|
+
|
|
574
|
+
string = string.replaceAll("undefined", "");
|
|
575
|
+
|
|
576
|
+
return string;
|
|
577
|
+
}
|
|
578
|
+
let bindings = []
|
|
579
|
+
globalThis.isBuilding = false
|
|
580
|
+
async function Build() {
|
|
581
|
+
globalThis.isBuilding = true
|
|
582
|
+
console.log('Compiling......')
|
|
583
|
+
let reader = async (file) => {
|
|
584
|
+
let text = await Bun.file(file).text();
|
|
585
|
+
return text;
|
|
586
|
+
};
|
|
587
|
+
let writer = async (file, data) => {
|
|
588
|
+
await Bun.write(file, data);
|
|
589
|
+
|
|
590
|
+
return { _written: true };
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
const glob = new Glob("**/*.{jsx,js}");
|
|
595
|
+
for await (let file of glob.scan({ cwd: process.cwd() + '/pages/', absolute: true })) {
|
|
596
|
+
let origin = file.split(process.cwd())[1] || file
|
|
597
|
+
file = file.split(process.cwd() + '/pages/')[1]
|
|
598
|
+
bindings[file] = ''
|
|
599
|
+
const router = new Bun.FileSystemRouter({
|
|
600
|
+
style: "nextjs",
|
|
601
|
+
dir: process.cwd() + "/pages/",
|
|
602
|
+
origin: process.env.ORIGIN || "http://localhost:3000",
|
|
603
|
+
assetPrefix: "_next/static/",
|
|
604
|
+
fileExtensions: [".jsx", ".js"],
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
let m = router.match(origin.includes('/pages/index.jsx') ? '/' : '/' + file)
|
|
609
|
+
router.reload()
|
|
610
|
+
|
|
611
|
+
if (!m) {
|
|
612
|
+
console.error(`Error: ${file} is not a valid route\nFollow Proper Routing Structure:
|
|
613
|
+
`)
|
|
614
|
+
console.info(`
|
|
615
|
+
/pages/index.jsx
|
|
616
|
+
/pages/folder/index.jsx
|
|
617
|
+
/pages/folder/[param].jsx
|
|
618
|
+
`)
|
|
619
|
+
process.exit(1)
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
let writtenpath = ''
|
|
624
|
+
// change /home/[app].jsx to /home
|
|
625
|
+
m && m.kind === 'dynamic' ? writtenpath = m.pathname.split('[')[0] : null
|
|
626
|
+
|
|
627
|
+
let obj = {
|
|
628
|
+
filePath: m.filePath,
|
|
629
|
+
kind: m.kind,
|
|
630
|
+
params: m.params,
|
|
631
|
+
query: m.query,
|
|
632
|
+
scriptSrc: m.scriptSrc,
|
|
633
|
+
src: m.src,
|
|
634
|
+
pathname: writtenpath || m.pathname,
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
let data = await reader(process.cwd() + "/pages/" + file)
|
|
638
|
+
data = Compiler(data)
|
|
639
|
+
await writer(process.cwd() + "/dist/pages/" + file, data);
|
|
640
|
+
let params = obj.params ? Object.keys(obj.params).map((r) => {
|
|
641
|
+
r = r.replace('[', '').replace(']', '')
|
|
642
|
+
return `:${r}`
|
|
643
|
+
}) : ''
|
|
644
|
+
|
|
645
|
+
obj.pathname === '//' ? obj.pathname = '/' : null
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
let js = `
|
|
650
|
+
router.get('${obj.pathname.includes('.jsx') ? obj.pathname.replace('.jsx', '') + params : obj.pathname + params}', async (req, res) => {
|
|
651
|
+
res.render(await require('./pages/${file}'), req, res)
|
|
652
|
+
})
|
|
653
|
+
//@desc ${obj.filePath}
|
|
654
|
+
` + '\n'
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
let before = await Bun.file(process.cwd() + "/dist/app.js").exists() ? await reader(process.cwd() + "/dist/app.js") : ''
|
|
659
|
+
|
|
660
|
+
let newfile = before + '\n' + js
|
|
661
|
+
if (!before.includes(`//@desc ${obj.filePath}`)) {
|
|
662
|
+
await writer(process.cwd() + "/dist/app.js", newfile);
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
const gb = new Glob("*");
|
|
668
|
+
const scannedSourceFiles = await Array.fromAsync(gb.scan({ cwd: process.cwd() + '/src/', absolute: true }));
|
|
669
|
+
scannedSourceFiles.forEach(async (file) => {
|
|
670
|
+
|
|
671
|
+
file = file.split(process.cwd() + '/src/')[1]
|
|
672
|
+
let data = await reader(process.cwd() + "/src/" + file)
|
|
673
|
+
bundleSize += fs.statSync(process.cwd() + "/src/" + file).size;
|
|
674
|
+
if(file.endsWith('.jsx')){
|
|
675
|
+
data = Compiler(data)
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
await writer(process.cwd() + "/dist/src/" + file, data);
|
|
679
|
+
})
|
|
680
|
+
|
|
681
|
+
const scannedPublicFiles = await Array.fromAsync(gb.scan({ cwd: process.cwd() + '/public/', absolute: true }));
|
|
682
|
+
scannedPublicFiles.forEach(async (file) => {
|
|
683
|
+
file = file.split(process.cwd() + '/public/')[1]
|
|
684
|
+
let data = await reader(process.cwd() + "/public/" + file)
|
|
685
|
+
bundleSize += fs.statSync(process.cwd() + "/public/" + file).size;
|
|
686
|
+
await writer(process.cwd() + "/dist/public/" + file, data);
|
|
687
|
+
})
|
|
688
|
+
const scannedFiles = await Array.fromAsync(gb.scan({ cwd: process.cwd() + '/node_modules/vaderjs/' + './runtime/static' }));
|
|
689
|
+
const scannedVaderFiles = await Array.fromAsync(
|
|
690
|
+
gb.scan({ cwd: process.cwd() + '/node_modules/vaderjs/' + "/runtime/" })
|
|
691
|
+
);
|
|
692
|
+
|
|
693
|
+
if (!fs.existsSync(process.cwd() + "/dist/index.html")) {
|
|
694
|
+
scannedFiles.forEach(async (file) => {
|
|
695
|
+
|
|
696
|
+
if (file === "app.js") {
|
|
697
|
+
return
|
|
698
|
+
}
|
|
699
|
+
bundleSize += fs.statSync(process.cwd() + '/node_modules/vaderjs/' + "/runtime/static/" + file).size;
|
|
700
|
+
let data = await reader(process.cwd() + '/node_modules/vaderjs/' + "/runtime/static/" + file);
|
|
701
|
+
await writer(process.cwd() + "/dist/" + file, data);
|
|
702
|
+
});
|
|
703
|
+
scannedVaderFiles.forEach(async (file) => {
|
|
704
|
+
bundleSize += fs.statSync(
|
|
705
|
+
process.cwd() + '/node_modules/vaderjs/' + "/runtime/" + file
|
|
706
|
+
).size;
|
|
707
|
+
let data = await reader(process.cwd() + '/node_modules/vaderjs/' + "/runtime/" + file);
|
|
708
|
+
await writer(process.cwd() + "/dist/public/vader/" + file, data);
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
if (!fs.existsSync(process.cwd() + "/dist/index.html")) {
|
|
714
|
+
scannedFiles.forEach(async (file) => {
|
|
715
|
+
|
|
716
|
+
bundleSize += fs.statSync(process.cwd() + '/node_modules/vaderjs/' + "/runtime/static/" + file).size;
|
|
717
|
+
let data = await reader(process.cwd() + '/node_modules/vaderjs/' + "/runtime/static/" + file);
|
|
718
|
+
await writer(process.cwd() + "/dist/" + file, data);
|
|
719
|
+
});
|
|
720
|
+
scannedVaderFiles.forEach(async (file) => {
|
|
721
|
+
bundleSize += fs.statSync(
|
|
722
|
+
process.cwd() + "/runtime/" + file
|
|
723
|
+
).size;
|
|
724
|
+
let data = await reader(process.cwd() + "/runtime/" + file);
|
|
725
|
+
await writer(process.cwd() + '/node_modules/vaderjs/' + "/dist/public/vader/" + file, data);
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
console.log(`Compilation completed`)
|
|
729
|
+
globalThis.isBuilding = false
|
|
730
|
+
}
|
|
731
|
+
import { watch } from "fs";
|
|
732
|
+
|
|
733
|
+
switch (true) {
|
|
734
|
+
case process.argv.includes('--watch'):
|
|
735
|
+
|
|
736
|
+
console.log(`
|
|
737
|
+
Vader.js v1.3.3
|
|
738
|
+
`)
|
|
739
|
+
Build()
|
|
740
|
+
const watcher = watch(
|
|
741
|
+
process.cwd() + '/pages',
|
|
742
|
+
{ recursive: true },
|
|
743
|
+
(event, filename) => {
|
|
744
|
+
if (event == 'change'
|
|
745
|
+
&& !globalThis.isBuilding
|
|
746
|
+
) {
|
|
747
|
+
Build()
|
|
748
|
+
}
|
|
749
|
+
},
|
|
750
|
+
);
|
|
751
|
+
watcher.on('error', (err) => console.log(err))
|
|
752
|
+
console.log('Watching for changes')
|
|
753
|
+
break;
|
|
754
|
+
case process.argv.includes('--build'):
|
|
755
|
+
|
|
756
|
+
console.log(`
|
|
757
|
+
Vader.js v1.3.3
|
|
758
|
+
Building to ./dist
|
|
759
|
+
`)
|
|
760
|
+
Build()
|
|
761
|
+
break;
|
|
762
|
+
default:
|
|
763
|
+
console.log(`
|
|
764
|
+
Vader.js is a reactive framework for building interactive applications for the web built ontop of bun.js!
|
|
765
|
+
|
|
766
|
+
Usage: vader <command>
|
|
767
|
+
|
|
768
|
+
Commands:
|
|
769
|
+
--watch Watch the pages folder for changes and recompile
|
|
770
|
+
|
|
771
|
+
--build Build the project
|
|
772
|
+
Learn more about vader: https://vader-js.pages.dev/
|
|
773
|
+
|
|
774
|
+
`)
|
|
775
|
+
break;
|
|
776
|
+
|
|
777
|
+
}
|
package/vader
DELETED
|
Binary file
|