baraqex 1.0.32 → 1.0.33

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 (36) hide show
  1. package/bin/baraqex.js +28 -27
  2. package/dist/server/index.d.ts +3 -6
  3. package/dist/server/index.d.ts.map +1 -1
  4. package/dist/server/index.js +8 -125
  5. package/dist/server/index.js.map +1 -1
  6. package/package.json +1 -1
  7. package/templates/fullstack-template/src/pages/index.js +193 -48
  8. package/templates/ssr-template/package-lock.json +5080 -0
  9. package/templates/ssr-template/package.json +8 -14
  10. package/templates/ssr-template/src/App.tsx +7 -19
  11. package/templates/ssr-template/src/client.tsx +1 -21
  12. package/templates/ssr-template/src/server.ts +14 -183
  13. package/templates/ssr-template/tsconfig.json +6 -15
  14. package/templates/ssr-template/tsconfig.server.json +5 -18
  15. package/templates/wasm/build-wasm.js +228 -0
  16. package/templates/wasm/esbuild.config.js +63 -0
  17. package/templates/wasm/go/main.go +256 -0
  18. package/templates/wasm/go/wasm_exec.js +0 -0
  19. package/templates/wasm/index.html +97 -0
  20. package/templates/wasm/jsx-shim.js +9 -0
  21. package/templates/wasm/package-lock.json +4848 -0
  22. package/templates/wasm/package.json +27 -0
  23. package/templates/wasm/public/example.wasm +0 -0
  24. package/templates/wasm/public/wasm_exec.js +572 -0
  25. package/templates/wasm/src/App.tsx +519 -0
  26. package/templates/wasm/src/client.tsx +220 -0
  27. package/templates/wasm/src/index.html +14 -0
  28. package/templates/wasm/src/index.tsx +21 -0
  29. package/templates/wasm/src/main.tsx +5 -0
  30. package/templates/wasm/src/server.ts +145 -0
  31. package/templates/wasm/src/wasm-loader.ts +119 -0
  32. package/templates/wasm/tsconfig.json +21 -0
  33. package/templates/wasm/tsconfig.node.json +13 -0
  34. package/templates/wasm/tsconfig.server.json +23 -0
  35. package/templates/wasm/vite.config.ts +73 -0
  36. package/templates/wasm/wasm-loader.js +103 -0
@@ -1,16 +1,13 @@
1
1
  {
2
- "name": "ssr-template",
2
+ "name": "ssr-version",
3
+ "private": true,
3
4
  "version": "0.0.0",
4
5
  "type": "module",
5
6
  "scripts": {
6
- "dev": "npm run build && npm run start",
7
+ "build:client": "esbuild src/client.tsx --bundle --outfile=dist/client.js --platform=browser --format=esm",
8
+ "build:server": "esbuild src/server.ts --bundle --outfile=dist/server.js --platform=node --format=esm --external:frontend-hamroun --packages=external",
7
9
  "build": "node esbuild.config.js",
8
- "build:vite": "npm run build:client && npm run build:server",
9
- "build:client": "cross-env BUILD_TARGET=client vite build",
10
- "build:server": "cross-env BUILD_TARGET=server vite build --ssr",
11
- "start": "node dist/server.js",
12
- "preview": "npm run build && npm run start",
13
- "clean": "rm -rf node_modules package-lock.json dist && npm install"
10
+ "start": "node dist/server.js"
14
11
  },
15
12
  "dependencies": {
16
13
  "express": "^4.18.2",
@@ -18,11 +15,8 @@
18
15
  },
19
16
  "devDependencies": {
20
17
  "@types/express": "^4.17.17",
21
- "@types/node": "^20.0.0",
22
- "@types/react": "^18.0.0",
23
- "cross-env": "^7.0.3",
24
- "esbuild": "^0.19.0",
25
- "typescript": "^5.0.0",
26
- "vite": "^5.0.0"
18
+ "@types/node": "^20.5.0",
19
+ "esbuild": "^0.19.12",
20
+ "typescript": "^5.0.0"
27
21
  }
28
22
  }
@@ -1,18 +1,5 @@
1
1
  import { useState, useEffect, useRef, useMemo } from 'frontend-hamroun';
2
2
 
3
- // Type definitions
4
- interface Todo {
5
- id: number;
6
- text: string;
7
- completed: boolean;
8
- }
9
-
10
- interface TodoItemProps {
11
- todo: Todo;
12
- onToggle: (id: number) => void;
13
- onDelete: (id: number) => void;
14
- }
15
-
16
3
  // Custom hooks for better code organization
17
4
  function useTimer(initialTime = 0) {
18
5
  const [time, setTime] = useState(initialTime);
@@ -165,7 +152,7 @@ function useTheme() {
165
152
  }
166
153
 
167
154
  // Todo Item Component
168
- function TodoItem({ todo, onToggle, onDelete }: TodoItemProps) {
155
+ function TodoItem({ todo, onToggle, onDelete, ...props }:any) {
169
156
  return (
170
157
  <div style={{
171
158
  display: 'flex',
@@ -185,7 +172,7 @@ function TodoItem({ todo, onToggle, onDelete }: TodoItemProps) {
185
172
  onChange={() => onToggle(todo.id)}
186
173
  style={{ marginRight: '0.75rem' }}
187
174
  />
188
- <span style={{ flex: 1 ,color:"black"}} >{todo.text}</span>
175
+ <span style={{ flex: 1 }}>{todo.text}</span>
189
176
  <button
190
177
  onClick={() => onDelete(todo.id)}
191
178
  style={{
@@ -205,7 +192,7 @@ function TodoItem({ todo, onToggle, onDelete }: TodoItemProps) {
205
192
  }
206
193
 
207
194
  // Stats Component
208
- function StatsCard({ title, value, color = '#3498db' }: { title: string; value: string | number; color?: string }) {
195
+ function StatsCard({ title, value, color = '#3498db' }) {
209
196
  return (
210
197
  <div style={{
211
198
  background: 'white',
@@ -249,7 +236,7 @@ export function App() {
249
236
  const inputRef = useRef(null);
250
237
 
251
238
  // Handle todo form submission
252
- const handleTodoSubmit = (e:any) => {
239
+ const handleTodoSubmit = (e: { preventDefault: () => void; }) => {
253
240
  e.preventDefault();
254
241
  // Ensure newTodo is a string before passing to addTodo
255
242
  const todoText = String(newTodo || '');
@@ -451,7 +438,7 @@ export function App() {
451
438
  min="1"
452
439
  max="10"
453
440
  value={step}
454
- onChange={(e: { target: { value: string; }; }) => setStep(parseInt(e.target.value))}
441
+ onChange={(e) => setStep(parseInt(e.target.value))}
455
442
  style={{ width: '100%' }}
456
443
  />
457
444
  </div>
@@ -492,7 +479,7 @@ export function App() {
492
479
  background: colors.bg,
493
480
  color: colors.text
494
481
  }}
495
- onKeyPress={(e: { key: string; target: { value: string; }; }) => {
482
+ onKeyPress={(e) => {
496
483
  if (e.key === 'Enter') {
497
484
  setValue(parseInt(e.target.value) || 0);
498
485
  e.target.value = '';
@@ -730,6 +717,7 @@ export function App() {
730
717
  ) : (
731
718
  todos.map(todo => (
732
719
  <TodoItem
720
+ key={todo.id}
733
721
  todo={todo}
734
722
  onToggle={toggleTodo}
735
723
  onDelete={deleteTodo}
@@ -1,24 +1,4 @@
1
1
  import { hydrate, jsx } from 'frontend-hamroun';
2
2
  import { App } from './App.js';
3
3
 
4
- document.addEventListener('DOMContentLoaded', () => {
5
- const root = document.getElementById('root');
6
- if (root) {
7
- try {
8
- // Create the app element
9
- const appElement = jsx(App, {});
10
-
11
- // Hydrate the app with error boundary
12
- hydrate(appElement, root);
13
-
14
- console.log('✅ Client hydrated successfully!');
15
- } catch (error) {
16
- console.error('❌ Hydration failed:', error);
17
-
18
- // Fallback rendering
19
- root.innerHTML = '<div style="padding: 2rem; text-align: center;">⚠️ Client-side rendering failed, but page content is still available.</div>';
20
- }
21
- } else {
22
- console.error('❌ Root element not found');
23
- }
24
- });
4
+ hydrate(jsx(App, {}), document.getElementById('root')!);
@@ -14,189 +14,20 @@ const port = 3000;
14
14
  app.use(express.static(path.join(__dirname)));
15
15
 
16
16
  app.get('/', async (req, res) => {
17
- try {
18
- // Create JSX element directly
19
- const appElement = jsx(App, {});
20
- const html = await renderToString(appElement);
21
-
22
- res.send(`
23
- <!DOCTYPE html>
24
- <html>
25
- <head>
26
- <title>Frontend Hamroun SSR - Advanced Template</title>
27
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
28
- <meta name="description" content="Advanced SSR template with hooks, modern design, and interactive components">
29
- <style>
30
- * {
31
- box-sizing: border-box;
32
- }
33
-
34
- body {
35
- margin: 0;
36
- padding: 0;
37
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
38
- line-height: 1.6;
39
- color: #333;
40
- background: #f5f5f5;
41
- }
42
-
43
- /* Responsive design */
44
- @media (max-width: 768px) {
45
- .grid-responsive {
46
- grid-template-columns: 1fr !important;
47
- }
48
-
49
- .flex-responsive {
50
- flex-direction: column;
51
- gap: 0.5rem !important;
52
- }
53
-
54
- .padding-responsive {
55
- padding: 1rem !important;
56
- }
57
- }
58
-
59
- /* Smooth transitions */
60
- * {
61
- transition: all 0.2s ease;
62
- }
63
-
64
- /* Button hover effects */
65
- button:hover {
66
- transform: translateY(-2px);
67
- box-shadow: 0 4px 12px rgba(0,0,0,0.2);
68
- }
69
-
70
- button:active {
71
- transform: translateY(0);
72
- }
73
-
74
- /* Input focus styles */
75
- input:focus {
76
- outline: none;
77
- box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.3);
78
- }
79
-
80
- /* Loading states */
81
- .loading {
82
- animation: pulse 2s infinite;
83
- }
84
-
85
- @keyframes pulse {
86
- 0% { opacity: 1; }
87
- 50% { opacity: 0.5; }
88
- 100% { opacity: 1; }
89
- }
90
-
91
- /* Grid animations */
92
- .grid-item {
93
- animation: slideInUp 0.6s ease-out;
94
- }
95
-
96
- @keyframes slideInUp {
97
- from {
98
- opacity: 0;
99
- transform: translateY(30px);
100
- }
101
- to {
102
- opacity: 1;
103
- transform: translateY(0);
104
- }
105
- }
106
-
107
- /* Dark theme support */
108
- .dark-theme {
109
- background: #1a1a1a;
110
- color: #ffffff;
111
- }
112
-
113
- /* Custom scrollbar */
114
- ::-webkit-scrollbar {
115
- width: 8px;
116
- }
117
-
118
- ::-webkit-scrollbar-track {
119
- background: #f1f1f1;
120
- border-radius: 4px;
121
- }
122
-
123
- ::-webkit-scrollbar-thumb {
124
- background: #c1c1c1;
125
- border-radius: 4px;
126
- }
127
-
128
- ::-webkit-scrollbar-thumb:hover {
129
- background: #a8a8a8;
130
- }
131
- </style>
132
- </head>
133
- <body>
134
- <div id="root">${html}</div>
135
- <script type="module" src="/client.js"></script>
136
-
137
- <!-- Performance monitoring -->
138
- <script>
139
- // Log performance metrics
140
- window.addEventListener('load', () => {
141
- const perfData = performance.getEntriesByType('navigation')[0];
142
- console.log('🚀 Frontend Hamroun SSR Performance:');
143
- console.log('⏱️ Page Load Time:', Math.round(perfData.loadEventEnd - perfData.fetchStart), 'ms');
144
- console.log('🎨 DOM Content Loaded:', Math.round(perfData.domContentLoadedEventEnd - perfData.fetchStart), 'ms');
145
- console.log('📡 Server Response:', Math.round(perfData.responseEnd - perfData.requestStart), 'ms');
146
- });
147
-
148
- // Enhanced error handling
149
- window.addEventListener('error', (event) => {
150
- console.error('🚨 Runtime Error:', event.error);
151
- });
152
-
153
- // Console welcome message
154
- console.log('%c🚀 Frontend Hamroun SSR Template', 'color: #3498db; font-size: 24px; font-weight: bold;');
155
- console.log('%cFeatures: SSR ✓ Hooks ✓ Modern Design ✓ TypeScript ✓', 'color: #27ae60; font-size: 14px;');
156
- </script>
157
- </body>
158
- </html>
159
- `);
160
- } catch (error) {
161
- console.error('Server-side rendering error:', error);
162
- res.status(500).send(`
163
- <!DOCTYPE html>
164
- <html>
165
- <head>
166
- <title>Frontend Hamroun SSR - Error</title>
167
- <style>
168
- body {
169
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
170
- display: flex;
171
- justify-content: center;
172
- align-items: center;
173
- min-height: 100vh;
174
- margin: 0;
175
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
176
- color: white;
177
- }
178
- .error-container {
179
- text-align: center;
180
- padding: 2rem;
181
- background: rgba(255,255,255,0.1);
182
- border-radius: 16px;
183
- backdrop-filter: blur(10px);
184
- border: 1px solid rgba(255,255,255,0.2);
185
- }
186
- </style>
187
- </head>
188
- <body>
189
- <div class="error-container">
190
- <h1>🚨 Server Error</h1>
191
- <p>The Frontend Hamroun SSR template encountered an error, but don't worry!</p>
192
- <p>Error: ${error instanceof Error ? error.message : String(error)}</p>
193
- <p><a href="/" style="color: white;">Try again</a></p>
194
- </div>
195
- <script type="module" src="/client.js"></script>
196
- </body>
197
- </html>
198
- `);
199
- }
17
+ const html = await renderToString(jsx(App, {}));
18
+
19
+ res.send(`
20
+ <!DOCTYPE html>
21
+ <html>
22
+ <head>
23
+ <title>SSR App</title>
24
+ </head>
25
+ <body>
26
+ <div id="root">${html}</div>
27
+ <script type="module" src="/client.js"></script>
28
+ </body>
29
+ </html>
30
+ `);
200
31
  });
201
32
 
202
33
  app.listen(port, () => {
@@ -2,31 +2,22 @@
2
2
  "compilerOptions": {
3
3
  "target": "ES2022",
4
4
  "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
- "allowJs": true,
5
+ "allowJs": false,
6
6
  "skipLibCheck": true,
7
- "esModuleInterop": true,
7
+ "esModuleInterop": false,
8
8
  "allowSyntheticDefaultImports": true,
9
9
  "strict": true,
10
10
  "forceConsistentCasingInFileNames": true,
11
11
  "module": "ESNext",
12
- "moduleResolution": "node",
12
+ "moduleResolution": "bundler",
13
13
  "resolveJsonModule": true,
14
14
  "isolatedModules": true,
15
15
  "noEmit": true,
16
16
  "jsx": "preserve",
17
- "declaration": true,
18
- "outDir": "./dist",
19
- "rootDir": "./src",
20
- "baseUrl": ".",
21
- "paths": {
22
- "@/*": ["./src/*"]
23
- }
17
+ "jsxImportSource": "frontend-hamroun"
24
18
  },
25
19
  "include": [
26
- "src/**/*"
27
- ],
28
- "exclude": [
29
- "node_modules",
30
- "dist"
20
+ "src",
21
+ "server.ts"
31
22
  ]
32
23
  }
@@ -1,24 +1,11 @@
1
1
  {
2
2
  "extends": "./tsconfig.json",
3
3
  "compilerOptions": {
4
- "target": "ES2022",
5
4
  "module": "ESNext",
6
- "moduleResolution": "node",
7
- "lib": ["ES2022"],
8
- "types": ["node"],
9
- "allowJs": true,
10
- "outDir": "./dist",
11
- "rootDir": "./src",
12
- "esModuleInterop": true,
13
- "allowSyntheticDefaultImports": true,
14
- "skipLibCheck": true
5
+ "outDir": "dist",
6
+ "noEmit": false,
7
+ "jsx": "preserve",
8
+ "moduleResolution": "bundler"
15
9
  },
16
- "include": [
17
- "src/server.ts",
18
- "src/**/*.ts"
19
- ],
20
- "exclude": [
21
- "src/client.tsx",
22
- "node_modules"
23
- ]
10
+ "include": ["src/server.ts"]
24
11
  }
@@ -0,0 +1,228 @@
1
+ import { spawn } from 'child_process';
2
+ import { join, dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import fs from 'fs';
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = dirname(__filename);
8
+
9
+ const goDir = join(__dirname, 'go');
10
+ const outputDir = join(__dirname, 'public');
11
+ const wasmFile = join(outputDir, 'example.wasm');
12
+
13
+ // Prevent infinite loops by checking if we're already running
14
+ const lockFile = join(__dirname, '.build-lock');
15
+ if (fs.existsSync(lockFile)) {
16
+ console.log('Build already in progress, skipping...');
17
+ process.exit(0);
18
+ }
19
+
20
+ // Create lock file
21
+ fs.writeFileSync(lockFile, process.pid.toString());
22
+
23
+ // Clean up lock file on exit
24
+ process.on('exit', () => {
25
+ try {
26
+ fs.unlinkSync(lockFile);
27
+ } catch (e) {
28
+ // Ignore cleanup errors
29
+ }
30
+ });
31
+
32
+ process.on('SIGINT', () => {
33
+ try {
34
+ fs.unlinkSync(lockFile);
35
+ } catch (e) {
36
+ // Ignore cleanup errors
37
+ }
38
+ process.exit(0);
39
+ });
40
+
41
+ // Ensure public directory exists
42
+ if (!fs.existsSync(outputDir)) {
43
+ fs.mkdirSync(outputDir, { recursive: true });
44
+ }
45
+
46
+ // Only create Go files if they don't exist (prevent infinite generation)
47
+ if (!fs.existsSync(goDir) || !fs.existsSync(join(goDir, 'main.go'))) {
48
+ console.log('Creating Go WASM example files...');
49
+ fs.mkdirSync(goDir, { recursive: true });
50
+
51
+ // Create the corrected Go main file with proper function names
52
+ const goMainContent = `package main
53
+
54
+ import (
55
+ "fmt"
56
+ "strings"
57
+ "syscall/js"
58
+ )
59
+
60
+ func goHello(this js.Value, inputs []js.Value) interface{} {
61
+ name := inputs[0].String()
62
+ return fmt.Sprintf("Hello, %s from Go WASM!", name)
63
+ }
64
+
65
+ func goAdd(this js.Value, inputs []js.Value) interface{} {
66
+ a := inputs[0].Int()
67
+ b := inputs[1].Int()
68
+ return a + b
69
+ }
70
+
71
+ func goMultiply(this js.Value, inputs []js.Value) interface{} {
72
+ a := inputs[0].Float()
73
+ b := inputs[1].Float()
74
+ return a * b
75
+ }
76
+
77
+ func goFibonacci(this js.Value, inputs []js.Value) interface{} {
78
+ n := inputs[0].Int()
79
+ if n <= 1 {
80
+ return n
81
+ }
82
+
83
+ a, b := 0, 1
84
+ for i := 2; i <= n; i++ {
85
+ a, b = b, a+b
86
+ }
87
+ return b
88
+ }
89
+
90
+ func goIsPrime(this js.Value, inputs []js.Value) interface{} {
91
+ n := inputs[0].Int()
92
+ if n < 2 {
93
+ return false
94
+ }
95
+ if n == 2 {
96
+ return true
97
+ }
98
+ if n%2 == 0 {
99
+ return false
100
+ }
101
+
102
+ for i := 3; i*i <= n; i += 2 {
103
+ if n%i == 0 {
104
+ return false
105
+ }
106
+ }
107
+ return true
108
+ }
109
+
110
+ func main() {
111
+ fmt.Println("Go WASM initialized")
112
+
113
+ // Register functions with correct names that match the frontend
114
+ js.Global().Set("goHello", js.FuncOf(goHello))
115
+ js.Global().Set("goAdd", js.FuncOf(goAdd))
116
+ js.Global().Set("goMultiply", js.FuncOf(goMultiply))
117
+ js.Global().Set("goFibonacci", js.FuncOf(goFibonacci))
118
+ js.Global().Set("goIsPrime", js.FuncOf(goIsPrime))
119
+
120
+ fmt.Println("Go functions registered and ready!")
121
+
122
+ // Keep the program running
123
+ select {}
124
+ }
125
+ `;
126
+
127
+ fs.writeFileSync(join(goDir, 'main.go'), goMainContent);
128
+
129
+ // Create go.mod file
130
+ const goModContent = `module wasm-example
131
+
132
+ go 1.21
133
+ `;
134
+
135
+ fs.writeFileSync(join(goDir, 'go.mod'), goModContent);
136
+
137
+ console.log('✅ Go example files created');
138
+ } else {
139
+ console.log('Go files already exist, skipping creation');
140
+ }
141
+
142
+ console.log('Building Go WASM module...');
143
+
144
+ // Set environment variables for WASM compilation
145
+ const env = {
146
+ ...process.env,
147
+ GOOS: 'js',
148
+ GOARCH: 'wasm'
149
+ };
150
+
151
+ // Build command
152
+ const buildArgs = ['build', '-o', wasmFile, 'main.go'];
153
+
154
+ console.log(`Running: go ${buildArgs.join(' ')}`);
155
+ console.log(`Working directory: ${goDir}`);
156
+ console.log(`Output: ${wasmFile}`);
157
+
158
+ const goProcess = spawn('go', buildArgs, {
159
+ cwd: goDir,
160
+ env: env,
161
+ stdio: 'inherit',
162
+ shell: true
163
+ });
164
+
165
+ goProcess.on('close', (code) => {
166
+ // Clean up lock file
167
+ try {
168
+ fs.unlinkSync(lockFile);
169
+ } catch (e) {
170
+ // Ignore cleanup errors
171
+ }
172
+
173
+ if (code === 0) {
174
+ console.log('✅ Go WASM build successful!');
175
+ console.log(`📦 WASM file created: ${wasmFile}`);
176
+
177
+ // Check if wasm_exec.js exists, if not, copy it
178
+ const wasmExecJs = join(outputDir, 'wasm_exec.js');
179
+ if (!fs.existsSync(wasmExecJs)) {
180
+ console.log('📋 Copying wasm_exec.js...');
181
+
182
+ // Try to find wasm_exec.js in GOROOT
183
+ const findWasmExec = spawn('go', ['env', 'GOROOT'], {
184
+ stdio: 'pipe',
185
+ shell: true
186
+ });
187
+
188
+ let goroot = '';
189
+ findWasmExec.stdout.on('data', (data) => {
190
+ goroot += data.toString().trim();
191
+ });
192
+
193
+ findWasmExec.on('close', () => {
194
+ if (goroot) {
195
+ const wasmExecSource = join(goroot, 'misc', 'wasm', 'wasm_exec.js');
196
+ if (fs.existsSync(wasmExecSource)) {
197
+ fs.copyFileSync(wasmExecSource, wasmExecJs);
198
+ console.log('✅ wasm_exec.js copied successfully');
199
+ } else {
200
+ console.log('⚠️ wasm_exec.js not found, you may need to copy it manually');
201
+ console.log(`Expected location: ${wasmExecSource}`);
202
+ }
203
+ }
204
+ });
205
+ }
206
+ } else {
207
+ console.error('❌ Go WASM build failed with exit code:', code);
208
+ console.log('\n💡 Troubleshooting tips:');
209
+ console.log('1. Make sure Go is installed and in your PATH');
210
+ console.log('2. Check that your Go code in ./go/main.go is valid');
211
+ console.log('3. Ensure you have Go 1.11+ for WASM support');
212
+ process.exit(1);
213
+ }
214
+ });
215
+
216
+ goProcess.on('error', (error) => {
217
+ // Clean up lock file
218
+ try {
219
+ fs.unlinkSync(lockFile);
220
+ } catch (e) {
221
+ // Ignore cleanup errors
222
+ }
223
+
224
+ console.error('❌ Failed to start Go build process:', error.message);
225
+ console.log('\n💡 Make sure Go is installed and available in your PATH');
226
+ console.log('Download Go from: https://golang.org/dl/');
227
+ process.exit(1);
228
+ });