frontend-hamroun 1.2.80 → 1.2.82

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 (104) hide show
  1. package/bin/cli.js +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +1 -0
  4. package/dist/index.js.map +1 -1
  5. package/package.json +1 -1
  6. package/templates/basic-app/src/App.jsx +16 -0
  7. package/templates/basic-app/src/client.jsx +5 -0
  8. package/templates/basic-app/src/components/Counter.jsx +13 -0
  9. package/templates/basic-app/src/jsx-shim.js +3 -0
  10. package/templates/basic-app/src/jsx-shim.ts +7 -0
  11. package/templates/basic-app/src/main.jsx +98 -0
  12. package/templates/basic-app/src/server.js +47 -0
  13. package/templates/complete-app/api/hello.js +0 -0
  14. package/templates/complete-app/lib/frontend-hamroun.js +182 -0
  15. package/templates/complete-app/package.json +18 -0
  16. package/templates/complete-app/pages/about.js +119 -0
  17. package/templates/complete-app/pages/about.jsx +0 -0
  18. package/templates/complete-app/pages/index.js +157 -0
  19. package/templates/complete-app/pages/index.jsx +0 -0
  20. package/templates/complete-app/pages/wasm-demo.js +290 -0
  21. package/templates/complete-app/pages/wasm-demo.jsx +0 -0
  22. package/templates/complete-app/public/client.js +89 -0
  23. package/templates/complete-app/public/index.html +118 -0
  24. package/templates/complete-app/public/styles.css +76 -0
  25. package/templates/complete-app/server.js +226 -0
  26. package/templates/complete-app/src/App.tsx +59 -0
  27. package/templates/complete-app/src/client.tsx +18 -0
  28. package/templates/complete-app/src/server.ts +218 -0
  29. package/templates/complete-app/tsconfig.json +22 -0
  30. package/templates/complete-app/tsconfig.server.json +19 -0
  31. package/templates/{ssr-template → complete-app}/vite.config.js +16 -5
  32. package/templates/complete-app/vite.config.ts +30 -0
  33. package/templates/complete-app/wasm/build.bat +0 -0
  34. package/templates/complete-app/wasm/build.sh +0 -0
  35. package/templates/complete-app/wasm/example.go +0 -0
  36. package/templates/fullstack-app/build/main.css +874 -874
  37. package/templates/fullstack-app/build/main.css.map +7 -7
  38. package/templates/fullstack-app/build/main.js +996 -967
  39. package/templates/fullstack-app/build/main.js.map +7 -7
  40. package/templates/fullstack-app/package-lock.json +6301 -0
  41. package/templates/fullstack-app/public/styles.css +768 -768
  42. package/templates/go/example.go +154 -99
  43. package/templates/ssr-template/esbuild.config.js +33 -0
  44. package/templates/ssr-template/jsx-shim.js +1 -0
  45. package/templates/ssr-template/package.json +22 -16
  46. package/templates/ssr-template/src/App.tsx +12 -52
  47. package/templates/ssr-template/src/client.tsx +3 -17
  48. package/templates/ssr-template/src/server.ts +21 -204
  49. package/templates/ssr-template/tsconfig.json +10 -13
  50. package/templates/ssr-template/tsconfig.server.json +6 -14
  51. package/templates/wasm/build-wasm.js +228 -0
  52. package/templates/wasm/esbuild.config.js +63 -0
  53. package/templates/wasm/go/main.go +256 -0
  54. package/templates/wasm/go/wasm_exec.js +0 -0
  55. package/templates/wasm/index.html +97 -0
  56. package/templates/wasm/jsx-shim.js +9 -0
  57. package/templates/wasm/package-lock.json +5307 -0
  58. package/templates/wasm/package.json +42 -0
  59. package/templates/wasm/public/example.wasm +0 -0
  60. package/templates/{go-wasm-app/public/wasm → wasm/public}/wasm_exec.js +561 -561
  61. package/templates/wasm/src/App.tsx +564 -0
  62. package/templates/wasm/src/client.tsx +220 -0
  63. package/templates/wasm/src/index.tsx +21 -0
  64. package/templates/wasm/src/server.ts +145 -0
  65. package/templates/wasm/tsconfig.json +21 -0
  66. package/templates/wasm/tsconfig.node.json +13 -0
  67. package/templates/wasm/tsconfig.server.json +23 -0
  68. package/templates/wasm/vite.config.ts +56 -0
  69. package/templates/wasm/wasm-loader.js +103 -0
  70. package/templates/basic-app/bun.lock +0 -196
  71. package/templates/basic-app/docs/rapport_pfe.aux +0 -27
  72. package/templates/basic-app/docs/rapport_pfe.out +0 -10
  73. package/templates/basic-app/docs/rapport_pfe.pdf +0 -0
  74. package/templates/basic-app/docs/rapport_pfe.tex +0 -68
  75. package/templates/basic-app/docs/rapport_pfe.toc +0 -14
  76. package/templates/basic-app/package-lock.json +0 -4185
  77. package/templates/go-wasm-app/README.md +0 -38
  78. package/templates/go-wasm-app/babel.config.js +0 -15
  79. package/templates/go-wasm-app/build-client.js +0 -49
  80. package/templates/go-wasm-app/build-wasm.js +0 -237
  81. package/templates/go-wasm-app/package.json +0 -23
  82. package/templates/go-wasm-app/public/index.html +0 -128
  83. package/templates/go-wasm-app/public/styles.css +0 -197
  84. package/templates/go-wasm-app/public/wasm/example.wasm +0 -0
  85. package/templates/go-wasm-app/public/wasm/wasm_exec_node.js +0 -39
  86. package/templates/go-wasm-app/server.js +0 -521
  87. package/templates/go-wasm-app/src/App.jsx +0 -38
  88. package/templates/go-wasm-app/src/app.js +0 -153
  89. package/templates/go-wasm-app/src/client.js +0 -57
  90. package/templates/go-wasm-app/src/components/Footer.jsx +0 -13
  91. package/templates/go-wasm-app/src/components/Header.jsx +0 -19
  92. package/templates/go-wasm-app/src/components/WasmDemo.jsx +0 -120
  93. package/templates/go-wasm-app/src/main.jsx +0 -12
  94. package/templates/go-wasm-app/src/wasm/example.go +0 -75
  95. package/templates/go-wasm-app/tsconfig.server.json +0 -18
  96. package/templates/go-wasm-app/vite.config.js +0 -34
  97. package/templates/ssr-template/package-lock.json +0 -2478
  98. package/templates/ssr-template/public/index.html +0 -47
  99. package/templates/ssr-template/server.js +0 -369
  100. /package/templates/{ssr-template → complete-app}/client.js +0 -0
  101. /package/templates/{ssr-template → complete-app}/readme.md +0 -0
  102. /package/templates/{ssr-template → complete-app}/server.ts +0 -0
  103. /package/templates/{ssr-template → complete-app}/src/client.ts +0 -0
  104. /package/templates/{ssr-template → complete-app}/src/pages/index.tsx +0 -0
@@ -3,214 +3,31 @@ import path from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  import { renderToString, jsx } from 'frontend-hamroun';
5
5
  import { App } from './App.js';
6
- import fs from 'fs';
7
6
 
8
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+
9
10
  const app = express();
10
11
  const port = 3000;
11
12
 
12
- // Find the client entry file
13
- const getClientEntry = () => {
14
- const assetsDir = path.join(__dirname, './');
15
- const files = fs.readdirSync(assetsDir);
16
- return files.find(file => file.startsWith("client") && file.endsWith('.js'));
17
- };
18
-
19
- // Serve static files from dist/assets
20
- app.use('/assets', express.static(path.join(__dirname, './')));
21
-
22
- // Serve static files from dist
23
- app.use(express.static(path.join(__dirname, 'dist')));
24
-
25
- // Auto-routing middleware - scans the pages directory for components
26
- const getPagesDirectory = () => {
27
- return path.join(__dirname, 'pages');
28
- };
29
-
30
- // Helper to check if a file exists
31
- const fileExists = async (filePath) => {
32
- try {
33
- await fs.promises.access(filePath);
34
- return true;
35
- } catch {
36
- return false;
37
- }
38
- };
39
-
40
- // Map URL path to component path
41
- const getComponentPath = async (urlPath) => {
42
- const pagesDir = getPagesDirectory();
43
-
44
- // Handle root path
45
- if (urlPath === '/') {
46
- const indexPath = path.join(pagesDir, 'index.js');
47
- if (await fileExists(indexPath)) {
48
- return {
49
- componentPath: indexPath,
50
- params: {}
51
- };
52
- }
53
- }
54
-
55
- // Try direct match (e.g., /about -> /pages/about.js)
56
- const directPath = path.join(pagesDir, `${urlPath.slice(1)}.js`);
57
- if (await fileExists(directPath)) {
58
- return {
59
- componentPath: directPath,
60
- params: {}
61
- };
62
- }
63
-
64
- // Try directory index (e.g., /about -> /pages/about/index.js)
65
- const dirIndexPath = path.join(pagesDir, urlPath.slice(1), 'index.js');
66
- if (await fileExists(dirIndexPath)) {
67
- return {
68
- componentPath: dirIndexPath,
69
- params: {}
70
- };
71
- }
72
-
73
- // Look for dynamic routes (with [param] in filename)
74
- const segments = urlPath.split('/').filter(Boolean);
75
- const dynamicRoutes = [];
76
-
77
- // Recursively scan pages directory for all files
78
- const scanDir = (dir, basePath = '') => {
79
- const items = fs.readdirSync(dir, { withFileTypes: true });
80
-
81
- for (const item of items) {
82
- const itemPath = path.join(dir, item.name);
83
- const routePath = path.join(basePath, item.name);
84
-
85
- if (item.isDirectory()) {
86
- scanDir(itemPath, routePath);
87
- } else if (item.name.endsWith('.js') && item.name.includes('[')) {
88
- // This is a dynamic route file
89
- const urlPattern = routePath
90
- .replace(/\.js$/, '')
91
- .replace(/\[([^\]]+)\]/g, ':$1');
92
-
93
- dynamicRoutes.push({
94
- pattern: urlPattern,
95
- componentPath: itemPath
96
- });
97
- }
98
- }
99
- };
100
-
101
- scanDir(pagesDir);
102
-
103
- // Check if any dynamic routes match
104
- for (const route of dynamicRoutes) {
105
- const routeSegments = route.pattern.split('/').filter(Boolean);
106
- if (routeSegments.length !== segments.length) continue;
107
-
108
- const params = {};
109
- let matches = true;
110
-
111
- for (let i = 0; i < segments.length; i++) {
112
- const routeSeg = routeSegments[i];
113
- const urlSeg = segments[i];
114
-
115
- if (routeSeg.startsWith(':')) {
116
- // This is a parameter
117
- const paramName = routeSeg.slice(1);
118
- params[paramName] = urlSeg;
119
- } else if (routeSeg !== urlSeg) {
120
- matches = false;
121
- break;
122
- }
123
- }
124
-
125
- if (matches) {
126
- return {
127
- componentPath: route.componentPath,
128
- params
129
- };
130
- }
131
- }
132
-
133
- // No match found
134
- return null;
135
- };
136
-
137
- // Handle all routes with auto-routing
138
- app.get('*', async (req, res) => {
139
- try {
140
- const clientEntry = getClientEntry();
141
- const routeResult = await getComponentPath(req.path);
142
-
143
- if (!routeResult) {
144
- return res.status(404).send(`
145
- <!DOCTYPE html>
146
- <html>
147
- <head>
148
- <title>404 - Page Not Found</title>
149
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
150
- </head>
151
- <body>
152
- <div id="root">
153
- <h1>404 - Page Not Found</h1>
154
- <p>The page you requested could not be found.</p>
155
- </div>
156
- <script type="module" src="/assets/${clientEntry}"></script>
157
- </body>
158
- </html>
159
- `);
160
- }
161
-
162
- // Import the component dynamically
163
- const { default: PageComponent } = await import(routeResult.componentPath);
164
-
165
- if (!PageComponent) {
166
- throw new Error(`Invalid component in ${routeResult.componentPath}`);
167
- }
168
-
169
- // Render the component with params
170
- const html = await renderToString(jsx(PageComponent, { params: routeResult.params }));
171
-
172
- // Create route data for client hydration
173
- const initialState = {
174
- route: req.path,
175
- params: routeResult.params,
176
- timestamp: new Date().toISOString()
177
- };
178
-
179
- res.send(`
180
- <!DOCTYPE html>
181
- <html>
182
- <head>
183
- <title>Frontend Hamroun SSR</title>
184
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
185
- <meta charset="UTF-8">
186
- </head>
187
- <body>
188
- <div id="root">${html}</div>
189
- <script>window.__INITIAL_STATE__ = ${JSON.stringify(initialState)}</script>
190
- <script type="module" src="/assets/${clientEntry}"></script>
191
- </body>
192
- </html>
193
- `);
194
- } catch (error) {
195
- console.error('Rendering error:', error);
196
- res.status(500).send(`
197
- <!DOCTYPE html>
198
- <html>
199
- <head>
200
- <title>500 - Server Error</title>
201
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
202
- </head>
203
- <body>
204
- <div id="root">
205
- <h1>500 - Server Error</h1>
206
- <p>Something went wrong on the server.</p>
207
- <pre>${process.env.NODE_ENV === 'production' ? '' : error.stack}</pre>
208
- </div>
209
- <script type="module" src="/assets/${clientEntry}"></script>
210
- </body>
211
- </html>
212
- `);
213
- }
13
+ // Serve static files from dist directory
14
+ app.use(express.static(path.join(__dirname)));
15
+
16
+ app.get('/', async (req, res) => {
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
+ `);
214
31
  });
215
32
 
216
33
  app.listen(port, () => {
@@ -1,22 +1,19 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "target": "ESNext",
4
- "useDefineForClassFields": true,
5
- "lib": ["DOM", "DOM.Iterable", "ESNext"],
6
- "allowJs": false,
7
- "skipLibCheck": true,
8
- "esModuleInterop": true,
9
- "allowSyntheticDefaultImports": true,
3
+ "target": "ES2020",
4
+ "module": "ESNext",
5
+ "moduleResolution": "node",
6
+ "jsx": "preserve",
10
7
  "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
11
10
  "forceConsistentCasingInFileNames": true,
12
- "module": "ESNext",
13
- "moduleResolution": "Node",
11
+ "allowSyntheticDefaultImports": true,
14
12
  "resolveJsonModule": true,
15
13
  "isolatedModules": true,
16
14
  "noEmit": true,
17
- "jsx": "preserve",
18
- "jsxFactory": "createElement",
19
- "jsxFragmentFactory": "Fragment"
15
+ "types": ["node"]
20
16
  },
21
- "include": ["src"]
17
+ "include": ["src"],
18
+ "exclude": ["node_modules", "dist"]
22
19
  }
@@ -1,19 +1,11 @@
1
1
  {
2
2
  "extends": "./tsconfig.json",
3
3
  "compilerOptions": {
4
- "target": "ES2020",
5
- "module": "NodeNext",
6
- "moduleResolution": "NodeNext",
7
- "esModuleInterop": true,
8
- "outDir": "./dist/server",
9
- "declaration": true,
10
- "sourceMap": true,
11
- "strict": true,
12
- "skipLibCheck": true,
13
- "jsx": "react",
14
- "jsxFactory": "createElement",
15
- "jsxFragmentFactory": "Fragment"
4
+ "module": "ESNext",
5
+ "outDir": "dist",
6
+ "noEmit": false,
7
+ "jsx": "preserve",
8
+ "moduleResolution": "bundler"
16
9
  },
17
- "include": ["server.ts", "src/pages/**/*.tsx"],
18
- "exclude": ["node_modules", "dist"]
10
+ "include": ["src/server.ts"]
19
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
+ });
@@ -0,0 +1,63 @@
1
+ import esbuild from 'esbuild';
2
+ import { fileURLToPath } from 'url';
3
+ import { dirname, join } from 'path';
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+
8
+ // Build client
9
+ await esbuild.build({
10
+ entryPoints: ['src/client.tsx'],
11
+ bundle: true,
12
+ outfile: 'dist/client.js',
13
+ platform: 'browser',
14
+ format: 'esm',
15
+ minify: false,
16
+ jsx: 'transform',
17
+ jsxFactory: 'jsx',
18
+ jsxFragment: 'Fragment',
19
+ inject: ['./jsx-shim.js'],
20
+ });
21
+
22
+ // Build server
23
+ await esbuild.build({
24
+ entryPoints: ['src/server.ts'],
25
+ bundle: true,
26
+ outfile: 'dist/server.js',
27
+ platform: 'node',
28
+ format: 'esm',
29
+ external: ['frontend-hamroun'],
30
+ packages: 'external',
31
+ minify: false,
32
+ jsx: 'transform',
33
+ jsxFactory: 'jsx',
34
+ jsxFragment: 'Fragment',
35
+ inject: ['./jsx-shim.js'],
36
+ });
37
+
38
+ const config = {
39
+ entryPoints: ['src/index.js'],
40
+ bundle: true,
41
+ outfile: 'dist/bundle.js',
42
+ format: 'esm',
43
+ target: 'es2020',
44
+ minify: process.env.NODE_ENV === 'production',
45
+ sourcemap: process.env.NODE_ENV !== 'production',
46
+ platform: 'browser',
47
+ loader: {
48
+ '.wasm': 'file'
49
+ },
50
+ external: [],
51
+ define: {
52
+ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
53
+ }
54
+ };
55
+
56
+ if (process.argv.includes('--watch')) {
57
+ const ctx = await esbuild.context(config);
58
+ await ctx.watch();
59
+ console.log('Watching for changes...');
60
+ } else {
61
+ await esbuild.build(config);
62
+ console.log('Build complete!');
63
+ }