frontend-hamroun 1.2.79 → 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 (259) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -1513
  3. package/bin/cli.js +506 -145
  4. package/dist/index.cjs +2 -0
  5. package/dist/index.cjs.map +1 -0
  6. package/dist/index.client.cjs +2 -0
  7. package/dist/index.client.cjs.map +1 -0
  8. package/dist/index.client.js +26 -0
  9. package/dist/index.client.js.map +1 -0
  10. package/dist/index.js +299 -1
  11. package/dist/index.js.map +1 -0
  12. package/dist/jsx-runtime.cjs +2 -0
  13. package/dist/jsx-runtime.cjs.map +1 -0
  14. package/dist/jsx-runtime.js +93 -1
  15. package/dist/jsx-runtime.js.map +1 -0
  16. package/dist/renderer-Bo9zkUZ_.js +52 -0
  17. package/dist/renderer-Bo9zkUZ_.js.map +1 -0
  18. package/dist/renderer-Din1y3YM.cjs +2 -0
  19. package/dist/renderer-Din1y3YM.cjs.map +1 -0
  20. package/dist/server-renderer-CqIpQ-od.cjs +2 -0
  21. package/dist/server-renderer-CqIpQ-od.cjs.map +1 -0
  22. package/dist/server-renderer-QHt45Ip2.js +255 -0
  23. package/dist/server-renderer-QHt45Ip2.js.map +1 -0
  24. package/dist/server-renderer.cjs +2 -0
  25. package/dist/server-renderer.cjs.map +1 -0
  26. package/dist/server-renderer.js +5 -1
  27. package/dist/server-renderer.js.map +1 -0
  28. package/package.json +77 -120
  29. package/templates/basic-app/build.js +22 -0
  30. package/templates/basic-app/dev.js +27 -0
  31. package/templates/basic-app/esbuild.config.js +28 -0
  32. package/templates/basic-app/index.html +1 -1
  33. package/templates/basic-app/package.json +29 -28
  34. package/templates/basic-app/server.js +24 -0
  35. package/templates/basic-app/src/App.jsx +16 -0
  36. package/templates/basic-app/src/App.tsx +26 -0
  37. package/templates/basic-app/src/client.jsx +5 -0
  38. package/templates/basic-app/src/client.tsx +11 -0
  39. package/templates/basic-app/src/components/Counter.jsx +13 -0
  40. package/templates/basic-app/src/components/Counter.tsx +18 -0
  41. package/templates/basic-app/src/jsx-shim.js +3 -0
  42. package/templates/basic-app/src/jsx-shim.ts +11 -0
  43. package/templates/basic-app/src/main.jsx +98 -0
  44. package/templates/basic-app/src/main.tsx +0 -1
  45. package/templates/basic-app/src/server.js +47 -0
  46. package/templates/basic-app/src/server.ts +52 -0
  47. package/templates/basic-app/tsconfig.server.json +11 -0
  48. package/templates/complete-app/lib/frontend-hamroun.js +182 -0
  49. package/templates/complete-app/package.json +2 -1
  50. package/templates/complete-app/pages/about.jsx +0 -0
  51. package/templates/complete-app/pages/index.jsx +0 -0
  52. package/templates/complete-app/pages/wasm-demo.jsx +0 -0
  53. package/templates/complete-app/public/client.js +58 -49
  54. package/templates/complete-app/public/index.html +88 -17
  55. package/templates/complete-app/public/styles.css +30 -533
  56. package/templates/complete-app/server.js +31 -222
  57. package/templates/complete-app/wasm/build.bat +0 -0
  58. package/templates/complete-app/wasm/build.sh +0 -0
  59. package/templates/complete-app/wasm/example.go +0 -0
  60. package/templates/fullstack-app/build/main.js +130 -101
  61. package/templates/fullstack-app/build/main.js.map +4 -4
  62. package/templates/fullstack-app/package-lock.json +1773 -566
  63. package/templates/ssr-template/esbuild.config.js +33 -0
  64. package/templates/ssr-template/jsx-shim.js +1 -0
  65. package/templates/ssr-template/package.json +22 -16
  66. package/templates/ssr-template/src/App.tsx +12 -52
  67. package/templates/ssr-template/src/client.tsx +3 -17
  68. package/templates/ssr-template/src/server.ts +21 -204
  69. package/templates/ssr-template/tsconfig.json +10 -13
  70. package/templates/ssr-template/tsconfig.server.json +6 -14
  71. package/templates/wasm/build-wasm.js +228 -0
  72. package/templates/wasm/esbuild.config.js +63 -0
  73. package/templates/wasm/go/main.go +256 -0
  74. package/templates/wasm/go/wasm_exec.js +0 -0
  75. package/templates/wasm/index.html +97 -0
  76. package/templates/wasm/jsx-shim.js +9 -0
  77. package/templates/{go-wasm-app → wasm}/package-lock.json +5307 -3732
  78. package/templates/wasm/package.json +42 -0
  79. package/templates/wasm/public/example.wasm +0 -0
  80. package/templates/wasm/src/App.tsx +564 -0
  81. package/templates/wasm/src/client.tsx +220 -0
  82. package/templates/wasm/src/index.tsx +21 -0
  83. package/templates/wasm/src/server.ts +145 -0
  84. package/templates/wasm/tsconfig.json +21 -0
  85. package/templates/wasm/tsconfig.node.json +13 -0
  86. package/templates/wasm/tsconfig.server.json +23 -0
  87. package/templates/wasm/vite.config.ts +56 -0
  88. package/templates/wasm/wasm-loader.js +103 -0
  89. package/dist/batch/package.json +0 -16
  90. package/dist/client-router/package.json +0 -16
  91. package/dist/component/package.json +0 -16
  92. package/dist/context/package.json +0 -16
  93. package/dist/event-bus/package.json +0 -16
  94. package/dist/forms/package.json +0 -16
  95. package/dist/hooks/package.json +0 -16
  96. package/dist/hooks-0728361a.cjs +0 -1
  97. package/dist/hooks-b58f947c.js +0 -133
  98. package/dist/hooks.js +0 -1
  99. package/dist/hooks.mjs +0 -13
  100. package/dist/index.mjs +0 -137
  101. package/dist/jsx-runtime/package.json +0 -16
  102. package/dist/jsx-runtime.mjs +0 -64
  103. package/dist/lifecycle-events/package.json +0 -16
  104. package/dist/package.json +0 -71
  105. package/dist/render-component/package.json +0 -16
  106. package/dist/renderer/package.json +0 -16
  107. package/dist/renderer.js +0 -1
  108. package/dist/renderer.mjs +0 -27
  109. package/dist/router/package.json +0 -16
  110. package/dist/server/package.json +0 -17
  111. package/dist/server/src/batch.d.ts +0 -3
  112. package/dist/server/src/batch.js +0 -23
  113. package/dist/server/src/batch.js.map +0 -1
  114. package/dist/server/src/client-router.d.ts +0 -60
  115. package/dist/server/src/client-router.js +0 -210
  116. package/dist/server/src/client-router.js.map +0 -1
  117. package/dist/server/src/component.d.ts +0 -14
  118. package/dist/server/src/component.js +0 -106
  119. package/dist/server/src/component.js.map +0 -1
  120. package/dist/server/src/context.d.ts +0 -13
  121. package/dist/server/src/context.js +0 -21
  122. package/dist/server/src/context.js.map +0 -1
  123. package/dist/server/src/event-bus.d.ts +0 -23
  124. package/dist/server/src/event-bus.js +0 -75
  125. package/dist/server/src/event-bus.js.map +0 -1
  126. package/dist/server/src/forms.d.ts +0 -40
  127. package/dist/server/src/forms.js +0 -148
  128. package/dist/server/src/forms.js.map +0 -1
  129. package/dist/server/src/hooks.d.ts +0 -12
  130. package/dist/server/src/hooks.js +0 -170
  131. package/dist/server/src/hooks.js.map +0 -1
  132. package/dist/server/src/index.client.d.ts +0 -12
  133. package/dist/server/src/index.client.js +0 -14
  134. package/dist/server/src/index.client.js.map +0 -1
  135. package/dist/server/src/index.d.ts +0 -88
  136. package/dist/server/src/index.js +0 -79
  137. package/dist/server/src/index.js.map +0 -1
  138. package/dist/server/src/jsx-runtime/jsx-dev-runtime.d.ts +0 -1
  139. package/dist/server/src/jsx-runtime/jsx-dev-runtime.js +0 -2
  140. package/dist/server/src/jsx-runtime/jsx-dev-runtime.js.map +0 -1
  141. package/dist/server/src/jsx-runtime/jsx-runtime.d.ts +0 -4
  142. package/dist/server/src/jsx-runtime/jsx-runtime.js +0 -41
  143. package/dist/server/src/jsx-runtime/jsx-runtime.js.map +0 -1
  144. package/dist/server/src/jsx-runtime.d.ts +0 -20
  145. package/dist/server/src/jsx-runtime.js +0 -105
  146. package/dist/server/src/jsx-runtime.js.map +0 -1
  147. package/dist/server/src/lifecycle-events.d.ts +0 -108
  148. package/dist/server/src/lifecycle-events.js +0 -177
  149. package/dist/server/src/lifecycle-events.js.map +0 -1
  150. package/dist/server/src/renderComponent.d.ts +0 -13
  151. package/dist/server/src/renderComponent.js +0 -30
  152. package/dist/server/src/renderComponent.js.map +0 -1
  153. package/dist/server/src/renderer.d.ts +0 -2
  154. package/dist/server/src/renderer.js +0 -31
  155. package/dist/server/src/renderer.js.map +0 -1
  156. package/dist/server/src/router.d.ts +0 -55
  157. package/dist/server/src/router.js +0 -166
  158. package/dist/server/src/router.js.map +0 -1
  159. package/dist/server/src/server/api-router.d.ts +0 -15
  160. package/dist/server/src/server/api-router.js +0 -111
  161. package/dist/server/src/server/api-router.js.map +0 -1
  162. package/dist/server/src/server/auth.d.ts +0 -32
  163. package/dist/server/src/server/auth.js +0 -80
  164. package/dist/server/src/server/auth.js.map +0 -1
  165. package/dist/server/src/server/database.d.ts +0 -24
  166. package/dist/server/src/server/database.js +0 -135
  167. package/dist/server/src/server/database.js.map +0 -1
  168. package/dist/server/src/server/index.d.ts +0 -116
  169. package/dist/server/src/server/index.js +0 -508
  170. package/dist/server/src/server/index.js.map +0 -1
  171. package/dist/server/src/server/middleware.d.ts +0 -11
  172. package/dist/server/src/server/middleware.js +0 -46
  173. package/dist/server/src/server/middleware.js.map +0 -1
  174. package/dist/server/src/server/server.d.ts +0 -9
  175. package/dist/server/src/server/server.js +0 -87
  176. package/dist/server/src/server/server.js.map +0 -1
  177. package/dist/server/src/server/templates.d.ts +0 -30
  178. package/dist/server/src/server/templates.js +0 -208
  179. package/dist/server/src/server/templates.js.map +0 -1
  180. package/dist/server/src/server/types.d.ts +0 -38
  181. package/dist/server/src/server/types.js +0 -4
  182. package/dist/server/src/server/types.js.map +0 -1
  183. package/dist/server/src/server/utils.d.ts +0 -70
  184. package/dist/server/src/server/utils.js +0 -156
  185. package/dist/server/src/server/utils.js.map +0 -1
  186. package/dist/server/src/server/wasm.d.ts +0 -9
  187. package/dist/server/src/server/wasm.js +0 -117
  188. package/dist/server/src/server/wasm.js.map +0 -1
  189. package/dist/server/src/server-renderer.d.ts +0 -5
  190. package/dist/server/src/server-renderer.js +0 -106
  191. package/dist/server/src/server-renderer.js.map +0 -1
  192. package/dist/server/src/server-types.d.ts +0 -42
  193. package/dist/server/src/server-types.js +0 -6
  194. package/dist/server/src/server-types.js.map +0 -1
  195. package/dist/server/src/store.d.ts +0 -41
  196. package/dist/server/src/store.js +0 -99
  197. package/dist/server/src/store.js.map +0 -1
  198. package/dist/server/src/types.d.ts +0 -19
  199. package/dist/server/src/types.js +0 -2
  200. package/dist/server/src/types.js.map +0 -1
  201. package/dist/server/src/utils.d.ts +0 -46
  202. package/dist/server/src/utils.js +0 -144
  203. package/dist/server/src/utils.js.map +0 -1
  204. package/dist/server/src/vdom.d.ts +0 -8
  205. package/dist/server/src/vdom.js +0 -22
  206. package/dist/server/src/vdom.js.map +0 -1
  207. package/dist/server/src/wasm.d.ts +0 -36
  208. package/dist/server/src/wasm.js +0 -159
  209. package/dist/server/src/wasm.js.map +0 -1
  210. package/dist/server/tsconfig.server.tsbuildinfo +0 -1
  211. package/dist/server-renderer/package.json +0 -16
  212. package/dist/server-renderer.mjs +0 -64
  213. package/dist/store/package.json +0 -16
  214. package/dist/types/package.json +0 -16
  215. package/dist/utils/package.json +0 -16
  216. package/dist/vdom/package.json +0 -16
  217. package/dist/wasm/package.json +0 -16
  218. package/dist/wasm.js +0 -1
  219. package/dist/wasm.mjs +0 -103
  220. package/templates/basic-app/docs/rapport_pfe.aux +0 -27
  221. package/templates/basic-app/docs/rapport_pfe.log +0 -399
  222. package/templates/basic-app/docs/rapport_pfe.out +0 -10
  223. package/templates/basic-app/docs/rapport_pfe.pdf +0 -0
  224. package/templates/basic-app/docs/rapport_pfe.tex +0 -68
  225. package/templates/basic-app/docs/rapport_pfe.toc +0 -14
  226. package/templates/complete-app/package-lock.json +0 -2536
  227. package/templates/go-wasm-app/README.md +0 -38
  228. package/templates/go-wasm-app/babel.config.js +0 -21
  229. package/templates/go-wasm-app/build-client.js +0 -49
  230. package/templates/go-wasm-app/build-wasm.js +0 -237
  231. package/templates/go-wasm-app/build.config.js +0 -62
  232. package/templates/go-wasm-app/build.js +0 -218
  233. package/templates/go-wasm-app/package.json +0 -32
  234. package/templates/go-wasm-app/public/index.html +0 -128
  235. package/templates/go-wasm-app/public/styles.css +0 -197
  236. package/templates/go-wasm-app/public/wasm/example.wasm +0 -0
  237. package/templates/go-wasm-app/public/wasm/wasm_exec_node.js +0 -39
  238. package/templates/go-wasm-app/server.js +0 -70
  239. package/templates/go-wasm-app/src/App.jsx +0 -38
  240. package/templates/go-wasm-app/src/app.js +0 -173
  241. package/templates/go-wasm-app/src/client.js +0 -57
  242. package/templates/go-wasm-app/src/components/Footer.jsx +0 -13
  243. package/templates/go-wasm-app/src/components/Header.jsx +0 -19
  244. package/templates/go-wasm-app/src/components/WasmDemo.jsx +0 -120
  245. package/templates/go-wasm-app/src/main.jsx +0 -12
  246. package/templates/go-wasm-app/src/wasm/example.go +0 -75
  247. package/templates/go-wasm-app/tsconfig.server.json +0 -18
  248. package/templates/go-wasm-app/vite.config.js +0 -45
  249. package/templates/ssr-template/client.js +0 -58
  250. package/templates/ssr-template/package-lock.json +0 -2478
  251. package/templates/ssr-template/public/index.html +0 -47
  252. package/templates/ssr-template/readme.md +0 -188
  253. package/templates/ssr-template/server.js +0 -369
  254. package/templates/ssr-template/server.ts +0 -275
  255. package/templates/ssr-template/src/client.ts +0 -61
  256. package/templates/ssr-template/src/pages/index.tsx +0 -51
  257. package/templates/ssr-template/vite.config.js +0 -57
  258. /package/{dist/Counter.d.ts → templates/complete-app/api/hello.js} +0 -0
  259. /package/templates/{go-wasm-app/public/wasm → wasm/public}/wasm_exec.js +0 -0
@@ -2,17 +2,15 @@ import express from 'express';
2
2
  import path from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  import fs from 'fs';
5
+ // Fix imports by using only the exports that exist
5
6
  import {
6
7
  renderToString,
7
- jsx,
8
- Server,
9
- createServer,
10
- rateLimit,
8
+ jsx,
11
9
  requestLogger,
12
10
  errorHandler,
13
11
  notFoundHandler,
14
- loadGoWasmFromFile
15
- } from 'frontend-hamroun';
12
+ rateLimit
13
+ } from './lib/frontend-hamroun.js';
16
14
  import dotenv from 'dotenv';
17
15
  import compression from 'compression';
18
16
  import cors from 'cors';
@@ -42,6 +40,7 @@ app.use(rateLimit({
42
40
  }));
43
41
 
44
42
  // Serve static files from the public directory
43
+ // Important: This middleware should be defined BEFORE your catch-all route
45
44
  app.use(express.static(path.join(__dirname, 'public')));
46
45
 
47
46
  // Add correct MIME type for client.js module
@@ -55,7 +54,7 @@ app.get('*.wasm', (req, res, next) => {
55
54
  next();
56
55
  });
57
56
 
58
- // Add API routes example with authentication
57
+ // Add API routes example
59
58
  app.get('/api/hello', (req, res) => {
60
59
  res.json({
61
60
  message: 'Hello from the API!',
@@ -63,31 +62,6 @@ app.get('/api/hello', (req, res) => {
63
62
  });
64
63
  });
65
64
 
66
- // Load WebAssembly modules if available
67
- async function loadWasmModules() {
68
- const wasmDir = path.join(__dirname, 'wasm');
69
-
70
- if (fs.existsSync(wasmDir)) {
71
- try {
72
- const wasmFiles = fs.readdirSync(wasmDir).filter(file => file.endsWith('.wasm'));
73
-
74
- for (const wasmFile of wasmFiles) {
75
- const wasmPath = path.join(wasmDir, wasmFile);
76
- const wasmModule = await loadGoWasmFromFile(wasmPath, { debug: true });
77
-
78
- console.log(`Loaded WASM module: ${wasmFile}`);
79
- console.log(`Available functions:`, Object.keys(wasmModule.functions));
80
-
81
- // Store modules globally for API routes to use
82
- global.wasmModules = global.wasmModules || {};
83
- global.wasmModules[wasmFile.replace('.wasm', '')] = wasmModule;
84
- }
85
- } catch (error) {
86
- console.error('Failed to load WASM modules:', error);
87
- }
88
- }
89
- }
90
-
91
65
  // Find the pages directory
92
66
  const getPagesDirectory = () => {
93
67
  return path.join(__dirname, 'pages');
@@ -103,31 +77,6 @@ const fileExists = async (filePath) => {
103
77
  }
104
78
  };
105
79
 
106
- // Generate meta tags for SEO
107
- async function generateMetaTags(content, title = '') {
108
- // Extract title from content or use provided title
109
- const pageTitle = title || 'Frontend Hamroun App';
110
-
111
- // Generate description from content
112
- const plainText = content.replace(/<[^>]*>/g, ' ').trim();
113
- const description = plainText.substring(0, 160) + (plainText.length > 160 ? '...' : '');
114
-
115
- // Extract keywords
116
- const keywords = plainText
117
- .toLowerCase()
118
- .replace(/[^\w\s]/g, '')
119
- .split(/\s+/)
120
- .filter(w => w.length > 3)
121
- .slice(0, 5)
122
- .join(', ');
123
-
124
- return {
125
- title: pageTitle,
126
- description,
127
- keywords
128
- };
129
- }
130
-
131
80
  // Map URL path to component path
132
81
  const getComponentPath = async (urlPath) => {
133
82
  const pagesDir = getPagesDirectory();
@@ -144,8 +93,7 @@ const getComponentPath = async (urlPath) => {
144
93
  }
145
94
 
146
95
  // Try direct match (e.g., /about -> /pages/about.js)
147
- // Only look for .js files since Node.js ESM doesn't support .jsx directly
148
- const possibleExtensions = ['.js']; // Remove .jsx, .ts, .tsx
96
+ const possibleExtensions = ['.js'];
149
97
 
150
98
  for (const ext of possibleExtensions) {
151
99
  const directPath = path.join(pagesDir, `${urlPath.slice(1)}${ext}`);
@@ -168,80 +116,24 @@ const getComponentPath = async (urlPath) => {
168
116
  }
169
117
  }
170
118
 
171
- // Look for dynamic routes (with [param] in filename)
172
- const segments = urlPath.split('/').filter(Boolean);
173
- const dynamicRoutes = [];
174
-
175
- // Recursively scan pages directory for all files
176
- const scanDir = (dir, basePath = '') => {
177
- const items = fs.readdirSync(dir, { withFileTypes: true });
178
-
179
- for (const item of items) {
180
- const itemPath = path.join(dir, item.name);
181
- const routePath = path.join(basePath, item.name);
182
-
183
- if (item.isDirectory()) {
184
- scanDir(itemPath, routePath);
185
- } else if (item.name.endsWith('.js')) {
186
- if (item.name.includes('[')) {
187
- // This is a dynamic route file
188
- const urlPattern = routePath
189
- .replace(/\.js$/, '')
190
- .replace(/\[([^\]]+)\]/g, ':$1');
191
-
192
- dynamicRoutes.push({
193
- pattern: urlPattern,
194
- componentPath: itemPath
195
- });
196
- }
197
- }
198
- }
199
- };
200
-
201
- scanDir(pagesDir);
202
-
203
- // Check if any dynamic routes match
204
- for (const route of dynamicRoutes) {
205
- const routeSegments = route.pattern.split('/').filter(Boolean);
206
- if (routeSegments.length !== segments.length) continue;
207
-
208
- const params = {};
209
- let matches = true;
210
-
211
- for (let i = 0; i < segments.length; i++) {
212
- const routeSeg = routeSegments[i];
213
- const urlSeg = segments[i];
214
-
215
- if (routeSeg.startsWith(':')) {
216
- // This is a parameter
217
- const paramName = routeSeg.slice(1);
218
- params[paramName] = urlSeg;
219
- } else if (routeSeg !== urlSeg) {
220
- matches = false;
221
- break;
222
- }
223
- }
224
-
225
- if (matches) {
226
- return {
227
- componentPath: route.componentPath,
228
- params
229
- };
230
- }
231
- }
232
-
233
119
  // No match found
234
120
  return null;
235
121
  };
236
122
 
237
- // Handle all routes with SSR
123
+ // Handle all GET routes with SSR - explicitly exclude /public/ paths
238
124
  app.get('*', async (req, res, next) => {
239
125
  try {
240
- // Skip static assets and API routes
241
- if (req.path.match(/\.(js|css|ico|png|jpg|jpeg|gif|svg|wasm)$/) || req.path.startsWith('/api/')) {
126
+ // Skip API routes
127
+ if (req.path.startsWith('/api/')) {
242
128
  return next();
243
129
  }
244
-
130
+
131
+ // Skip static assets - check file extensions that should be handled as static
132
+ if (req.path.match(/\.(js|css|ico|png|jpg|jpeg|gif|svg|wasm|txt|pdf|json|map)$/)) {
133
+ return next();
134
+ }
135
+
136
+ // Try to find the matching component
245
137
  const routeResult = await getComponentPath(req.path);
246
138
 
247
139
  if (!routeResult) {
@@ -271,16 +163,14 @@ app.get('*', async (req, res, next) => {
271
163
  `);
272
164
  }
273
165
 
274
- // Fixed component loading to use file:// URL scheme for Windows
275
- const componentUrl = new URL(`file://${routeResult.componentPath}`).href;
276
-
166
+ // Import the component
277
167
  try {
278
- // Import the component - handle both module.default and direct module exports
168
+ const componentUrl = `file://${routeResult.componentPath}`;
279
169
  const moduleImport = await import(componentUrl);
280
170
  const PageComponent = moduleImport.default || moduleImport;
281
171
 
282
172
  if (!PageComponent || typeof PageComponent !== 'function') {
283
- throw new Error(`Invalid component in ${routeResult.componentPath}: component is not a function`);
173
+ throw new Error(`Invalid component in ${routeResult.componentPath}`);
284
174
  }
285
175
 
286
176
  // Create props with route data
@@ -293,40 +183,9 @@ app.get('*', async (req, res, next) => {
293
183
  }
294
184
  };
295
185
 
296
- // Use a simpler rendering approach for more reliability
297
- let html;
298
- try {
299
- // Create a simple HTML structure based on the component's output
300
- const result = PageComponent(initialProps);
301
-
302
- // Create a fallback HTML if the result is not valid
303
- if (!result || typeof result !== 'object' || !result.type) {
304
- html = `
305
- <div class="error-container">
306
- <h1>Frontend Hamroun App</h1>
307
- <p>This is a simple fallback page.</p>
308
- <p>Path: ${req.path}</p>
309
- <p>Server time: ${initialProps.api.serverTime}</p>
310
- </div>
311
- `;
312
- } else {
313
- // Use renderToString with error handling
314
- html = renderToString(result) || '<div>Rendering failed</div>';
315
- }
316
- } catch (err) {
317
- console.error("Error with renderToString:", err);
318
- html = `
319
- <div class="error-container">
320
- <h1>Rendering Error</h1>
321
- <p>There was an error rendering this page: ${err.message}</p>
322
- <p>Path: ${req.path}</p>
323
- </div>
324
- `;
325
- }
326
-
327
- // Generate meta tags
328
- const metaTags = await generateMetaTags(html,
329
- typeof PageComponent.getTitle === 'function' ? PageComponent.getTitle(initialProps) : 'Frontend Hamroun App');
186
+ // Render the component
187
+ const result = PageComponent(initialProps);
188
+ let html = renderToString(result);
330
189
 
331
190
  // Send complete HTML with hydration data
332
191
  res.send(`
@@ -335,61 +194,22 @@ app.get('*', async (req, res, next) => {
335
194
  <head>
336
195
  <meta charset="UTF-8">
337
196
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
338
-
339
- <!-- Generated Meta Tags -->
340
- <title>${metaTags.title}</title>
341
- <meta name="description" content="${metaTags.description}">
342
- <meta name="keywords" content="${metaTags.keywords}">
343
-
344
- <!-- Open Graph Meta Tags -->
345
- <meta property="og:title" content="${metaTags.title}">
346
- <meta property="og:description" content="${metaTags.description}">
347
- <meta property="og:type" content="website">
348
- <meta property="og:url" content="${req.protocol}://${req.get('host')}${req.originalUrl}">
349
-
350
- <!-- Import styles -->
197
+ <title>Frontend Hamroun App</title>
351
198
  <link href="/styles.css" rel="stylesheet" type="text/css">
352
199
  </head>
353
200
  <body>
354
201
  <div id="app">${html}</div>
355
-
356
- <!-- Add initial state for hydration -->
357
202
  <script id="__APP_DATA__" type="application/json">${JSON.stringify(initialProps)}</script>
358
203
  <script type="module" src="/client.js"></script>
359
204
  </body>
360
205
  </html>
361
206
  `);
362
- } catch (importError) {
363
- console.error(`Error importing component from ${componentUrl}:`, importError);
364
- throw new Error(`Failed to import component: ${importError.message}`);
207
+ } catch (error) {
208
+ console.error('Error rendering component:', error);
209
+ next(error);
365
210
  }
366
211
  } catch (error) {
367
- console.error('Rendering error:', error);
368
- res.status(500).send(`
369
- <!DOCTYPE html>
370
- <html>
371
- <head>
372
- <title>500 - Server Error</title>
373
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
374
- <link href="/styles.css" rel="stylesheet" type="text/css">
375
- </head>
376
- <body>
377
- <div id="app">
378
- <div class="container">
379
- <h1>500 - Server Error</h1>
380
- <p>Something went wrong on the server.</p>
381
- ${process.env.NODE_ENV === 'development' ? `<pre>${error.stack}</pre>` : ''}
382
- <a href="/" class="button">Go to Home</a>
383
- </div>
384
- </div>
385
- <script id="__APP_DATA__" type="application/json">${JSON.stringify({
386
- path: req.path,
387
- error: 'server_error'
388
- })}</script>
389
- <script type="module" src="/client.js"></script>
390
- </body>
391
- </html>
392
- `);
212
+ next(error);
393
213
  }
394
214
  });
395
215
 
@@ -400,18 +220,7 @@ app.use(errorHandler);
400
220
  app.use(notFoundHandler);
401
221
 
402
222
  // Start the server
403
- const startServer = async () => {
404
- // Load WebAssembly modules if available
405
- await loadWasmModules();
406
-
407
- // Start the server
408
- app.listen(PORT, () => {
409
- console.log(`Server running at http://localhost:${PORT}`);
410
- console.log(`Mode: ${process.env.NODE_ENV || 'development'}`);
411
- });
412
- };
413
-
414
- startServer().catch(err => {
415
- console.error('Failed to start server:', err);
416
- process.exit(1);
223
+ app.listen(PORT, () => {
224
+ console.log(`Server running at http://localhost:${PORT}`);
225
+ console.log(`Mode: ${process.env.NODE_ENV || 'development'}`);
417
226
  });
File without changes
File without changes
File without changes
@@ -14,7 +14,90 @@ var __export = (target, all) => {
14
14
  __defProp(target, name, { get: all[name], enumerable: true });
15
15
  };
16
16
 
17
- // node_modules/frontend-hamroun/dist/index.mjs
17
+ // node_modules/frontend-hamroun/dist/jsx-runtime.js
18
+ function jsx(type, props) {
19
+ console.log("JSX Transform:", { type, props });
20
+ const processedProps = { ...props };
21
+ if (arguments.length > 2) {
22
+ processedProps.children = Array.prototype.slice.call(arguments, 2);
23
+ }
24
+ return { type, props: processedProps };
25
+ }
26
+ async function createElement(vnode) {
27
+ console.log("Creating element from:", vnode);
28
+ if (vnode == null) {
29
+ return document.createTextNode("");
30
+ }
31
+ if (typeof vnode === "boolean") {
32
+ return document.createTextNode("");
33
+ }
34
+ if (typeof vnode === "number" || typeof vnode === "string") {
35
+ return document.createTextNode(String(vnode));
36
+ }
37
+ if (Array.isArray(vnode)) {
38
+ const fragment = document.createDocumentFragment();
39
+ for (const child of vnode) {
40
+ const node = await createElement(child);
41
+ fragment.appendChild(node);
42
+ }
43
+ return fragment;
44
+ }
45
+ if ("type" in vnode && vnode.props !== void 0) {
46
+ const { type, props } = vnode;
47
+ if (typeof type === "function") {
48
+ try {
49
+ const result = await type(props || {});
50
+ const node = await createElement(result);
51
+ if (node instanceof Element) {
52
+ node.setAttribute("data-component-id", type.name || type.toString());
53
+ }
54
+ return node;
55
+ } catch (error) {
56
+ console.error("Error rendering component:", error);
57
+ return document.createTextNode("");
58
+ }
59
+ }
60
+ const element = document.createElement(type);
61
+ for (const [key, value] of Object.entries(props || {})) {
62
+ if (key === "children")
63
+ continue;
64
+ if (key.startsWith("on") && typeof value === "function") {
65
+ const eventName = key.toLowerCase().slice(2);
66
+ const existingHandler = element.__events?.[eventName];
67
+ if (existingHandler) {
68
+ element.removeEventListener(eventName, existingHandler);
69
+ }
70
+ element.addEventListener(eventName, value);
71
+ if (!element.__events) {
72
+ element.__events = {};
73
+ }
74
+ element.__events[eventName] = value;
75
+ } else if (key === "style" && typeof value === "object") {
76
+ Object.assign(element.style, value);
77
+ } else if (key === "className") {
78
+ element.setAttribute("class", String(value));
79
+ } else if (key !== "key" && key !== "ref") {
80
+ element.setAttribute(key, String(value));
81
+ }
82
+ }
83
+ const children = props?.children;
84
+ if (children != null) {
85
+ const childArray = Array.isArray(children) ? children.flat() : [children];
86
+ for (const child of childArray) {
87
+ const childNode = await createElement(child);
88
+ element.appendChild(childNode);
89
+ }
90
+ }
91
+ return element;
92
+ }
93
+ return document.createTextNode(String(vnode));
94
+ }
95
+ var init_jsx_runtime = __esm({
96
+ "node_modules/frontend-hamroun/dist/jsx-runtime.js"() {
97
+ }
98
+ });
99
+
100
+ // node_modules/frontend-hamroun/dist/server-renderer-QHt45Ip2.js
18
101
  function batchUpdates(fn) {
19
102
  if (isBatching) {
20
103
  queue.push(fn);
@@ -25,7 +108,7 @@ function batchUpdates(fn) {
25
108
  fn();
26
109
  while (queue.length > 0) {
27
110
  const nextFn = queue.shift();
28
- nextFn == null ? void 0 : nextFn();
111
+ nextFn?.();
29
112
  }
30
113
  } finally {
31
114
  isBatching = false;
@@ -61,7 +144,7 @@ function useState(initial) {
61
144
  componentState.set(index2, initial);
62
145
  }
63
146
  const state2 = componentState.get(index2);
64
- const setState2 = (newValue) => {
147
+ const setState2 = (_newValue) => {
65
148
  };
66
149
  stateIndices.set(currentRender, index2 + 1);
67
150
  return [state2, setState2];
@@ -70,7 +153,7 @@ function useState(initial) {
70
153
  states.set(currentRender, []);
71
154
  }
72
155
  const componentStates = states.get(currentRender);
73
- const index = stateIndices.get(currentRender);
156
+ const index = stateIndices.get(currentRender) || 0;
74
157
  if (index >= componentStates.length) {
75
158
  componentStates.push(initial);
76
159
  }
@@ -92,19 +175,24 @@ function useState(initial) {
92
175
  function useEffect(callback, deps) {
93
176
  if (!currentRender)
94
177
  throw new Error("useEffect must be called within a render");
95
- const effectIndex = stateIndices.get(currentRender);
178
+ if (isServer) {
179
+ const effectIndex2 = stateIndices.get(currentRender) || 0;
180
+ stateIndices.set(currentRender, effectIndex2 + 1);
181
+ return;
182
+ }
183
+ const effectIndex = stateIndices.get(currentRender) || 0;
96
184
  if (!effects.has(currentRender)) {
97
185
  effects.set(currentRender, []);
98
186
  }
99
187
  const componentEffects = effects.get(currentRender);
100
188
  const prevEffect = componentEffects[effectIndex];
101
189
  if (!prevEffect || !deps || !prevEffect.deps || deps.some((dep, i) => dep !== prevEffect.deps[i])) {
102
- if (prevEffect == null ? void 0 : prevEffect.cleanup) {
190
+ if (prevEffect?.cleanup) {
103
191
  prevEffect.cleanup();
104
192
  }
105
193
  queueMicrotask(() => {
106
194
  const cleanup = callback() || void 0;
107
- componentEffects[effectIndex] = { cleanup, deps };
195
+ componentEffects[effectIndex] = { cleanup, deps: deps || [] };
108
196
  });
109
197
  }
110
198
  stateIndices.set(currentRender, effectIndex + 1);
@@ -112,7 +200,7 @@ function useEffect(callback, deps) {
112
200
  function useMemo(factory, deps) {
113
201
  if (!currentRender)
114
202
  throw new Error("useMemo must be called within a render");
115
- const memoIndex = stateIndices.get(currentRender);
203
+ const memoIndex = stateIndices.get(currentRender) || 0;
116
204
  if (!memos.has(currentRender)) {
117
205
  memos.set(currentRender, []);
118
206
  }
@@ -120,7 +208,7 @@ function useMemo(factory, deps) {
120
208
  const prevMemo = componentMemos[memoIndex];
121
209
  if (!prevMemo || deps && deps.some((dep, i) => !Object.is(dep, prevMemo.deps[i]))) {
122
210
  const value = factory();
123
- componentMemos[memoIndex] = { value, deps };
211
+ componentMemos[memoIndex] = { value, deps: deps || [] };
124
212
  stateIndices.set(currentRender, memoIndex + 1);
125
213
  return value;
126
214
  }
@@ -148,84 +236,25 @@ function useErrorBoundary() {
148
236
  const [error, setError] = useState(null);
149
237
  return [error, () => setError(null)];
150
238
  }
151
- function jsx(type, props) {
152
- console.log("JSX Transform:", { type, props });
153
- const processedProps = { ...props };
154
- if (arguments.length > 2) {
155
- processedProps.children = Array.prototype.slice.call(arguments, 2);
156
- }
157
- return { type, props: processedProps };
158
- }
159
- async function createElement(vnode) {
160
- var _a;
161
- console.log("Creating element from:", vnode);
162
- if (vnode == null) {
163
- return document.createTextNode("");
164
- }
165
- if (typeof vnode === "boolean") {
166
- return document.createTextNode("");
167
- }
168
- if (typeof vnode === "number" || typeof vnode === "string") {
169
- return document.createTextNode(String(vnode));
170
- }
171
- if (Array.isArray(vnode)) {
172
- const fragment = document.createDocumentFragment();
173
- for (const child of vnode) {
174
- const node = await createElement(child);
175
- fragment.appendChild(node);
176
- }
177
- return fragment;
178
- }
179
- if ("type" in vnode && vnode.props !== void 0) {
180
- const { type, props } = vnode;
181
- if (typeof type === "function") {
182
- try {
183
- const result = await type(props || {});
184
- const node = await createElement(result);
185
- if (node instanceof Element) {
186
- node.setAttribute("data-component-id", type.name || type.toString());
187
- }
188
- return node;
189
- } catch (error) {
190
- console.error("Error rendering component:", error);
191
- return document.createTextNode("");
192
- }
193
- }
194
- const element = document.createElement(type);
195
- for (const [key, value] of Object.entries(props || {})) {
196
- if (key === "children")
197
- continue;
198
- if (key.startsWith("on") && typeof value === "function") {
199
- const eventName = key.toLowerCase().slice(2);
200
- const existingHandler = (_a = element.__events) == null ? void 0 : _a[eventName];
201
- if (existingHandler) {
202
- element.removeEventListener(eventName, existingHandler);
203
- }
204
- element.addEventListener(eventName, value);
205
- if (!element.__events) {
206
- element.__events = {};
207
- }
208
- element.__events[eventName] = value;
209
- } else if (key === "style" && typeof value === "object") {
210
- Object.assign(element.style, value);
211
- } else if (key === "className") {
212
- element.setAttribute("class", String(value));
213
- } else if (key !== "key" && key !== "ref") {
214
- element.setAttribute(key, String(value));
215
- }
216
- }
217
- const children = props == null ? void 0 : props.children;
218
- if (children != null) {
219
- const childArray = Array.isArray(children) ? children.flat() : [children];
220
- for (const child of childArray) {
221
- const childNode = await createElement(child);
222
- element.appendChild(childNode);
223
- }
224
- }
225
- return element;
239
+ var isBatching, queue, currentRender, states, stateIndices, effects, memos, isServer, serverStates, globalRenderCallback, globalContainer, currentElement;
240
+ var init_server_renderer_QHt45Ip2 = __esm({
241
+ "node_modules/frontend-hamroun/dist/server-renderer-QHt45Ip2.js"() {
242
+ isBatching = false;
243
+ queue = [];
244
+ currentRender = 0;
245
+ states = /* @__PURE__ */ new Map();
246
+ stateIndices = /* @__PURE__ */ new Map();
247
+ effects = /* @__PURE__ */ new Map();
248
+ memos = /* @__PURE__ */ new Map();
249
+ isServer = typeof window === "undefined";
250
+ serverStates = /* @__PURE__ */ new Map();
251
+ globalRenderCallback = null;
252
+ globalContainer = null;
253
+ currentElement = null;
226
254
  }
227
- return document.createTextNode(String(vnode));
228
- }
255
+ });
256
+
257
+ // node_modules/frontend-hamroun/dist/renderer-Bo9zkUZ_.js
229
258
  async function hydrate(element, container) {
230
259
  isHydrating = true;
231
260
  try {
@@ -250,25 +279,25 @@ async function render(element, container) {
250
279
  }
251
280
  });
252
281
  }
253
- var isBatching, queue, currentRender, states, stateIndices, effects, memos, globalRenderCallback, globalContainer, currentElement, isServer, serverStates, isHydrating;
254
- var init_dist = __esm({
255
- "node_modules/frontend-hamroun/dist/index.mjs"() {
256
- isBatching = false;
257
- queue = [];
258
- currentRender = 0;
259
- states = /* @__PURE__ */ new Map();
260
- stateIndices = /* @__PURE__ */ new Map();
261
- effects = /* @__PURE__ */ new Map();
262
- memos = /* @__PURE__ */ new Map();
263
- globalRenderCallback = null;
264
- globalContainer = null;
265
- currentElement = null;
266
- isServer = typeof window === "undefined";
267
- serverStates = /* @__PURE__ */ new Map();
282
+ var isHydrating;
283
+ var init_renderer_Bo9zkUZ = __esm({
284
+ "node_modules/frontend-hamroun/dist/renderer-Bo9zkUZ_.js"() {
285
+ init_jsx_runtime();
286
+ init_server_renderer_QHt45Ip2();
268
287
  isHydrating = false;
269
288
  }
270
289
  });
271
290
 
291
+ // node_modules/frontend-hamroun/dist/index.js
292
+ var init_dist = __esm({
293
+ "node_modules/frontend-hamroun/dist/index.js"() {
294
+ init_jsx_runtime();
295
+ init_renderer_Bo9zkUZ();
296
+ init_server_renderer_QHt45Ip2();
297
+ init_server_renderer_QHt45Ip2();
298
+ }
299
+ });
300
+
272
301
  // src/pages/404.tsx
273
302
  var __exports = {};
274
303
  __export(__exports, {