vaderjs 1.4.0 → 1.4.1-d560b9aa7f

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.
@@ -0,0 +1,1318 @@
1
+ import { Glob } from "bun";
2
+
3
+ import fs from "fs";
4
+
5
+ import * as Bun from "bun";
6
+
7
+ let config = await import(process.cwd() + "/vader.config.js")
8
+ .then((m) => (m ? m.default : {}))
9
+ .catch((e) => {
10
+ return {};
11
+ });
12
+
13
+ async function checkIFUptodate() {
14
+ let lts = await fetch("https://registry.npmjs.org/vaderjs").then((res) =>
15
+ res.json()
16
+ );
17
+ let latest = lts["dist-tags"].latest;
18
+ let current = JSON.parse(
19
+ fs.readFileSync(process.cwd() + "/node_modules/vaderjs/package.json")
20
+ ).version;
21
+ return {
22
+ latest,
23
+ current,
24
+ };
25
+ }
26
+
27
+ import IPCServer from "vaderjs/binaries/IPC/index.js";
28
+ import { exec } from "child_process";
29
+
30
+ const IPC = IPCServer;
31
+
32
+ globalThis.isVader = true;
33
+
34
+ /**
35
+
36
+ * @description - Call functions when the integration is triggered
37
+
38
+ * @param {function} fn
39
+
40
+ * @param {args} args
41
+
42
+ */
43
+
44
+ globalThis.call = async (fn, args) => {
45
+ return (await fn(args)) || void 0;
46
+ };
47
+
48
+ /**@description - Used to store hmr websocket clients */
49
+
50
+ globalThis.clients = [];
51
+
52
+ /**@description - Used to keep track of routes */
53
+
54
+ globalThis.routes = [];
55
+
56
+ /**
57
+
58
+ * @description - Used to keep track of the mode
59
+
60
+ */
61
+
62
+ globalThis.mode = "";
63
+
64
+ /**@usedby @transForm */
65
+
66
+ globalThis.isBuilding = false;
67
+
68
+ globalThis.hasGenerated = [];
69
+
70
+ let currentState = "";
71
+
72
+ /**
73
+
74
+ * @description - Used to keep track of the bundle size
75
+
76
+ */
77
+
78
+ let bundleSize = 0;
79
+
80
+ /**
81
+
82
+ * @description - variables used to generate arrays of paths recursively
83
+
84
+ */
85
+
86
+ const glob = new Glob("/pages/**/**/*.{,tsx,js,jsx,md}", {
87
+ absolute: true,
88
+ });
89
+
90
+ const vaderGlob = new Glob("/node_modules/vaderjs/runtime/**/**/*.{,tsx,js}", {
91
+ absolute: true,
92
+ });
93
+
94
+ const srcGlob = new Glob("/src/**/**/*.{jsx,ts,tsx,js}", {
95
+ absolute: true,
96
+ });
97
+
98
+ const publicGlob = new Glob(
99
+ "/public/**/**/*.{css,js,html,jpg,png,gif,svg,ico,video,webm,mp4,jpeg}",
100
+ {
101
+ absolute: true,
102
+ }
103
+ );
104
+
105
+ const distPages = new Glob("/dist/pages/**/**/*.{tsx,js,jsx}", {
106
+ absolute: true,
107
+ });
108
+
109
+ const distSrc = new Glob("/dist/src/**/**/*.{tsx,js,jsx}", {
110
+ absolute: true,
111
+ });
112
+
113
+ const distPublic = new Glob(
114
+ "/dist/public/**/**/*.{css,js,html,jpg,png,gif,svg,ico,video,webm,mp4,jpeg}",
115
+ {
116
+ absolute: true,
117
+ }
118
+ );
119
+
120
+ const router = new Bun.FileSystemRouter({
121
+ style: "nextjs",
122
+
123
+ dir: process.cwd() + "/pages",
124
+
125
+ origin: process.env.ORIGIN || "http://localhost:3000",
126
+
127
+ assetPrefix: "_next/static/",
128
+ });
129
+
130
+ /**
131
+
132
+ * @function handleReplaceMents
133
+
134
+ * @description - replaces data to be compatible with Vader.js
135
+
136
+ * @param {*} data
137
+
138
+ * @returns
139
+
140
+ */
141
+ const cssToObj = (css) => {
142
+ let styles = {};
143
+ let currentSelector = "";
144
+
145
+ css.split("\n").forEach((line) => {
146
+ line = line.trim();
147
+
148
+
149
+ if (line.endsWith("{")) {
150
+ // Start of a block, extract the selector
151
+ currentSelector = line.slice(0, -1).trim();
152
+ currentSelector = currentSelector.replace(/-./g, (x) => x[1].toUpperCase());
153
+ currentSelector = currentSelector.replace('.', '');
154
+ styles[currentSelector] = {};
155
+ } else if (line.endsWith("}")) {
156
+ // End of a block
157
+ currentSelector = "";
158
+ } else if (line.includes(":") && currentSelector) {
159
+ // Inside a block and contains key-value pair
160
+ let [key, value] = line.split(":").map((part) => part.trim());
161
+ styles[currentSelector][key] = value;
162
+ }
163
+ });
164
+
165
+ return styles;
166
+ };
167
+
168
+ function handleReplaceMents(data) {
169
+ data.split("\n").forEach(async (line, index) => {
170
+ switch (true) {
171
+ case line.includes("import") && line.includes("module.css"):
172
+ let path = line.split("from")[1].trim().split(";")[0].trim();
173
+ let name = line.split("import")[1].split("from")[0].trim();
174
+ path = path.replace(";", "");
175
+ path = path.replace(/'/g, "").trim().replace(/"/g, "").trim();
176
+ path = path.replaceAll(".jsx", ".js");
177
+ path = path.replaceAll("../", "");
178
+ let css = fs.readFileSync(process.cwd() + "/" + path, "utf8");
179
+ let styles = cssToObj(css);
180
+ let style = JSON.stringify(styles);
181
+ let newLine = `let ${name} = ${style}`;
182
+ data = data.replace(line, newLine);
183
+
184
+ break;
185
+
186
+ case line.includes("useReducer") && !line.includes("import"):
187
+ line = line.replaceAll(/\s+/g, " ");
188
+
189
+ let varTypereducer = line.split("=")[0].trim().split("[")[0].trim();
190
+
191
+ let keyreducer = line
192
+ .split("=")[0]
193
+ .trim()
194
+ .split("[")[1]
195
+ .trim()
196
+ .split(",")[0]
197
+ .trim();
198
+
199
+ let setKeyreducer = line
200
+ .split("=")[0]
201
+ .trim()
202
+ .split(",")[1]
203
+ .trim()
204
+ .replace("]", "");
205
+
206
+ let reducer = line.split("=")[1].split("useReducer(")[1];
207
+
208
+ let newStatereducer = `${varTypereducer} [${keyreducer}, ${setKeyreducer}] = this.useReducer('${keyreducer}', ${
209
+ line.includes("=>") ? reducer + "=>{" : reducer
210
+ }`;
211
+
212
+ data = datam(line, newStatereducer);
213
+
214
+ break;
215
+
216
+ case line.includes("useState") && !line.includes("import"):
217
+ let varType = line.split("[")[0];
218
+
219
+ if (!line.split("=")[0].split(",")[1]) {
220
+ throw new Error(
221
+ "You forgot to value selector (useState) " +
222
+ " at " +
223
+ `${file}:${string.split(line)[0].split("\n").length}`
224
+ );
225
+ }
226
+
227
+ let key = line.split("=")[0].split(",")[0].trim().split("[")[1];
228
+
229
+ if (!line.split("=")[0].split(",")[1]) {
230
+ throw new Error(
231
+ "You forgot to add a setter (useState) " +
232
+ " at " +
233
+ `${file}:${string.split(line)[0].split("\n").length}`
234
+ );
235
+ }
236
+
237
+ let setKey = line.split("=")[0].split(",")[1].trim().replace("]", "");
238
+
239
+ key = key.replace("[", "").replace(",", "");
240
+
241
+ let valuestate = line.split("=")[1].split("useState(")[1];
242
+
243
+ let regex = /useState\((.*)\)/gs;
244
+
245
+ valuestate = valuestate.match(regex)
246
+ ? valuestate
247
+ .match(regex)[0]
248
+ .split("useState(")[1]
249
+ .split(")")[0]
250
+ .trim()
251
+ : valuestate;
252
+
253
+ let newState = `${varType} [${key}, ${setKey}] = this.useState('${key}', ${valuestate}`;
254
+
255
+ data = data.replace(line, newState);
256
+
257
+ break;
258
+
259
+ case line.includes("useRef") && !line.includes("import"):
260
+ line = line.trim();
261
+
262
+ let typeref = line.split(" ")[0];
263
+
264
+ let keyref = line
265
+ .split(typeref)[1]
266
+ .split("=")[0]
267
+ .trim()
268
+ .replace("[", "")
269
+ .replace(",", "");
270
+
271
+ let valueref = line.split("=")[1].split("useRef(")[1];
272
+
273
+ let newStateref = `${typeref} ${keyref} = this.useRef('${keyref}', ${valueref}`;
274
+
275
+ data = data.replace(line, newStateref);
276
+
277
+ case (line.includes(".jsx") && line.includes("import")) ||
278
+ (line.includes(".tsx") && line.includes("import")):
279
+ let old = line;
280
+
281
+ line = line.replace(".jsx", ".js");
282
+
283
+ line = line.replace(".tsx", ".js");
284
+
285
+ data = data.replace(old, line);
286
+
287
+ break;
288
+ }
289
+ });
290
+
291
+ data = data.replaceAll("jsxDEV", "Vader.createElement");
292
+
293
+ data = data.replaceAll("jsx", "Vader.createElement");
294
+
295
+ data = data.replaceAll("vaderjs/client", "/vader.js");
296
+
297
+ data = data.replaceAll(".tsx", ".js");
298
+
299
+ let reactImportMatch = data.match(/import React/g);
300
+
301
+ if (reactImportMatch) {
302
+ let fullmatch = data.match(/import React from "react"/g);
303
+
304
+ if (fullmatch) {
305
+ data = data.replaceAll('import React from "react"', "");
306
+ }
307
+ }
308
+
309
+ data = data.replaceAll(".ts", ".js");
310
+
311
+ // check if Vader is imported
312
+
313
+ let vaderImport = data.match(/import Vader/g);
314
+
315
+ if (!vaderImport) {
316
+ data = `import Vader from "/vader.js";\n` + data;
317
+ }
318
+
319
+ return data;
320
+ }
321
+
322
+ /**
323
+
324
+ * @function ContentType
325
+
326
+ * @description - returns the content type based on the file extension
327
+
328
+ * @param {*} url
329
+
330
+ * @returns
331
+
332
+ */
333
+
334
+ const ContentType = (url) => {
335
+ switch (url.split(".").pop()) {
336
+ case "css":
337
+ return "text/css";
338
+
339
+ case "js":
340
+ return "text/javascript";
341
+
342
+ case "json":
343
+ return "application/json";
344
+
345
+ case "html":
346
+ return "text/html";
347
+
348
+ case "jpg":
349
+ return "image/jpg";
350
+
351
+ case "png":
352
+ return "image/png";
353
+
354
+ case "gif":
355
+ return "image/gif";
356
+
357
+ case "svg":
358
+ return "image/svg+xml";
359
+
360
+ case "webp":
361
+ return "image/webp";
362
+ case "ico":
363
+ return "image/x-icon";
364
+
365
+ default:
366
+ return "text/html";
367
+ }
368
+ };
369
+
370
+ /**
371
+
372
+ * @function Server
373
+
374
+ * @description - Creates a hmr development server
375
+
376
+ * @param {Number} port
377
+
378
+ */
379
+
380
+ function Server(port) {
381
+ Bun.serve({
382
+ port: port,
383
+
384
+ async fetch(req, res) {
385
+ const url = new URL(req.url);
386
+
387
+ const success = res.upgrade(req);
388
+
389
+ if (success) {
390
+ return new Response("Connected", {
391
+ headers: {
392
+ "Content-Type": "text/html",
393
+ },
394
+ });
395
+ }
396
+
397
+ if (req.url.includes(".")) {
398
+ if (!fs.existsSync(process.cwd() + "/dist" + url.pathname)) {
399
+ return new Response("Not Found", {
400
+ status: 404,
401
+
402
+ headers: {
403
+ "Content-Type": "text/html",
404
+ },
405
+ });
406
+ }
407
+
408
+ console.log(`HTTP GET: ${url.pathname} -> ${ContentType(req.url)}`);
409
+ return new Response(
410
+ fs.readFileSync(process.cwd() + "/dist" + url.pathname),
411
+ {
412
+ headers: {
413
+ "Content-Type": ContentType(req.url),
414
+ },
415
+ }
416
+ );
417
+ }
418
+
419
+ let matchedRoute =
420
+ router.match(url.pathname)
421
+
422
+ if (matchedRoute) {
423
+ let { filePath, kind, name, params, pathname, query, scriptSrc, isAbsolute } =
424
+ matchedRoute;
425
+
426
+ scriptSrc = scriptSrc.split("pages").pop().split("index.js").shift().split('_next/static')[1]
427
+ // split the furthest file and turn it into index.js
428
+ scriptSrc = scriptSrc.split('/').filter(f => f !== '').join('/')
429
+ // ex: .JSX -> .JS
430
+ scriptSrc.includes('[[...catchall]]') ? scriptSrc = scriptSrc.replace('[[...catchall]]', 'index.js') : scriptSrc = scriptSrc.replace('.jsx', '.js')
431
+ // split if it has a param
432
+ if(scriptSrc.includes('[')){
433
+ scriptSrc = scriptSrc.split('[').shift() + 'index.js'
434
+ }
435
+ scriptSrc = scriptSrc.split('index.js').shift() + 'index.js'
436
+
437
+ let folder = '/' +scriptSrc.split("index.js").shift();
438
+ folder = folder
439
+ .split("/")
440
+ .filter((f) => f !== "dist")
441
+ .join("/");
442
+ let pageContent = fs.readFileSync(
443
+ process.cwd() + "/dist/" + folder + "/index.html",
444
+ "utf8"
445
+ );
446
+
447
+ globalThis.mode === "dev"
448
+ ? (pageContent += `
449
+
450
+ <script type="module">
451
+
452
+ let ws = new WebSocket('ws://localhost:${port}');
453
+
454
+ ws.onmessage = async (e) => {
455
+
456
+ if(e.data === 'reload'){
457
+
458
+ window.location.reload()
459
+
460
+ console.log('Reloading...')
461
+
462
+ }
463
+
464
+ }
465
+
466
+ </script>
467
+
468
+ `)
469
+ : void 0;
470
+
471
+ return new Response(pageContent, {
472
+ headers: {
473
+ "Content-Type": "text/html",
474
+
475
+ "X-Powered-By": "Vader.js v1.3.3",
476
+ },
477
+ });
478
+ }
479
+
480
+ return new Response("Not Found", {
481
+ status: 404,
482
+
483
+ headers: {
484
+ "Content-Type": "text/html",
485
+ },
486
+ });
487
+ },
488
+
489
+ websocket: {
490
+ open(ws) {
491
+ clients.push(ws);
492
+ },
493
+ },
494
+ });
495
+ }
496
+
497
+ /**
498
+
499
+ * @function write
500
+
501
+ * @description - Writes data to a file
502
+
503
+ * @returns {void} 0
504
+
505
+ * @param {string} file
506
+
507
+ * @param {any} data
508
+
509
+ * @returns
510
+
511
+ */
512
+
513
+ const write = (file, data) => {
514
+ try {
515
+ if (!fs.existsSync("./dist")) {
516
+ fs.mkdirSync("./dist");
517
+ }
518
+
519
+ Bun.write(file, data);
520
+ } catch (error) {
521
+ console.error(error);
522
+ }
523
+ };
524
+
525
+ /**
526
+
527
+ * @function read
528
+
529
+ * @param {path} file
530
+
531
+ * @returns {Promise<string>}
532
+
533
+ */
534
+
535
+ const read = async (file) => {
536
+ return await Bun.file(file).text();
537
+ };
538
+
539
+ /**
540
+
541
+ * @object integrationStates
542
+
543
+ * @description - Used to store integration states
544
+
545
+ */
546
+
547
+ globalThis.integrationStates = [];
548
+
549
+ /**
550
+
551
+ * @description a boolean value that checks if vader is being used - useful for running toplevel code at integration start
552
+
553
+ */
554
+
555
+ globalThis.context = {
556
+ vader: true,
557
+ };
558
+
559
+ /**
560
+
561
+ * @function handleIntegrations
562
+
563
+ * @description - Handles module integrations that add more functionality to Vader.js
564
+
565
+ * @returns {void} 0
566
+
567
+ */
568
+
569
+ function handleIntegrations() {
570
+ if (config?.integrations) {
571
+ config.integrations.forEach((integration) => {
572
+ let int = integration;
573
+
574
+ globalThis.integrationStates.push(int);
575
+ });
576
+ }
577
+
578
+ return void 0;
579
+ }
580
+
581
+ handleIntegrations();
582
+
583
+ /**
584
+
585
+ * @function generateProviderRoutes
586
+
587
+ * @description - Generates routes for hosting provders ie: vercel, cloudflare
588
+
589
+ * @returns {void} 0
590
+
591
+ */
592
+
593
+ async function generateProviderRoutes() {
594
+ if (!config?.host?.provider) {
595
+ console.warn(
596
+ "No provider found in vader.config.js ignoring route generation..."
597
+ );
598
+
599
+ return void 0;
600
+ }
601
+
602
+ let providerType = [
603
+ {
604
+ provider: "vercel",
605
+
606
+ file: "vercel.json",
607
+
608
+ out: process.cwd() + "/vercel.json",
609
+
610
+ obj: {
611
+ rewrites: [],
612
+ },
613
+ },
614
+ {
615
+ provider: "cloudflare",
616
+
617
+ file: "_redirects",
618
+
619
+ out: "dist/_redirects",
620
+ },
621
+ {
622
+ "provider":"regular_http_server",
623
+ "file":"htaaccess",
624
+ "out":"dist/.htaccess",
625
+ "obj":`
626
+ RewriteEngine On
627
+ RewriteCond %{REQUEST_FILENAME} !-f
628
+ RewriteRule ^ index.html [QSA,L]
629
+ `,
630
+ }
631
+ ];
632
+
633
+ let provider = providerType.find((p) => p.provider === config.host.provider);
634
+
635
+ if (provider) {
636
+ let prev = null;
637
+
638
+ switch (provider.provider) {
639
+ case "vercel":
640
+ if (!fs.existsSync(provider.out)) {
641
+ fs.writeFileSync(
642
+ provider.out,
643
+ JSON.stringify({
644
+ rewrites: [],
645
+ })
646
+ );
647
+ }
648
+
649
+ // make sure file isnt empty
650
+ if (fs.readFileSync(provider.out).toString().match(/\S/g) === null) {
651
+ console.warn("Rewrites file is empty, ignoring...");
652
+ fs.writeFileSync(
653
+ provider.out,
654
+ JSON.stringify({
655
+ rewrites: [],
656
+ })
657
+ );
658
+ }
659
+
660
+ prev = JSON.parse(fs.readFileSync(provider.out).toString()).rewrites;
661
+
662
+ for(var i in routes){
663
+ let r = routes[i];
664
+ let previous = prev.find((p) => p.source.includes(r.path));
665
+
666
+ if (previous) {
667
+ return void 0;
668
+ }
669
+
670
+ if(r.path.includes('[')){
671
+ r.path = r.path.split('[').shift() + '/:param';
672
+ }
673
+ // replace duplicate slashes
674
+ r.path = r.path.replace(/\/\//g, '/');
675
+ prev.push({
676
+ source: "/" + r.path,
677
+
678
+ destination: "/" + r.path + "/index.html",
679
+ });
680
+
681
+ if (r.params.length > 0) {
682
+ r.params.forEach((param) => {
683
+ if (!param.paramData) {
684
+ return void 0;
685
+ }
686
+
687
+ let parampath = Object.keys(param.paramData)
688
+ .map((p) => `:${p}`)
689
+ .join("/");
690
+
691
+ prev.push({
692
+ source: "/" + r.path + "/" + parampath,
693
+
694
+ destination: "/" + r.path + "/index.html",
695
+ });
696
+ });
697
+ }
698
+
699
+ fs.writeFileSync(
700
+ provider.out,
701
+ JSON.stringify(
702
+ {
703
+ rewrites: prev,
704
+ },
705
+ null,
706
+ 2
707
+ )
708
+ );
709
+ }
710
+
711
+ provider.obj.rewrites = prev;
712
+
713
+ write(provider.out, JSON.stringify(provider.obj, null, 2));
714
+
715
+ break;
716
+
717
+ case "cloudflare":
718
+ console.warn(
719
+ "Cloudflare is not supported yet refer to their documentation for more information:https://developers.cloudflare.com/pages/configuration/redirects/"
720
+ );
721
+
722
+
723
+ break;
724
+ }
725
+ }
726
+
727
+ return void 0;
728
+ }
729
+
730
+ /**
731
+
732
+ * @function transform
733
+
734
+ * @description - Transforms the jsx files to js files based on file paths
735
+
736
+ */
737
+
738
+ async function transForm() {
739
+ return new Promise(async (resolve, reject) => {
740
+ globalThis.isBuilding = true;
741
+
742
+ router.reload();
743
+
744
+ for await (var file of glob.scan(".")) {
745
+ file = file.replace(/\\/g, "/");
746
+
747
+ let isBasePath = file.split("pages/")?.[1]?.split("/").length === 1;
748
+
749
+ let folder =
750
+ file.split("pages/")?.[1]?.split("/").slice(0, -1).join("/") || null;
751
+
752
+ if (isBasePath) {
753
+ folder = "/";
754
+ }
755
+
756
+ if (file.endsWith(".md")) {
757
+ let data = await read(file);
758
+ if (
759
+ integrationStates.find((int) => int?._df && int?._df === "i18mdf")
760
+ ) {
761
+ console.log(
762
+ `Using markdown parser ${
763
+ integrationStates.find((int) => int?._df && int?._df === "i18mdf")
764
+ .name
765
+ } v${
766
+ integrationStates.find((int) => int?._df && int?._df === "i18mdf")
767
+ .version
768
+ }`
769
+ );
770
+ let parser = integrationStates.find(
771
+ (int) => int?._df && int?._df === "i18mdf"
772
+ );
773
+
774
+ parser.parse(data);
775
+ parser._class.stylesheets.forEach((sheet) => {
776
+ parser._class.output =
777
+ `<link rel="stylesheet" href="${sheet}">` + parser._class.output;
778
+ });
779
+ let output = `./dist/${
780
+ isBasePath ? "index.html" : folder + "/index.html"
781
+ }`;
782
+ write(output, parser._class.output);
783
+ }
784
+ continue;
785
+ }
786
+
787
+
788
+ let route = isBasePath ? router.match("/") : router.match("/" + folder);
789
+
790
+ if (route) {
791
+ let { filePath, kind, name, params, pathname, query } = route;
792
+
793
+ let data = await read(filePath);
794
+
795
+ try {
796
+ data = new Bun.Transpiler({
797
+ loader: "tsx",
798
+ target: "browser",
799
+ }).transformSync(data);
800
+ } catch (e) {
801
+ console.error(e);
802
+ }
803
+
804
+ let out = `./dist/${isBasePath ? "index.js" : folder + "/index.js"}`;
805
+
806
+ isBasePath ? (folder = "/") : null;
807
+
808
+ data = handleReplaceMents(data);
809
+
810
+
811
+ let isAparam = null;
812
+
813
+ if (folder === "") {
814
+ return;
815
+ }
816
+
817
+ switch (true) {
818
+ case kind === "dynamic":
819
+ isAparam = true;
820
+
821
+ break;
822
+
823
+ case kind === "catch-all":
824
+ isAparam = true;
825
+
826
+ break;
827
+
828
+ case kind === "optional-catch-all":
829
+ isAparam = true;
830
+
831
+ break;
832
+ }
833
+
834
+ if(!routes.find(r => r.path === folder)){
835
+ routes.push({
836
+ path: folder,
837
+ file: out,
838
+ isParam: isAparam,
839
+ params: params,
840
+ kind,
841
+ isCatchAll: kind.includes("catch-all"),
842
+ query,
843
+ pathname,
844
+ });
845
+ }
846
+
847
+ console.log(`Transforming ${file} -> ${out}`);
848
+
849
+ write(out, data);
850
+
851
+ //terser
852
+ Bun.spawn({
853
+ cwd: process.cwd(),
854
+
855
+ isVader: true,
856
+
857
+ cmd: ["npx", "terser", out, "--output", out],
858
+ });
859
+
860
+ bundleSize += data.length;
861
+ }
862
+ }
863
+
864
+ for await (var file of srcGlob.scan(".")) {
865
+ if (!fs.existsSync(process.cwd() + "/dist/src/")) {
866
+ fs.mkdirSync(process.cwd() + "/dist/src/");
867
+ }
868
+
869
+ file = file.replace(/\\/g, "/");
870
+
871
+ switch (file.split(".").pop()) {
872
+ case "ts":
873
+ let transpiler = new Bun.Transpiler({
874
+ loader: "ts",
875
+ target: "browser",
876
+ });
877
+
878
+ let data = await read(file);
879
+
880
+ try {
881
+ data = transpiler.transformSync(data);
882
+ } catch (error) {
883
+ console.error(error);
884
+ }
885
+
886
+ file = file.replace(".ts", ".js");
887
+
888
+ let path = process.cwd() + "/dist/src/" + file.split("src/").pop();
889
+
890
+ write(path, data);
891
+
892
+ bundleSize += data.length;
893
+
894
+ break;
895
+
896
+ case "tsx":
897
+ let transpilerx = new Bun.Transpiler({
898
+ loader: "tsx",
899
+ target: "browser",
900
+ });
901
+
902
+ let datax = await read(file);
903
+
904
+ try {
905
+ datax = transpilerx.transformSync(datax);
906
+ } catch (error) {
907
+ console.error(error);
908
+ }
909
+
910
+ datax = handleReplaceMents(datax);
911
+
912
+ file = file.replace(".tsx", ".js");
913
+
914
+ let pathx = process.cwd() + "/dist/src/" + file.split("src/").pop();
915
+
916
+ write(pathx, datax);
917
+
918
+ break;
919
+
920
+ case "jsx":
921
+ let transpilerjx = new Bun.Transpiler({
922
+ loader: "jsx",
923
+ target: "browser",
924
+ });
925
+
926
+ let datajx = await read(file);
927
+
928
+ let source = transpilerjx.scan(datajx);
929
+
930
+ try {
931
+ datajx = transpilerjx.transformSync(datajx);
932
+ } catch (error) {
933
+ console.error(error);
934
+ }
935
+
936
+ datajx = handleReplaceMents(datajx);
937
+
938
+ file = file.replace(".jsx", ".js");
939
+
940
+ let pathjx = process.cwd() + "/dist/src/" + file.split("src/").pop();
941
+
942
+ write(pathjx, datajx);
943
+
944
+ bundleSize += datajx.length;
945
+
946
+ break;
947
+ default:
948
+ break;
949
+ }
950
+ }
951
+
952
+ for await (var file of publicGlob.scan(".")) {
953
+ // works
954
+
955
+ let data = null;
956
+ let isBuff = false;
957
+ file = file.replace(/\\/g, "/");
958
+ if (
959
+ file.endsWith(".png") ||
960
+ file.endsWith(".jpg") ||
961
+ file.endsWith(".jpeg") ||
962
+ file.endsWith(".gif") ||
963
+ file.endsWith(".webp") ||
964
+ file.endsWith(".ico") ||
965
+ file.endsWith(".mp4") ||
966
+ file.endsWith(".webm")
967
+ ) {
968
+ data = Buffer.from(fs.readFileSync(file)).toString("base64");
969
+ isBuff = true;
970
+ }
971
+ data = data || (await read(file));
972
+
973
+ let path = process.cwd() + "/dist/public/" + file.split("public/").pop();
974
+ if(!fs.existsSync(path.split(file.split("/").pop()).shift())){
975
+ fs.mkdirSync(path.split(file.split("/").pop()).shift(), { recursive: true });
976
+ }
977
+
978
+ fs.writeFileSync(path, data, isBuff ? "base64" : "utf8");
979
+
980
+ bundleSize += data.length;
981
+ }
982
+
983
+ for await (var file of vaderGlob.scan(".")) {
984
+ file = file.replace(/\\/g, "/");
985
+ if (
986
+ fs.existsSync(
987
+ process.cwd() +
988
+ "/dist/" +
989
+ file.split("node_modules/vaderjs/runtime/").pop()
990
+ )
991
+ ) {
992
+ continue;
993
+ }
994
+ let data = await read(file);
995
+
996
+ file = file.replace(/\\/g, "/");
997
+
998
+ write(
999
+ process.cwd() +
1000
+ "/dist/" +
1001
+ file.split("node_modules/vaderjs/runtime/").pop(),
1002
+ data
1003
+ );
1004
+
1005
+ bundleSize += fs.statSync(
1006
+ process.cwd() +
1007
+ "/dist/" +
1008
+ file.split("node_modules/vaderjs/runtime/").pop()
1009
+ ).size;
1010
+ }
1011
+
1012
+ // clean dist folder
1013
+
1014
+ for await (var file of distPages.scan(".")) {
1015
+ file = file.replace(/\\/g, "/");
1016
+
1017
+ let path = process.cwd() + "/pages/" + file.split("dist/pages/").pop();
1018
+
1019
+ path = path.replace(".js", config?.files?.mimeType || ".jsx");
1020
+
1021
+ if (!fs.existsSync(path)) {
1022
+ fs.unlinkSync(file);
1023
+ }
1024
+ }
1025
+
1026
+ /**
1027
+
1028
+ * @function organizeRoutes
1029
+
1030
+ * @description - Organizes routes that have param paths
1031
+
1032
+ */
1033
+
1034
+
1035
+
1036
+ globalThis.isBuilding = false;
1037
+
1038
+ if (!fs.existsSync(process.cwd() + "/_dev/meta")) {
1039
+ fs.mkdirSync(process.cwd() + "/_dev/meta");
1040
+ }
1041
+
1042
+ // handle [{}]
1043
+
1044
+ generateProviderRoutes();
1045
+ write( process.cwd() + "/_dev/meta/routes.json", JSON.stringify(routes, null, 2));
1046
+
1047
+ console.log(`Finished building ${Math.round(bundleSize / 1000)}kb`);
1048
+
1049
+ bundleSize = 0;
1050
+
1051
+ resolve();
1052
+ });
1053
+ }
1054
+
1055
+ let port = 3000;
1056
+ let hasRan = [];
1057
+
1058
+ switch (true) {
1059
+ case process.argv.includes("dev") &&
1060
+ !process.argv.includes("build") &&
1061
+ !process.argv.includes("start"):
1062
+ port = process.argv.includes("-p")
1063
+ ? process.argv[process.argv.indexOf("-p") + 1]
1064
+ : config?.dev?.port || 3000;
1065
+
1066
+ globalThis.oneAndDone = false;
1067
+ let v = await checkIFUptodate();
1068
+
1069
+ console.log(`
1070
+
1071
+ ${
1072
+ v.current !== v.latest
1073
+ ? `Update available: ${v.latest} (current: ${v.current})`
1074
+ : `Vader.js v${v.current}`
1075
+ }
1076
+ - Watching for changes in ./pages
1077
+ - Watching for changes in ./src
1078
+ - Watching for changes in ./public
1079
+ - Serving on port http://localhost:${port}
1080
+
1081
+ `);
1082
+
1083
+ globalThis.mode = "dev";
1084
+
1085
+ Server(port);
1086
+ for (var ints in integrationStates) {
1087
+ if (
1088
+ integrationStates &&
1089
+ integrationStates[ints]?.on &&
1090
+ integrationStates[ints].on.includes("dev") &&
1091
+ !hasRan.includes(integrationStates[ints].name)
1092
+ ) {
1093
+ console.log("Starting integration...");
1094
+
1095
+ let int = integrationStates[ints];
1096
+
1097
+ let { name, version, useRuntime, entryPoint, onAction, doOn } = int;
1098
+
1099
+ globalThis[`isRunning${name}`] = true;
1100
+ console.log(`Using integration: ${name} v${version}`);
1101
+
1102
+ Bun.spawn({
1103
+ cwd: process.cwd(),
1104
+
1105
+ isVader: true,
1106
+
1107
+ env: {
1108
+ PWD: process.cwd(),
1109
+
1110
+ isVader: true,
1111
+
1112
+ FOLDERS: "pages,src,public",
1113
+
1114
+ onExit: (code) => {
1115
+ globalThis.isBuilding = false;
1116
+
1117
+ globalThis[`isRunning${name}`] = false;
1118
+ },
1119
+ },
1120
+
1121
+ cmd: [useRuntime || "node", entryPoint],
1122
+ });
1123
+
1124
+ hasRan.push(integrationStates[ints].name);
1125
+ }
1126
+ }
1127
+
1128
+ transForm();
1129
+
1130
+ Bun.spawn({
1131
+ cwd: process.cwd() + "/node_modules/vaderjs/binaries/",
1132
+
1133
+ env: {
1134
+ PWD: process.cwd(),
1135
+
1136
+ IPC: IPC,
1137
+
1138
+ FOLDERS: "pages,src,public",
1139
+
1140
+ onExit: (code) => {
1141
+ globalThis.isBuilding = false;
1142
+
1143
+ globalThis.oneAndDone = true;
1144
+ },
1145
+ },
1146
+
1147
+ cmd: ["node", "watcher.js"],
1148
+ });
1149
+
1150
+ async function runOnChange() {
1151
+ for (var ints in integrationStates) {
1152
+ if (
1153
+ integrationStates &&
1154
+ integrationStates[ints].on &&
1155
+ integrationStates[ints]?.on.includes("dev:change")
1156
+ ) {
1157
+ let int = integrationStates[ints];
1158
+
1159
+ let { name, version, useRuntime, entryPoint, onAction, doOn } = int;
1160
+
1161
+ if (globalThis[`isRunning${name}`]) {
1162
+ setTimeout(() => {
1163
+ globalThis[`isRunning${name}`] = false;
1164
+ }, 1000);
1165
+ return void 0;
1166
+ }
1167
+
1168
+ globalThis[`isRunning${name}`] = true;
1169
+ console.log(`Using integration: ${name} v${version}`);
1170
+
1171
+ Bun.spawn({
1172
+ cwd: process.cwd(),
1173
+
1174
+ isVader: true,
1175
+
1176
+ env: {
1177
+ PWD: process.cwd(),
1178
+
1179
+ isVader: true,
1180
+
1181
+ FOLDERS: "pages,src,public",
1182
+
1183
+ onExit: (code) => {
1184
+ globalThis.isBuilding = false;
1185
+
1186
+ globalThis[`isRunning${name}`] = false;
1187
+ },
1188
+ },
1189
+
1190
+ cmd: [useRuntime || "node", entryPoint],
1191
+ });
1192
+
1193
+ console.log(`Using integration: ${name} v${version}`);
1194
+ }
1195
+ }
1196
+ }
1197
+
1198
+ IPC.client({
1199
+ use: IPCServer.typeEnums.WATCHER,
1200
+
1201
+ port: 3434,
1202
+ }).Console.read(async (message) => {
1203
+ message = message.msg;
1204
+
1205
+ switch (true) {
1206
+ case message.data?.type === "change":
1207
+ console.log("File changed:", message.data.filename);
1208
+
1209
+ transForm();
1210
+
1211
+ clients.forEach((client) => {
1212
+ client.send("reload");
1213
+ });
1214
+
1215
+ // reload config
1216
+ config = await import(process.cwd() + "/vader.config.js").then((m) =>
1217
+ m ? m.default : {}
1218
+ );
1219
+
1220
+ runOnChange();
1221
+
1222
+ break;
1223
+
1224
+ case message.data?.type === "add":
1225
+ console.log("File added:", message.data.filename);
1226
+
1227
+ transForm();
1228
+
1229
+ break;
1230
+ }
1231
+ });
1232
+
1233
+ break;
1234
+
1235
+ case process.argv.includes("build") &&
1236
+ !process.argv.includes("dev") &&
1237
+ !process.argv.includes("start"):
1238
+ globalThis.devMode = false;
1239
+
1240
+ globalThis.mode = "prod";
1241
+
1242
+ globalThis.isProduction = true;
1243
+
1244
+ globalThis.routeStates = [];
1245
+
1246
+ console.log(`
1247
+ Vader.js v1.3.3
1248
+ Building to ./dist
1249
+ `);
1250
+
1251
+ transForm();
1252
+
1253
+ for (var ints in integrationStates) {
1254
+ if (
1255
+ integrationStates &&
1256
+ integrationStates[ints].on &&
1257
+ integrationStates[ints]?.on.includes("build")
1258
+ ) {
1259
+ console.log("Starting integration...");
1260
+
1261
+ let int = integrationStates[ints];
1262
+
1263
+ let { name, version, useRuntime, entryPoint, onAction, doOn } = int;
1264
+
1265
+ console.log(`Using integration: ${name} v${version}`);
1266
+
1267
+ Bun.spawn({
1268
+ cwd: process.cwd(),
1269
+
1270
+ isVader: true,
1271
+
1272
+ env: {
1273
+ PWD: process.cwd(),
1274
+
1275
+ isVader: true,
1276
+
1277
+ FOLDERS: "pages,src,public",
1278
+
1279
+ onExit: (code) => {
1280
+ globalThis.isBuilding = false;
1281
+ },
1282
+ },
1283
+
1284
+ cmd: ["node", entryPoint],
1285
+ });
1286
+ }
1287
+ }
1288
+
1289
+ break;
1290
+
1291
+ case process.argv.includes("start") &&
1292
+ !process.argv.includes("dev") &&
1293
+ !process.argv.includes("build"):
1294
+ port = process.argv.includes("-p")
1295
+ ? process.argv[process.argv.indexOf("-p") + 1]
1296
+ : config?.host?.prod?.port || 3000;
1297
+
1298
+ console.log(`
1299
+
1300
+ Vader.js v1.3.3
1301
+
1302
+ Serving ./dist on port ${port}
1303
+
1304
+ url: ${config?.host?.prod?.hostname || "http://localhost"}:${port}
1305
+
1306
+ `);
1307
+
1308
+ globalThis.devMode = false;
1309
+
1310
+ globalThis.isProduction = true;
1311
+
1312
+ Server(port);
1313
+
1314
+ break;
1315
+
1316
+ default:
1317
+ break;
1318
+ }