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.
- package/dist/batch/package.json +16 -0
- package/dist/client-router/package.json +16 -0
- package/dist/component/package.json +16 -0
- package/dist/context/package.json +16 -0
- package/dist/event-bus/package.json +16 -0
- package/dist/forms/package.json +16 -0
- package/dist/hooks/package.json +16 -0
- package/dist/jsx-runtime/package.json +16 -0
- package/dist/lifecycle-events/package.json +16 -0
- package/dist/package.json +71 -0
- package/dist/render-component/package.json +16 -0
- package/dist/renderer/package.json +16 -0
- package/dist/router/package.json +16 -0
- package/dist/server/package.json +17 -0
- package/dist/server/src/client-router.d.ts +60 -0
- package/dist/server/src/client-router.js +210 -0
- package/dist/server/src/client-router.js.map +1 -0
- package/dist/server/src/component.js +1 -1
- package/dist/server/src/event-bus.d.ts +23 -0
- package/dist/server/src/event-bus.js +75 -0
- package/dist/server/src/event-bus.js.map +1 -0
- package/dist/server/src/forms.d.ts +40 -0
- package/dist/server/src/forms.js +148 -0
- package/dist/server/src/forms.js.map +1 -0
- package/dist/server/src/hooks.js +2 -2
- package/dist/server/src/index.js +19 -11
- package/dist/server/src/lifecycle-events.d.ts +108 -0
- package/dist/server/src/lifecycle-events.js +177 -0
- package/dist/server/src/lifecycle-events.js.map +1 -0
- package/dist/server/src/renderComponent.js +1 -1
- package/dist/server/src/renderer.js +3 -3
- package/dist/server/src/router.d.ts +55 -0
- package/dist/server/src/router.js +166 -0
- package/dist/server/src/router.js.map +1 -0
- package/dist/server/src/server/index.d.ts +75 -2
- package/dist/server/src/server/index.js +224 -8
- package/dist/server/src/server/index.js.map +1 -1
- package/dist/server/src/server/server.js +1 -1
- package/dist/server/src/server/templates.d.ts +28 -0
- package/dist/server/src/server/templates.js +204 -0
- package/dist/server/src/server/templates.js.map +1 -0
- package/dist/server/src/server/utils.d.ts +70 -0
- package/dist/server/src/server/utils.js +156 -0
- package/dist/server/src/server/utils.js.map +1 -0
- package/dist/server/src/server-renderer.js +1 -1
- package/dist/server/src/store.d.ts +41 -0
- package/dist/server/src/store.js +99 -0
- package/dist/server/src/store.js.map +1 -0
- package/dist/server/src/utils.d.ts +46 -0
- package/dist/server/src/utils.js +144 -0
- package/dist/server/src/utils.js.map +1 -0
- package/dist/server/tsconfig.server.tsbuildinfo +1 -1
- package/dist/server-renderer/package.json +16 -0
- package/dist/store/package.json +16 -0
- package/dist/types/package.json +16 -0
- package/dist/utils/package.json +16 -0
- package/dist/vdom/package.json +16 -0
- package/dist/wasm/package.json +16 -0
- package/package.json +14 -13
- package/templates/complete-app/build.js +284 -0
- package/templates/complete-app/package.json +40 -0
- package/templates/complete-app/public/styles.css +345 -0
- package/templates/complete-app/src/api/index.js +31 -0
- package/templates/complete-app/src/client.js +93 -0
- package/templates/complete-app/src/components/App.js +66 -0
- package/templates/complete-app/src/components/Footer.js +19 -0
- package/templates/complete-app/src/components/Header.js +38 -0
- package/templates/complete-app/src/pages/About.js +59 -0
- package/templates/complete-app/src/pages/Home.js +54 -0
- package/templates/complete-app/src/pages/WasmDemo.js +136 -0
- package/templates/complete-app/src/server.js +186 -0
- package/templates/complete-app/src/wasm/build.bat +16 -0
- package/templates/complete-app/src/wasm/build.sh +16 -0
- package/templates/complete-app/src/wasm/example.go +101 -0
- package/templates/fullstack-app/build/main.css +225 -15
- package/templates/fullstack-app/build/main.css.map +2 -2
- package/templates/fullstack-app/build/main.js +657 -372
- package/templates/fullstack-app/build/main.js.map +4 -4
- package/templates/fullstack-app/build.ts +3 -4
- package/templates/fullstack-app/public/styles.css +222 -15
- package/templates/fullstack-app/server.ts +46 -12
- package/templates/fullstack-app/src/components/ClientHome.tsx +0 -0
- package/templates/fullstack-app/src/components/ErrorBoundary.tsx +36 -0
- package/templates/fullstack-app/src/components/Layout.tsx +23 -26
- package/templates/fullstack-app/src/components/StateDemo.tsx +207 -0
- package/templates/fullstack-app/src/components/UserList.tsx +30 -13
- package/templates/fullstack-app/src/data/api.ts +173 -38
- package/templates/fullstack-app/src/main.tsx +88 -154
- package/templates/fullstack-app/src/middleware.ts +28 -0
- package/templates/fullstack-app/src/pages/404.tsx +28 -0
- package/templates/fullstack-app/src/pages/[id].tsx +0 -0
- package/templates/fullstack-app/src/pages/_app.tsx +11 -0
- package/templates/fullstack-app/src/pages/_document.tsx +25 -0
- package/templates/fullstack-app/src/pages/_error.tsx +45 -0
- package/templates/fullstack-app/src/pages/about.tsx +71 -0
- package/templates/fullstack-app/src/pages/api/users/[id].ts +73 -0
- package/templates/fullstack-app/src/pages/api/users/index.ts +43 -0
- package/templates/fullstack-app/src/pages/index.tsx +97 -20
- package/templates/fullstack-app/src/pages/users/[id].tsx +153 -0
- package/templates/fullstack-app/src/pages/wasm-demo.tsx +1 -0
- package/templates/go/example.go +99 -86
- package/templates/go-wasm-app/babel.config.js +8 -2
- package/templates/go-wasm-app/build.config.js +62 -0
- package/templates/go-wasm-app/build.js +218 -0
- package/templates/go-wasm-app/package.json +21 -12
- package/templates/go-wasm-app/server.js +59 -510
- package/templates/go-wasm-app/src/app.js +173 -0
- package/templates/go-wasm-app/vite.config.js +16 -5
- package/templates/ssr-template/client.js +54 -26
- package/templates/ssr-template/server.js +5 -28
- package/templates/ssr-template/vite.config.js +21 -5
- package/dist/server/wasm.d.ts +0 -7
- 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
|
-
|
22
|
-
|
23
|
-
|
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
|
-
//
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
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
|
-
//
|
30
|
-
|
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
|
250
|
+
console.log('Fetching meta tags for the page...');
|
252
251
|
const metaTags = await generateMetaTags(contentForMetaTags);
|
253
252
|
|
254
|
-
//
|
255
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
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: {
|
package/dist/server/wasm.d.ts
DELETED
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
|
-
};
|