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
@@ -0,0 +1,173 @@
1
+ // Support both ESM and CommonJS importing styles
2
+ const frontendHamroun =
3
+ typeof require !== 'undefined'
4
+ ? require('frontend-hamroun')
5
+ : await import('frontend-hamroun');
6
+
7
+ // Destructure the imports from either ESM or CJS modules
8
+ const {
9
+ useState,
10
+ useEffect,
11
+ jsx,
12
+ Fragment,
13
+ loadGoWasm,
14
+ createTypedWasmFunction,
15
+ goValues
16
+ } = frontendHamroun;
17
+
18
+ export function GoWasmDemo() {
19
+ // Track loading state
20
+ const [loading, setLoading] = useState(true);
21
+ const [error, setError] = useState(null);
22
+ const [wasm, setWasm] = useState(null);
23
+
24
+ // Track calculation values
25
+ const [num1, setNum1] = useState(5);
26
+ const [num2, setNum2] = useState(7);
27
+ const [result, setResult] = useState(null);
28
+
29
+ // Track JSON example
30
+ const [jsonInput, setJsonInput] = useState('{"name": "Frontend Hamroun", "version": "1.0"}');
31
+ const [jsonResult, setJsonResult] = useState(null);
32
+
33
+ // Load the WASM module when component mounts
34
+ useEffect(() => {
35
+ async function loadWasmModule() {
36
+ try {
37
+ setLoading(true);
38
+ console.log('Loading WASM module...');
39
+
40
+ // Load WASM module using frontend-hamroun's loadGoWasm
41
+ const wasmInstance = await loadGoWasm('/wasm/example.wasm', {
42
+ debug: true, // Enable debug logging
43
+ goWasmPath: '/wasm/wasm_exec.js' // Path to Go's wasm_exec.js
44
+ });
45
+
46
+ console.log('WASM module loaded successfully!', wasmInstance);
47
+ setWasm(wasmInstance);
48
+
49
+ // Demonstrate calling a function right away
50
+ if (wasmInstance.functions.goAdd) {
51
+ const sum = wasmInstance.functions.goAdd(5, 7);
52
+ console.log('5 + 7 =', sum);
53
+ setResult(sum);
54
+ }
55
+
56
+ setLoading(false);
57
+ } catch (err) {
58
+ console.error('Failed to load WASM module:', err);
59
+ setError(err.toString());
60
+ setLoading(false);
61
+ }
62
+ }
63
+
64
+ loadWasmModule();
65
+
66
+ // Cleanup function
67
+ return () => {
68
+ console.log('Cleaning up WASM resources...');
69
+ // Any cleanup needed for WASM resources
70
+ };
71
+ }, []); // Empty dependency array means this runs once on mount
72
+
73
+ // Function to calculate using WASM
74
+ const calculateResult = () => {
75
+ if (!wasm || !wasm.functions.goAdd) {
76
+ setError('WASM module not loaded or function not available');
77
+ return;
78
+ }
79
+
80
+ try {
81
+ // Call the WASM function
82
+ const sum = wasm.functions.goAdd(parseInt(num1), parseInt(num2));
83
+ setResult(sum);
84
+ setError(null);
85
+ } catch (err) {
86
+ console.error('Error calling WASM function:', err);
87
+ setError('Error calling WASM function: ' + err);
88
+ }
89
+ };
90
+
91
+ // Function to parse JSON using WASM
92
+ const parseJsonWithWasm = () => {
93
+ if (!wasm || !wasm.functions.goParseJSON) {
94
+ setError('WASM module not loaded or JSON parsing function not available');
95
+ return;
96
+ }
97
+
98
+ try {
99
+ // Call the WASM function
100
+ const parsed = wasm.functions.goParseJSON(jsonInput);
101
+ setJsonResult(JSON.stringify(parsed, null, 2));
102
+ setError(null);
103
+ } catch (err) {
104
+ console.error('Error parsing JSON with WASM:', err);
105
+ setError('Error parsing JSON with WASM: ' + err);
106
+ }
107
+ };
108
+
109
+ // Render the component
110
+ return (
111
+ <div className="wasm-demo">
112
+ <h1>Go WebAssembly Demo</h1>
113
+
114
+ {loading && <p>Loading WASM module...</p>}
115
+
116
+ {error && (
117
+ <div className="error">
118
+ <h3>Error:</h3>
119
+ <pre>{error}</pre>
120
+ </div>
121
+ )}
122
+
123
+ {wasm && !loading && (
124
+ <div className="demo-section">
125
+ <h2>WASM Addition</h2>
126
+ <div className="calculator">
127
+ <input
128
+ type="number"
129
+ value={num1}
130
+ onChange={(e) => setNum1(e.target.value)}
131
+ />
132
+ <span> + </span>
133
+ <input
134
+ type="number"
135
+ value={num2}
136
+ onChange={(e) => setNum2(e.target.value)}
137
+ />
138
+ <button onClick={calculateResult}>Calculate</button>
139
+ <span className="result">Result: {result}</span>
140
+ </div>
141
+
142
+ <h2>WASM JSON Parsing</h2>
143
+ <div className="json-parser">
144
+ <textarea
145
+ rows="5"
146
+ value={jsonInput}
147
+ onChange={(e) => setJsonInput(e.target.value)}
148
+ />
149
+ <button onClick={parseJsonWithWasm}>Parse JSON</button>
150
+ {jsonResult && (
151
+ <pre className="json-result">{jsonResult}</pre>
152
+ )}
153
+ </div>
154
+
155
+ <h2>Available WASM Functions</h2>
156
+ <ul>
157
+ {wasm && Object.keys(wasm.functions).map(funcName => (
158
+ <li key={funcName}>{funcName}</li>
159
+ ))}
160
+ </ul>
161
+ </div>
162
+ )}
163
+ </div>
164
+ );
165
+ }
166
+
167
+ // Support both CommonJS and ESM exports
168
+ export default GoWasmDemo;
169
+
170
+ // Add CommonJS compatibility
171
+ if (typeof module !== 'undefined' && module.exports) {
172
+ module.exports = { GoWasmDemo };
173
+ }
@@ -17,11 +17,22 @@ export default defineConfig({
17
17
  input: {
18
18
  client: resolve(__dirname, 'src/client.js')
19
19
  },
20
- output: {
21
- entryFileNames: 'assets/[name].js',
22
- chunkFileNames: 'assets/[name]-[hash].js',
23
- assetFileNames: 'assets/[name]-[hash].[ext]'
24
- }
20
+ output: [
21
+ {
22
+ // ESM output
23
+ entryFileNames: 'assets/[name].mjs',
24
+ chunkFileNames: 'assets/[name]-[hash].mjs',
25
+ assetFileNames: 'assets/[name]-[hash].[ext]',
26
+ format: 'es',
27
+ },
28
+ {
29
+ // CommonJS output
30
+ entryFileNames: 'assets/[name].js',
31
+ chunkFileNames: 'assets/[name]-[hash].js',
32
+ assetFileNames: 'assets/[name]-[hash].[ext]',
33
+ format: 'cjs',
34
+ }
35
+ ]
25
36
  }
26
37
  },
27
38
 
@@ -1,30 +1,58 @@
1
- import { hydrate } from 'frontend-hamroun';
1
+ import { hydrate, jsx } from 'frontend-hamroun';
2
2
 
3
- // Dynamically import the page component that matches the current URL
4
- async function hydratePage() {
5
- try {
6
- // Get the current path
7
- const path = window.location.pathname;
8
-
9
- // Import the corresponding page component
10
- const pagePath = `/src/pages${path === '/' ? '/index' : path}.jsx`;
11
-
12
- try {
13
- const { default: PageComponent } = await import(pagePath);
14
-
15
- // Find the root element to hydrate
16
- const rootElement = document.getElementById('app');
17
- if (rootElement) {
18
- // Hydrate the server-rendered HTML with the client component
19
- hydrate(<PageComponent />, rootElement);
3
+ // Create a sample virtual DOM matching what was rendered on the server
4
+ const app = {
5
+ type: 'div',
6
+ props: {
7
+ id: 'app',
8
+ children: [
9
+ {
10
+ type: 'h1',
11
+ props: {
12
+ children: 'Hello from Server-Side Rendering!'
13
+ }
14
+ },
15
+ {
16
+ type: 'p',
17
+ props: {
18
+ children: `This page was rendered at ${new Date().toISOString()}`
19
+ }
20
+ },
21
+ {
22
+ type: 'button',
23
+ props: {
24
+ id: 'counter-btn',
25
+ className: 'btn',
26
+ onClick: () => {
27
+ let count = 1; // Start at 1 since we're updating
28
+ const btn = document.getElementById('counter-btn');
29
+ if (btn) {
30
+ btn.textContent = `Click me (${count})`;
31
+ btn.addEventListener('click', () => {
32
+ count++;
33
+ btn.textContent = `Click me (${count})`;
34
+ });
35
+ }
36
+ },
37
+ children: 'Click me (0)'
38
+ }
20
39
  }
21
- } catch (error) {
22
- console.error(`Error importing page component for path ${path}:`, error);
23
- }
24
- } catch (error) {
25
- console.error('Error during hydration:', error);
40
+ ]
26
41
  }
27
- }
42
+ };
28
43
 
29
- // Start hydration when the DOM is ready
30
- document.addEventListener('DOMContentLoaded', hydratePage);
44
+ // Wait for DOM to be fully loaded before hydrating
45
+ window.addEventListener('DOMContentLoaded', () => {
46
+ console.log('Hydrating client-side content...');
47
+
48
+ // Get the container element
49
+ const container = document.getElementById('app');
50
+ if (!container) {
51
+ console.error('Could not find app container for hydration');
52
+ return;
53
+ }
54
+
55
+ // Hydrate the app
56
+ hydrate(app, container);
57
+ console.log('Hydration complete!');
58
+ });
@@ -3,6 +3,8 @@ import path from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  import fetch from 'node-fetch';
5
5
  import dotenv from 'dotenv';
6
+ import fs from 'fs';
7
+ import { renderToString } from 'frontend-hamroun/ssr';
6
8
 
7
9
  // Load environment variables
8
10
  dotenv.config();
@@ -211,9 +213,6 @@ async function generateMetaTagsWithGemini(pageContent) {
211
213
  app.get('/', async (req, res) => {
212
214
  console.log('Handling root route for SSR');
213
215
  try {
214
- // Import the renderToString function
215
- const frontendLib = await import('frontend-hamroun');
216
-
217
216
  // Create a simple virtual DOM tree
218
217
  const vnode = {
219
218
  type: 'div',
@@ -248,33 +247,11 @@ app.get('/', async (req, res) => {
248
247
  const contentForMetaTags = 'Server-side rendered page using Frontend Hamroun framework. ' +
249
248
  'This demonstrates SSR capabilities with dynamic content generation and client-side hydration.';
250
249
 
251
- console.log('Fetching meta tags for the page using Gemini 2.0 Flash...');
250
+ console.log('Fetching meta tags for the page...');
252
251
  const metaTags = await generateMetaTags(contentForMetaTags);
253
252
 
254
- // The renderToString function exists and works properly
255
- console.log('renderToString type:', typeof frontendLib.renderToString);
256
-
257
- // Generate HTML from our virtual node
258
- let content;
259
- if (typeof frontendLib.renderToString === 'function') {
260
- // Call the function
261
- const renderResult = frontendLib.renderToString(vnode);
262
-
263
- // If it returns a promise, await it
264
- if (renderResult instanceof Promise) {
265
- console.log('renderToString returned a Promise, awaiting it');
266
- content = await renderResult;
267
- } else {
268
- console.log('renderToString returned directly:', typeof renderResult);
269
- content = renderResult;
270
- }
271
- } else {
272
- throw new Error('renderToString is not a function');
273
- }
274
-
275
- // Log the content to verify it's not empty or still a Promise
276
- console.log('Final content type:', typeof content);
277
- console.log('Content preview:', content ? content.substring(0, 100) : 'empty');
253
+ // Generate HTML from our virtual node directly using imported renderToString
254
+ const content = renderToString(vnode);
278
255
 
279
256
  // Send complete HTML document with explicit content type
280
257
  res.setHeader('Content-Type', 'text/html');
@@ -17,14 +17,30 @@ export default defineConfig({
17
17
  input: {
18
18
  client: resolve(__dirname, 'src/client.ts')
19
19
  },
20
- output: {
21
- entryFileNames: 'assets/[name].js',
22
- chunkFileNames: 'assets/[name]-[hash].js',
23
- assetFileNames: 'assets/[name]-[hash].[ext]'
24
- }
20
+ output: [
21
+ {
22
+ // ESM output
23
+ entryFileNames: 'assets/[name].mjs',
24
+ chunkFileNames: 'assets/[name]-[hash].mjs',
25
+ assetFileNames: 'assets/[name]-[hash].[ext]',
26
+ format: 'es',
27
+ },
28
+ {
29
+ // CommonJS output
30
+ entryFileNames: 'assets/[name].js',
31
+ chunkFileNames: 'assets/[name]-[hash].js',
32
+ assetFileNames: 'assets/[name]-[hash].[ext]',
33
+ format: 'cjs',
34
+ }
35
+ ]
25
36
  }
26
37
  },
27
38
 
39
+ // Add optimizations for frontend-hamroun
40
+ optimizeDeps: {
41
+ include: ['frontend-hamroun']
42
+ },
43
+
28
44
  // Resolve aliases for better imports
29
45
  resolve: {
30
46
  alias: {
@@ -1,7 +0,0 @@
1
- import { GoWasmInstance, GoWasmOptions } from '../wasm.js';
2
-
3
- export declare function initNodeWasm(): Promise<void>;
4
- export declare function loadGoWasmFromFile(
5
- wasmFilePath: string,
6
- options?: GoWasmOptions
7
- ): Promise<GoWasmInstance>;
package/dist/wasm.d.ts DELETED
@@ -1,37 +0,0 @@
1
- export interface GoWasmInstance {
2
- instance: WebAssembly.Instance;
3
- module: WebAssembly.Module;
4
- exports: any;
5
- functions: Record<string, Function>;
6
- }
7
-
8
- export interface GoWasmOptions {
9
- goWasmPath?: string;
10
- importObject?: WebAssembly.Imports;
11
- loadGo?: boolean;
12
- onLoad?: (instance: GoWasmInstance) => void;
13
- debug?: boolean;
14
- }
15
-
16
- export declare function loadGoWasm(
17
- wasmUrl: string,
18
- options?: GoWasmOptions
19
- ): Promise<GoWasmInstance>;
20
-
21
- export declare function createTypedWasmFunction<T extends (...args: any[]) => any>(
22
- instance: GoWasmInstance,
23
- functionName: string
24
- ): T;
25
-
26
- export declare const goValues: {
27
- stringToGo: (instance: GoWasmInstance, str: string) => number;
28
- stringFromGo: (instance: GoWasmInstance, ptr: number) => string;
29
- objectToGo: (instance: GoWasmInstance, obj: any) => number;
30
- objectFromGo: (instance: GoWasmInstance, ptr: number) => any;
31
- };
32
-
33
- export declare const wasm: {
34
- loadGoWasm: typeof loadGoWasm;
35
- createTypedWasmFunction: typeof createTypedWasmFunction;
36
- goValues: typeof goValues;
37
- };