vaderjs 2.3.11 → 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 +305 -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
  }
@@ -102,7 +223,7 @@ export function defineConfig(config) {
102
223
  return config;
103
224
  }
104
225
 
105
- async function runPluginHook(hookName) {
226
+ async function runPluginHook(hookName) {
106
227
  if (!config.plugins) return;
107
228
  for (const plugin of config.plugins) {
108
229
  if (typeof plugin[hookName] === "function") {
@@ -115,8 +236,6 @@ async function runPluginHook(hookName) {
115
236
  }
116
237
  }
117
238
 
118
-
119
-
120
239
  // --- BUILD LOGIC ---
121
240
 
122
241
  /**
@@ -146,6 +265,7 @@ async function buildVaderCore() {
146
265
  function patchHooksUsage(code) {
147
266
  return code.replace(/import\s+{[^}]*use(State|Effect|Memo|Navigation)[^}]*}\s+from\s+['"]vaderjs['"];?\n?/g, "");
148
267
  }
268
+
149
269
  function publicAssetPlugin() {
150
270
  return {
151
271
  name: "public-asset-replacer",
@@ -182,7 +302,6 @@ function publicAssetPlugin() {
182
302
  /**
183
303
  * Step 3: Pre-processes all files in `/src` into a temporary directory.
184
304
  */
185
-
186
305
  async function preprocessSources(srcDir, tempDir) {
187
306
  await fs.mkdir(tempDir, { recursive: true });
188
307
  for (const entry of await fs.readdir(srcDir, { withFileTypes: true })) {
@@ -193,7 +312,7 @@ async function preprocessSources(srcDir, tempDir) {
193
312
  await preprocessSources(srcPath, destPath);
194
313
  } else if (/\.(tsx|jsx|ts|js)$/.test(entry.name)) {
195
314
  let content = await fs.readFile(srcPath, "utf8");
196
- content = patchHooksUsage(content);
315
+ content = patchHooksUsage(content);
197
316
  await fs.writeFile(destPath, content);
198
317
  } else {
199
318
  await fs.copyFile(srcPath, destPath);
@@ -249,14 +368,28 @@ async function copyPublicAssets() {
249
368
  }
250
369
  }
251
370
 
252
- async function buildAppEntrypoints(isDev = false) {
253
- if (!fsSync.existsSync(APP_DIR)) {
254
- logger.warn("No '/app' directory found, skipping app entrypoint build.");
255
- return;
256
- }
257
-
258
- if (!fsSync.existsSync(DIST_DIR)) {
259
- 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
+ }
260
393
  }
261
394
 
262
395
  const devClientScript = isDev
@@ -267,49 +400,8 @@ async function copyPublicAssets() {
267
400
  </script>`
268
401
  : "";
269
402
 
270
- const entries = fsSync.readdirSync(APP_DIR, { recursive: true })
271
- .filter(file => /index\.(jsx|tsx)$/.test(file))
272
- .map(file => ({
273
- name: path.dirname(file) === '.' ? 'index' : path.dirname(file).replace(/\\/g, '/'),
274
- path: path.join(APP_DIR, file)
275
- }));
276
-
277
- // Helper to resolve any asset path from /public
278
- function resolvePublicPath(p) {
279
- const assetPath = p.replace(/^(\.\/|\/)/, ""); // strip leading ./ or /
280
- const absPath = path.join(PUBLIC_DIR, assetPath);
281
- if (fsSync.existsSync(absPath)) {
282
- return "/" + assetPath.replace(/\\/g, "/");
283
- }
284
- return p; // leave unchanged if not in public
285
- }
286
-
287
- for (const { name, path: entryPath } of entries) {
288
- const outDir = path.join(DIST_DIR, name === 'index' ? '' : name);
289
- const outJsPath = path.join(outDir, 'index.js');
290
- await fs.mkdir(outDir, { recursive: true });
291
-
292
- // --- CSS HANDLING ---
293
- const cssLinks = [];
294
- let content = await fs.readFile(entryPath, "utf8");
295
- const cssImports = [...content.matchAll(/import\s+['"](.*\.css)['"]/g)];
296
- for (const match of cssImports) {
297
- const cssImportPath = match[1];
298
- const sourceCssPath = path.resolve(path.dirname(entryPath), cssImportPath);
299
- if (fsSync.existsSync(sourceCssPath)) {
300
- const relativeCssPath = path.relative(APP_DIR, sourceCssPath);
301
- const destCssPath = path.join(DIST_DIR, relativeCssPath);
302
- await fs.mkdir(path.dirname(destCssPath), { recursive: true });
303
- await fs.copyFile(sourceCssPath, destCssPath);
304
- const htmlRelativePath = path.relative(outDir, destCssPath).replace(/\\/g, '/');
305
- cssLinks.push(`<link rel="stylesheet" href="${htmlRelativePath}">`);
306
- } else {
307
- logger.warn(`CSS file not found: ${sourceCssPath}`);
308
- }
309
- }
310
-
311
- // --- HTML GENERATION ---
312
- let htmlContent = `<!DOCTYPE html>
403
+ // --- HTML GENERATION ---
404
+ let htmlContent = `<!DOCTYPE html>
313
405
  <html lang="en">
314
406
  <head>
315
407
  <meta charset="UTF-8" />
@@ -330,50 +422,79 @@ async function copyPublicAssets() {
330
422
  </body>
331
423
  </html>`;
332
424
 
333
- // --- FIX ASSET PATHS IN HTML ---
334
- htmlContent = htmlContent.replace(
335
- /(["'(])([^"'()]+?\.(png|jpe?g|gif|svg|webp|ico))(["')])/gi,
336
- (match, p1, assetPath, ext, p4) => p1 + resolvePublicPath(assetPath) + p4
337
- );
338
-
339
- await fs.writeFile(path.join(outDir, "index.html"), htmlContent);
340
-
341
- // --- JS BUILD ---
342
- await build({
343
- entrypoints: [entryPath],
344
- outdir: outDir,
345
- target: "browser",
346
- minify: false,
347
- sourcemap: "external",
348
- external: ["vaderjs"],
349
- jsxFactory: "e",
350
- jsxFragment: "Fragment",
351
- 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: [
352
454
  publicAssetPlugin(),
353
455
  ],
354
- jsxImportSource: "vaderjs",
355
- });
456
+ jsxImportSource: "vaderjs",
457
+ });
356
458
 
357
- // --- FIX IMPORT PATHS IN JS ---
358
- let jsContent = await fs.readFile(outJsPath, "utf8");
459
+ // --- FIX IMPORT PATHS IN JS ---
460
+ let jsContent = await fs.readFile(outJsPath, "utf8");
359
461
 
360
- // Vader import fix
361
- 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'`);
362
464
 
363
- // Asset path fix for JS
364
- jsContent = jsContent.replace(
365
- /(["'(])([^"'()]+?\.(png|jpe?g|gif|svg|webp|ico))(["')])/gi,
366
- (match, p1, assetPath, ext, p4) => p1 + resolvePublicPath(assetPath) + p4
367
- );
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
+ );
368
470
 
369
- await fs.writeFile(outJsPath, jsContent);
370
- }
471
+ await fs.writeFile(outJsPath, jsContent);
371
472
  }
372
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
+ }));
373
491
 
374
-
492
+ for (const { name, path: entryPath } of entries) {
493
+ await buildAppEntrypoint(entryPath, name, isDev);
494
+ }
495
+ }
375
496
 
376
- async function buildAll(isDev = false) {
497
+ async function buildAll(isDev = false) {
377
498
  logger.info(`Starting VaderJS ${isDev ? 'development' : 'production'} build...`);
378
499
  const totalTime = performance.now();
379
500
 
@@ -411,7 +532,35 @@ async function runDevServer() {
411
532
 
412
533
  logger.info(`Starting dev server at http://localhost:${port}`);
413
534
 
414
- 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({
415
564
  port,
416
565
  fetch(req, server) {
417
566
  const url = new URL(req.url);
@@ -433,40 +582,51 @@ async function runDevServer() {
433
582
  },
434
583
  });
435
584
 
436
- const debouncedBuild = debounce(async (event, filename) => {
437
- logger.info(`File change detected: ${filename || 'unknown'}`);
585
+ const rebuild = async (changedFile) => {
438
586
  try {
439
- // Reload config in case plugins or ports changed
440
- 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
+ }
441
595
 
596
+ // Always rebuild when something changes in development
442
597
  await buildAll(true);
443
598
 
599
+ // Send reload signal to all clients
444
600
  for (const client of clients) {
445
601
  client.send("reload");
446
602
  }
603
+
604
+ logger.success("Rebuild complete");
447
605
  } catch (e) {
448
606
  logger.error("Rebuild failed:", e);
607
+ } finally {
608
+ watcher.setRebuilding(false);
449
609
  }
450
- }, 200);
451
-
452
- // --- IMPROVED WATCHER ---
453
- const configPath = path.join(PROJECT_ROOT, "vaderjs.config.js");
454
- const configPathTs = path.join(PROJECT_ROOT, "vaderjs.config.ts");
610
+ };
455
611
 
456
- const watchTargets = [
457
- APP_DIR,
458
- SRC_DIR,
459
- PUBLIC_DIR,
460
- configPath,
461
- configPathTs
462
- ].filter(p => fsSync.existsSync(p));
612
+ // Set up file change listener
613
+ const removeListener = watcher.onChange((changedFile) => {
614
+ rebuild(changedFile);
615
+ });
463
616
 
464
- 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
+ };
465
624
 
466
- for (const target of watchTargets) {
467
- safeWatch(target, debouncedBuild);
468
- }
625
+ process.on('SIGINT', cleanup);
626
+ process.on('SIGTERM', cleanup);
627
+ process.on('exit', cleanup);
469
628
  }
629
+
470
630
  async function runProdServer() {
471
631
  const port = config.port || 3000;
472
632
  logger.info(`Serving production build from /dist on http://localhost:${port}`);
@@ -486,14 +646,6 @@ async function runProdServer() {
486
646
  });
487
647
  }
488
648
 
489
- function debounce(fn, delay) {
490
- let timeoutId;
491
- return (...args) => {
492
- clearTimeout(timeoutId);
493
- timeoutId = setTimeout(() => fn(...args), delay);
494
- };
495
- }
496
-
497
649
  // --- SCRIPT ENTRYPOINT ---
498
650
 
499
651
  async function main() {
@@ -522,7 +674,7 @@ async function main() {
522
674
  logger.error("Please specify a plugin to add.");
523
675
  process.exit(1);
524
676
  }
525
- await addPlugin(arg)
677
+ await addPlugin(arg);
526
678
  return;
527
679
  }
528
680
 
@@ -533,21 +685,21 @@ async function main() {
533
685
  switch (command) {
534
686
  case "add":
535
687
  if (!arg) {
536
- logger.error("Please specify a plugin to add.");
537
- process.exit(1);
538
- }
539
- await addPlugin(arg)
540
- return;
688
+ logger.error("Please specify a plugin to add.");
689
+ process.exit(1);
690
+ }
691
+ await addPlugin(arg);
692
+ return;
541
693
  case "list_plugins":
542
- await listPlugins()
543
- return
544
- case "remove":
694
+ await listPlugins();
695
+ return;
696
+ case "remove":
545
697
  if (!arg) {
546
- logger.error("Please specify a plugin to remove.");
547
- process.exit(1);
548
- }
549
- await removePlugin(arg)
550
- return
698
+ logger.error("Please specify a plugin to remove.");
699
+ process.exit(1);
700
+ }
701
+ await removePlugin(arg);
702
+ return;
551
703
 
552
704
  case "dev":
553
705
  globalThis.isDev = true;
@@ -584,14 +736,15 @@ Available commands:
584
736
  }
585
737
  }
586
738
 
587
-
588
739
  main().catch(err => {
589
740
  logger.error("An unexpected error occurred:", err);
590
741
  process.exit(1);
591
742
  });
743
+
592
744
  process.on("unhandledRejection", (err) => {
593
745
  logger.error("Unhandled Promise rejection:", err);
594
746
  });
747
+
595
748
  process.on("uncaughtException", (err) => {
596
749
  logger.error("Uncaught Exception:", err);
597
750
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vaderjs",
3
- "version": "2.3.11",
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"