frontend-hamroun 1.2.84 → 1.2.85

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 (215) hide show
  1. package/package.json +1 -1
  2. package/templates/basic-app/build.d.ts +2 -0
  3. package/templates/basic-app/build.d.ts.map +1 -0
  4. package/templates/basic-app/dev.d.ts +2 -0
  5. package/templates/basic-app/dev.d.ts.map +1 -0
  6. package/templates/basic-app/esbuild.config.d.ts +2 -0
  7. package/templates/basic-app/esbuild.config.d.ts.map +1 -0
  8. package/templates/basic-app/postcss.config.d.ts +8 -0
  9. package/templates/basic-app/postcss.config.d.ts.map +1 -0
  10. package/templates/basic-app/server.d.ts +2 -0
  11. package/templates/basic-app/server.d.ts.map +1 -0
  12. package/templates/basic-app/src/App.d.ts +2 -0
  13. package/templates/basic-app/src/App.d.ts.map +1 -0
  14. package/templates/basic-app/src/App.js +148 -0
  15. package/templates/basic-app/src/client.d.ts +2 -0
  16. package/templates/basic-app/src/client.d.ts.map +1 -0
  17. package/templates/basic-app/src/client.js +6 -0
  18. package/templates/basic-app/src/components/Counter.d.ts +4 -0
  19. package/templates/basic-app/src/components/Counter.d.ts.map +1 -0
  20. package/templates/basic-app/src/components/Counter.js +9 -0
  21. package/templates/basic-app/src/jsx-shim.d.ts +8 -0
  22. package/templates/basic-app/src/jsx-shim.d.ts.map +1 -0
  23. package/templates/basic-app/src/main.d.ts +2 -0
  24. package/templates/basic-app/src/main.d.ts.map +1 -0
  25. package/templates/basic-app/src/main.js +57 -0
  26. package/templates/basic-app/src/server.d.ts +2 -0
  27. package/templates/basic-app/src/server.d.ts.map +1 -0
  28. package/templates/basic-app/tailwind.config.d.ts +9 -0
  29. package/templates/basic-app/tailwind.config.d.ts.map +1 -0
  30. package/templates/basic-app/vite.config.d.ts +3 -0
  31. package/templates/basic-app/vite.config.d.ts.map +1 -0
  32. package/templates/basic-app/vite.config.js +7 -0
  33. package/templates/complete-app/api/hello.d.ts +1 -0
  34. package/templates/complete-app/api/hello.d.ts.map +1 -0
  35. package/templates/complete-app/client.d.ts +2 -0
  36. package/templates/complete-app/client.d.ts.map +1 -0
  37. package/templates/complete-app/lib/frontend-hamroun.d.ts +18 -0
  38. package/templates/complete-app/lib/frontend-hamroun.d.ts.map +1 -0
  39. package/templates/complete-app/pages/about.d.ts +7 -0
  40. package/templates/complete-app/pages/about.d.ts.map +1 -0
  41. package/templates/complete-app/pages/index.d.ts +7 -0
  42. package/templates/complete-app/pages/index.d.ts.map +1 -0
  43. package/templates/complete-app/pages/wasm-demo.d.ts +7 -0
  44. package/templates/complete-app/pages/wasm-demo.d.ts.map +1 -0
  45. package/templates/complete-app/public/client.d.ts +17 -0
  46. package/templates/complete-app/public/client.d.ts.map +1 -0
  47. package/templates/complete-app/server.d.ts +2 -0
  48. package/templates/complete-app/server.d.ts.map +1 -0
  49. package/templates/complete-app/server.js +236 -218
  50. package/templates/complete-app/src/App.d.ts +2 -0
  51. package/templates/complete-app/src/App.d.ts.map +1 -0
  52. package/templates/complete-app/src/App.js +27 -0
  53. package/templates/complete-app/src/client.d.ts +2 -0
  54. package/templates/complete-app/src/client.d.ts.map +1 -0
  55. package/templates/complete-app/src/client.js +52 -0
  56. package/templates/complete-app/src/pages/index.d.ts +2 -0
  57. package/templates/complete-app/src/pages/index.d.ts.map +1 -0
  58. package/templates/complete-app/src/pages/index.js +19 -0
  59. package/templates/complete-app/src/server.d.ts +2 -0
  60. package/templates/complete-app/src/server.d.ts.map +1 -0
  61. package/templates/complete-app/src/server.js +192 -0
  62. package/templates/complete-app/vite.config.d.ts +3 -0
  63. package/templates/complete-app/vite.config.d.ts.map +1 -0
  64. package/templates/complete-app/vite.config.js +29 -57
  65. package/templates/fullstack-app/api/hello.d.ts +4 -0
  66. package/templates/fullstack-app/api/hello.d.ts.map +1 -0
  67. package/templates/fullstack-app/api/hello.js +14 -11
  68. package/templates/fullstack-app/api/users/[id].d.ts +5 -0
  69. package/templates/fullstack-app/api/users/[id].d.ts.map +1 -0
  70. package/templates/fullstack-app/api/users/[id].js +52 -0
  71. package/templates/fullstack-app/api/users/index.d.ts +4 -0
  72. package/templates/fullstack-app/api/users/index.d.ts.map +1 -0
  73. package/templates/fullstack-app/api/users/index.js +25 -0
  74. package/templates/fullstack-app/build/main.d.ts +211 -0
  75. package/templates/fullstack-app/build/main.d.ts.map +1 -0
  76. package/templates/fullstack-app/build.d.ts +2 -0
  77. package/templates/fullstack-app/build.d.ts.map +1 -0
  78. package/templates/fullstack-app/build.js +190 -0
  79. package/templates/fullstack-app/postcss.config.d.ts +5 -0
  80. package/templates/fullstack-app/postcss.config.d.ts.map +1 -0
  81. package/templates/fullstack-app/process-tailwind.d.ts +2 -0
  82. package/templates/fullstack-app/process-tailwind.d.ts.map +1 -0
  83. package/templates/fullstack-app/public/route-handler.d.ts +1 -0
  84. package/templates/fullstack-app/public/route-handler.d.ts.map +1 -0
  85. package/templates/fullstack-app/server.d.ts +2 -0
  86. package/templates/fullstack-app/server.d.ts.map +1 -0
  87. package/templates/fullstack-app/server.js +428 -266
  88. package/templates/fullstack-app/src/client.d.ts +2 -0
  89. package/templates/fullstack-app/src/client.d.ts.map +1 -0
  90. package/templates/fullstack-app/src/components/ClientHome.d.ts +1 -0
  91. package/templates/fullstack-app/src/components/ClientHome.d.ts.map +1 -0
  92. package/templates/fullstack-app/src/components/ClientHome.js +1 -0
  93. package/templates/fullstack-app/src/components/ErrorBoundary.d.ts +7 -0
  94. package/templates/fullstack-app/src/components/ErrorBoundary.d.ts.map +1 -0
  95. package/templates/fullstack-app/src/components/ErrorBoundary.js +12 -0
  96. package/templates/fullstack-app/src/components/Layout.d.ts +7 -0
  97. package/templates/fullstack-app/src/components/Layout.d.ts.map +1 -0
  98. package/templates/fullstack-app/src/components/Layout.js +4 -0
  99. package/templates/fullstack-app/src/components/StateDemo.d.ts +2 -0
  100. package/templates/fullstack-app/src/components/StateDemo.d.ts.map +1 -0
  101. package/templates/fullstack-app/src/components/StateDemo.js +86 -0
  102. package/templates/fullstack-app/src/components/UserList.d.ts +11 -0
  103. package/templates/fullstack-app/src/components/UserList.d.ts.map +1 -0
  104. package/templates/fullstack-app/src/components/UserList.js +7 -0
  105. package/templates/fullstack-app/src/config.d.ts +29 -0
  106. package/templates/fullstack-app/src/config.d.ts.map +1 -0
  107. package/templates/fullstack-app/src/config.js +36 -0
  108. package/templates/fullstack-app/src/data/api.d.ts +35 -0
  109. package/templates/fullstack-app/src/data/api.d.ts.map +1 -0
  110. package/templates/fullstack-app/src/data/api.js +173 -0
  111. package/templates/fullstack-app/src/main.d.ts +7 -0
  112. package/templates/fullstack-app/src/main.d.ts.map +1 -0
  113. package/templates/fullstack-app/src/main.js +130 -0
  114. package/templates/fullstack-app/src/middleware.d.ts +10 -0
  115. package/templates/fullstack-app/src/middleware.d.ts.map +1 -0
  116. package/templates/fullstack-app/src/middleware.js +14 -0
  117. package/templates/fullstack-app/src/pages/404.d.ts +4 -0
  118. package/templates/fullstack-app/src/pages/404.d.ts.map +1 -0
  119. package/templates/fullstack-app/src/pages/404.js +4 -0
  120. package/templates/fullstack-app/src/pages/[id].d.ts +1 -0
  121. package/templates/fullstack-app/src/pages/[id].d.ts.map +1 -0
  122. package/templates/fullstack-app/src/pages/[id].js +1 -0
  123. package/templates/fullstack-app/src/pages/_app.d.ts +6 -0
  124. package/templates/fullstack-app/src/pages/_app.d.ts.map +1 -0
  125. package/templates/fullstack-app/src/pages/_app.js +6 -0
  126. package/templates/fullstack-app/src/pages/_document.d.ts +7 -0
  127. package/templates/fullstack-app/src/pages/_document.d.ts.map +1 -0
  128. package/templates/fullstack-app/src/pages/_document.js +4 -0
  129. package/templates/fullstack-app/src/pages/_error.d.ts +4 -0
  130. package/templates/fullstack-app/src/pages/_error.d.ts.map +1 -0
  131. package/templates/fullstack-app/src/pages/_error.js +8 -0
  132. package/templates/fullstack-app/src/pages/about/index.d.ts +5 -0
  133. package/templates/fullstack-app/src/pages/about/index.d.ts.map +1 -0
  134. package/templates/fullstack-app/src/pages/about/index.js +6 -0
  135. package/templates/fullstack-app/src/pages/about.d.ts +10 -0
  136. package/templates/fullstack-app/src/pages/about.d.ts.map +1 -0
  137. package/templates/fullstack-app/src/pages/about.js +21 -0
  138. package/templates/fullstack-app/src/pages/api/users/[id].d.ts +6 -0
  139. package/templates/fullstack-app/src/pages/api/users/[id].d.ts.map +1 -0
  140. package/templates/fullstack-app/src/pages/api/users/[id].js +51 -0
  141. package/templates/fullstack-app/src/pages/api/users/index.d.ts +4 -0
  142. package/templates/fullstack-app/src/pages/api/users/index.d.ts.map +1 -0
  143. package/templates/fullstack-app/src/pages/api/users/index.js +33 -0
  144. package/templates/fullstack-app/src/pages/index.d.ts +21 -0
  145. package/templates/fullstack-app/src/pages/index.d.ts.map +1 -0
  146. package/templates/fullstack-app/src/pages/index.js +66 -0
  147. package/templates/fullstack-app/src/pages/users/[id].d.ts +38 -0
  148. package/templates/fullstack-app/src/pages/users/[id].d.ts.map +1 -0
  149. package/templates/fullstack-app/src/pages/users/[id].js +79 -0
  150. package/templates/fullstack-app/src/pages/users.d.ts +14 -0
  151. package/templates/fullstack-app/src/pages/users.d.ts.map +1 -0
  152. package/templates/fullstack-app/src/pages/users.js +14 -0
  153. package/templates/fullstack-app/src/pages/wasm-demo.d.ts +1 -0
  154. package/templates/fullstack-app/src/pages/wasm-demo.d.ts.map +1 -0
  155. package/templates/fullstack-app/src/pages/wasm-demo.js +2 -0
  156. package/templates/fullstack-app/src/router.d.ts +22 -0
  157. package/templates/fullstack-app/src/router.d.ts.map +1 -0
  158. package/templates/fullstack-app/src/router.js +210 -0
  159. package/templates/fullstack-app/tailwind.config.d.ts +3 -0
  160. package/templates/fullstack-app/tailwind.config.d.ts.map +1 -0
  161. package/templates/fullstack-app/vite.config.d.ts +3 -0
  162. package/templates/fullstack-app/vite.config.d.ts.map +1 -0
  163. package/templates/ssr-template/dist/client/assets/main-D-VH3xOb.d.ts +2 -0
  164. package/templates/ssr-template/dist/client/assets/main-D-VH3xOb.d.ts.map +1 -0
  165. package/templates/ssr-template/dist/client.d.ts +85 -0
  166. package/templates/ssr-template/dist/client.d.ts.map +1 -0
  167. package/templates/ssr-template/dist/server.d.ts +2 -0
  168. package/templates/ssr-template/dist/server.d.ts.map +1 -0
  169. package/templates/ssr-template/esbuild.config.d.ts +2 -0
  170. package/templates/ssr-template/esbuild.config.d.ts.map +1 -0
  171. package/templates/ssr-template/jsx-shim.d.ts +2 -0
  172. package/templates/ssr-template/jsx-shim.d.ts.map +1 -0
  173. package/templates/ssr-template/src/App.d.ts +2 -0
  174. package/templates/ssr-template/src/App.d.ts.map +1 -0
  175. package/templates/ssr-template/src/App.js +625 -0
  176. package/templates/ssr-template/src/client.d.ts +2 -0
  177. package/templates/ssr-template/src/client.d.ts.map +1 -0
  178. package/templates/ssr-template/src/client.js +3 -0
  179. package/templates/ssr-template/src/server.d.ts +2 -0
  180. package/templates/ssr-template/src/server.d.ts.map +1 -0
  181. package/templates/ssr-template/src/server.js +29 -0
  182. package/templates/ssr-template/vite.config.d.ts +3 -0
  183. package/templates/ssr-template/vite.config.d.ts.map +1 -0
  184. package/templates/ssr-template/vite.config.js +30 -0
  185. package/templates/wasm/build-wasm.d.ts +2 -0
  186. package/templates/wasm/build-wasm.d.ts.map +1 -0
  187. package/templates/wasm/dist/assets/index-BNqTDBdE.d.ts +30 -0
  188. package/templates/wasm/dist/assets/index-BNqTDBdE.d.ts.map +1 -0
  189. package/templates/wasm/dist/wasm_exec.d.ts +1 -0
  190. package/templates/wasm/dist/wasm_exec.d.ts.map +1 -0
  191. package/templates/wasm/esbuild.config.d.ts +2 -0
  192. package/templates/wasm/esbuild.config.d.ts.map +1 -0
  193. package/templates/wasm/go/wasm_exec.d.ts +1 -0
  194. package/templates/wasm/go/wasm_exec.d.ts.map +1 -0
  195. package/templates/wasm/jsx-shim.d.ts +5 -0
  196. package/templates/wasm/jsx-shim.d.ts.map +1 -0
  197. package/templates/wasm/public/wasm_exec.d.ts +1 -0
  198. package/templates/wasm/public/wasm_exec.d.ts.map +1 -0
  199. package/templates/wasm/src/App.d.ts +2 -0
  200. package/templates/wasm/src/App.d.ts.map +1 -0
  201. package/templates/wasm/src/App.js +381 -0
  202. package/templates/wasm/src/client.d.ts +2 -0
  203. package/templates/wasm/src/client.d.ts.map +1 -0
  204. package/templates/wasm/src/client.js +210 -0
  205. package/templates/wasm/src/index.d.ts +2 -0
  206. package/templates/wasm/src/index.d.ts.map +1 -0
  207. package/templates/wasm/src/index.js +20 -0
  208. package/templates/wasm/src/server.d.ts +2 -0
  209. package/templates/wasm/src/server.d.ts.map +1 -0
  210. package/templates/wasm/src/server.js +131 -0
  211. package/templates/wasm/vite.config.d.ts +3 -0
  212. package/templates/wasm/vite.config.d.ts.map +1 -0
  213. package/templates/wasm/vite.config.js +36 -0
  214. package/templates/wasm/wasm-loader.d.ts +6 -0
  215. package/templates/wasm/wasm-loader.d.ts.map +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frontend-hamroun",
3
- "version": "1.2.84",
3
+ "version": "1.2.85",
4
4
  "description": "A lightweight full-stack JavaScript framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["build.js"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["dev.js"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=esbuild.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"esbuild.config.d.ts","sourceRoot":"","sources":["esbuild.config.js"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ declare namespace _default {
2
+ namespace plugins {
3
+ let tailwindcss: {};
4
+ let autoprefixer: {};
5
+ }
6
+ }
7
+ export default _default;
8
+ //# sourceMappingURL=postcss.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postcss.config.d.ts","sourceRoot":"","sources":["postcss.config.js"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["server.js"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export declare function App(): JSX.Element;
2
+ //# sourceMappingURL=App.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["App.tsx"],"names":[],"mappings":"AAwFA,wBAAgB,GAAG,gBA2TlB"}
@@ -0,0 +1,148 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "frontend-hamroun/jsx-runtime";
2
+ import { useState, useEffect, useMemo, useErrorBoundary, useForm } from 'frontend-hamroun';
3
+ // Todo Item Component
4
+ function TodoItem({ todo, onToggle, onDelete }) {
5
+ return (_jsxs("div", { className: `todo-item ${todo.completed ? 'completed' : ''}`, children: [_jsx("input", { type: "checkbox", checked: todo.completed, onChange: () => onToggle(todo.id), className: "todo-checkbox" }), _jsx("span", { className: "todo-text", children: todo.text }), _jsxs("span", { className: `todo-priority priority-${todo.priority}`, children: [todo.priority === 'high' && '🔴', todo.priority === 'medium' && '🟡', todo.priority === 'low' && '🟢', todo.priority] }), _jsx("div", { className: "todo-actions", children: _jsx("button", { onClick: () => onDelete(todo.id), className: "btn btn-sm btn-danger", title: "Delete todo", children: "\uD83D\uDDD1\uFE0F" }) })] }));
6
+ }
7
+ // Theme Toggle Button Component
8
+ function ThemeToggleButton({ theme, onToggle }) {
9
+ return (_jsx("button", { onClick: onToggle, className: "btn btn-secondary theme-toggle", title: "Toggle theme", children: theme === 'light' ? '🌙' : '☀️' }));
10
+ }
11
+ // App Footer Component
12
+ function AppFooter({ theme }) {
13
+ return (_jsx("footer", { className: "app-footer", children: _jsxs("div", { className: "container", children: [_jsx("p", { children: "Built with Frontend Hamroun \u2022 Hooks: useState, useEffect, useMemo, useErrorBoundary, useForm" }), _jsxs("p", { children: ["Theme: ", _jsx("strong", { children: theme }), " \u2022 Environment: ", _jsx("strong", { children: "Client" })] })] }) }));
14
+ }
15
+ export function App() {
16
+ // State hooks with proper typing
17
+ const [todos, setTodos] = useState([
18
+ { id: 1, text: 'Learn Frontend Hamroun hooks', completed: false, priority: 'high' },
19
+ { id: 2, text: 'Build a todo app', completed: false, priority: 'medium' },
20
+ { id: 3, text: 'Master client-side concepts', completed: true, priority: 'low' }
21
+ ]);
22
+ const [theme, setTheme] = useState('light');
23
+ const [taskFilter, setTaskFilter] = useState('all');
24
+ // Error boundary hook
25
+ const [error, resetError] = useErrorBoundary();
26
+ // Form hook for adding new todos
27
+ const addTodoForm = useForm({
28
+ initialValues: {
29
+ text: '',
30
+ priority: 'medium'
31
+ },
32
+ validate: (values) => {
33
+ const errors = {};
34
+ if (!values.text.trim()) {
35
+ errors.text = 'Todo text is required';
36
+ }
37
+ return errors;
38
+ },
39
+ onSubmit: (values) => {
40
+ const newTodo = {
41
+ id: Date.now(),
42
+ text: values.text.trim(),
43
+ completed: false,
44
+ priority: values.priority
45
+ };
46
+ setTodos(prev => [...prev, newTodo]);
47
+ addTodoForm.resetForm();
48
+ }
49
+ });
50
+ // Mount effect
51
+ useEffect(() => {
52
+ console.log('Todo App mounted');
53
+ // Load saved todos from localStorage
54
+ const savedTodos = localStorage.getItem('todos');
55
+ const savedTheme = localStorage.getItem('theme');
56
+ if (savedTodos) {
57
+ try {
58
+ setTodos(JSON.parse(savedTodos));
59
+ }
60
+ catch (e) {
61
+ console.error('Failed to load saved todos');
62
+ }
63
+ }
64
+ if (savedTheme) {
65
+ setTheme(savedTheme);
66
+ }
67
+ return () => {
68
+ console.log('Todo App unmounting');
69
+ };
70
+ }, []);
71
+ // Theme effect
72
+ useEffect(() => {
73
+ document.body.className = `theme-${theme}`;
74
+ document.documentElement.setAttribute('data-theme', theme);
75
+ localStorage.setItem('theme', theme);
76
+ }, [theme]);
77
+ // Save todos effect
78
+ useEffect(() => {
79
+ if (todos.length === 0)
80
+ return;
81
+ localStorage.setItem('todos', JSON.stringify(todos));
82
+ }, [todos]);
83
+ // Memoized filtered todos
84
+ const filteredTodos = useMemo(() => {
85
+ console.log('Filtering todos - memoized computation');
86
+ return todos.filter(todo => {
87
+ if (taskFilter === 'completed')
88
+ return todo.completed;
89
+ if (taskFilter === 'active')
90
+ return !todo.completed;
91
+ if (taskFilter === 'high')
92
+ return todo.priority === 'high';
93
+ if (taskFilter === 'medium')
94
+ return todo.priority === 'medium';
95
+ if (taskFilter === 'low')
96
+ return todo.priority === 'low';
97
+ return true;
98
+ });
99
+ }, [todos, taskFilter]);
100
+ // Memoized todo stats
101
+ const todoStats = useMemo(() => {
102
+ const total = todos.length;
103
+ const completed = todos.filter(t => t.completed).length;
104
+ const active = total - completed;
105
+ const highPriority = todos.filter(t => t.priority === 'high' && !t.completed).length;
106
+ return { total, completed, active, highPriority };
107
+ }, [todos]);
108
+ // Todo action handlers
109
+ const handleToggleTodo = (id) => {
110
+ console.log('Toggling todo:', id);
111
+ setTodos(prev => prev.map(todo => todo.id === id ? { ...todo, completed: !todo.completed } : todo));
112
+ };
113
+ const handleDeleteTodo = (id) => {
114
+ console.log('Deleting todo:', id);
115
+ setTodos(prev => prev.filter(todo => todo.id !== id));
116
+ };
117
+ // Event handlers
118
+ const clearCompleted = () => {
119
+ setTodos(prev => prev.filter(todo => !todo.completed));
120
+ };
121
+ const markAllComplete = () => {
122
+ setTodos(prev => prev.map(todo => ({ ...todo, completed: true })));
123
+ };
124
+ const toggleTheme = () => {
125
+ setTheme(prev => prev === 'light' ? 'dark' : 'light');
126
+ };
127
+ const simulateError = () => {
128
+ throw new Error('Simulated error for testing error boundary');
129
+ };
130
+ if (error) {
131
+ return (_jsxs("div", { className: "error-container", children: [_jsx("h2", { children: "Something went wrong!" }), _jsx("p", { children: error.message }), _jsx("button", { onClick: resetError, className: "btn btn-primary", children: "Try Again" })] }));
132
+ }
133
+ return (_jsxs("div", { className: `app theme-${theme}`, children: [_jsx("header", { className: "app-header", children: _jsxs("div", { className: "container", children: [_jsxs("h1", { className: "app-title", children: ["\uD83D\uDCDD Todo App", _jsx("span", { className: "subtitle", children: "Built with Frontend Hamroun" })] }), _jsxs("div", { className: "header-controls", children: [_jsx(ThemeToggleButton, { theme: theme, onToggle: toggleTheme }), _jsxs("div", { className: "stats", children: [_jsxs("span", { className: "stat", children: ["Total: ", _jsx("strong", { children: todoStats.total })] }), _jsxs("span", { className: "stat", children: ["Active: ", _jsx("strong", { children: todoStats.active })] }), _jsxs("span", { className: "stat", children: ["Done: ", _jsx("strong", { children: todoStats.completed })] })] })] })] }) }), _jsx("main", { className: "main-content", children: _jsxs("div", { className: "container", children: [_jsxs("section", { className: "card add-todo-section", children: [_jsx("h2", { children: "\u2795 Add New Todo" }), _jsxs("form", { onSubmit: addTodoForm.handleSubmit, className: "add-todo-form", children: [_jsx("input", { type: "text", name: "text", value: addTodoForm.values.text, onChange: addTodoForm.handleChange, onBlur: addTodoForm.handleBlur, placeholder: "What needs to be done?", className: `input todo-input ${addTodoForm.errors.text && addTodoForm.touched.text ? 'error' : ''}` }), _jsxs("select", { name: "priority", value: addTodoForm.values.priority, onChange: addTodoForm.handleChange, className: "select priority-select", children: [_jsx("option", { value: "low", children: "\uD83D\uDFE2 Low Priority" }), _jsx("option", { value: "medium", children: "\uD83D\uDFE1 Medium Priority" }), _jsx("option", { value: "high", children: "\uD83D\uDD34 High Priority" })] }), _jsx("button", { type: "submit", className: `btn btn-primary add-btn ${addTodoForm.isSubmitting ? 'loading' : ''}`, disabled: addTodoForm.isSubmitting || !addTodoForm.values.text.trim(), children: addTodoForm.isSubmitting ? '⏳ Adding...' : '➕ Add Todo' })] }), addTodoForm.errors.text && addTodoForm.touched.text && (_jsx("div", { className: "error-message", children: addTodoForm.errors.text }))] }), _jsxs("section", { className: "card filters-section", children: [_jsx("h2", { children: "\uD83D\uDD0D Filter Todos" }), _jsx("div", { className: "filters", children: ['all', 'active', 'completed', 'high', 'medium', 'low'].map(filterType => (_jsxs("button", { onClick: () => setTaskFilter(filterType), className: `btn btn-sm filter-btn ${taskFilter === filterType ? 'btn-primary' : 'btn-outline'}`, children: [filterType === 'all' && '📋 All', filterType === 'active' && '⏳ Active', filterType === 'completed' && '✅ Completed', filterType === 'high' && '🔴 High Priority', filterType === 'medium' && '🟡 Medium Priority', filterType === 'low' && '🟢 Low Priority'] }, filterType))) }), _jsxs("div", { className: "bulk-actions", children: [_jsx("button", { onClick: markAllComplete, className: "btn btn-success btn-sm", disabled: todoStats.active === 0, children: "\u2705 Mark All Complete" }), _jsx("button", { onClick: clearCompleted, className: "btn btn-warning btn-sm", disabled: todoStats.completed === 0, children: "\uD83D\uDDD1\uFE0F Clear Completed" })] })] }), _jsxs("section", { className: "card todos-section", children: [_jsxs("div", { className: "section-header", children: [_jsx("h2", { children: "\uD83D\uDCCB Todo List" }), _jsxs("div", { className: "filter-info", children: ["Showing ", _jsx("strong", { children: filteredTodos.length }), " of ", _jsx("strong", { children: todoStats.total }), " todos", taskFilter !== 'all' && _jsx("span", { className: "filter-badge", children: taskFilter })] })] }), _jsx("div", { className: "todos-list", children: filteredTodos.length > 0 ? (filteredTodos.map(todo => (_jsx(TodoItem, { todo: todo, onToggle: handleToggleTodo, onDelete: handleDeleteTodo }, todo.id)))) : (_jsx("div", { className: "empty-state", children: _jsx("p", { children: taskFilter === 'all' ? '🎉 No todos yet. Add one above!' :
134
+ taskFilter === 'completed' ? '📝 No completed todos yet.' :
135
+ taskFilter === 'active' ? '🎯 No active todos. Great job!' :
136
+ `🔍 No ${taskFilter} priority todos found.` }) })) })] }), _jsxs("section", { className: "card actions-section", children: [_jsx("h2", { children: "\u2699\uFE0F Actions" }), _jsx("div", { className: "action-buttons", children: _jsx("button", { onClick: simulateError, className: "btn btn-danger", children: "\uD83D\uDCA5 Test Error Boundary" }) })] })] }) }), _jsx(AppFooter, { theme: theme }), _jsx("style", { children: `
137
+ /* ...existing styles... */
138
+ .error-message {
139
+ color: #e74c3c;
140
+ font-size: 0.875rem;
141
+ margin-top: 0.5rem;
142
+ }
143
+
144
+ .input.error {
145
+ border-color: #e74c3c;
146
+ }
147
+ ` })] }));
148
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["client.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "frontend-hamroun/jsx-runtime";
2
+ import { hydrate } from 'frontend-hamroun';
3
+ import { App } from './App';
4
+ document.addEventListener('DOMContentLoaded', () => {
5
+ hydrate(_jsx(App, {}), document.getElementById('root'));
6
+ });
@@ -0,0 +1,4 @@
1
+ export declare function Counter({ initial }: {
2
+ initial?: number | undefined;
3
+ }): JSX.Element;
4
+ //# sourceMappingURL=Counter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Counter.d.ts","sourceRoot":"","sources":["Counter.tsx"],"names":[],"mappings":"AAEA,wBAAgB,OAAO,CAAC,EAAE,OAAW,EAAE;;CAAA,eAetC"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "frontend-hamroun/jsx-runtime";
2
+ import { useState, useEffect } from 'frontend-hamroun';
3
+ export function Counter({ initial = 0 }) {
4
+ const [count, setCount] = useState(initial);
5
+ useEffect(() => {
6
+ document.title = `Count: ${count}`;
7
+ }, [count]);
8
+ return (_jsxs("div", { children: [_jsx("h2", { children: "Counter Component" }), _jsx("button", { onClick: () => setCount(count - 1), children: "-" }), _jsx("span", { style: { margin: '0 10px' }, children: count }), _jsx("button", { onClick: () => setCount(count + 1), children: "+" })] }));
9
+ }
@@ -0,0 +1,8 @@
1
+ import { jsx as createElement, Fragment } from 'frontend-hamroun';
2
+ declare global {
3
+ interface Window {
4
+ createElement: typeof createElement;
5
+ Fragment: typeof Fragment;
6
+ }
7
+ }
8
+ //# sourceMappingURL=jsx-shim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-shim.d.ts","sourceRoot":"","sources":["jsx-shim.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAElE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,aAAa,EAAE,OAAO,aAAa,CAAC;QACpC,QAAQ,EAAE,OAAO,QAAQ,CAAC;KAC3B;CACF"}
@@ -0,0 +1,2 @@
1
+ import './main.css';
2
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["main.tsx"],"names":[],"mappings":"AACA,OAAO,YAAY,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "frontend-hamroun/jsx-runtime";
2
+ import { render, useState, useEffect, useMemo, useRef, useErrorBoundary, createContext, useContext } from 'frontend-hamroun';
3
+ import './main.css';
4
+ // Create a theme context
5
+ const ThemeContext = createContext('light');
6
+ // Create a component that will throw an error when clicked
7
+ function BuggyComponent() {
8
+ const [shouldError, setShouldError] = useState(false);
9
+ if (shouldError) {
10
+ throw new Error("Test error from BuggyComponent");
11
+ }
12
+ return (_jsx("button", { onClick: () => setShouldError(true), className: "bg-red-600 text-white px-4 py-2 rounded mt-4 hover:bg-red-700", children: "Trigger Error" }));
13
+ }
14
+ function App() {
15
+ const [count, setCount] = useState(0);
16
+ const [theme, setTheme] = useState('light');
17
+ const renderCount = useRef(0);
18
+ const [error, resetError] = useErrorBoundary();
19
+ // Demonstrate useEffect
20
+ useEffect(() => {
21
+ document.title = `Count: ${count}`;
22
+ renderCount.current += 1;
23
+ return () => {
24
+ console.log('Cleanup effect');
25
+ };
26
+ }, [count]);
27
+ // Demonstrate useMemo
28
+ const doubled = useMemo(() => count * 2, [count]);
29
+ if (error) {
30
+ return (_jsxs("div", { className: "p-8 max-w-md mx-auto bg-red-50 rounded-lg shadow-lg", children: [_jsx("h1", { className: "text-2xl font-bold text-red-600 mb-4", children: "Something went wrong!" }), _jsx("button", { onClick: resetError, className: "bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded", children: "Try again" })] }));
31
+ }
32
+ return (_jsx(ThemeContext.Provider, { value: theme, children: _jsxs("div", { className: `p-8 max-w-4xl mx-auto rounded-lg shadow-lg transition-colors ${theme === 'dark'
33
+ ? 'bg-gray-800 text-white'
34
+ : 'bg-white text-gray-900'}`, children: [_jsx("h1", { className: "text-3xl font-bold mb-6", children: "Welcome to Frontend Hamroun" }), _jsxs("div", { className: "mb-6", children: [_jsx("button", { onClick: () => setCount(count - 1), className: "bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded", children: "-" }), _jsx("span", { className: "mx-4 text-xl", children: count }), _jsx("button", { onClick: () => setCount(count + 1), className: "bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded", children: "+" })] }), _jsxs("p", { className: "mb-2 text-lg", children: ["Doubled value: ", _jsx("span", { className: "font-semibold", children: doubled })] }), _jsxs("p", { className: "mb-4 text-lg", children: ["Render count: ", _jsx("span", { className: "font-semibold", children: renderCount.current })] }), _jsxs("button", { onClick: () => setTheme(theme === 'light' ? 'dark' : 'light'), className: `px-4 py-2 rounded mb-8 ${theme === 'dark'
35
+ ? 'bg-yellow-400 text-gray-900 hover:bg-yellow-300'
36
+ : 'bg-gray-800 text-white hover:bg-gray-700'}`, children: ["Toggle Theme (", theme, ")"] }), _jsxs("div", { className: "mt-8 border-t pt-6", children: [_jsx("h2", { className: "text-2xl font-bold mb-4", children: "Test Error Boundary" }), _jsx(BuggyComponent, {})] }), _jsxs("div", { className: "mt-8 border-t pt-6", children: [_jsx("h2", { className: "text-2xl font-bold mb-4", children: "Test Context" }), _jsx(ContextConsumer, {})] })] }) }));
37
+ }
38
+ // Component to test context
39
+ function ContextConsumer() {
40
+ // Get the full context object for debugging
41
+ const themeContext = useContext(ThemeContext);
42
+ console.log('Theme context object:', themeContext);
43
+ // Access the current theme from the parent component instead
44
+ // This is a workaround until context is properly implemented
45
+ return (_jsxs("div", { className: `mt-4 p-4 rounded-md border ${themeContext === 'dark' ? 'border-gray-600' : 'border-gray-300'}`, children: [_jsxs("p", { className: "mb-2", children: [_jsx("strong", { children: "Note:" }), " Context API needs a fix in the framework."] }), _jsxs("p", { className: "mb-1", children: ["Context object type: ", typeof themeContext] }), _jsxs("p", { className: "mb-4", children: ["Context object keys: ", Object.keys(themeContext).join(', ') || 'none'] }), _jsx("button", { onClick: () => {
46
+ // Since we can't get the value directly from context,
47
+ // Let's add a button to demonstrate we can still use the Provider
48
+ const newTheme = document.body.style.backgroundColor === 'rgb(51, 51, 51)'
49
+ ? 'light' : 'dark';
50
+ console.log('Manually changing theme to:', newTheme);
51
+ // This won't work yet, but demonstrates the intent
52
+ if (ThemeContext) {
53
+ console.log('Provider exists, would set value to:', newTheme);
54
+ }
55
+ }, className: "bg-purple-500 hover:bg-purple-600 text-white px-4 py-2 rounded", children: "Check Context Implementation" })] }));
56
+ }
57
+ render(_jsx(App, {}), document.getElementById('root'));
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["server.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ declare const _default: {
2
+ content: string[];
3
+ theme: {
4
+ extend: {};
5
+ };
6
+ plugins: never[];
7
+ };
8
+ export default _default;
9
+ //# sourceMappingURL=tailwind.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailwind.config.d.ts","sourceRoot":"","sources":["tailwind.config.js"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("vite").UserConfig;
2
+ export default _default;
3
+ //# sourceMappingURL=vite.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite.config.d.ts","sourceRoot":"","sources":["vite.config.ts"],"names":[],"mappings":";AAEA,wBAKG"}
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from 'vite';
2
+ export default defineConfig({
3
+ esbuild: {
4
+ jsxFactory: 'jsx',
5
+ jsxFragment: 'Fragment'
6
+ }
7
+ });
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=hello.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hello.d.ts","sourceRoot":"","sources":["hello.js"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["client.js"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Simple JSX implementation for server-side rendering
3
+ */
4
+ export function renderToString(vnode: any): any;
5
+ export function jsx(type: any, props: any, ...children: any[]): {
6
+ type: any;
7
+ props: any;
8
+ };
9
+ export function requestLogger(req: any, res: any, next: any): void;
10
+ export function errorHandler(err: any, req: any, res: any, next: any): void;
11
+ export function notFoundHandler(req: any, res: any): void;
12
+ export function rateLimit(options?: {
13
+ windowMs: number;
14
+ max: number;
15
+ }): (req: any, res: any, next: any) => any;
16
+ export function loadGoWasmFromFile(): void;
17
+ export const Fragment: unique symbol;
18
+ //# sourceMappingURL=frontend-hamroun.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontend-hamroun.d.ts","sourceRoot":"","sources":["frontend-hamroun.js"],"names":[],"mappings":"AAAA;;GAEG;AAGH,gDAuGC;AAGD;;;EAMC;AAkBD,mEAGC;AAGD,4EAGC;AAGD,0DAEC;AAGD;;;2CAuBC;AAID,2CAEC;AAHD,qCAAqD"}
@@ -0,0 +1,7 @@
1
+ declare function AboutPage(props: any): import("frontend-hamroun").VNode;
2
+ declare namespace AboutPage {
3
+ function getTitle(): string;
4
+ function getDescription(): string;
5
+ }
6
+ export default AboutPage;
7
+ //# sourceMappingURL=about.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"about.d.ts","sourceRoot":"","sources":["about.js"],"names":[],"mappings":"AAoBA,yEA8FC;;IAGD,4BAA+D;IAC/D,kCAAoH"}
@@ -0,0 +1,7 @@
1
+ declare function HomePage(props: any): import("frontend-hamroun").VNode;
2
+ declare namespace HomePage {
3
+ function getTitle(props: any): string;
4
+ function getDescription(props: any): string;
5
+ }
6
+ export default HomePage;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.js"],"names":[],"mappings":"AAqFA,wEAmEC;;IAGD,sCAA+E;IAC/E,4CAAsJ"}
@@ -0,0 +1,7 @@
1
+ declare function WasmDemo(props: any): import("frontend-hamroun").VNode;
2
+ declare namespace WasmDemo {
3
+ function getTitle(): string;
4
+ function getDescription(): string;
5
+ }
6
+ export default WasmDemo;
7
+ //# sourceMappingURL=wasm-demo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wasm-demo.d.ts","sourceRoot":"","sources":["wasm-demo.js"],"names":[],"mappings":"AAGA,wEA0RC;;IAGD,4BAA+D;IAC/D,kCAAiI"}
@@ -0,0 +1,17 @@
1
+ declare function jsx(type: any, props: any, ...children: any[]): {
2
+ type: any;
3
+ props: any;
4
+ };
5
+ declare function jsx(type: any, props: any, ...args: any[]): {
6
+ type: any;
7
+ props: any;
8
+ };
9
+ declare function jsx(type: any, props: any, ...args: any[]): {
10
+ type: any;
11
+ props: any;
12
+ };
13
+ declare function hydrate(element: any, container: any): void;
14
+ declare function hydrate(element: any, container: any): Promise<void>;
15
+ declare function hydrate(element: any, container: any): Promise<void>;
16
+ declare const Fragment: typeof Fragment;
17
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["client.js"],"names":[],"mappings":"AAGA;;;EAMC;;;;;;;;;AAMD,6DAsCC;;;AAzCD,wCAA8C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["server.ts"],"names":[],"mappings":""}