vaderjs 2.3.10 → 2.3.12

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.
Files changed (3) hide show
  1. package/index.ts +342 -152
  2. package/main.js +304 -152
  3. package/package.json +1 -1
package/main.js CHANGED
@@ -1,11 +1,10 @@
1
1
  #!/usr/bin/env bun
2
-
3
2
 
4
3
  import { build, serve } from "bun";
5
4
  import fs from "fs/promises";
6
5
  import fsSync from "fs";
7
6
  import path from "path";
8
- import { initProject, addPlugin, listPlugins, removePlugin} from "./cli";
7
+ import { initProject, addPlugin, listPlugins, removePlugin } from "./cli";
9
8
 
10
9
  // --- UTILITIES for a Sleek CLI ---
11
10
 
@@ -19,17 +18,6 @@ const colors = {
19
18
  cyan: "\x1b[36m",
20
19
  };
21
20
 
22
- function safeWatch(dir, cb) {
23
- try {
24
- const watcher = fsSync.watch(dir, { recursive: true }, cb);
25
- watcher.on("error", (err) => logger.warn(`Watcher error on ${dir}:`, err));
26
- return watcher;
27
- } catch (err) {
28
- logger.warn(`Failed to watch ${dir}:`, err);
29
- }
30
- }
31
-
32
-
33
21
  const logger = {
34
22
  _log: (color, ...args) => console.log(color, ...args, colors.reset),
35
23
  info: (...args) => logger._log(colors.cyan, "ℹ", ...args),
@@ -62,6 +50,141 @@ const SRC_DIR = path.join(PROJECT_ROOT, "src");
62
50
  const VADER_SRC_PATH = path.join(PROJECT_ROOT, "node_modules", "vaderjs", "index.ts");
63
51
  const TEMP_SRC_DIR = path.join(PROJECT_ROOT, ".vader_temp_src");
64
52
 
53
+ // --- SIMPLIFIED WATCHER ---
54
+
55
+ class FileWatcher {
56
+ constructor() {
57
+ this.watchers = new Map();
58
+ this.onChangeCallbacks = [];
59
+ this.isRebuilding = false;
60
+ this.lastRebuildTime = 0;
61
+ this.REBUILD_COOLDOWN = 1000; // 1 second cooldown between rebuilds
62
+ }
63
+
64
+ shouldIgnorePath(filePath) {
65
+ const normalized = path.normalize(filePath);
66
+ // Ignore dist folder and its contents
67
+ if (normalized.includes(path.normalize(DIST_DIR))) {
68
+ return true;
69
+ }
70
+ // Ignore node_modules
71
+ if (normalized.includes(path.normalize('node_modules'))) {
72
+ return true;
73
+ }
74
+ // Ignore .git folder
75
+ if (normalized.includes(path.normalize('.git'))) {
76
+ return true;
77
+ }
78
+ // Ignore the temporary source directory
79
+ if (normalized.includes(path.normalize(TEMP_SRC_DIR))) {
80
+ return true;
81
+ }
82
+ return false;
83
+ }
84
+
85
+ async watchDirectory(dirPath, recursive = true) {
86
+ // Skip if directory should be ignored
87
+ if (this.shouldIgnorePath(dirPath) || !fsSync.existsSync(dirPath)) {
88
+ return;
89
+ }
90
+
91
+ try {
92
+ // Close existing watcher if any
93
+ if (this.watchers.has(dirPath)) {
94
+ try {
95
+ this.watchers.get(dirPath).close();
96
+ } catch (err) {
97
+ // Ignore close errors
98
+ }
99
+ }
100
+
101
+ // Create new watcher
102
+ const watcher = fsSync.watch(dirPath, { recursive }, (eventType, filename) => {
103
+ if (!filename) return;
104
+
105
+ const changedFile = path.join(dirPath, filename);
106
+ const normalizedChanged = path.normalize(changedFile);
107
+
108
+ // Skip if file should be ignored
109
+ if (this.shouldIgnorePath(normalizedChanged)) {
110
+ return;
111
+ }
112
+
113
+ // Check if this is a file we care about
114
+ if (this.shouldTriggerRebuild(normalizedChanged)) {
115
+ logger.info(`File changed: ${path.relative(PROJECT_ROOT, normalizedChanged)}`);
116
+
117
+ // Only trigger if not already rebuilding and cooldown has passed
118
+ const now = Date.now();
119
+ if (!this.isRebuilding && (now - this.lastRebuildTime) > this.REBUILD_COOLDOWN) {
120
+ this.triggerChange(normalizedChanged);
121
+ } else if (this.isRebuilding) {
122
+ logger.info(`Skipping rebuild - already rebuilding`);
123
+ } else {
124
+ logger.info(`Skipping rebuild - cooldown period`);
125
+ }
126
+ }
127
+ });
128
+
129
+ watcher.on('error', (err) => {
130
+ logger.warn(`Watcher error on ${dirPath}:`, err.message);
131
+ });
132
+
133
+ this.watchers.set(dirPath, watcher);
134
+
135
+ logger.info(`Watching directory: ${path.relative(PROJECT_ROOT, dirPath)}`);
136
+ } catch (err) {
137
+ logger.warn(`Could not watch directory ${dirPath}:`, err.message);
138
+ }
139
+ }
140
+
141
+ shouldTriggerRebuild(filePath) {
142
+ // Only trigger rebuild for specific file types
143
+ const ext = path.extname(filePath).toLowerCase();
144
+ const triggerExtensions = ['.js', '.jsx', '.ts', '.tsx', '.css', '.html', '.json', '.config.js', '.config.ts'];
145
+ return triggerExtensions.includes(ext) || ext === '';
146
+ }
147
+
148
+ triggerChange(filePath) {
149
+ for (const callback of this.onChangeCallbacks) {
150
+ try {
151
+ callback(filePath);
152
+ } catch (err) {
153
+ logger.error("Change callback error:", err);
154
+ }
155
+ }
156
+ }
157
+
158
+ onChange(callback) {
159
+ this.onChangeCallbacks.push(callback);
160
+ return () => {
161
+ const index = this.onChangeCallbacks.indexOf(callback);
162
+ if (index > -1) this.onChangeCallbacks.splice(index, 1);
163
+ };
164
+ }
165
+
166
+ setRebuilding(state) {
167
+ this.isRebuilding = state;
168
+ if (state) {
169
+ this.lastRebuildTime = Date.now();
170
+ }
171
+ }
172
+
173
+ clear() {
174
+ for (const [dir, watcher] of this.watchers) {
175
+ try {
176
+ watcher.close();
177
+ } catch (err) {
178
+ // Ignore close errors
179
+ }
180
+ }
181
+ this.watchers.clear();
182
+ this.onChangeCallbacks = [];
183
+ this.isRebuilding = false;
184
+ }
185
+ }
186
+
187
+ const watcher = new FileWatcher();
65
188
 
66
189
  // --- CONFIG & PLUGIN SYSTEM ---
67
190
 
@@ -77,8 +200,7 @@ const vaderAPI = {
77
200
  injectHTML: (content) => htmlInjections.push(content),
78
201
  log: {
79
202
  warn: (msg) => logger.warn(msg),
80
- info: (msg) => logger.info(msg),
81
- error: (msg) => logger.error(msg),
203
+ info: (msg) => logger.info(msg),
82
204
  success: (msg) => logger.success(msg),
83
205
  step: (msg) => logger.step(msg)
84
206
  },
@@ -89,11 +211,10 @@ const vaderAPI = {
89
211
 
90
212
  async function loadConfig() {
91
213
  try {
92
- const configModule = await import(path.join(PROJECT_ROOT, "vaderjs.config.js"));
214
+ const configModule = await import(path.join(PROJECT_ROOT, "vaderjs.config.js"));
93
215
  return configModule.default || configModule;
94
216
  } catch {
95
- console.log(path.join(PROJECT_ROOT, "vaderjs.config.js"))
96
- logger.warn("No 'vader.config.js' found, using defaults.");
217
+ logger.warn("No 'vaderjs.config.js' found, using defaults.");
97
218
  return {};
98
219
  }
99
220
  }
@@ -103,7 +224,6 @@ export function defineConfig(config) {
103
224
  }
104
225
 
105
226
  async function runPluginHook(hookName) {
106
- console.log(config)
107
227
  if (!config.plugins) return;
108
228
  for (const plugin of config.plugins) {
109
229
  if (typeof plugin[hookName] === "function") {
@@ -116,8 +236,6 @@ async function runPluginHook(hookName) {
116
236
  }
117
237
  }
118
238
 
119
-
120
-
121
239
  // --- BUILD LOGIC ---
122
240
 
123
241
  /**
@@ -147,6 +265,7 @@ async function buildVaderCore() {
147
265
  function patchHooksUsage(code) {
148
266
  return code.replace(/import\s+{[^}]*use(State|Effect|Memo|Navigation)[^}]*}\s+from\s+['"]vaderjs['"];?\n?/g, "");
149
267
  }
268
+
150
269
  function publicAssetPlugin() {
151
270
  return {
152
271
  name: "public-asset-replacer",
@@ -183,7 +302,6 @@ function publicAssetPlugin() {
183
302
  /**
184
303
  * Step 3: Pre-processes all files in `/src` into a temporary directory.
185
304
  */
186
-
187
305
  async function preprocessSources(srcDir, tempDir) {
188
306
  await fs.mkdir(tempDir, { recursive: true });
189
307
  for (const entry of await fs.readdir(srcDir, { withFileTypes: true })) {
@@ -194,7 +312,7 @@ async function preprocessSources(srcDir, tempDir) {
194
312
  await preprocessSources(srcPath, destPath);
195
313
  } else if (/\.(tsx|jsx|ts|js)$/.test(entry.name)) {
196
314
  let content = await fs.readFile(srcPath, "utf8");
197
- content = patchHooksUsage(content);
315
+ content = patchHooksUsage(content);
198
316
  await fs.writeFile(destPath, content);
199
317
  } else {
200
318
  await fs.copyFile(srcPath, destPath);
@@ -250,14 +368,28 @@ async function copyPublicAssets() {
250
368
  }
251
369
  }
252
370
 
253
- async function buildAppEntrypoints(isDev = false) {
254
- if (!fsSync.existsSync(APP_DIR)) {
255
- logger.warn("No '/app' directory found, skipping app entrypoint build.");
256
- return;
257
- }
258
-
259
- if (!fsSync.existsSync(DIST_DIR)) {
260
- await fs.mkdir(DIST_DIR, { recursive: true });
371
+ async function buildAppEntrypoint(entryPath, name, isDev = false) {
372
+ const outDir = path.join(DIST_DIR, name === 'index' ? '' : name);
373
+ const outJsPath = path.join(outDir, 'index.js');
374
+ await fs.mkdir(outDir, { recursive: true });
375
+
376
+ // --- CSS HANDLING ---
377
+ const cssLinks = [];
378
+ let content = await fs.readFile(entryPath, "utf8");
379
+ const cssImports = [...content.matchAll(/import\s+['"](.*\.css)['"]/g)];
380
+ for (const match of cssImports) {
381
+ const cssImportPath = match[1];
382
+ const sourceCssPath = path.resolve(path.dirname(entryPath), cssImportPath);
383
+ if (fsSync.existsSync(sourceCssPath)) {
384
+ const relativeCssPath = path.relative(APP_DIR, sourceCssPath);
385
+ const destCssPath = path.join(DIST_DIR, relativeCssPath);
386
+ await fs.mkdir(path.dirname(destCssPath), { recursive: true });
387
+ await fs.copyFile(sourceCssPath, destCssPath);
388
+ const htmlRelativePath = path.relative(outDir, destCssPath).replace(/\\/g, '/');
389
+ cssLinks.push(`<link rel="stylesheet" href="${htmlRelativePath}">`);
390
+ } else {
391
+ logger.warn(`CSS file not found: ${sourceCssPath}`);
392
+ }
261
393
  }
262
394
 
263
395
  const devClientScript = isDev
@@ -268,49 +400,8 @@ async function copyPublicAssets() {
268
400
  </script>`
269
401
  : "";
270
402
 
271
- const entries = fsSync.readdirSync(APP_DIR, { recursive: true })
272
- .filter(file => /index\.(jsx|tsx)$/.test(file))
273
- .map(file => ({
274
- name: path.dirname(file) === '.' ? 'index' : path.dirname(file).replace(/\\/g, '/'),
275
- path: path.join(APP_DIR, file)
276
- }));
277
-
278
- // Helper to resolve any asset path from /public
279
- function resolvePublicPath(p) {
280
- const assetPath = p.replace(/^(\.\/|\/)/, ""); // strip leading ./ or /
281
- const absPath = path.join(PUBLIC_DIR, assetPath);
282
- if (fsSync.existsSync(absPath)) {
283
- return "/" + assetPath.replace(/\\/g, "/");
284
- }
285
- return p; // leave unchanged if not in public
286
- }
287
-
288
- for (const { name, path: entryPath } of entries) {
289
- const outDir = path.join(DIST_DIR, name === 'index' ? '' : name);
290
- const outJsPath = path.join(outDir, 'index.js');
291
- await fs.mkdir(outDir, { recursive: true });
292
-
293
- // --- CSS HANDLING ---
294
- const cssLinks = [];
295
- let content = await fs.readFile(entryPath, "utf8");
296
- const cssImports = [...content.matchAll(/import\s+['"](.*\.css)['"]/g)];
297
- for (const match of cssImports) {
298
- const cssImportPath = match[1];
299
- const sourceCssPath = path.resolve(path.dirname(entryPath), cssImportPath);
300
- if (fsSync.existsSync(sourceCssPath)) {
301
- const relativeCssPath = path.relative(APP_DIR, sourceCssPath);
302
- const destCssPath = path.join(DIST_DIR, relativeCssPath);
303
- await fs.mkdir(path.dirname(destCssPath), { recursive: true });
304
- await fs.copyFile(sourceCssPath, destCssPath);
305
- const htmlRelativePath = path.relative(outDir, destCssPath).replace(/\\/g, '/');
306
- cssLinks.push(`<link rel="stylesheet" href="${htmlRelativePath}">`);
307
- } else {
308
- logger.warn(`CSS file not found: ${sourceCssPath}`);
309
- }
310
- }
311
-
312
- // --- HTML GENERATION ---
313
- let htmlContent = `<!DOCTYPE html>
403
+ // --- HTML GENERATION ---
404
+ let htmlContent = `<!DOCTYPE html>
314
405
  <html lang="en">
315
406
  <head>
316
407
  <meta charset="UTF-8" />
@@ -331,50 +422,79 @@ async function copyPublicAssets() {
331
422
  </body>
332
423
  </html>`;
333
424
 
334
- // --- FIX ASSET PATHS IN HTML ---
335
- htmlContent = htmlContent.replace(
336
- /(["'(])([^"'()]+?\.(png|jpe?g|gif|svg|webp|ico))(["')])/gi,
337
- (match, p1, assetPath, ext, p4) => p1 + resolvePublicPath(assetPath) + p4
338
- );
339
-
340
- await fs.writeFile(path.join(outDir, "index.html"), htmlContent);
341
-
342
- // --- JS BUILD ---
343
- await build({
344
- entrypoints: [entryPath],
345
- outdir: outDir,
346
- target: "browser",
347
- minify: false,
348
- sourcemap: "external",
349
- external: ["vaderjs"],
350
- jsxFactory: "e",
351
- jsxFragment: "Fragment",
352
- plugins: [
425
+ // Helper to resolve any asset path from /public
426
+ function resolvePublicPath(p) {
427
+ const assetPath = p.replace(/^(\.\/|\/)/, ""); // strip leading ./ or /
428
+ const absPath = path.join(PUBLIC_DIR, assetPath);
429
+ if (fsSync.existsSync(absPath)) {
430
+ return "/" + assetPath.replace(/\\/g, "/");
431
+ }
432
+ return p; // leave unchanged if not in public
433
+ }
434
+
435
+ // --- FIX ASSET PATHS IN HTML ---
436
+ htmlContent = htmlContent.replace(
437
+ /(["'(])([^"'()]+?\.(png|jpe?g|gif|svg|webp|ico))(["')])/gi,
438
+ (match, p1, assetPath, ext, p4) => p1 + resolvePublicPath(assetPath) + p4
439
+ );
440
+
441
+ await fs.writeFile(path.join(outDir, "index.html"), htmlContent);
442
+
443
+ // --- JS BUILD ---
444
+ await build({
445
+ entrypoints: [entryPath],
446
+ outdir: outDir,
447
+ target: "browser",
448
+ minify: false,
449
+ sourcemap: "external",
450
+ external: ["vaderjs"],
451
+ jsxFactory: "e",
452
+ jsxFragment: "Fragment",
453
+ plugins: [
353
454
  publicAssetPlugin(),
354
455
  ],
355
- jsxImportSource: "vaderjs",
356
- });
456
+ jsxImportSource: "vaderjs",
457
+ });
357
458
 
358
- // --- FIX IMPORT PATHS IN JS ---
359
- let jsContent = await fs.readFile(outJsPath, "utf8");
459
+ // --- FIX IMPORT PATHS IN JS ---
460
+ let jsContent = await fs.readFile(outJsPath, "utf8");
360
461
 
361
- // Vader import fix
362
- jsContent = jsContent.replace(/from\s+['"]vaderjs['"]/g, `from '/src/vader/index.js'`);
462
+ // Vader import fix
463
+ jsContent = jsContent.replace(/from\s+['"]vaderjs['"]/g, `from '/src/vader/index.js'`);
363
464
 
364
- // Asset path fix for JS
365
- jsContent = jsContent.replace(
366
- /(["'(])([^"'()]+?\.(png|jpe?g|gif|svg|webp|ico))(["')])/gi,
367
- (match, p1, assetPath, ext, p4) => p1 + resolvePublicPath(assetPath) + p4
368
- );
465
+ // Asset path fix for JS
466
+ jsContent = jsContent.replace(
467
+ /(["'(])([^"'()]+?\.(png|jpe?g|gif|svg|webp|ico))(["')])/gi,
468
+ (match, p1, assetPath, ext, p4) => p1 + resolvePublicPath(assetPath) + p4
469
+ );
369
470
 
370
- await fs.writeFile(outJsPath, jsContent);
371
- }
471
+ await fs.writeFile(outJsPath, jsContent);
372
472
  }
373
473
 
474
+ async function buildAppEntrypoints(isDev = false) {
475
+ if (!fsSync.existsSync(APP_DIR)) {
476
+ logger.warn("No '/app' directory found, skipping app entrypoint build.");
477
+ return;
478
+ }
479
+
480
+ if (!fsSync.existsSync(DIST_DIR)) {
481
+ await fs.mkdir(DIST_DIR, { recursive: true });
482
+ }
483
+
484
+ // Find all index.jsx/tsx files in app directory
485
+ const entries = fsSync.readdirSync(APP_DIR, { recursive: true })
486
+ .filter(file => /index\.(jsx|tsx)$/.test(file))
487
+ .map(file => ({
488
+ name: path.dirname(file) === '.' ? 'index' : path.dirname(file).replace(/\\/g, '/'),
489
+ path: path.join(APP_DIR, file)
490
+ }));
374
491
 
375
-
492
+ for (const { name, path: entryPath } of entries) {
493
+ await buildAppEntrypoint(entryPath, name, isDev);
494
+ }
495
+ }
376
496
 
377
- async function buildAll(isDev = false) {
497
+ async function buildAll(isDev = false) {
378
498
  logger.info(`Starting VaderJS ${isDev ? 'development' : 'production'} build...`);
379
499
  const totalTime = performance.now();
380
500
 
@@ -412,7 +532,35 @@ async function runDevServer() {
412
532
 
413
533
  logger.info(`Starting dev server at http://localhost:${port}`);
414
534
 
415
- serve({
535
+ // Set up watchers for all important directories
536
+ logger.info("Setting up file watchers...");
537
+
538
+ // Clear any existing watchers
539
+ watcher.clear();
540
+
541
+ // Watch app directory (excluding dist)
542
+ if (fsSync.existsSync(APP_DIR)) {
543
+ await watcher.watchDirectory(APP_DIR, true);
544
+ }
545
+
546
+ // Watch src directory (excluding dist)
547
+ if (fsSync.existsSync(SRC_DIR)) {
548
+ await watcher.watchDirectory(SRC_DIR, true);
549
+ }
550
+
551
+ // Watch public directory (excluding dist)
552
+ if (fsSync.existsSync(PUBLIC_DIR)) {
553
+ await watcher.watchDirectory(PUBLIC_DIR, true);
554
+ }
555
+
556
+ // Watch config files by watching their directory
557
+ const configPath = path.join(PROJECT_ROOT, "vaderjs.config.js");
558
+ const configPathTs = path.join(PROJECT_ROOT, "vaderjs.config.ts");
559
+
560
+ // Watch the project root for config files
561
+ await watcher.watchDirectory(PROJECT_ROOT, false);
562
+
563
+ const server = serve({
416
564
  port,
417
565
  fetch(req, server) {
418
566
  const url = new URL(req.url);
@@ -434,40 +582,51 @@ async function runDevServer() {
434
582
  },
435
583
  });
436
584
 
437
- const debouncedBuild = debounce(async (event, filename) => {
438
- logger.info(`File change detected: ${filename || 'unknown'}`);
585
+ const rebuild = async (changedFile) => {
439
586
  try {
440
- // Reload config in case plugins or ports changed
441
- config = await loadConfig();
587
+ watcher.setRebuilding(true);
588
+
589
+ logger.info(`Rebuilding due to: ${path.relative(PROJECT_ROOT, changedFile)}`);
590
+
591
+ // Reload config if config file changed
592
+ if (changedFile.includes('vaderjs.config.')) {
593
+ config = await loadConfig();
594
+ }
442
595
 
596
+ // Always rebuild when something changes in development
443
597
  await buildAll(true);
444
598
 
599
+ // Send reload signal to all clients
445
600
  for (const client of clients) {
446
601
  client.send("reload");
447
602
  }
603
+
604
+ logger.success("Rebuild complete");
448
605
  } catch (e) {
449
606
  logger.error("Rebuild failed:", e);
607
+ } finally {
608
+ watcher.setRebuilding(false);
450
609
  }
451
- }, 200);
452
-
453
- // --- IMPROVED WATCHER ---
454
- const configPath = path.join(PROJECT_ROOT, "vaderjs.config.js");
455
- const configPathTs = path.join(PROJECT_ROOT, "vaderjs.config.ts");
610
+ };
456
611
 
457
- const watchTargets = [
458
- APP_DIR,
459
- SRC_DIR,
460
- PUBLIC_DIR,
461
- configPath,
462
- configPathTs
463
- ].filter(p => fsSync.existsSync(p));
612
+ // Set up file change listener
613
+ const removeListener = watcher.onChange((changedFile) => {
614
+ rebuild(changedFile);
615
+ });
464
616
 
465
- logger.info(`Watching for changes in: ${watchTargets.map(p => path.basename(p)).join(", ")}`);
617
+ // Cleanup on exit
618
+ const cleanup = () => {
619
+ removeListener();
620
+ watcher.clear();
621
+ server.stop();
622
+ process.exit(0);
623
+ };
466
624
 
467
- for (const target of watchTargets) {
468
- safeWatch(target, debouncedBuild);
469
- }
625
+ process.on('SIGINT', cleanup);
626
+ process.on('SIGTERM', cleanup);
627
+ process.on('exit', cleanup);
470
628
  }
629
+
471
630
  async function runProdServer() {
472
631
  const port = config.port || 3000;
473
632
  logger.info(`Serving production build from /dist on http://localhost:${port}`);
@@ -487,14 +646,6 @@ async function runProdServer() {
487
646
  });
488
647
  }
489
648
 
490
- function debounce(fn, delay) {
491
- let timeoutId;
492
- return (...args) => {
493
- clearTimeout(timeoutId);
494
- timeoutId = setTimeout(() => fn(...args), delay);
495
- };
496
- }
497
-
498
649
  // --- SCRIPT ENTRYPOINT ---
499
650
 
500
651
  async function main() {
@@ -523,7 +674,7 @@ async function main() {
523
674
  logger.error("Please specify a plugin to add.");
524
675
  process.exit(1);
525
676
  }
526
- await addPlugin(arg)
677
+ await addPlugin(arg);
527
678
  return;
528
679
  }
529
680
 
@@ -534,21 +685,21 @@ async function main() {
534
685
  switch (command) {
535
686
  case "add":
536
687
  if (!arg) {
537
- logger.error("Please specify a plugin to add.");
538
- process.exit(1);
539
- }
540
- await addPlugin(arg)
541
- return;
688
+ logger.error("Please specify a plugin to add.");
689
+ process.exit(1);
690
+ }
691
+ await addPlugin(arg);
692
+ return;
542
693
  case "list_plugins":
543
- await listPlugins()
544
- return
545
- case "remove":
694
+ await listPlugins();
695
+ return;
696
+ case "remove":
546
697
  if (!arg) {
547
- logger.error("Please specify a plugin to remove.");
548
- process.exit(1);
549
- }
550
- await removePlugin(arg)
551
- return
698
+ logger.error("Please specify a plugin to remove.");
699
+ process.exit(1);
700
+ }
701
+ await removePlugin(arg);
702
+ return;
552
703
 
553
704
  case "dev":
554
705
  globalThis.isDev = true;
@@ -585,14 +736,15 @@ Available commands:
585
736
  }
586
737
  }
587
738
 
588
-
589
739
  main().catch(err => {
590
740
  logger.error("An unexpected error occurred:", err);
591
741
  process.exit(1);
592
742
  });
743
+
593
744
  process.on("unhandledRejection", (err) => {
594
745
  logger.error("Unhandled Promise rejection:", err);
595
746
  });
747
+
596
748
  process.on("uncaughtException", (err) => {
597
749
  logger.error("Uncaught Exception:", err);
598
750
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vaderjs",
3
- "version": "2.3.10",
3
+ "version": "2.3.12",
4
4
  "description": "A simple and powerful JavaScript library for building modern web applications.",
5
5
  "bin": {
6
6
  "vaderjs": "./main.js"