neutronium 2.8.7 → 2.9.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/README.md CHANGED
@@ -36,7 +36,7 @@ npm i neutronium@latest -g
36
36
  ## šŸ› ļø Setup
37
37
 
38
38
  ```
39
- neu-cli create-app && npm i neutronium@latest -g
39
+ neu-cli create-app my-app
40
40
  ```
41
41
 
42
42
  ## Usage Example
@@ -61,24 +61,4 @@ createApp(App).mount('body');
61
61
  ```
62
62
 
63
63
  ## Result:
64
- <iframe
65
- style="width:100%; height:200px; border:1px solid #ccc;"
66
- srcdoc='
67
- <!DOCTYPE html>
68
- <html>
69
- <head>
70
- <style>
71
- body {
72
- font-family: sans-serif;
73
- margin: 0;
74
- padding: 1em;
75
- }
76
- </style>
77
- </head>
78
- <body>
79
- <h1>Welcome to Neutronium</h1>
80
- <h2>Hello, yourName!</h2>
81
- </body>
82
- </html>
83
- '>
84
- </iframe>
64
+ ![Results](https://raw.githubusercontent.com/PFMCODES/neutronium/main/results.png)
package/cli/index.js CHANGED
@@ -1,6 +1,5 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
- // --- Module Imports ---
4
3
  const { default: inquirer } = require('inquirer');
5
4
  const fs = require('fs');
6
5
  const path = require('path');
@@ -8,37 +7,34 @@ const { execSync } = require('child_process');
8
7
  const { transformSync } = require('@babel/core');
9
8
  const { compileProject, compileProjectWatch } = require('../compiler/compiler');
10
9
 
11
- // --- CLI Arguments ---
12
10
  const [, , command, ...args] = process.argv;
13
11
 
14
- // --- Default Babel Config ---
15
12
  const babelRc = `{
16
- "plugins": [
17
- ["@babel/plugin-transform-react-jsx", {
18
- "pragma": "_neutronium.h",
19
- "pragmaFrag": "_neutronium.Fragment",
20
- "runtime": "classic",
21
- "useBuiltIns": false,
22
- "sourceMaps": true,
23
- "comments": false,
24
- "minified": true,
25
- }]
26
- ]
27
- `;
13
+ "plugins": [
14
+ ["@babel/plugin-transform-react-jsx", {
15
+ "pragma": "_neutronium.h",
16
+ "pragmaFrag": "_neutronium.Fragment",
17
+ "runtime": "classic",
18
+ "useBuiltIns": false,
19
+ "sourceMaps": true,
20
+ "comments": false,
21
+ "minified": true
22
+ }]
23
+ ]
24
+ }`;
28
25
 
29
26
  const AppTs = `
30
27
  import { createApp } from 'neutronium';
31
28
 
32
29
  function App() {
33
30
  return (
34
- <h1>Hello World</h1>
31
+ <h1>Hello World (TypeScript)</h1>
35
32
  );
36
33
  }
37
34
 
38
- createApp(App).mount('body');
39
- `
35
+ createApp(App).mount("body");
36
+ `;
40
37
 
41
- // --- Default App.js Starter Template ---
42
38
  const AppJs = `
43
39
  import { createApp } from 'neutronium';
44
40
 
@@ -48,31 +44,28 @@ function App() {
48
44
  );
49
45
  }
50
46
 
51
- createApp(App).mount('body');
47
+ createApp(App).mount("body");
52
48
  `;
53
49
 
54
- // --- Basic HTML Template Function ---
55
50
  const htmlTemplate = (title, jsCode) => `
56
51
  <!DOCTYPE html>
57
52
  <html>
58
- <head>
59
- <meta charset="UTF-8" />
60
- <title>${title}</title>
61
- </head>
62
- <body>
63
- <script type="module">
64
- ${jsCode}
65
- </script>
66
- </body>
53
+ <head>
54
+ <meta charset="UTF-8" />
55
+ <title>${title}</title>
56
+ </head>
57
+ <body>
58
+ <script type="module">
59
+ ${jsCode}
60
+ </script>
61
+ </body>
67
62
  </html>
68
63
  `.trim();
69
64
 
70
- // --- Project Initializer Function ---
71
65
  async function init() {
72
- let targetPath = process.cwd(); // default to current folder
66
+ let targetPath = process.cwd();
73
67
  let createdFolder = false;
74
68
 
75
- // Prompt user for init location
76
69
  const { confirmInit } = await inquirer.prompt([
77
70
  {
78
71
  type: 'confirm',
@@ -84,13 +77,12 @@ async function init() {
84
77
 
85
78
  let appName = 'neutronium-app';
86
79
 
87
- // If no, ask for folder name and create it
88
80
  if (!confirmInit) {
89
81
  const { projectName } = await inquirer.prompt([
90
82
  {
91
83
  type: 'input',
92
84
  name: 'projectName',
93
- message: 'Please enter your project name:',
85
+ message: 'Enter your project name:',
94
86
  default: 'neutronium-app'
95
87
  }
96
88
  ]);
@@ -98,142 +90,163 @@ async function init() {
98
90
  targetPath = path.resolve(process.cwd(), projectName);
99
91
  createdFolder = true;
100
92
  if (!fs.existsSync(targetPath)) fs.mkdirSync(targetPath);
101
- else console.log('āš ļø Folder already exists. Using it anyway.');
102
93
  }
103
94
 
104
- // Write App.js
105
- const appPath = path.join(targetPath, 'App.js');
106
- fs.writeFileSync(appPath, AppJs.trim());
95
+ // Ask language preference
96
+ const { language } = await inquirer.prompt([
97
+ {
98
+ type: 'list',
99
+ name: 'language',
100
+ message: 'Choose your language:',
101
+ choices: ['JavaScript', 'TypeScript']
102
+ }
103
+ ]);
104
+
105
+ const appFileName = language === 'TypeScript' ? 'App.ts' : 'App.js';
106
+ fs.writeFileSync(path.join(targetPath, appFileName), (language === 'TypeScript' ? AppTs : AppJs).trim());
107
107
 
108
- // Write .babelrc
109
108
  fs.writeFileSync(path.join(targetPath, '.babelrc'), babelRc);
110
109
 
111
- // Init NPM and install dependencies
112
- await execSync('npm init -y', { cwd: targetPath, stdio: 'inherit' });
113
- await execSync('npm install neutronium', { cwd: targetPath, stdio: 'inherit' });
114
- await execSync('npm install --save-dev @babel/core @babel/cli @babel/plugin-transform-react-jsx', {
115
- cwd: targetPath,
116
- stdio: 'inherit'
110
+ execSync('npm init -y', { cwd: targetPath, stdio: 'inherit' });
111
+ execSync('npm install neutronium', { cwd: targetPath, stdio: 'inherit' });
112
+ execSync('npm install --save-dev @babel/core @babel/cli @babel/plugin-transform-react-jsx', {
113
+ cwd: targetPath, stdio: 'inherit'
117
114
  });
118
115
 
119
- // Read and parse package.json
120
- const packageJson = await JSON.parse(fs.readFileSync('package.json', 'utf-8'));
116
+ if (language === 'TypeScript') {
117
+ execSync('npm install --save-dev typescript', { cwd: targetPath, stdio: 'inherit' });
118
+ fs.writeFileSync(path.join(targetPath, 'tsconfig.json'), `
119
+ {
120
+ "compilerOptions": {
121
+ "outDir": "build",
122
+ "rootDir": ".",
123
+ "target": "ES2020",
124
+ "module": "ESNext",
125
+ "lib": ["DOM", "ES2020"],
126
+ "jsx": "react",
127
+ "jsxFactory": "h",
128
+ "jsxFragmentFactory": "Fragment",
129
+ "moduleResolution": "Node",
130
+ "strict": true,
131
+ "allowJs": true,
132
+ "checkJs": false,
133
+ "noEmit": true,
134
+ "esModuleInterop": true,
135
+ "skipLibCheck": true,
136
+ "forceConsistentCasingInFileNames": true
137
+ },
138
+ "include": ["**/*"],
139
+ "exclude": ["dist", "node_modules"]
140
+ }
141
+ `.trim());
142
+ }
143
+
144
+ const packageJsonPath = path.join(targetPath, 'package.json');
145
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
121
146
 
122
- // Modify the "start" script
123
147
  packageJson.scripts = packageJson.scripts || {};
124
- packageJson.scripts.start = "neu-cli start --watch"; // example: "node index.js"
125
- packageJson.scripts.compile = "neu-cli start"
126
- packageJson.scripts.update = "npm i neutronium@latest -g && npm i netronium@latest"
148
+ packageJson.scripts.start = language === 'TypeScript'
149
+ ? 'tsc && neu-cli start --watch'
150
+ : 'neu-cli start --watch';
151
+
152
+ packageJson.scripts.compile = 'neu-cli start';
153
+ packageJson.scripts.update = 'npm i neutronium@latest -g && npm i neutronium@latest';
154
+
155
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
127
156
 
128
- // Write back to package.json
129
- await fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2));
130
- // Transpile App.js (in-memory) for preview HTML
157
+ // Create preview HTML
131
158
  const jsxWithImport = `import * as _neutronium from 'neutronium';\n\n${AppJs}`;
132
- const result = transformSync(jsxWithImport, {
133
- filename: 'App.js',
134
- babelrc: false,
135
- configFile: false,
136
- presets: [],
137
- plugins: [
138
- ['@babel/plugin-transform-react-jsx', {
139
- pragma: '_neutronium.h',
140
- pragmaFrag: '_neutronium.Fragment',
141
- runtime: 'classic',
142
- useBuiltIns: false,
143
- sourceMaps: true,
144
- comments: false,
145
- minified: true,
146
- }]
147
- ]
148
- });
159
+ let compiledCode = '';
160
+ try {
161
+ compiledCode = transformSync(jsxWithImport, {
162
+ filename: 'App.js',
163
+ babelrc: false,
164
+ configFile: false,
165
+ presets: [],
166
+ plugins: [[
167
+ '@babel/plugin-transform-react-jsx',
168
+ {
169
+ pragma: '_neutronium.h',
170
+ pragmaFrag: '_neutronium.Fragment',
171
+ runtime: 'classic'
172
+ }
173
+ ]]
174
+ }).code;
175
+ } catch (e) {
176
+ console.warn('āš ļø Babel preview transform failed:', e.message);
177
+ }
149
178
 
150
- // Write dist/index.html with inlined JS
151
- const finalHtml = htmlTemplate(appName, result.code);
152
179
  const distPath = path.join(targetPath, 'dist');
153
180
  if (!fs.existsSync(distPath)) fs.mkdirSync(distPath);
154
- fs.writeFileSync(path.join(distPath, 'index.html'), finalHtml);
181
+ fs.writeFileSync(path.join(distPath, 'index.html'), htmlTemplate(appName, compiledCode));
155
182
 
156
- // Print instructions to user
157
183
  const folderCmd = createdFolder ? `cd ${path.basename(targetPath)}` : '';
158
184
  console.log('\nāœ… Neutronium app is ready!');
159
- console.log(`āž”ļø Run the following to get started:\n\n ${folderCmd}\n npm start\n`);
160
-
185
+ console.log(`āž”ļø Run the following to get started:\n\n ${folderCmd}\n npm start\n`);
161
186
  }
162
187
 
163
188
  // --- CLI Command Routing ---
164
189
  switch (command) {
165
190
  case 'init':
166
191
  case 'create-app':
167
- case 'create-neu-app':
168
- case 'create-new-app':
169
192
  case 'create-neutronium-app':
170
193
  init();
171
194
  break;
172
195
 
173
196
  case 'start':
174
- // Watch mode for development
175
- if (args[0] === '--watch') {
176
- compileProjectWatch();
177
- } else {
178
- // Build once without watching
179
- compileProject();
180
- }
197
+ if (args[0] === '--watch') compileProjectWatch();
198
+ else compileProject();
181
199
  break;
200
+
182
201
  case '--lang':
183
202
  const lang = args[0];
203
+ const pkgPath = path.join(process.cwd(), 'package.json');
204
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
184
205
 
185
- if (lang === "ts") {
206
+ if (lang === 'ts') {
186
207
  fs.unlinkSync('App.js');
187
208
  fs.writeFileSync('App.ts', AppTs);
188
209
  fs.writeFileSync('tsconfig.json', `
189
- {
190
- "compilerOptions": {
191
- "outDir": "build",
192
- "rootDir": ".",
193
- "target": "ES2020",
194
- "module": "ESNext",
195
- "lib": ["DOM", "ES2020"],
196
- "jsx": "react",
197
- "jsxFactory": "h",
198
- "jsxFragmentFactory": "Fragment",
199
- "moduleResolution": "Node",
200
- "strict": true,
201
- "allowJs": true,
202
- "checkJs": false,
203
- "noEmit": true,
204
- "esModuleInterop": true,
205
- "skipLibCheck": true,
206
- "forceConsistentCasingInFileNames": true
207
- },
208
- "include": ["**/*"],
209
- "exclude": ["dist", "node_modules"]
210
- }
211
- `);
212
- const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
213
- packageJson.scripts = packageJson.scripts || {};
214
- packageJson.scripts.start = 'tsc && ' + packageJson.scripts.start;
215
- fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2));
210
+ {
211
+ "compilerOptions": {
212
+ "outDir": "build",
213
+ "rootDir": ".",
214
+ "target": "ES2020",
215
+ "module": "ESNext",
216
+ "lib": ["DOM", "ES2020"],
217
+ "jsx": "react",
218
+ "jsxFactory": "h",
219
+ "jsxFragmentFactory": "Fragment",
220
+ "moduleResolution": "Node",
221
+ "strict": true,
222
+ "allowJs": true,
223
+ "checkJs": false,
224
+ "noEmit": true,
225
+ "esModuleInterop": true,
226
+ "skipLibCheck": true,
227
+ "forceConsistentCasingInFileNames": true
228
+ },
229
+ "include": ["**/*"],
230
+ "exclude": ["dist", "node_modules"]
231
+ }
232
+ `.trim());
233
+ pkg.scripts.start = 'tsc && neu-cli start --watch';
216
234
  }
217
235
 
218
- if (lang === "js") {
236
+ if (lang === 'js') {
219
237
  fs.unlinkSync('App.ts');
220
- fs.writeFileSync('App.js', AppJs); // assuming `AppJs` is defined
221
- if (fs.existsSync('tsconfig.json')) {
222
- fs.unlinkSync('tsconfig.json');
223
- }
224
- const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
225
- if (packageJson.scripts && packageJson.scripts.start?.startsWith('tsc &&')) {
226
- packageJson.scripts.start = packageJson.scripts.start.replace(/^tsc &&\s*/, '');
227
- }
228
- fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2));
238
+ fs.writeFileSync('App.js', AppJs);
239
+ if (fs.existsSync('tsconfig.json')) fs.unlinkSync('tsconfig.json');
240
+ pkg.scripts.start = pkg.scripts.start.replace(/^tsc &&\s*/, '');
229
241
  }
242
+
243
+ fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
230
244
  break;
245
+
231
246
  default:
232
- // Help text
233
247
  console.log('āŒ Unknown command.');
234
248
  console.log(`
235
249
  Available Commands:
236
-
237
250
  init | create-app | create-neutronium-app
238
251
  šŸ‘‰ Initialize a new Neutronium project
239
252
 
@@ -242,5 +255,8 @@ Available Commands:
242
255
 
243
256
  start --watch
244
257
  šŸ‘‰ Start dev server and rebuild on changes
258
+
259
+ --lang js | ts
260
+ šŸ‘‰ Switch between JS and TS
245
261
  `);
246
262
  }
@@ -1,262 +1,146 @@
1
- #!/usr/bin/env node
2
-
3
- const { default: inquirer } = require('inquirer');
4
- const fs = require('fs');
1
+ const babel = require('@babel/core');
5
2
  const path = require('path');
3
+ const fs = require('fs');
4
+ const { baseHtml } = require('./template');
5
+ const { log, writeFile, ensureDir } = require('./utils');
6
+ const chokidar = require('chokidar');
7
+ const http = require('http');
8
+ const { default: Mime } = require('mime');
9
+ const WebSocket = require('ws');
10
+ const { default: open } = require('open');
6
11
  const { execSync } = require('child_process');
7
- const { transformSync } = require('@babel/core');
8
- const { compileProject, compileProjectWatch } = require('../compiler/compiler');
9
-
10
- const [, , command, ...args] = process.argv;
11
-
12
- const babelRc = `{
13
- "plugins": [
14
- ["@babel/plugin-transform-react-jsx", {
15
- "pragma": "_neutronium.h",
16
- "pragmaFrag": "_neutronium.Fragment",
17
- "runtime": "classic",
18
- "useBuiltIns": false,
19
- "sourceMaps": true,
20
- "comments": false,
21
- "minified": true
22
- }]
23
- ]
24
- }`;
25
-
26
- const AppTs = `
27
- import { createApp } from 'neutronium';
28
-
29
- function App() {
30
- return (
31
- <h1>Hello World (TypeScript)</h1>
32
- );
33
- }
34
-
35
- createApp(App).mount("body");
36
- `;
37
-
38
- const AppJs = `
39
- import { createApp } from 'neutronium';
40
12
 
41
- function App() {
42
- return (
43
- <h1>Hello World</h1>
44
- );
45
- }
46
-
47
- createApp(App).mount("body");
48
- `;
49
-
50
- const htmlTemplate = (title, jsCode) => `
51
- <!DOCTYPE html>
52
- <html>
53
- <head>
54
- <meta charset="UTF-8" />
55
- <title>${title}</title>
56
- </head>
57
- <body>
58
- <script type="module">
59
- ${jsCode}
60
- </script>
61
- </body>
62
- </html>
63
- `.trim();
64
-
65
- async function init() {
66
- let targetPath = process.cwd();
67
- let createdFolder = false;
68
-
69
- const { confirmInit } = await inquirer.prompt([
70
- {
71
- type: 'confirm',
72
- name: 'confirmInit',
73
- message: 'Initialize a Neutronium app in this folder?',
74
- default: true
75
- }
76
- ]);
77
-
78
- let appName = 'neutronium-app';
13
+ async function compileProject(projectDir = process.cwd()) {
14
+ const distDir = path.join(projectDir, 'dist');
15
+ const neutroniumPath = '../node_modules/neutronium/src/index.js';
16
+ const packageJson = JSON.parse(fs.readFileSync(path.join(projectDir, 'package.json')));
17
+ const entry = packageJson.main || 'App.js';
79
18
 
80
- if (!confirmInit) {
81
- const { projectName } = await inquirer.prompt([
82
- {
83
- type: 'input',
84
- name: 'projectName',
85
- message: 'Enter your project name:',
86
- default: 'neutronium-app'
19
+ try {
20
+ log('šŸ“ Scanning project files...');
21
+ const allFiles = fs.readdirSync(projectDir);
22
+ const jsFiles = allFiles.filter(f => f.endsWith('.js') && f !== 'compiler.js' && !f.startsWith('.'));
23
+
24
+ if (fs.existsSync(path.join(projectDir, 'tsconfig.json'))) {
25
+ try {
26
+ require.resolve('typescript');
27
+ } catch {
28
+ log('šŸ“¦ Installing TypeScript...');
29
+ execSync('npm install typescript@latest', { stdio: 'inherit' });
87
30
  }
88
- ]);
89
- appName = projectName;
90
- targetPath = path.resolve(process.cwd(), projectName);
91
- createdFolder = true;
92
- if (!fs.existsSync(targetPath)) fs.mkdirSync(targetPath);
93
- }
94
31
 
95
- // Ask language preference
96
- const { language } = await inquirer.prompt([
97
- {
98
- type: 'list',
99
- name: 'language',
100
- message: 'Choose your language:',
101
- choices: ['JavaScript', 'TypeScript']
32
+ log('šŸ› ļø Compiling TypeScript...');
33
+ execSync('npx tsc', { stdio: 'inherit' });
102
34
  }
103
- ]);
104
-
105
- const appFileName = language === 'TypeScript' ? 'App.ts' : 'App.js';
106
- fs.writeFileSync(path.join(targetPath, appFileName), (language === 'TypeScript' ? AppTs : AppJs).trim());
107
35
 
108
- fs.writeFileSync(path.join(targetPath, '.babelrc'), babelRc);
109
-
110
- execSync('npm init -y', { cwd: targetPath, stdio: 'inherit' });
111
- execSync('npm install neutronium', { cwd: targetPath, stdio: 'inherit' });
112
- execSync('npm install --save-dev @babel/core @babel/cli @babel/plugin-transform-react-jsx', {
113
- cwd: targetPath, stdio: 'inherit'
114
- });
115
-
116
- if (language === 'TypeScript') {
117
- execSync('npm install --save-dev typescript', { cwd: targetPath, stdio: 'inherit' });
118
- fs.writeFileSync(path.join(targetPath, 'tsconfig.json'), `
119
- {
120
- "compilerOptions": {
121
- "outDir": "build",
122
- "rootDir": ".",
123
- "target": "ES2020",
124
- "module": "ESNext",
125
- "lib": ["DOM", "ES2020"],
126
- "jsx": "react",
127
- "jsxFactory": "h",
128
- "jsxFragmentFactory": "Fragment",
129
- "moduleResolution": "Node",
130
- "strict": true,
131
- "allowJs": true,
132
- "checkJs": false,
133
- "noEmit": true,
134
- "esModuleInterop": true,
135
- "skipLibCheck": true,
136
- "forceConsistentCasingInFileNames": true
137
- },
138
- "include": ["**/*"],
139
- "exclude": ["dist", "node_modules"]
140
- }
141
- `.trim());
142
- }
36
+ if (!jsFiles.includes(entry)) {
37
+ throw new Error(`āŒ Entry file "${entry}" not found!`);
38
+ }
143
39
 
144
- const packageJsonPath = path.join(targetPath, 'package.json');
145
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
40
+ ensureDir(distDir);
41
+
42
+ for (const file of jsFiles) {
43
+ const inputPath = path.join(projectDir, file);
44
+ const outputPath = path.join(distDir, file);
45
+
46
+ log(`āš™ļø Babel transforming ${file}...`);
47
+ const source = fs.readFileSync(inputPath, 'utf-8');
48
+
49
+ let { code } = babel.transformSync(source, {
50
+ filename: file,
51
+ babelrc: false,
52
+ configFile: false,
53
+ presets: [],
54
+ plugins: [[
55
+ '@babel/plugin-transform-react-jsx',
56
+ {
57
+ pragma: '_neutronium.h',
58
+ pragmaFrag: '_neutronium.Fragment',
59
+ runtime: 'classic',
60
+ }
61
+ ]]
62
+ });
63
+
64
+ if (!source.includes('_neutronium')) {
65
+ code = `import * as _neutronium from '${neutroniumPath}';\n\n${code}`;
66
+ }
146
67
 
147
- packageJson.scripts = packageJson.scripts || {};
148
- packageJson.scripts.start = language === 'TypeScript'
149
- ? 'tsc && neu-cli start --watch'
150
- : 'neu-cli start --watch';
68
+ code = code.replace(/from\s+['"]neutronium['"]/g, `from '${neutroniumPath}'`);
69
+ code = code.replace("_neutronium.createApp(App).mount('#app');")
151
70
 
152
- packageJson.scripts.compile = 'neu-cli start';
153
- packageJson.scripts.update = 'npm i neutronium@latest -g && npm i neutronium@latest';
71
+ writeFile(outputPath, code);
72
+ }
154
73
 
155
- fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
74
+ log('šŸ› ļø Generating index.html...');
75
+ const htmlContent = baseHtml(``, entry);
76
+ writeFile(path.join(distDir, 'index.html'), htmlContent);
156
77
 
157
- // Create preview HTML
158
- const jsxWithImport = `import * as _neutronium from 'neutronium';\n\n${AppJs}`;
159
- let compiledCode = '';
160
- try {
161
- compiledCode = transformSync(jsxWithImport, {
162
- filename: 'App.js',
163
- babelrc: false,
164
- configFile: false,
165
- presets: [],
166
- plugins: [[
167
- '@babel/plugin-transform-react-jsx',
168
- {
169
- pragma: '_neutronium.h',
170
- pragmaFrag: '_neutronium.Fragment',
171
- runtime: 'classic'
172
- }
173
- ]]
174
- }).code;
78
+ log('āœ… Compilation complete!');
175
79
  } catch (e) {
176
- console.warn('āš ļø Babel preview transform failed:', e.message);
80
+ console.error('āŒ Compilation failed:', e.message);
177
81
  }
178
-
179
- const distPath = path.join(targetPath, 'dist');
180
- if (!fs.existsSync(distPath)) fs.mkdirSync(distPath);
181
- fs.writeFileSync(path.join(distPath, 'index.html'), htmlTemplate(appName, compiledCode));
182
-
183
- const folderCmd = createdFolder ? `cd ${path.basename(targetPath)}` : '';
184
- console.log('\nāœ… Neutronium app is ready!');
185
- console.log(`āž”ļø Run the following to get started:\n\n ${folderCmd}\n npm start\n`);
186
82
  }
187
83
 
188
- // --- CLI Command Routing ---
189
- switch (command) {
190
- case 'init':
191
- case 'create-app':
192
- case 'create-neutronium-app':
193
- init();
194
- break;
195
-
196
- case 'start':
197
- if (args[0] === '--watch') compileProjectWatch();
198
- else compileProject();
199
- break;
84
+ function compileProjectWatch(projectDir = process.cwd(), port = 3000) {
85
+ const server = serveProject(projectDir, port);
86
+ compileProject(projectDir);
87
+
88
+ log('šŸ‘€ Watching project for changes...');
89
+ let timeout;
90
+
91
+ chokidar.watch([
92
+ path.join(projectDir, '**/*.js'),
93
+ path.join(projectDir, '**/*.ts'),
94
+ path.join(projectDir, '**/*.tsx'),
95
+ ]).on('change', () => {
96
+ clearTimeout(timeout);
97
+ timeout = setTimeout(() => {
98
+ console.clear();
99
+ log('šŸ” File changed, rebuilding...');
100
+ try {
101
+ compileProject(projectDir);
102
+ if (server.broadcastReload) server.broadcastReload();
103
+ } catch (err) {
104
+ console.error('āŒ Rebuild failed:', err.message);
105
+ }
106
+ }, 100);
107
+ });
108
+ }
200
109
 
201
- case '--lang':
202
- const lang = args[0];
203
- const pkgPath = path.join(process.cwd(), 'package.json');
204
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
110
+ function serveProject(projectDir = process.cwd(), port = 3000) {
205
111
 
206
- if (lang === 'ts') {
207
- fs.unlinkSync('App.js');
208
- fs.writeFileSync('App.ts', AppTs);
209
- fs.writeFileSync('tsconfig.json', `
210
- {
211
- "compilerOptions": {
212
- "outDir": "build",
213
- "rootDir": ".",
214
- "target": "ES2020",
215
- "module": "ESNext",
216
- "lib": ["DOM", "ES2020"],
217
- "jsx": "react",
218
- "jsxFactory": "h",
219
- "jsxFragmentFactory": "Fragment",
220
- "moduleResolution": "Node",
221
- "strict": true,
222
- "allowJs": true,
223
- "checkJs": false,
224
- "noEmit": true,
225
- "esModuleInterop": true,
226
- "skipLibCheck": true,
227
- "forceConsistentCasingInFileNames": true
228
- },
229
- "include": ["**/*"],
230
- "exclude": ["dist", "node_modules"]
231
- }
232
- `.trim());
233
- pkg.scripts.start = 'tsc && neu-cli start --watch';
112
+ const server = http.createServer((req, res) => {
113
+ let reqPath = req.url;
114
+ if (reqPath === '/' || reqPath === '/index.html') {
115
+ reqPath = '/dist/index.html';
234
116
  }
235
117
 
236
- if (lang === 'js') {
237
- fs.unlinkSync('App.ts');
238
- fs.writeFileSync('App.js', AppJs);
239
- if (fs.existsSync('tsconfig.json')) fs.unlinkSync('tsconfig.json');
240
- pkg.scripts.start = pkg.scripts.start.replace(/^tsc &&\s*/, '');
118
+ const filePath = path.join(projectDir, reqPath);
119
+ if (!fs.existsSync(filePath)) {
120
+ res.writeHead(404);
121
+ return res.end('404 Not Found');
241
122
  }
242
123
 
243
- fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
244
- break;
124
+ const content = fs.readFileSync(filePath);
125
+ res.writeHead(200, { 'Content-Type': Mime.getType(filePath) });
126
+ res.end(content);
127
+ });
245
128
 
246
- default:
247
- console.log('āŒ Unknown command.');
248
- console.log(`
249
- Available Commands:
250
- init | create-app | create-neutronium-app
251
- šŸ‘‰ Initialize a new Neutronium project
129
+ const wss = new WebSocket.Server({ server });
130
+ server.broadcastReload = () => {
131
+ wss.clients.forEach(client => {
132
+ if (client.readyState === WebSocket.OPEN) {
133
+ client.send('reload');
134
+ }
135
+ });
136
+ };
252
137
 
253
- start
254
- šŸ‘‰ Compiles your app once
138
+ server.listen(port, () => {
139
+ log(`šŸš€ Server running at http://localhost:${port}`);
140
+ open(`http://localhost:${port}/dist/index.html`);
141
+ });
255
142
 
256
- start --watch
257
- šŸ‘‰ Start dev server and rebuild on changes
143
+ return server;
144
+ }
258
145
 
259
- --lang js | ts
260
- šŸ‘‰ Switch between JS and TS
261
- `);
262
- }
146
+ module.exports = { compileProject, compileProjectWatch };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neutronium",
3
- "version": "2.8.7",
3
+ "version": "2.9.3",
4
4
  "description": "A dense, efficient JavaScript framework for building modern web applications",
5
5
  "main": "src/index.js",
6
6
  "type": "commonjs",
package/results.png ADDED
Binary file