pulse-js-framework 1.4.10 → 1.5.1

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/cli/analyze.js CHANGED
@@ -6,6 +6,7 @@
6
6
  import { readFileSync, statSync, existsSync } from 'fs';
7
7
  import { join, dirname, basename, relative } from 'path';
8
8
  import { findPulseFiles, parseArgs, formatBytes, relativePath, resolveImportPath } from './utils/file-utils.js';
9
+ import { log } from './logger.js';
9
10
 
10
11
  /**
11
12
  * Analyze the bundle/project
@@ -472,28 +473,28 @@ export async function runAnalyze(args) {
472
473
 
473
474
  // Check if src directory exists
474
475
  if (!existsSync(join(root, 'src'))) {
475
- console.error('Error: No src/ directory found.');
476
- console.log('Run this command from your Pulse project root.');
476
+ log.error('Error: No src/ directory found.');
477
+ log.info('Run this command from your Pulse project root.');
477
478
  process.exit(1);
478
479
  }
479
480
 
480
- console.log('Analyzing bundle...\n');
481
+ log.info('Analyzing bundle...\n');
481
482
 
482
483
  try {
483
484
  const analysis = await analyzeBundle(root);
484
485
 
485
486
  if (json) {
486
- console.log(JSON.stringify(analysis, null, 2));
487
+ log.info(JSON.stringify(analysis, null, 2));
487
488
  } else {
488
- console.log(formatConsoleOutput(analysis, verbose));
489
+ log.info(formatConsoleOutput(analysis, verbose));
489
490
  }
490
491
 
491
492
  // Exit with error if dead code found
492
493
  if (analysis.deadCode.length > 0 && !json) {
493
- console.log(`\nWarning: ${analysis.deadCode.length} potentially unused file(s) found.`);
494
+ log.warn(`\nWarning: ${analysis.deadCode.length} potentially unused file(s) found.`);
494
495
  }
495
496
  } catch (error) {
496
- console.error('Analysis failed:', error.message);
497
+ log.error('Analysis failed:', error.message);
497
498
  process.exit(1);
498
499
  }
499
500
  }
package/cli/build.js CHANGED
@@ -7,6 +7,7 @@
7
7
  import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync, copyFileSync } from 'fs';
8
8
  import { join, extname, relative, dirname } from 'path';
9
9
  import { compile } from '../compiler/index.js';
10
+ import { log } from './logger.js';
10
11
 
11
12
  /**
12
13
  * Build project for production
@@ -19,7 +20,7 @@ export async function buildProject(args) {
19
20
  try {
20
21
  const viteConfig = join(root, 'vite.config.js');
21
22
  if (existsSync(viteConfig)) {
22
- console.log('Vite config detected, using Vite build...');
23
+ log.info('Vite config detected, using Vite build...');
23
24
  const { build } = await import('vite');
24
25
  await build({ root });
25
26
  return;
@@ -28,7 +29,7 @@ export async function buildProject(args) {
28
29
  // Vite not available, use built-in build
29
30
  }
30
31
 
31
- console.log('Building with Pulse compiler...');
32
+ log.info('Building with Pulse compiler...');
32
33
 
33
34
  // Create output directory
34
35
  if (!existsSync(outDir)) {
@@ -67,7 +68,7 @@ export async function buildProject(args) {
67
68
  // Bundle runtime
68
69
  bundleRuntime(outDir);
69
70
 
70
- console.log(`
71
+ log.success(`
71
72
  Build complete!
72
73
 
73
74
  Output directory: ${relative(root, outDir)}
@@ -104,11 +105,11 @@ function processDirectory(srcDir, outDir) {
104
105
  if (result.success) {
105
106
  const outPath = join(outDir, file.replace('.pulse', '.js'));
106
107
  writeFileSync(outPath, result.code);
107
- console.log(` Compiled: ${file}`);
108
+ log.info(` Compiled: ${file}`);
108
109
  } else {
109
- console.error(` Error compiling ${file}:`);
110
+ log.error(` Error compiling ${file}:`);
110
111
  for (const error of result.errors) {
111
- console.error(` ${error.message}`);
112
+ log.error(` ${error.message}`);
112
113
  }
113
114
  }
114
115
  } else if (file.endsWith('.js') || file.endsWith('.mjs')) {
@@ -129,7 +130,7 @@ function processDirectory(srcDir, outDir) {
129
130
 
130
131
  const outPath = join(outDir, file);
131
132
  writeFileSync(outPath, content);
132
- console.log(` Processed & minified: ${file}`);
133
+ log.info(` Processed & minified: ${file}`);
133
134
  } else {
134
135
  // Copy other files
135
136
  const outPath = join(outDir, file);
@@ -155,9 +156,9 @@ ${readRuntimeFile('store.js')}
155
156
 
156
157
  if (shouldMinify) {
157
158
  runtimeCode = minifyJS(runtimeCode);
158
- console.log(' Bundled & minified: runtime.js');
159
+ log.info(' Bundled & minified: runtime.js');
159
160
  } else {
160
- console.log(' Bundled: runtime.js');
161
+ log.info(' Bundled: runtime.js');
161
162
  }
162
163
 
163
164
  writeFileSync(join(outDir, 'assets', 'runtime.js'), runtimeCode);
@@ -178,7 +179,7 @@ function readRuntimeFile(filename) {
178
179
  }
179
180
  }
180
181
 
181
- console.warn(` Warning: Could not find runtime file: ${filename}`);
182
+ log.warn(` Warning: Could not find runtime file: ${filename}`);
182
183
  return '';
183
184
  }
184
185
 
@@ -263,7 +264,7 @@ export async function previewBuild(args) {
263
264
  const distDir = join(root, 'dist');
264
265
 
265
266
  if (!existsSync(distDir)) {
266
- console.error('No dist folder found. Run "pulse build" first.');
267
+ log.error('No dist folder found. Run "pulse build" first.');
267
268
  process.exit(1);
268
269
  }
269
270
 
@@ -271,7 +272,7 @@ export async function previewBuild(args) {
271
272
  try {
272
273
  const viteConfig = join(root, 'vite.config.js');
273
274
  if (existsSync(viteConfig)) {
274
- console.log('Using Vite preview...');
275
+ log.info('Using Vite preview...');
275
276
  const { preview } = await import('vite');
276
277
  const server = await preview({
277
278
  root,
@@ -327,7 +328,7 @@ export async function previewBuild(args) {
327
328
  });
328
329
 
329
330
  server.listen(port, () => {
330
- console.log(`
331
+ log.success(`
331
332
  Pulse Preview Server running at:
332
333
 
333
334
  Local: http://localhost:${port}/
package/cli/dev.js CHANGED
@@ -8,6 +8,7 @@ import { createServer } from 'http';
8
8
  import { readFileSync, existsSync, statSync, watch } from 'fs';
9
9
  import { join, extname, resolve } from 'path';
10
10
  import { compile } from '../compiler/index.js';
11
+ import { log } from './logger.js';
11
12
 
12
13
  const MIME_TYPES = {
13
14
  '.html': 'text/html',
@@ -31,14 +32,28 @@ const clients = new Set();
31
32
  * Start the development server
32
33
  */
33
34
  export async function startDevServer(args) {
34
- const port = parseInt(args[0]) || 3000;
35
- const root = process.cwd();
35
+ // Parse args: can be [port], [dir], or [dir, port]
36
+ let port = 3000;
37
+ let root = process.cwd();
38
+
39
+ if (args.length >= 1) {
40
+ if (/^\d+$/.test(args[0])) {
41
+ // First arg is a port number
42
+ port = parseInt(args[0]);
43
+ } else {
44
+ // First arg is a directory
45
+ root = resolve(process.cwd(), args[0]);
46
+ if (args[1] && /^\d+$/.test(args[1])) {
47
+ port = parseInt(args[1]);
48
+ }
49
+ }
50
+ }
36
51
 
37
52
  // Check if vite is available, use it if so
38
53
  try {
39
54
  const viteConfig = join(root, 'vite.config.js');
40
55
  if (existsSync(viteConfig)) {
41
- console.log('Vite config detected, using Vite...');
56
+ log.info('Vite config detected, using Vite...');
42
57
  const { createServer: createViteServer } = await import('vite');
43
58
  const server = await createViteServer({
44
59
  root,
@@ -79,7 +94,10 @@ export async function startDevServer(args) {
79
94
  try {
80
95
  const source = readFileSync(filePath, 'utf-8');
81
96
  const result = compile(source, {
82
- runtime: '/runtime/index.js'
97
+ runtime: '/runtime/index.js',
98
+ sourceMap: true,
99
+ inlineSourceMap: true,
100
+ sourceFileName: pathname
83
101
  });
84
102
 
85
103
  if (result.success) {
@@ -112,7 +130,10 @@ export async function startDevServer(args) {
112
130
  try {
113
131
  const source = readFileSync(pulseFilePath, 'utf-8');
114
132
  const result = compile(source, {
115
- runtime: '/runtime/index.js'
133
+ runtime: '/runtime/index.js',
134
+ sourceMap: true,
135
+ inlineSourceMap: true,
136
+ sourceFileName: pulseFilePath.replace(root, '')
116
137
  });
117
138
 
118
139
  if (result.success) {
@@ -181,7 +202,7 @@ export async function startDevServer(args) {
181
202
  watchFiles(root);
182
203
 
183
204
  server.listen(port, () => {
184
- console.log(`
205
+ log.success(`
185
206
  Pulse Dev Server running at:
186
207
 
187
208
  Local: http://localhost:${port}/
@@ -200,7 +221,7 @@ function watchFiles(root) {
200
221
  if (existsSync(srcDir)) {
201
222
  watch(srcDir, { recursive: true }, (eventType, filename) => {
202
223
  if (filename && filename.endsWith('.pulse')) {
203
- console.log(`File changed: ${filename}`);
224
+ log.debug(`File changed: ${filename}`);
204
225
  // Notify HMR clients (simplified)
205
226
  notifyClients({ type: 'update', path: `/src/${filename}` });
206
227
  }
package/cli/format.js CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  import { readFileSync, writeFileSync } from 'fs';
7
7
  import { findPulseFiles, parseArgs, relativePath } from './utils/file-utils.js';
8
+ import { log } from './logger.js';
8
9
 
9
10
  /**
10
11
  * Default format options
@@ -645,11 +646,11 @@ export async function runFormat(args) {
645
646
  const files = findPulseFiles(patterns);
646
647
 
647
648
  if (files.length === 0) {
648
- console.log('No .pulse files found to format.');
649
+ log.info('No .pulse files found to format.');
649
650
  return;
650
651
  }
651
652
 
652
- console.log(`${check ? 'Checking' : 'Formatting'} ${files.length} file(s)...\n`);
653
+ log.info(`${check ? 'Checking' : 'Formatting'} ${files.length} file(s)...\n`);
653
654
 
654
655
  let changedCount = 0;
655
656
  let errorCount = 0;
@@ -659,7 +660,7 @@ export async function runFormat(args) {
659
660
  const relPath = relativePath(file);
660
661
 
661
662
  if (result.error) {
662
- console.log(` ${relPath} - ERROR: ${result.error}`);
663
+ log.error(` ${relPath} - ERROR: ${result.error}`);
663
664
  errorCount++;
664
665
  continue;
665
666
  }
@@ -668,37 +669,37 @@ export async function runFormat(args) {
668
669
  changedCount++;
669
670
 
670
671
  if (check) {
671
- console.log(` ${relPath} - needs formatting`);
672
+ log.warn(` ${relPath} - needs formatting`);
672
673
  } else if (write) {
673
674
  writeFileSync(file, result.formatted);
674
- console.log(` ${relPath} - formatted`);
675
+ log.info(` ${relPath} - formatted`);
675
676
  }
676
677
  } else {
677
678
  if (!check) {
678
- console.log(` ${relPath} - unchanged`);
679
+ log.info(` ${relPath} - unchanged`);
679
680
  }
680
681
  }
681
682
  }
682
683
 
683
684
  // Summary
684
- console.log('\n' + '─'.repeat(60));
685
+ log.info('\n' + '─'.repeat(60));
685
686
 
686
687
  if (errorCount > 0) {
687
- console.log(`✗ ${errorCount} file(s) had errors`);
688
+ log.error(`✗ ${errorCount} file(s) had errors`);
688
689
  }
689
690
 
690
691
  if (check) {
691
692
  if (changedCount > 0) {
692
- console.log(`✗ ${changedCount} file(s) need formatting`);
693
+ log.error(`✗ ${changedCount} file(s) need formatting`);
693
694
  process.exit(1);
694
695
  } else {
695
- console.log(`✓ All ${files.length} file(s) are properly formatted`);
696
+ log.success(`✓ All ${files.length} file(s) are properly formatted`);
696
697
  }
697
698
  } else {
698
699
  if (changedCount > 0) {
699
- console.log(`✓ ${changedCount} file(s) formatted`);
700
+ log.success(`✓ ${changedCount} file(s) formatted`);
700
701
  } else {
701
- console.log(`✓ All ${files.length} file(s) were already formatted`);
702
+ log.success(`✓ All ${files.length} file(s) were already formatted`);
702
703
  }
703
704
  }
704
705
  }
package/cli/index.js CHANGED
@@ -28,7 +28,8 @@ const commands = {
28
28
  mobile: runMobile,
29
29
  lint: runLint,
30
30
  format: runFormat,
31
- analyze: runAnalyze
31
+ analyze: runAnalyze,
32
+ release: runReleaseCmd
32
33
  };
33
34
 
34
35
  /**
@@ -66,6 +67,7 @@ Commands:
66
67
  lint [files] Validate .pulse files for errors and style
67
68
  format [files] Format .pulse files consistently
68
69
  analyze Analyze bundle size and dependencies
70
+ release <type> Create a new release (patch, minor, major)
69
71
  version Show version number
70
72
  help Show this help message
71
73
 
@@ -80,6 +82,12 @@ Analyze Options:
80
82
  --json Output analysis as JSON
81
83
  --verbose Show detailed metrics
82
84
 
85
+ Release Options:
86
+ --dry-run Show what would be done without making changes
87
+ --no-push Create commit and tag but don't push
88
+ --title <text> Release title for changelog
89
+ --skip-prompt Use empty changelog (for automation)
90
+
83
91
  Examples:
84
92
  pulse create my-app
85
93
  pulse dev
@@ -96,6 +104,9 @@ Examples:
96
104
  pulse format src/App.pulse
97
105
  pulse analyze
98
106
  pulse analyze --json
107
+ pulse release patch
108
+ pulse release minor --title "New Features"
109
+ pulse release major --dry-run
99
110
 
100
111
  Documentation: https://github.com/vincenthirtz/pulse-js-framework
101
112
  `);
@@ -359,6 +370,14 @@ async function runAnalyze(args) {
359
370
  await runAnalyze(args);
360
371
  }
361
372
 
373
+ /**
374
+ * Run release command
375
+ */
376
+ async function runReleaseCmd(args) {
377
+ const { runRelease } = await import('./release.js');
378
+ await runRelease(args);
379
+ }
380
+
362
381
  /**
363
382
  * Compile a single .pulse file
364
383
  */
package/cli/lint.js CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  import { readFileSync, writeFileSync } from 'fs';
7
7
  import { findPulseFiles, parseArgs, relativePath } from './utils/file-utils.js';
8
+ import { log } from './logger.js';
8
9
 
9
10
  /**
10
11
  * Lint rules configuration
@@ -710,11 +711,11 @@ export async function runLint(args) {
710
711
  const files = findPulseFiles(patterns);
711
712
 
712
713
  if (files.length === 0) {
713
- console.log('No .pulse files found to lint.');
714
+ log.info('No .pulse files found to lint.');
714
715
  return;
715
716
  }
716
717
 
717
- console.log(`Linting ${files.length} file(s)...\n`);
718
+ log.info(`Linting ${files.length} file(s)...\n`);
718
719
 
719
720
  let totalErrors = 0;
720
721
  let totalWarnings = 0;
@@ -725,10 +726,10 @@ export async function runLint(args) {
725
726
  const relPath = relativePath(file);
726
727
 
727
728
  if (result.diagnostics.length > 0) {
728
- console.log(`\n${relPath}`);
729
+ log.info(`\n${relPath}`);
729
730
 
730
731
  for (const diag of result.diagnostics) {
731
- console.log(formatDiagnostic(diag));
732
+ log.info(formatDiagnostic(diag));
732
733
 
733
734
  switch (diag.severity) {
734
735
  case 'error': totalErrors++; break;
@@ -740,16 +741,16 @@ export async function runLint(args) {
740
741
  }
741
742
 
742
743
  // Summary
743
- console.log('\n' + '─'.repeat(60));
744
+ log.info('\n' + '─'.repeat(60));
744
745
  const parts = [];
745
746
  if (totalErrors > 0) parts.push(`${totalErrors} error(s)`);
746
747
  if (totalWarnings > 0) parts.push(`${totalWarnings} warning(s)`);
747
748
  if (totalInfo > 0) parts.push(`${totalInfo} info`);
748
749
 
749
750
  if (parts.length === 0) {
750
- console.log(`✓ ${files.length} file(s) passed`);
751
+ log.success(`✓ ${files.length} file(s) passed`);
751
752
  } else {
752
- console.log(`✗ ${parts.join(', ')} in ${files.length} file(s)`);
753
+ log.error(`✗ ${parts.join(', ')} in ${files.length} file(s)`);
753
754
  }
754
755
 
755
756
  // Exit with error code if errors found