frontend-hamroun 1.2.75 → 1.2.77

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 (113) hide show
  1. package/dist/batch/package.json +16 -0
  2. package/dist/client-router/package.json +16 -0
  3. package/dist/component/package.json +16 -0
  4. package/dist/context/package.json +16 -0
  5. package/dist/event-bus/package.json +16 -0
  6. package/dist/forms/package.json +16 -0
  7. package/dist/hooks/package.json +16 -0
  8. package/dist/jsx-runtime/package.json +16 -0
  9. package/dist/lifecycle-events/package.json +16 -0
  10. package/dist/package.json +71 -0
  11. package/dist/render-component/package.json +16 -0
  12. package/dist/renderer/package.json +16 -0
  13. package/dist/router/package.json +16 -0
  14. package/dist/server/package.json +17 -0
  15. package/dist/server/src/client-router.d.ts +60 -0
  16. package/dist/server/src/client-router.js +210 -0
  17. package/dist/server/src/client-router.js.map +1 -0
  18. package/dist/server/src/component.js +1 -1
  19. package/dist/server/src/event-bus.d.ts +23 -0
  20. package/dist/server/src/event-bus.js +75 -0
  21. package/dist/server/src/event-bus.js.map +1 -0
  22. package/dist/server/src/forms.d.ts +40 -0
  23. package/dist/server/src/forms.js +148 -0
  24. package/dist/server/src/forms.js.map +1 -0
  25. package/dist/server/src/hooks.js +2 -2
  26. package/dist/server/src/index.js +19 -11
  27. package/dist/server/src/lifecycle-events.d.ts +108 -0
  28. package/dist/server/src/lifecycle-events.js +177 -0
  29. package/dist/server/src/lifecycle-events.js.map +1 -0
  30. package/dist/server/src/renderComponent.js +1 -1
  31. package/dist/server/src/renderer.js +3 -3
  32. package/dist/server/src/router.d.ts +55 -0
  33. package/dist/server/src/router.js +166 -0
  34. package/dist/server/src/router.js.map +1 -0
  35. package/dist/server/src/server/index.d.ts +75 -2
  36. package/dist/server/src/server/index.js +224 -8
  37. package/dist/server/src/server/index.js.map +1 -1
  38. package/dist/server/src/server/server.js +1 -1
  39. package/dist/server/src/server/templates.d.ts +28 -0
  40. package/dist/server/src/server/templates.js +204 -0
  41. package/dist/server/src/server/templates.js.map +1 -0
  42. package/dist/server/src/server/utils.d.ts +70 -0
  43. package/dist/server/src/server/utils.js +156 -0
  44. package/dist/server/src/server/utils.js.map +1 -0
  45. package/dist/server/src/server-renderer.js +1 -1
  46. package/dist/server/src/store.d.ts +41 -0
  47. package/dist/server/src/store.js +99 -0
  48. package/dist/server/src/store.js.map +1 -0
  49. package/dist/server/src/utils.d.ts +46 -0
  50. package/dist/server/src/utils.js +144 -0
  51. package/dist/server/src/utils.js.map +1 -0
  52. package/dist/server/tsconfig.server.tsbuildinfo +1 -1
  53. package/dist/server-renderer/package.json +16 -0
  54. package/dist/store/package.json +16 -0
  55. package/dist/types/package.json +16 -0
  56. package/dist/utils/package.json +16 -0
  57. package/dist/vdom/package.json +16 -0
  58. package/dist/wasm/package.json +16 -0
  59. package/package.json +14 -13
  60. package/templates/complete-app/build.js +284 -0
  61. package/templates/complete-app/package.json +40 -0
  62. package/templates/complete-app/public/styles.css +345 -0
  63. package/templates/complete-app/src/api/index.js +31 -0
  64. package/templates/complete-app/src/client.js +93 -0
  65. package/templates/complete-app/src/components/App.js +66 -0
  66. package/templates/complete-app/src/components/Footer.js +19 -0
  67. package/templates/complete-app/src/components/Header.js +38 -0
  68. package/templates/complete-app/src/pages/About.js +59 -0
  69. package/templates/complete-app/src/pages/Home.js +54 -0
  70. package/templates/complete-app/src/pages/WasmDemo.js +136 -0
  71. package/templates/complete-app/src/server.js +186 -0
  72. package/templates/complete-app/src/wasm/build.bat +16 -0
  73. package/templates/complete-app/src/wasm/build.sh +16 -0
  74. package/templates/complete-app/src/wasm/example.go +101 -0
  75. package/templates/fullstack-app/build/main.css +225 -15
  76. package/templates/fullstack-app/build/main.css.map +2 -2
  77. package/templates/fullstack-app/build/main.js +657 -372
  78. package/templates/fullstack-app/build/main.js.map +4 -4
  79. package/templates/fullstack-app/build.ts +3 -4
  80. package/templates/fullstack-app/public/styles.css +222 -15
  81. package/templates/fullstack-app/server.ts +46 -12
  82. package/templates/fullstack-app/src/components/ClientHome.tsx +0 -0
  83. package/templates/fullstack-app/src/components/ErrorBoundary.tsx +36 -0
  84. package/templates/fullstack-app/src/components/Layout.tsx +23 -26
  85. package/templates/fullstack-app/src/components/StateDemo.tsx +207 -0
  86. package/templates/fullstack-app/src/components/UserList.tsx +30 -13
  87. package/templates/fullstack-app/src/data/api.ts +173 -38
  88. package/templates/fullstack-app/src/main.tsx +88 -154
  89. package/templates/fullstack-app/src/middleware.ts +28 -0
  90. package/templates/fullstack-app/src/pages/404.tsx +28 -0
  91. package/templates/fullstack-app/src/pages/[id].tsx +0 -0
  92. package/templates/fullstack-app/src/pages/_app.tsx +11 -0
  93. package/templates/fullstack-app/src/pages/_document.tsx +25 -0
  94. package/templates/fullstack-app/src/pages/_error.tsx +45 -0
  95. package/templates/fullstack-app/src/pages/about.tsx +71 -0
  96. package/templates/fullstack-app/src/pages/api/users/[id].ts +73 -0
  97. package/templates/fullstack-app/src/pages/api/users/index.ts +43 -0
  98. package/templates/fullstack-app/src/pages/index.tsx +97 -20
  99. package/templates/fullstack-app/src/pages/users/[id].tsx +153 -0
  100. package/templates/fullstack-app/src/pages/wasm-demo.tsx +1 -0
  101. package/templates/go/example.go +99 -86
  102. package/templates/go-wasm-app/babel.config.js +8 -2
  103. package/templates/go-wasm-app/build.config.js +62 -0
  104. package/templates/go-wasm-app/build.js +218 -0
  105. package/templates/go-wasm-app/package.json +21 -12
  106. package/templates/go-wasm-app/server.js +59 -510
  107. package/templates/go-wasm-app/src/app.js +173 -0
  108. package/templates/go-wasm-app/vite.config.js +16 -5
  109. package/templates/ssr-template/client.js +54 -26
  110. package/templates/ssr-template/server.js +5 -28
  111. package/templates/ssr-template/vite.config.js +21 -5
  112. package/dist/server/wasm.d.ts +0 -7
  113. package/dist/wasm.d.ts +0 -37
@@ -47,6 +47,107 @@ function finishRender() {
47
47
  }
48
48
  currentRender = 0;
49
49
  }
50
+ function useState(initial) {
51
+ if (!currentRender) {
52
+ throw new Error("useState must be called within a render");
53
+ }
54
+ if (isServer) {
55
+ if (!serverStates.has(currentRender)) {
56
+ serverStates.set(currentRender, /* @__PURE__ */ new Map());
57
+ }
58
+ const componentState = serverStates.get(currentRender);
59
+ const index2 = stateIndices.get(currentRender) || 0;
60
+ if (!componentState.has(index2)) {
61
+ componentState.set(index2, initial);
62
+ }
63
+ const state2 = componentState.get(index2);
64
+ const setState2 = (newValue) => {
65
+ };
66
+ stateIndices.set(currentRender, index2 + 1);
67
+ return [state2, setState2];
68
+ }
69
+ if (!states.has(currentRender)) {
70
+ states.set(currentRender, []);
71
+ }
72
+ const componentStates = states.get(currentRender);
73
+ const index = stateIndices.get(currentRender);
74
+ if (index >= componentStates.length) {
75
+ componentStates.push(initial);
76
+ }
77
+ const state = componentStates[index];
78
+ const setState = (newValue) => {
79
+ const nextValue = typeof newValue === "function" ? newValue(componentStates[index]) : newValue;
80
+ if (componentStates[index] === nextValue)
81
+ return;
82
+ componentStates[index] = nextValue;
83
+ if (isBatching) {
84
+ batchUpdates(() => rerender(currentRender));
85
+ } else {
86
+ rerender(currentRender);
87
+ }
88
+ };
89
+ stateIndices.set(currentRender, index + 1);
90
+ return [state, setState];
91
+ }
92
+ function useEffect(callback, deps) {
93
+ if (!currentRender)
94
+ throw new Error("useEffect must be called within a render");
95
+ const effectIndex = stateIndices.get(currentRender);
96
+ if (!effects.has(currentRender)) {
97
+ effects.set(currentRender, []);
98
+ }
99
+ const componentEffects = effects.get(currentRender);
100
+ const prevEffect = componentEffects[effectIndex];
101
+ if (!prevEffect || !deps || !prevEffect.deps || deps.some((dep, i) => dep !== prevEffect.deps[i])) {
102
+ if (prevEffect == null ? void 0 : prevEffect.cleanup) {
103
+ prevEffect.cleanup();
104
+ }
105
+ queueMicrotask(() => {
106
+ const cleanup = callback() || void 0;
107
+ componentEffects[effectIndex] = { cleanup, deps };
108
+ });
109
+ }
110
+ stateIndices.set(currentRender, effectIndex + 1);
111
+ }
112
+ function useMemo(factory, deps) {
113
+ if (!currentRender)
114
+ throw new Error("useMemo must be called within a render");
115
+ const memoIndex = stateIndices.get(currentRender);
116
+ if (!memos.has(currentRender)) {
117
+ memos.set(currentRender, []);
118
+ }
119
+ const componentMemos = memos.get(currentRender);
120
+ const prevMemo = componentMemos[memoIndex];
121
+ if (!prevMemo || deps && deps.some((dep, i) => !Object.is(dep, prevMemo.deps[i]))) {
122
+ const value = factory();
123
+ componentMemos[memoIndex] = { value, deps };
124
+ stateIndices.set(currentRender, memoIndex + 1);
125
+ return value;
126
+ }
127
+ stateIndices.set(currentRender, memoIndex + 1);
128
+ return prevMemo.value;
129
+ }
130
+ async function rerender(rendererId) {
131
+ try {
132
+ const componentEffects = effects.get(rendererId);
133
+ if (componentEffects) {
134
+ componentEffects.forEach((effect) => {
135
+ if (effect.cleanup)
136
+ effect.cleanup();
137
+ });
138
+ effects.set(rendererId, []);
139
+ }
140
+ if (globalRenderCallback && globalContainer && currentElement) {
141
+ await globalRenderCallback(currentElement, globalContainer);
142
+ }
143
+ } catch (error) {
144
+ console.error("Error during rerender:", error);
145
+ }
146
+ }
147
+ function useErrorBoundary() {
148
+ const [error, setError] = useState(null);
149
+ return [error, () => setError(null)];
150
+ }
50
151
  function jsx(type, props) {
51
152
  console.log("JSX Transform:", { type, props });
52
153
  const processedProps = { ...props };
@@ -149,13 +250,16 @@ async function render(element, container) {
149
250
  }
150
251
  });
151
252
  }
152
- var isBatching, queue, currentRender, stateIndices, globalRenderCallback, globalContainer, currentElement, isServer, serverStates, isHydrating;
253
+ var isBatching, queue, currentRender, states, stateIndices, effects, memos, globalRenderCallback, globalContainer, currentElement, isServer, serverStates, isHydrating;
153
254
  var init_dist = __esm({
154
255
  "node_modules/frontend-hamroun/dist/index.mjs"() {
155
256
  isBatching = false;
156
257
  queue = [];
157
258
  currentRender = 0;
259
+ states = /* @__PURE__ */ new Map();
158
260
  stateIndices = /* @__PURE__ */ new Map();
261
+ effects = /* @__PURE__ */ new Map();
262
+ memos = /* @__PURE__ */ new Map();
159
263
  globalRenderCallback = null;
160
264
  globalContainer = null;
161
265
  currentElement = null;
@@ -165,143 +269,382 @@ var init_dist = __esm({
165
269
  }
166
270
  });
167
271
 
168
- // src/config.ts
169
- var AppConfig, config_default;
170
- var init_config = __esm({
171
- "src/config.ts"() {
272
+ // src/pages/404.tsx
273
+ var __exports = {};
274
+ __export(__exports, {
275
+ default: () => NotFound
276
+ });
277
+ function NotFound({ initialState: initialState2 }) {
278
+ return /* @__PURE__ */ jsx("div", { className: "not-found-container max-w-4xl mx-auto p-6" }, /* @__PURE__ */ jsx("div", { className: "bg-gray-50 border border-gray-200 rounded-lg p-8 shadow-sm" }, /* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold text-gray-700 mb-4" }, "Page Not Found"), /* @__PURE__ */ jsx("p", { className: "text-lg text-gray-600 mb-4" }, "The page you are looking for does not exist or has been moved."), /* @__PURE__ */ jsx("p", { className: "text-gray-600 mb-6" }, "Path: ", /* @__PURE__ */ jsx("code", { className: "bg-gray-100 px-2 py-1 rounded" }, initialState2?.route || "unknown")), /* @__PURE__ */ jsx("div", { className: "mt-6" }, /* @__PURE__ */ jsx(
279
+ "a",
280
+ {
281
+ href: "/",
282
+ className: "inline-block px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"
283
+ },
284
+ "Back to Home"
285
+ ))));
286
+ }
287
+ var init__ = __esm({
288
+ "src/pages/404.tsx"() {
289
+ "use strict";
290
+ init_dist();
291
+ }
292
+ });
293
+
294
+ // src/pages/[id].tsx
295
+ var id_exports = {};
296
+ var init_id = __esm({
297
+ "src/pages/[id].tsx"() {
172
298
  "use strict";
173
- AppConfig = {
174
- // App information
175
- title: "Frontend Hamroun App",
176
- description: "A full-stack application built with Frontend Hamroun",
177
- // Navigation
178
- navigation: [
179
- { path: "/", label: "Home" },
180
- { path: "/about", label: "About" },
181
- { path: "/users", label: "Users" }
182
- ],
183
- // API endpoints
184
- api: {
185
- baseUrl: "/api",
186
- endpoints: {
187
- users: "/users",
188
- posts: "/posts"
189
- }
190
- },
191
- // Default meta tags
192
- meta: {
193
- viewport: "width=device-width, initial-scale=1.0",
194
- charset: "UTF-8",
195
- author: "Your Name",
196
- keywords: "frontend-hamroun, fullstack, template"
197
- },
198
- // Style customization
199
- theme: {
200
- primaryColor: "#0066cc",
201
- backgroundColor: "#ffffff",
202
- textColor: "#333333",
203
- fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif'
204
- }
205
- };
206
- config_default = AppConfig;
207
299
  }
208
300
  });
209
301
 
210
302
  // src/components/Layout.tsx
211
- function Layout({ children, title = config_default.title, showNavigation = true }) {
212
- const { navigation } = config_default;
213
- return /* @__PURE__ */ jsx("div", { className: "container mx-auto px-4 py-8 max-w-5xl" }, /* @__PURE__ */ jsx("header", { className: "mb-8" }, /* @__PURE__ */ jsx("h1", { className: "text-4xl font-bold text-gray-800 mb-4" }, title), showNavigation && /* @__PURE__ */ jsx("nav", { className: "mb-6" }, /* @__PURE__ */ jsx("ul", { className: "flex space-x-6" }, navigation.map((item) => /* @__PURE__ */ jsx("li", { key: item.path }, /* @__PURE__ */ jsx(
303
+ function Layout({ children, title = "Frontend Hamroun App" }) {
304
+ return /* @__PURE__ */ jsx("div", { className: "min-h-screen flex flex-col bg-gray-50" }, /* @__PURE__ */ jsx("header", { className: "bg-blue-600 text-white" }, /* @__PURE__ */ jsx("div", { className: "container mx-auto px-4 py-4 flex justify-between items-center" }, /* @__PURE__ */ jsx("h1", { className: "text-xl font-bold" }, /* @__PURE__ */ jsx("a", { href: "/", className: "hover:text-blue-100" }, title)), /* @__PURE__ */ jsx("nav", null, /* @__PURE__ */ jsx("ul", { className: "flex space-x-6" }, /* @__PURE__ */ jsx("li", null, /* @__PURE__ */ jsx("a", { href: "/", className: "hover:text-blue-100" }, "Home")), /* @__PURE__ */ jsx("li", null, /* @__PURE__ */ jsx("a", { href: "/about", className: "hover:text-blue-100" }, "About")))))), /* @__PURE__ */ jsx("main", { className: "flex-grow container mx-auto px-4 py-8" }, children), /* @__PURE__ */ jsx("footer", { className: "bg-gray-800 text-white" }, /* @__PURE__ */ jsx("div", { className: "container mx-auto px-4 py-6" }, /* @__PURE__ */ jsx("p", { className: "text-center text-gray-400" }, "\xA9 ", (/* @__PURE__ */ new Date()).getFullYear(), " Frontend Hamroun App. All rights reserved."))));
305
+ }
306
+ var init_Layout = __esm({
307
+ "src/components/Layout.tsx"() {
308
+ "use strict";
309
+ init_dist();
310
+ }
311
+ });
312
+
313
+ // src/pages/_app.tsx
314
+ var app_exports = {};
315
+ __export(app_exports, {
316
+ default: () => App
317
+ });
318
+ function App({ Component, pageProps, initialState: initialState2 }) {
319
+ return /* @__PURE__ */ jsx(Layout, null, /* @__PURE__ */ jsx(Component, { ...pageProps, initialState: initialState2 }));
320
+ }
321
+ var init_app = __esm({
322
+ "src/pages/_app.tsx"() {
323
+ "use strict";
324
+ init_dist();
325
+ init_Layout();
326
+ }
327
+ });
328
+
329
+ // src/pages/_document.tsx
330
+ var document_exports = {};
331
+ __export(document_exports, {
332
+ default: () => Document
333
+ });
334
+ function Document({
335
+ title = "Frontend Hamroun App",
336
+ headContent,
337
+ bodyContent,
338
+ scripts
339
+ }) {
340
+ return /* @__PURE__ */ jsx("html", { lang: "en" }, /* @__PURE__ */ jsx("head", null, /* @__PURE__ */ jsx("meta", { charSet: "UTF-8" }), /* @__PURE__ */ jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }), /* @__PURE__ */ jsx("title", null, title), /* @__PURE__ */ jsx("link", { rel: "stylesheet", href: "/styles.css" }), headContent), /* @__PURE__ */ jsx("body", null, /* @__PURE__ */ jsx("div", { id: "root" }, bodyContent), /* @__PURE__ */ jsx("script", { src: "/build/main.js", type: "module" }), scripts));
341
+ }
342
+ var init_document = __esm({
343
+ "src/pages/_document.tsx"() {
344
+ "use strict";
345
+ init_dist();
346
+ }
347
+ });
348
+
349
+ // src/pages/_error.tsx
350
+ var error_exports = {};
351
+ __export(error_exports, {
352
+ default: () => ErrorPage
353
+ });
354
+ function ErrorPage({ initialState: initialState2 }) {
355
+ const { error } = initialState2 || {};
356
+ const [showDetails, setShowDetails] = useState(false);
357
+ const isDev = true;
358
+ return /* @__PURE__ */ jsx("div", { className: "error-page-container max-w-4xl mx-auto p-6" }, /* @__PURE__ */ jsx("div", { className: "bg-red-50 border border-red-200 rounded-lg p-8 shadow-sm" }, /* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold text-red-700 mb-4" }, "Something went wrong"), /* @__PURE__ */ jsx("p", { className: "text-lg text-red-600 mb-4" }, error?.message || "An unexpected error occurred"), isDev && error?.stack && /* @__PURE__ */ jsx("div", { className: "mt-6" }, /* @__PURE__ */ jsx(
359
+ "button",
360
+ {
361
+ className: "text-blue-600 underline mb-2",
362
+ onClick: () => setShowDetails(!showDetails)
363
+ },
364
+ showDetails ? "Hide" : "Show",
365
+ " technical details"
366
+ ), showDetails && /* @__PURE__ */ jsx("pre", { className: "bg-gray-100 p-4 rounded-md text-sm overflow-auto max-h-96 text-gray-800" }, error.stack)), /* @__PURE__ */ jsx("div", { className: "mt-6" }, /* @__PURE__ */ jsx(
214
367
  "a",
215
368
  {
216
- href: item.path,
217
- className: "text-blue-600 hover:text-blue-800 hover:underline transition-colors font-medium"
369
+ href: "/",
370
+ className: "inline-block px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"
218
371
  },
219
- item.label
220
- )))))), /* @__PURE__ */ jsx("main", { className: "min-h-[50vh]" }, children), /* @__PURE__ */ jsx("footer", { className: "mt-12 pt-6 border-t border-gray-200 text-gray-600 text-sm" }, /* @__PURE__ */ jsx("p", null, config_default.title, " \xA9 ", (/* @__PURE__ */ new Date()).getFullYear())));
372
+ "Back to Home"
373
+ ))));
221
374
  }
222
- var init_Layout = __esm({
223
- "src/components/Layout.tsx"() {
375
+ var init_error = __esm({
376
+ "src/pages/_error.tsx"() {
224
377
  "use strict";
225
378
  init_dist();
226
- init_config();
227
379
  }
228
380
  });
229
381
 
230
- // src/pages/about/index.tsx
382
+ // src/pages/about.tsx
231
383
  var about_exports = {};
232
384
  __export(about_exports, {
233
- default: () => about_default
385
+ default: () => AboutPage,
386
+ getServerSideProps: () => getServerSideProps
234
387
  });
235
- var AboutPage, about_default;
388
+ function AboutPage({ initialState: initialState2 }) {
389
+ return /* @__PURE__ */ jsx(Layout, { title: "About - Frontend Hamroun" }, /* @__PURE__ */ jsx("div", { className: "max-w-4xl mx-auto" }, /* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold text-blue-600 mb-6" }, "About Frontend Hamroun"), /* @__PURE__ */ jsx("div", { className: "bg-white shadow-lg rounded-lg p-8 mb-8" }, /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-800 mb-4" }, "What is Frontend Hamroun?"), /* @__PURE__ */ jsx("p", { className: "text-gray-600 mb-4" }, "Frontend Hamroun is a lightweight JavaScript framework for building modern web applications. It provides a familiar component-based architecture with hooks, JSX support, and server-side rendering capabilities."), /* @__PURE__ */ jsx("p", { className: "text-gray-600 mb-4" }, "This framework is designed to be simple yet powerful, offering the essential features needed for web application development without the complexity of larger frameworks."), /* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-gray-700 mt-6 mb-2" }, "Key Features:"), /* @__PURE__ */ jsx("ul", { className: "list-disc pl-6 text-gray-600 space-y-2" }, /* @__PURE__ */ jsx("li", null, "Component-based architecture"), /* @__PURE__ */ jsx("li", null, "JSX support"), /* @__PURE__ */ jsx("li", null, "Hooks for state and effects"), /* @__PURE__ */ jsx("li", null, "Server-side rendering"), /* @__PURE__ */ jsx("li", null, "Minimal API surface"), /* @__PURE__ */ jsx("li", null, "File-based routing"), /* @__PURE__ */ jsx("li", null, "Built-in API routes"))), /* @__PURE__ */ jsx("div", { className: "bg-white shadow-lg rounded-lg p-8" }, /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-800 mb-4" }, "Getting Started"), /* @__PURE__ */ jsx("p", { className: "text-gray-600 mb-4" }, "This application was created using the Frontend Hamroun fullstack template, which provides a complete setup for building applications with server-side rendering, API routes, and client-side navigation."), /* @__PURE__ */ jsx("div", { className: "bg-gray-50 p-4 rounded-md mt-4" }, /* @__PURE__ */ jsx("h3", { className: "text-md font-medium text-gray-700 mb-2" }, "Quick Start:"), /* @__PURE__ */ jsx("pre", { className: "bg-gray-800 text-gray-100 p-4 rounded overflow-x-auto" }, /* @__PURE__ */ jsx("code", null, `# Create a new application
390
+ npx frontend-hamroun create my-app
391
+
392
+ # Change directory
393
+ cd my-app
394
+
395
+ # Start the development server
396
+ npm run dev`))))));
397
+ }
398
+ async function getServerSideProps() {
399
+ return {
400
+ props: {
401
+ pageTitle: "About Frontend Hamroun",
402
+ description: "Learn more about the Frontend Hamroun framework"
403
+ }
404
+ };
405
+ }
236
406
  var init_about = __esm({
407
+ "src/pages/about.tsx"() {
408
+ "use strict";
409
+ init_dist();
410
+ init_Layout();
411
+ }
412
+ });
413
+
414
+ // src/pages/about/index.tsx
415
+ var about_exports2 = {};
416
+ __export(about_exports2, {
417
+ default: () => about_default
418
+ });
419
+ var AboutPage2, about_default;
420
+ var init_about2 = __esm({
237
421
  "src/pages/about/index.tsx"() {
238
422
  "use strict";
239
423
  init_dist();
240
424
  init_Layout();
241
- AboutPage = ({ initialState: initialState2 }) => {
425
+ AboutPage2 = ({ initialState: initialState2 }) => {
242
426
  return /* @__PURE__ */ jsx(Layout, { title: "About This App" }, /* @__PURE__ */ jsx("div", { className: "max-w-4xl mx-auto bg-white shadow-lg rounded-lg overflow-hidden" }, /* @__PURE__ */ jsx("div", { className: "p-8" }, /* @__PURE__ */ jsx("p", { className: "text-lg text-gray-700 mb-6" }, "This is a frontend application built with Frontend Hamroun framework and styled with Tailwind CSS."), /* @__PURE__ */ jsx("p", { className: "text-gray-600 mb-8" }, "It features server-side rendering, client-side navigation, and websocket-based live reloading during development."), /* @__PURE__ */ jsx("div", { className: "bg-gray-50 p-6 rounded-lg border border-gray-200 mb-8" }, /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-800 mb-4" }, "Key Features"), /* @__PURE__ */ jsx("ul", { className: "space-y-2 text-gray-700" }, /* @__PURE__ */ jsx("li", { className: "flex items-center" }, /* @__PURE__ */ jsx("svg", { className: "w-5 h-5 text-green-500 mr-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M5 13l4 4L19 7" })), "Server-side rendering"), /* @__PURE__ */ jsx("li", { className: "flex items-center" }, /* @__PURE__ */ jsx("svg", { className: "w-5 h-5 text-green-500 mr-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M5 13l4 4L19 7" })), "Client-side navigation"), /* @__PURE__ */ jsx("li", { className: "flex items-center" }, /* @__PURE__ */ jsx("svg", { className: "w-5 h-5 text-green-500 mr-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M5 13l4 4L19 7" })), "Component-based architecture"), /* @__PURE__ */ jsx("li", { className: "flex items-center" }, /* @__PURE__ */ jsx("svg", { className: "w-5 h-5 text-green-500 mr-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M5 13l4 4L19 7" })), "Integrated API backend"), /* @__PURE__ */ jsx("li", { className: "flex items-center" }, /* @__PURE__ */ jsx("svg", { className: "w-5 h-5 text-green-500 mr-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M5 13l4 4L19 7" })), "Live reload during development"), /* @__PURE__ */ jsx("li", { className: "flex items-center" }, /* @__PURE__ */ jsx("svg", { className: "w-5 h-5 text-green-500 mr-2", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M5 13l4 4L19 7" })), "Tailwind CSS for styling"))), /* @__PURE__ */ jsx("a", { href: "/", className: "inline-block px-6 py-3 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 transition-colors" }, "Back to Home"))));
243
427
  };
244
- about_default = AboutPage;
428
+ about_default = AboutPage2;
245
429
  }
246
430
  });
247
431
 
248
432
  // src/components/UserList.tsx
249
- var UserList, UserList_default;
433
+ function UserList({ users }) {
434
+ if (!users || users.length === 0) {
435
+ return /* @__PURE__ */ jsx("div", { className: "empty-state p-4 text-center bg-gray-50 rounded" }, /* @__PURE__ */ jsx("p", { className: "text-gray-500" }, "No users available"));
436
+ }
437
+ return /* @__PURE__ */ jsx("div", { className: "user-list" }, /* @__PURE__ */ jsx("ul", { className: "divide-y divide-gray-100" }, users.map((user) => /* @__PURE__ */ jsx("li", { key: user.id, className: "py-3" }, /* @__PURE__ */ jsx("div", { className: "flex justify-between" }, /* @__PURE__ */ jsx("div", null, /* @__PURE__ */ jsx("p", { className: "font-medium text-gray-900" }, user.name), /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500" }, user.email)), /* @__PURE__ */ jsx(
438
+ "a",
439
+ {
440
+ href: `/users/${user.id}`,
441
+ className: "text-blue-600 hover:underline text-sm self-center"
442
+ },
443
+ "View Profile"
444
+ ))))));
445
+ }
250
446
  var init_UserList = __esm({
251
447
  "src/components/UserList.tsx"() {
252
448
  "use strict";
253
449
  init_dist();
254
- UserList = ({ users }) => {
255
- if (!users || users.length === 0) {
256
- return /* @__PURE__ */ jsx("div", { className: "p-4 bg-gray-50 rounded-lg border border-gray-200 my-4" }, /* @__PURE__ */ jsx("p", { className: "text-gray-500 italic" }, "No users found or still loading..."));
257
- }
258
- return /* @__PURE__ */ jsx("div", { className: "rounded-lg overflow-hidden my-4" }, /* @__PURE__ */ jsx("h3", { className: "text-lg font-medium mb-3" }, "Users (", users.length, ")"), /* @__PURE__ */ jsx("ul", { className: "divide-y divide-gray-200 border border-gray-200 rounded-lg overflow-hidden" }, users.map((user) => /* @__PURE__ */ jsx("li", { key: user.id, className: "flex justify-between items-center p-4 hover:bg-gray-50" }, /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-800" }, user.name), /* @__PURE__ */ jsx("span", { className: "text-gray-500 text-sm" }, user.email)))));
259
- };
260
- UserList_default = UserList;
261
450
  }
262
451
  });
263
452
 
264
- // src/data/api.ts
265
- async function fetchApi(endpoint, options = {}) {
266
- const url = endpoint.startsWith("/") ? `/api${endpoint}` : `/api/${endpoint}`;
267
- try {
268
- console.log(`[API] Fetching data from: ${url}`);
269
- const response = await fetch(url, {
270
- headers: {
271
- "Content-Type": "application/json",
272
- "Accept": "application/json"
273
- },
274
- ...options
453
+ // src/components/StateDemo.tsx
454
+ function StateDemo() {
455
+ const [state, setState] = useState({
456
+ count: 0,
457
+ lastUpdated: null,
458
+ history: []
459
+ });
460
+ const [isLoading, setIsLoading] = useState(false);
461
+ const [showHistory, setShowHistory] = useState(false);
462
+ const isSSR = typeof window === "undefined";
463
+ const stats = useMemo(() => {
464
+ if (isSSR || !state || !state.history || state.history.length === 0) {
465
+ return { avg: 0, max: 0, min: 0 };
466
+ }
467
+ try {
468
+ const sum = state.history.reduce((a, b) => a + b, 0);
469
+ return {
470
+ avg: parseFloat((sum / state.history.length).toFixed(1)),
471
+ max: Math.max(...state.history),
472
+ min: Math.min(...state.history)
473
+ };
474
+ } catch (error) {
475
+ console.error("Error calculating stats:", error);
476
+ return { avg: 0, max: 0, min: 0 };
477
+ }
478
+ }, [state?.history]);
479
+ const increment = () => {
480
+ if (isSSR)
481
+ return;
482
+ setIsLoading(true);
483
+ setTimeout(() => {
484
+ setState((prevState) => ({
485
+ count: prevState.count + 1,
486
+ lastUpdated: (/* @__PURE__ */ new Date()).toLocaleTimeString(),
487
+ history: [...prevState.history || [], prevState.count + 1]
488
+ }));
489
+ setIsLoading(false);
490
+ }, 300);
491
+ };
492
+ const decrement = () => {
493
+ if (isSSR)
494
+ return;
495
+ setIsLoading(true);
496
+ setTimeout(() => {
497
+ setState((prevState) => ({
498
+ count: Math.max(0, prevState.count - 1),
499
+ lastUpdated: (/* @__PURE__ */ new Date()).toLocaleTimeString(),
500
+ history: prevState.count > 0 ? [...prevState.history || [], prevState.count - 1] : prevState.history || []
501
+ }));
502
+ setIsLoading(false);
503
+ }, 300);
504
+ };
505
+ const reset = () => {
506
+ if (isSSR)
507
+ return;
508
+ setState({
509
+ count: 0,
510
+ lastUpdated: (/* @__PURE__ */ new Date()).toLocaleTimeString(),
511
+ history: []
275
512
  });
276
- if (!response.ok) {
277
- throw new Error(`API request failed: ${response.status} ${response.statusText}`);
513
+ };
514
+ const toggleHistory = () => {
515
+ if (isSSR)
516
+ return;
517
+ setShowHistory((prev) => !prev);
518
+ };
519
+ if (isSSR) {
520
+ return /* @__PURE__ */ jsx("div", { className: "bg-white shadow-lg rounded-lg p-6 mb-8" }, /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-800 mb-4" }, "State Management Demo"), /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between mb-4" }, /* @__PURE__ */ jsx("button", { className: "px-4 py-2 bg-gray-200 text-gray-800 rounded-lg" }, "-"), /* @__PURE__ */ jsx("span", { className: "text-2xl font-bold mx-4" }, "0"), /* @__PURE__ */ jsx("button", { className: "px-4 py-2 bg-blue-600 text-white rounded-lg" }, "+")), /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500" }, "Interactive counter (client-side only)"));
521
+ }
522
+ return /* @__PURE__ */ jsx("div", { className: "bg-white shadow-lg rounded-lg p-6 mb-8" }, /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-800 mb-4" }, "State Management Demo"), /* @__PURE__ */ jsx("div", { className: "mb-6" }, /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between mb-4" }, /* @__PURE__ */ jsx(
523
+ "button",
524
+ {
525
+ onClick: decrement,
526
+ className: "px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 disabled:opacity-50",
527
+ disabled: state.count === 0 || isLoading
528
+ },
529
+ isLoading ? "..." : "-"
530
+ ), /* @__PURE__ */ jsx("span", { className: "text-2xl font-bold mx-4" }, state.count), /* @__PURE__ */ jsx(
531
+ "button",
532
+ {
533
+ onClick: increment,
534
+ className: "px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50",
535
+ disabled: isLoading
536
+ },
537
+ isLoading ? "..." : "+"
538
+ )), /* @__PURE__ */ jsx(
539
+ "button",
540
+ {
541
+ onClick: reset,
542
+ className: "text-sm text-gray-600 hover:text-red-600",
543
+ disabled: state.count === 0 && (!state.history || state.history.length === 0)
544
+ },
545
+ "Reset Counter"
546
+ )), state.lastUpdated && /* @__PURE__ */ jsx("div", { className: "mb-4" }, /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500" }, "Last updated: ", state.lastUpdated)), state.history && state.history.length > 0 && /* @__PURE__ */ jsx("div", { className: "border-t pt-4 mt-4" }, /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ jsx("h3", { className: "text-md font-medium text-gray-700" }, "Statistics"), /* @__PURE__ */ jsx(
547
+ "button",
548
+ {
549
+ onClick: toggleHistory,
550
+ className: "text-sm text-blue-600 hover:underline"
551
+ },
552
+ showHistory ? "Hide History" : "Show History"
553
+ )), /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-2 mb-3" }, /* @__PURE__ */ jsx("div", { className: "bg-blue-50 p-2 rounded text-center" }, /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500" }, "Average"), /* @__PURE__ */ jsx("div", { className: "font-bold" }, stats.avg)), /* @__PURE__ */ jsx("div", { className: "bg-green-50 p-2 rounded text-center" }, /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500" }, "Maximum"), /* @__PURE__ */ jsx("div", { className: "font-bold" }, stats.max)), /* @__PURE__ */ jsx("div", { className: "bg-red-50 p-2 rounded text-center" }, /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500" }, "Minimum"), /* @__PURE__ */ jsx("div", { className: "font-bold" }, stats.min))), showHistory && /* @__PURE__ */ jsx("div", { className: "mt-3" }, /* @__PURE__ */ jsx("h4", { className: "text-sm font-medium text-gray-600 mb-1" }, "History (", state.history.length, " events)"), /* @__PURE__ */ jsx("div", { className: "bg-gray-50 p-2 rounded max-h-24 overflow-y-auto text-xs" }, state.history.map((value, index) => /* @__PURE__ */ jsx(
554
+ "span",
555
+ {
556
+ key: index,
557
+ className: "inline-block bg-gray-200 rounded px-2 py-1 m-1"
558
+ },
559
+ value
560
+ ))))));
561
+ }
562
+ var init_StateDemo = __esm({
563
+ "src/components/StateDemo.tsx"() {
564
+ "use strict";
565
+ init_dist();
566
+ }
567
+ });
568
+
569
+ // src/components/ErrorBoundary.tsx
570
+ function ErrorBoundary({ children, fallback }) {
571
+ const [error, resetError] = useErrorBoundary();
572
+ if (error) {
573
+ if (fallback) {
574
+ return fallback(error, resetError);
278
575
  }
279
- const data = await response.json();
280
- console.log(`[API] Successfully fetched data from: ${url}`);
281
- return data;
282
- } catch (error) {
283
- console.error(`[API] Error fetching from ${url}:`, error);
284
- return null;
576
+ return /* @__PURE__ */ jsx("div", { className: "error-boundary p-4 border border-red-500 rounded bg-red-50" }, /* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-red-800 mb-2" }, "Something went wrong"), /* @__PURE__ */ jsx("p", { className: "text-red-600 mb-2" }, error.message), /* @__PURE__ */ jsx(
577
+ "button",
578
+ {
579
+ onClick: resetError,
580
+ className: "px-3 py-1 bg-red-600 text-white rounded hover:bg-red-700"
581
+ },
582
+ "Try again"
583
+ ), /* @__PURE__ */ jsx("pre", { className: "mt-3 text-xs overflow-auto p-2 bg-gray-100" }, error.stack));
285
584
  }
585
+ return children;
286
586
  }
287
- var UserApi;
587
+ var init_ErrorBoundary = __esm({
588
+ "src/components/ErrorBoundary.tsx"() {
589
+ "use strict";
590
+ init_dist();
591
+ }
592
+ });
593
+
594
+ // src/data/api.ts
595
+ var sampleUsers, samplePosts, delay, UserApi;
288
596
  var init_api = __esm({
289
597
  "src/data/api.ts"() {
290
598
  "use strict";
599
+ init_dist();
600
+ sampleUsers = [
601
+ { id: 1, name: "User 1", email: "user1@example.com" },
602
+ { id: 2, name: "User 2", email: "user2@example.com" },
603
+ { id: 3, name: "User 3", email: "user3@example.com" }
604
+ ];
605
+ samplePosts = [
606
+ { id: 1, title: "Post 1", content: "Content for post 1", authorId: 1 },
607
+ { id: 2, title: "Post 2", content: "Content for post 2", authorId: 2 },
608
+ { id: 3, title: "Post 3", content: "Content for post 3", authorId: 1 }
609
+ ];
610
+ delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
291
611
  UserApi = {
292
- getAll: () => fetchApi("/users"),
293
- getById: (id) => fetchApi(`/users/${id}`),
294
- create: (data) => fetchApi("/users", {
295
- method: "POST",
296
- body: JSON.stringify(data)
297
- }),
298
- update: (id, data) => fetchApi(`/users/${id}`, {
299
- method: "PUT",
300
- body: JSON.stringify(data)
301
- }),
302
- delete: (id) => fetchApi(`/users/${id}`, {
303
- method: "DELETE"
304
- })
612
+ // Get all users
613
+ async getAll() {
614
+ try {
615
+ await delay(300);
616
+ return [...sampleUsers];
617
+ } catch (error) {
618
+ console.error("Error fetching users:", error);
619
+ return [];
620
+ }
621
+ },
622
+ // Get user by ID
623
+ async getById(id) {
624
+ try {
625
+ const userId = typeof id === "string" ? parseInt(id, 10) : id;
626
+ await delay(200);
627
+ const user = sampleUsers.find((u) => u.id === userId);
628
+ if (!user)
629
+ throw new Error("User not found");
630
+ return { ...user };
631
+ } catch (error) {
632
+ console.error(`Error fetching user ${id}:`, error);
633
+ return null;
634
+ }
635
+ },
636
+ // Get posts (all or by author)
637
+ async getPosts(authorId) {
638
+ try {
639
+ const userId = authorId ? typeof authorId === "string" ? parseInt(authorId, 10) : authorId : void 0;
640
+ await delay(400);
641
+ const posts = userId ? samplePosts.filter((p) => p.authorId === userId) : samplePosts;
642
+ return [...posts];
643
+ } catch (error) {
644
+ console.error("Error fetching posts:", error);
645
+ return [];
646
+ }
647
+ }
305
648
  };
306
649
  }
307
650
  });
@@ -309,23 +652,78 @@ var init_api = __esm({
309
652
  // src/pages/index.tsx
310
653
  var pages_exports = {};
311
654
  __export(pages_exports, {
312
- default: () => pages_default
655
+ default: () => HomePage,
656
+ getServerSideProps: () => getServerSideProps2
313
657
  });
314
- var HomePage, pages_default;
658
+ function HomePage({ users, posts, initialState: initialState2 }) {
659
+ const [state, setState] = useState(initialState2 || {});
660
+ const [refreshTrigger, setRefreshTrigger] = useState(0);
661
+ useEffect(() => {
662
+ if (refreshTrigger === 0)
663
+ return;
664
+ async function fetchData() {
665
+ try {
666
+ const [users2, posts2] = await Promise.all([
667
+ UserApi.getAll(),
668
+ UserApi.getPosts()
669
+ ]);
670
+ batchUpdates(() => {
671
+ setState((prev) => ({
672
+ ...prev,
673
+ data: {
674
+ ...prev.data,
675
+ users: users2,
676
+ posts: posts2
677
+ },
678
+ lastUpdate: (/* @__PURE__ */ new Date()).toISOString()
679
+ }));
680
+ });
681
+ } catch (error) {
682
+ console.error("Error fetching data:", error);
683
+ }
684
+ }
685
+ fetchData();
686
+ }, [refreshTrigger]);
687
+ const handleRefresh = () => {
688
+ setRefreshTrigger((t) => t + 1);
689
+ };
690
+ return /* @__PURE__ */ jsx("div", { className: "max-w-4xl mx-auto py-8" }, /* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold text-blue-600 mb-6" }, "Welcome to your Next-style Frontend Hamroun application!"), /* @__PURE__ */ jsx("div", { className: "mb-8" }, /* @__PURE__ */ jsx(
691
+ "button",
692
+ {
693
+ className: "mb-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700",
694
+ onClick: handleRefresh
695
+ },
696
+ "Refresh Data"
697
+ ), /* @__PURE__ */ jsx("div", { className: "bg-blue-50 p-4 rounded-lg border border-blue-100 mb-6" }, /* @__PURE__ */ jsx("p", { className: "text-blue-700" }, "Last updated: ", state.lastUpdate || "Never"))), /* @__PURE__ */ jsx(ErrorBoundary, null, /* @__PURE__ */ jsx("div", { className: "bg-white shadow-lg rounded-lg p-6 mb-8" }, /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-800 mb-4" }, "User List"), /* @__PURE__ */ jsx(UserList, { users: users || state.data?.users || [] }))), /* @__PURE__ */ jsx(ErrorBoundary, null, /* @__PURE__ */ jsx(StateDemo, null)), /* @__PURE__ */ jsx("div", { className: "bg-gray-50 rounded-lg p-6 border border-gray-200 mt-8" }, /* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-gray-700 mb-3" }, "Application State"), /* @__PURE__ */ jsx("pre", { className: "overflow-auto p-4 bg-gray-100 rounded-md text-sm text-gray-800" }, JSON.stringify({ users, posts, ...state }, null, 2))));
698
+ }
699
+ async function getServerSideProps2() {
700
+ try {
701
+ const users = await UserApi.getAll();
702
+ const posts = await UserApi.getPosts();
703
+ return {
704
+ props: {
705
+ users,
706
+ posts
707
+ }
708
+ };
709
+ } catch (error) {
710
+ console.error("Error fetching initial data:", error);
711
+ return {
712
+ props: {
713
+ users: [],
714
+ posts: []
715
+ }
716
+ };
717
+ }
718
+ }
315
719
  var init_pages = __esm({
316
720
  "src/pages/index.tsx"() {
317
721
  "use strict";
318
722
  init_dist();
319
- init_Layout();
320
723
  init_UserList();
724
+ init_StateDemo();
725
+ init_ErrorBoundary();
321
726
  init_api();
322
- HomePage = ({ initialState: initialState2 }) => /* @__PURE__ */ jsx(Layout, { title: "Home" }, /* @__PURE__ */ jsx("div", { className: "max-w-4xl mx-auto py-8" }, /* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold text-blue-600 mb-6" }, "Welcome to your Frontend Hamroun application!"), /* @__PURE__ */ jsx("div", { className: "bg-white shadow-lg rounded-lg p-6 mb-8" }, /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-800 mb-4" }, "User List"), /* @__PURE__ */ jsx(UserList_default, { users: initialState2.data?.users || [] })), /* @__PURE__ */ jsx("div", { className: "bg-gray-50 rounded-lg p-6 border border-gray-200" }, /* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-gray-700 mb-3" }, "Application State"), /* @__PURE__ */ jsx("pre", { className: "overflow-auto p-4 bg-gray-100 rounded-md text-sm text-gray-800" }, JSON.stringify(initialState2, null, 2)))));
323
- HomePage.getInitialData = async () => {
324
- return {
325
- users: await UserApi.getAll()
326
- };
327
- };
328
- pages_default = HomePage;
329
727
  }
330
728
  });
331
729
 
@@ -354,185 +752,118 @@ var init_users = __esm({
354
752
  }
355
753
  });
356
754
 
357
- // src/main.tsx
358
- init_dist();
359
-
360
- // src/router.ts
361
- init_dist();
362
-
363
- // import("./pages/**/*.tsx") in src/router.ts
364
- var globImport_pages_tsx = __glob({
365
- "./pages/about/index.tsx": () => Promise.resolve().then(() => (init_about(), about_exports)),
366
- "./pages/index.tsx": () => Promise.resolve().then(() => (init_pages(), pages_exports)),
367
- "./pages/users.tsx": () => Promise.resolve().then(() => (init_users(), users_exports))
368
- });
369
-
370
- // import("./pages/**/*/index.tsx") in src/router.ts
371
- var globImport_pages_index_tsx = __glob({
372
- "./pages/about/index.tsx": () => Promise.resolve().then(() => (init_about(), about_exports))
755
+ // src/pages/users/[id].tsx
756
+ var id_exports2 = {};
757
+ __export(id_exports2, {
758
+ default: () => UserDetail,
759
+ getServerSideProps: () => getServerSideProps3
373
760
  });
374
-
375
- // src/router.ts
376
- var Router = class {
377
- constructor() {
378
- this.routes = {};
379
- this.notFoundComponent = null;
380
- }
381
- // Register a component for a specific route
382
- register(path, component) {
383
- const normalizedPath = path === "/" ? "index" : path.replace(/^\//, "");
384
- this.routes[normalizedPath] = component;
385
- console.log(`[Router] Registered component for path: ${normalizedPath}`);
386
- return this;
387
- }
388
- // Set the not found component
389
- setNotFound(component) {
390
- this.notFoundComponent = component;
391
- return this;
761
+ function UserDetail({ user, posts, initialState: initialState2 }) {
762
+ const [userData, setUserData] = useState(user);
763
+ const [userPosts, setUserPosts] = useState(posts || []);
764
+ const [loading, setLoading] = useState(false);
765
+ const [error, setError] = useState(null);
766
+ const { id } = initialState2?.params || {};
767
+ useEffect(() => {
768
+ if (!userData && id) {
769
+ setLoading(true);
770
+ Promise.all([
771
+ UserApi.getById(id),
772
+ UserApi.getPosts(id)
773
+ ]).then(([userData2, postsData]) => {
774
+ setUserData(userData2);
775
+ setUserPosts(postsData);
776
+ setLoading(false);
777
+ }).catch((err) => {
778
+ console.error("Error fetching user data:", err);
779
+ setError(err.message || "Failed to load user data");
780
+ setLoading(false);
781
+ });
782
+ }
783
+ }, [userData, id]);
784
+ if (loading) {
785
+ return /* @__PURE__ */ jsx("div", { className: "max-w-4xl mx-auto p-4" }, /* @__PURE__ */ jsx("div", { className: "animate-pulse rounded-md bg-gray-100 p-8" }, /* @__PURE__ */ jsx("div", { className: "h-8 bg-gray-200 rounded w-1/4 mb-4" }), /* @__PURE__ */ jsx("div", { className: "h-4 bg-gray-200 rounded w-1/2 mb-2" }), /* @__PURE__ */ jsx("div", { className: "h-4 bg-gray-200 rounded w-3/4 mb-4" }), /* @__PURE__ */ jsx("div", { className: "h-40 bg-gray-200 rounded mb-4" })));
392
786
  }
393
- // Get the not found component
394
- getNotFound() {
395
- return this.notFoundComponent;
787
+ if (error) {
788
+ return /* @__PURE__ */ jsx("div", { className: "max-w-4xl mx-auto p-4" }, /* @__PURE__ */ jsx("div", { className: "rounded-md bg-red-50 p-4 border border-red-200" }, /* @__PURE__ */ jsx("h2", { className: "text-lg font-bold text-red-700" }, "Error Loading User"), /* @__PURE__ */ jsx("p", { className: "text-red-600" }, error)));
396
789
  }
397
- // Get all registered routes
398
- getAllRoutes() {
399
- return this.routes;
790
+ if (!userData) {
791
+ return /* @__PURE__ */ jsx("div", { className: "max-w-4xl mx-auto p-4" }, /* @__PURE__ */ jsx("div", { className: "rounded-md bg-yellow-50 p-4 border border-yellow-200" }, /* @__PURE__ */ jsx("h2", { className: "text-lg font-bold text-yellow-700" }, "User Not Found"), /* @__PURE__ */ jsx("p", { className: "text-yellow-600" }, "Could not find user with ID: ", id), /* @__PURE__ */ jsx("a", { href: "/users", className: "text-blue-600 hover:underline mt-2 block" }, "Back to Users List")));
400
792
  }
401
- // Find component for a given path
402
- async resolve(path) {
403
- const normalizedPath = path === "/" ? "index" : path.replace(/^\//, "");
404
- console.log(`[Router] Resolving component for path: ${normalizedPath}`);
405
- if (this.routes[normalizedPath]) {
406
- return this.routes[normalizedPath];
407
- }
408
- const pathSegments = normalizedPath.split("/");
409
- const registeredRoutes = Object.keys(this.routes);
410
- for (const route of registeredRoutes) {
411
- const routeSegments = route.split("/");
412
- if (routeSegments.length !== pathSegments.length)
413
- continue;
414
- let isMatch = true;
415
- const params = {};
416
- for (let i = 0; i < routeSegments.length; i++) {
417
- const routeSegment = routeSegments[i];
418
- const pathSegment = pathSegments[i];
419
- if (routeSegment.startsWith("[") && routeSegment.endsWith("]")) {
420
- const paramName = routeSegment.slice(1, -1);
421
- params[paramName] = pathSegment;
422
- } else if (routeSegment !== pathSegment) {
423
- isMatch = false;
424
- break;
425
- }
426
- }
427
- if (isMatch) {
428
- console.log(`[Router] Found dynamic route match: ${route}`);
429
- return this.routes[route];
430
- }
793
+ return /* @__PURE__ */ jsx("div", { className: "max-w-4xl mx-auto p-4" }, /* @__PURE__ */ jsx("div", { className: "bg-white shadow-lg rounded-lg p-6 mb-6" }, /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold text-gray-800 mb-4" }, userData.name), /* @__PURE__ */ jsx("div", { className: "user-info mb-6" }, /* @__PURE__ */ jsx("p", { className: "text-gray-600" }, /* @__PURE__ */ jsx("span", { className: "font-bold" }, "ID:"), " ", userData.id), /* @__PURE__ */ jsx("p", { className: "text-gray-600" }, /* @__PURE__ */ jsx("span", { className: "font-bold" }, "Email:"), " ", userData.email)), /* @__PURE__ */ jsx("a", { href: "/users", className: "text-blue-600 hover:underline" }, "Back to Users List")), userPosts && userPosts.length > 0 ? /* @__PURE__ */ jsx("div", { className: "bg-white shadow-lg rounded-lg p-6" }, /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-gray-800 mb-4" }, "Posts by ", userData.name), /* @__PURE__ */ jsx("div", { className: "space-y-4" }, userPosts.map((post) => /* @__PURE__ */ jsx("div", { key: post.id, className: "border-b pb-4" }, /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold" }, post.title), /* @__PURE__ */ jsx("p", { className: "text-gray-600" }, post.content))))) : /* @__PURE__ */ jsx("div", { className: "bg-white shadow-lg rounded-lg p-6" }, /* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-gray-800 mb-4" }, "Posts by ", userData.name), /* @__PURE__ */ jsx("p", { className: "text-gray-500 italic" }, "No posts found for this user.")));
794
+ }
795
+ async function getServerSideProps3({ params }) {
796
+ try {
797
+ const userId = params.id;
798
+ const [user, posts] = await Promise.all([
799
+ UserApi.getById(parseInt(userId)),
800
+ UserApi.getPosts(parseInt(userId))
801
+ ]);
802
+ if (!user) {
803
+ return {
804
+ notFound: true
805
+ };
431
806
  }
432
- try {
433
- let component = null;
434
- let resolvedPath = normalizedPath;
435
- try {
436
- try {
437
- console.log(`[Router] Trying direct import: ./pages/${resolvedPath}.tsx`);
438
- const directModule = await /* @vite-ignore */
439
- globImport_pages_tsx(`./pages/${resolvedPath}.tsx`).catch(() => null);
440
- if (directModule) {
441
- component = directModule.default || directModule;
442
- }
443
- } catch (e) {
444
- console.warn(`[Router] Error importing ./pages/${resolvedPath}.tsx:`, e);
445
- }
446
- if (!component && !resolvedPath.endsWith("index")) {
447
- try {
448
- console.log(`[Router] Trying index file: ./pages/${resolvedPath}/index.tsx`);
449
- const indexModule = await /* @vite-ignore */
450
- globImport_pages_index_tsx(`./pages/${resolvedPath}/index.tsx`).catch(() => null);
451
- if (indexModule) {
452
- component = indexModule.default || indexModule;
453
- }
454
- } catch (e) {
455
- console.warn(`[Router] Error importing ./pages/${resolvedPath}/index.tsx:`, e);
456
- }
457
- }
458
- } catch (routeError) {
459
- console.warn(`[Router] Error resolving Next.js style route:`, routeError);
807
+ return {
808
+ props: {
809
+ user,
810
+ posts
460
811
  }
461
- if (component) {
462
- this.routes[normalizedPath] = component;
463
- return component;
812
+ };
813
+ } catch (error) {
814
+ console.error(`Error fetching user ${params.id}:`, error);
815
+ return {
816
+ props: {
817
+ error: {
818
+ message: error.message,
819
+ status: error.status || 500
820
+ },
821
+ user: null,
822
+ posts: []
464
823
  }
465
- } catch (error) {
466
- console.warn(`[Router] Error importing component for ${normalizedPath}:`, error);
467
- }
468
- console.warn(`[Router] No component found for path: ${normalizedPath}`);
469
- return this.notFoundComponent;
824
+ };
470
825
  }
471
- // Auto-discover components in the pages directory
472
- async discoverRoutes() {
473
- console.log("[Router] Auto-discovering routes from pages directory...");
474
- try {
475
- await this.tryLoadCoreRoutes();
476
- console.log("[Router] Route discovery complete. Available routes:", Object.keys(this.routes));
477
- return this.routes;
478
- } catch (error) {
479
- console.error("[Router] Error discovering routes:", error);
480
- await this.tryLoadCoreRoutes();
481
- return this.routes;
482
- }
826
+ }
827
+ var init_id2 = __esm({
828
+ "src/pages/users/[id].tsx"() {
829
+ "use strict";
830
+ init_dist();
831
+ init_api();
483
832
  }
484
- // Fallback method to load core routes
485
- async tryLoadCoreRoutes() {
486
- const pageModules = [
487
- { path: "./pages/index", route: "index" },
488
- { path: "./pages/about/index", route: "about" },
489
- { path: "./pages/users", route: "users" }
490
- ];
491
- for (const { path, route } of pageModules) {
492
- if (!this.routes[route]) {
493
- try {
494
- console.log(`[Router] Attempting to load route: ${route}`);
495
- const module = await import(
496
- /* @vite-ignore */
497
- `${path}.tsx`
498
- ).catch(() => null);
499
- if (module && module.default) {
500
- this.routes[route] = module.default;
501
- console.log(`[Router] Registered route: ${route}`);
502
- }
503
- } catch (error) {
504
- console.warn(`[Router] Could not load route: ${route}`, error);
505
- }
506
- }
507
- }
833
+ });
834
+
835
+ // src/pages/wasm-demo.tsx
836
+ var wasm_demo_exports = {};
837
+ var init_wasm_demo = __esm({
838
+ "src/pages/wasm-demo.tsx"() {
839
+ "use strict";
508
840
  }
509
- };
510
- var router = new Router();
511
- var NotFound = ({ initialState: initialState2 }) => {
512
- return jsx("div", { className: "container mx-auto px-4 py-12 max-w-4xl" }, [
513
- jsx("div", { className: "bg-white shadow-lg rounded-lg overflow-hidden p-8" }, [
514
- jsx("h1", { className: "text-3xl font-bold text-gray-800 mb-4" }, ["Page Not Found"]),
515
- jsx("p", { className: "text-gray-600 mb-6" }, [`No component found for path: ${initialState2?.route || "unknown"}`]),
516
- jsx("a", { href: "/", className: "text-blue-600 hover:text-blue-800 hover:underline transition-colors" }, ["Go to Home"]),
517
- jsx("div", { className: "mt-8 p-6 bg-gray-50 rounded-lg border border-gray-200" }, [
518
- jsx("h3", { className: "text-lg font-medium text-gray-700 mb-3" }, ["Available Routes"]),
519
- jsx("ul", { className: "space-y-2" }, [
520
- jsx("li", {}, [jsx("a", { href: "/", className: "text-blue-600 hover:text-blue-800 hover:underline" }, ["Home"])]),
521
- jsx("li", {}, [jsx("a", { href: "/about", className: "text-blue-600 hover:text-blue-800 hover:underline" }, ["About"])]),
522
- jsx("li", {}, [jsx("a", { href: "/users", className: "text-blue-600 hover:text-blue-800 hover:underline" }, ["Users"])])
523
- ])
524
- ])
525
- ])
526
- ]);
527
- };
528
- router.setNotFound(NotFound);
841
+ });
842
+
843
+ // src/main.tsx
844
+ init_dist();
845
+
846
+ // import("./pages/**/*.tsx") in src/main.tsx
847
+ var globImport_pages_tsx = __glob({
848
+ "./pages/404.tsx": () => Promise.resolve().then(() => (init__(), __exports)),
849
+ "./pages/[id].tsx": () => Promise.resolve().then(() => (init_id(), id_exports)),
850
+ "./pages/_app.tsx": () => Promise.resolve().then(() => (init_app(), app_exports)),
851
+ "./pages/_document.tsx": () => Promise.resolve().then(() => (init_document(), document_exports)),
852
+ "./pages/_error.tsx": () => Promise.resolve().then(() => (init_error(), error_exports)),
853
+ "./pages/about.tsx": () => Promise.resolve().then(() => (init_about(), about_exports)),
854
+ "./pages/about/index.tsx": () => Promise.resolve().then(() => (init_about2(), about_exports2)),
855
+ "./pages/index.tsx": () => Promise.resolve().then(() => (init_pages(), pages_exports)),
856
+ "./pages/users.tsx": () => Promise.resolve().then(() => (init_users(), users_exports)),
857
+ "./pages/users/[id].tsx": () => Promise.resolve().then(() => (init_id2(), id_exports2)),
858
+ "./pages/wasm-demo.tsx": () => Promise.resolve().then(() => (init_wasm_demo(), wasm_demo_exports))
859
+ });
860
+
861
+ // import("./pages/**/*/index.tsx") in src/main.tsx
862
+ var globImport_pages_index_tsx = __glob({
863
+ "./pages/about/index.tsx": () => Promise.resolve().then(() => (init_about2(), about_exports2))
864
+ });
529
865
 
530
866
  // src/main.tsx
531
- init_pages();
532
- init_about();
533
- init_users();
534
- var isHydrating2 = document.getElementById("root")?.innerHTML.trim() !== "";
535
- console.log("[Client] Running client-side code. Hydration state:", isHydrating2);
536
867
  var initialState = window.__INITIAL_STATE__ || {
537
868
  route: window.location.pathname,
538
869
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -543,113 +874,73 @@ var initialState = window.__INITIAL_STATE__ || {
543
874
  }
544
875
  };
545
876
  console.log("[Client] Initial state:", initialState);
546
- async function fetchData(path) {
547
- try {
548
- console.log(`[Client] Fetching data from API: ${path}`);
549
- const response = await fetch(`/api${path}`);
550
- if (!response.ok) {
551
- throw new Error(`API request failed: ${response.status}`);
552
- }
553
- const data = await response.json();
554
- console.log(`[Client] Received data:`, data);
555
- return data;
556
- } catch (error) {
557
- console.error(`[Client] Error fetching data from ${path}:`, error);
558
- return null;
559
- }
560
- }
561
- function initializeRouter() {
562
- console.log("[Client] Initializing router with known pages");
563
- router.register("index", pages_default);
564
- router.register("about", about_default);
565
- router.register("users", users_default);
566
- }
567
- initializeRouter();
568
- async function renderApp() {
877
+ var isHydrating2 = document.getElementById("root")?.innerHTML.trim() !== "";
878
+ async function handleRouteChange(path, isPushState = true) {
569
879
  try {
570
- const currentPath = window.location.pathname;
571
- console.log(`[Client] Rendering for path: ${currentPath}`);
572
- const rootElement = document.getElementById("root");
573
- if (!rootElement) {
574
- console.error("[Client] Root element not found");
575
- return;
880
+ console.log(`[Router] Navigating to: ${path}`);
881
+ if (isPushState) {
882
+ window.history.pushState(null, "", path);
576
883
  }
577
- console.log(`[Client] Fetching users data for ${currentPath}`);
578
- const users = await fetchData("/users");
579
- if (users) {
580
- initialState.data = {
581
- ...initialState.data,
582
- users
583
- };
584
- console.log(`[Client] Updated state with ${users.length} users`);
585
- }
586
- let PageComponent = null;
587
- if (currentPath === "/about") {
588
- try {
589
- const AboutPage2 = await Promise.resolve().then(() => (init_about(), about_exports));
590
- PageComponent = AboutPage2.default;
591
- } catch (err) {
592
- console.error("[Client] Failed to load about page:", err);
593
- }
594
- } else if (currentPath === "/users") {
884
+ const normalizedPath = path === "/" ? "index" : path.replace(/^\//, "");
885
+ let Page;
886
+ try {
887
+ const module = await globImport_pages_tsx(`./pages/${normalizedPath}.tsx`);
888
+ Page = module.default;
889
+ } catch (error) {
890
+ console.warn(`[Router] Could not load page for ${path}, trying index file`);
595
891
  try {
596
- const UsersPage2 = await Promise.resolve().then(() => (init_users(), users_exports));
597
- PageComponent = UsersPage2.default;
598
- } catch (err) {
599
- console.error("[Client] Failed to load users page:", err);
600
- }
601
- } else {
602
- PageComponent = await router.resolve(currentPath);
603
- }
604
- if (!PageComponent) {
605
- console.warn(`[Client] Page component not found for ${currentPath}, checking special cases`);
606
- if (currentPath === "/users") {
892
+ const module = await globImport_pages_index_tsx(`./pages/${normalizedPath}/index.tsx`);
893
+ Page = module.default;
894
+ } catch (innerError) {
895
+ console.error(`[Router] Failed to load page component for ${path}`);
607
896
  try {
608
- console.log("[Client] Attempting direct import of Users page");
609
- const UsersModule = await Promise.resolve().then(() => (init_users(), users_exports));
610
- if (UsersModule.default) {
611
- PageComponent = UsersModule.default;
897
+ const notFoundModule = await Promise.resolve().then(() => (init__(), __exports));
898
+ Page = notFoundModule.default;
899
+ } catch (notFoundError) {
900
+ const rootElement2 = document.getElementById("root");
901
+ if (rootElement2) {
902
+ render(
903
+ /* @__PURE__ */ jsx("div", { style: { padding: "20px", maxWidth: "800px", margin: "0 auto" } }, /* @__PURE__ */ jsx("h1", null, "Page Not Found"), /* @__PURE__ */ jsx("p", null, "The page you requested could not be found."), /* @__PURE__ */ jsx("a", { href: "/", style: { color: "#0066cc" } }, "Go to Home")),
904
+ rootElement2
905
+ );
612
906
  }
613
- } catch (err) {
614
- console.error("[Client] Failed to import Users page:", err);
907
+ return;
615
908
  }
616
909
  }
617
910
  }
618
- if (!PageComponent) {
619
- PageComponent = ({ initialState: initialState2 }) => jsx("div", {
620
- style: "padding: 20px; max-width: 800px; margin: 0 auto;"
621
- }, [
622
- jsx("h1", {}, ["Page Not Found"]),
623
- jsx("p", {}, [`No component found for path: ${initialState2.route}`]),
624
- jsx("a", { href: "/", style: "color: #0066cc;" }, ["Go to Home"])
625
- ]);
911
+ let pageProps = initialState.pageProps || {};
912
+ if (Page.getServerSideProps) {
913
+ try {
914
+ const response = await fetch(`/api/__props${path}`);
915
+ if (response.ok) {
916
+ const data = await response.json();
917
+ pageProps = data.props || {};
918
+ }
919
+ } catch (error) {
920
+ console.error("[Router] Error fetching page props:", error);
921
+ }
626
922
  }
627
- initialState.route = currentPath;
628
- initialState.timestamp = (/* @__PURE__ */ new Date()).toISOString();
629
- initialState.serverRendered = false;
630
- if (isHydrating2) {
923
+ const updatedState = {
924
+ ...initialState,
925
+ route: path,
926
+ pageProps
927
+ };
928
+ const rootElement = document.getElementById("root");
929
+ if (!rootElement)
930
+ return;
931
+ if (isHydrating2 && path === initialState.route) {
631
932
  console.log("[Client] Hydrating server-rendered content");
632
- hydrate(/* @__PURE__ */ jsx(PageComponent, { initialState }), rootElement);
933
+ hydrate(/* @__PURE__ */ jsx(Page, { ...pageProps, initialState: updatedState }), rootElement);
633
934
  isHydrating2 = false;
634
935
  } else {
635
936
  console.log("[Client] Rendering client-side");
636
- render(/* @__PURE__ */ jsx(PageComponent, { initialState }), rootElement);
937
+ render(/* @__PURE__ */ jsx(Page, { ...pageProps, initialState: updatedState }), rootElement);
637
938
  }
638
939
  } catch (error) {
639
- console.error("[Client] Error rendering app:", error);
640
- const rootElement = document.getElementById("root");
641
- if (rootElement) {
642
- rootElement.innerHTML = `
643
- <div style="padding: 20px; color: red;">
644
- <h1>Error</h1>
645
- <p>${error.message}</p>
646
- <pre>${error.stack}</pre>
647
- </div>
648
- `;
649
- }
940
+ console.error("[Router] Navigation error:", error);
650
941
  }
651
942
  }
652
- renderApp();
943
+ handleRouteChange(window.location.pathname, false);
653
944
  document.addEventListener("click", (e) => {
654
945
  let target = e.target;
655
946
  while (target && target.tagName !== "A") {
@@ -657,17 +948,14 @@ document.addEventListener("click", (e) => {
657
948
  if (!target)
658
949
  break;
659
950
  }
660
- if (target && target.tagName === "A" && target.getAttribute("href") && target.getAttribute("href").startsWith("/") && !target.getAttribute("href").startsWith("//") && !target.getAttribute("target")) {
951
+ if (target && target.tagName === "A" && target.getAttribute("href") && target.getAttribute("href")?.startsWith("/") && !target.getAttribute("href")?.startsWith("//") && !target.getAttribute("target")) {
661
952
  e.preventDefault();
662
- const href = target.getAttribute("href");
663
- window.history.pushState(null, "", href);
664
- isHydrating2 = false;
665
- renderApp();
953
+ const href = target.getAttribute("href") || "/";
954
+ handleRouteChange(href);
666
955
  }
667
956
  });
668
957
  window.addEventListener("popstate", () => {
669
- isHydrating2 = false;
670
- renderApp();
958
+ handleRouteChange(window.location.pathname, false);
671
959
  });
672
960
  if (typeof io !== "undefined") {
673
961
  const socket = io();
@@ -675,8 +963,5 @@ if (typeof io !== "undefined") {
675
963
  console.log("[Dev] Reloading page due to file changes");
676
964
  window.location.reload();
677
965
  });
678
- socket.on("welcome", (data) => {
679
- console.log("[Dev] Connected to development server:", data);
680
- });
681
966
  }
682
967
  //# sourceMappingURL=main.js.map