frontend-hamroun 1.2.74 → 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/Counter.d.ts +0 -0
- 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/hooks-0728361a.cjs +1 -0
- package/dist/hooks-b58f947c.js +133 -0
- package/dist/hooks.js +1 -0
- package/dist/hooks.mjs +13 -0
- package/dist/index.js +1 -384
- package/dist/index.mjs +130 -374
- package/dist/jsx-runtime/package.json +16 -0
- package/dist/jsx-runtime.js +1 -0
- package/dist/jsx-runtime.mjs +64 -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/renderer.js +1 -0
- package/dist/renderer.mjs +27 -0
- package/dist/router/package.json +16 -0
- package/dist/server/package.json +17 -0
- package/dist/server/src/batch.d.ts +3 -0
- package/dist/server/src/batch.js +23 -0
- package/dist/server/src/batch.js.map +1 -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.d.ts +14 -0
- package/dist/server/src/component.js +106 -0
- package/dist/server/src/component.js.map +1 -0
- package/dist/server/src/context.d.ts +13 -0
- package/dist/server/src/context.js +21 -0
- package/dist/server/src/context.js.map +1 -0
- 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.d.ts +12 -0
- package/dist/server/src/hooks.js +170 -0
- package/dist/server/src/hooks.js.map +1 -0
- package/dist/server/src/index.client.d.ts +12 -0
- package/dist/server/src/index.client.js +14 -0
- package/dist/server/src/index.client.js.map +1 -0
- package/dist/server/src/index.d.ts +88 -0
- package/dist/server/src/index.js +78 -0
- package/dist/server/src/index.js.map +1 -0
- package/dist/server/src/jsx-runtime/jsx-dev-runtime.d.ts +1 -0
- package/dist/server/src/jsx-runtime/jsx-dev-runtime.js +2 -0
- package/dist/server/src/jsx-runtime/jsx-dev-runtime.js.map +1 -0
- package/dist/server/src/jsx-runtime/jsx-runtime.d.ts +4 -0
- package/dist/server/src/jsx-runtime/jsx-runtime.js +41 -0
- package/dist/server/src/jsx-runtime/jsx-runtime.js.map +1 -0
- package/dist/server/src/jsx-runtime.d.ts +20 -0
- package/dist/server/src/jsx-runtime.js +105 -0
- package/dist/server/src/jsx-runtime.js.map +1 -0
- 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.d.ts +14 -0
- package/dist/server/src/renderComponent.js +25 -0
- package/dist/server/src/renderComponent.js.map +1 -0
- package/dist/server/src/renderer.d.ts +2 -0
- package/dist/server/src/renderer.js +31 -0
- package/dist/server/src/renderer.js.map +1 -0
- 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/api-router.d.ts +15 -0
- package/dist/server/src/server/api-router.js +111 -0
- package/dist/server/src/server/api-router.js.map +1 -0
- package/dist/server/src/server/auth.d.ts +32 -0
- package/dist/server/src/server/auth.js +80 -0
- package/dist/server/src/server/auth.js.map +1 -0
- package/dist/server/src/server/database.d.ts +24 -0
- package/dist/server/src/server/database.js +135 -0
- package/dist/server/src/server/database.js.map +1 -0
- package/dist/server/src/server/index.d.ts +127 -0
- package/dist/server/src/server/index.js +388 -0
- package/dist/server/src/server/index.js.map +1 -0
- package/dist/server/src/server/middleware.d.ts +11 -0
- package/dist/server/src/server/middleware.js +46 -0
- package/dist/server/src/server/middleware.js.map +1 -0
- package/dist/server/src/server/server.d.ts +9 -0
- package/dist/server/src/server/server.js +87 -0
- package/dist/server/src/server/server.js.map +1 -0
- 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/types.d.ts +38 -0
- package/dist/server/src/server/types.js +4 -0
- package/dist/server/src/server/types.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/wasm.d.ts +9 -0
- package/dist/server/src/server/wasm.js +117 -0
- package/dist/server/src/server/wasm.js.map +1 -0
- package/dist/server/src/server-renderer.d.ts +5 -0
- package/dist/server/src/server-renderer.js +106 -0
- package/dist/server/src/server-renderer.js.map +1 -0
- package/dist/server/src/server-types.d.ts +42 -0
- package/dist/server/src/server-types.js +6 -0
- package/dist/server/src/server-types.js.map +1 -0
- 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/types.d.ts +19 -0
- package/dist/server/src/types.js +2 -0
- package/dist/server/src/types.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/src/vdom.d.ts +8 -0
- package/dist/server/src/vdom.js +22 -0
- package/dist/server/src/vdom.js.map +1 -0
- package/dist/server/src/wasm.d.ts +36 -0
- package/dist/server/src/wasm.js +159 -0
- package/dist/server/src/wasm.js.map +1 -0
- package/dist/server/tsconfig.server.tsbuildinfo +1 -0
- package/dist/server-renderer/package.json +16 -0
- package/dist/server-renderer.js +1 -0
- package/dist/server-renderer.mjs +64 -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/dist/wasm.js +1 -0
- package/dist/wasm.mjs +103 -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/build.sh +43 -43
- package/templates/go/example.go +99 -86
- package/templates/go-wasm-app/babel.config.js +8 -2
- package/templates/go-wasm-app/build-wasm.js +84 -84
- 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 -11
- package/templates/go-wasm-app/public/index.html +49 -53
- package/templates/go-wasm-app/server.js +56 -695
- 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/index.d.ts +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
@@ -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/index.d.ts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
export {}
|
package/dist/index.js.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/batch.ts","../src/hooks.ts","../src/context.ts","../src/jsx-runtime.ts","../src/renderer.ts","../src/server-renderer.ts","../src/index.client.ts"],"sourcesContent":["export let isBatching = false;\r\nconst queue: Function[] = [];\r\n\r\nexport function batchUpdates(fn: Function) {\r\n if (isBatching) {\r\n queue.push(fn);\r\n return;\r\n }\r\n\r\n isBatching = true;\r\n try {\r\n fn();\r\n while (queue.length > 0) {\r\n const nextFn = queue.shift();\r\n nextFn?.();\r\n }\r\n } finally {\r\n isBatching = false;\r\n }\r\n}\r\n\r\nexport function getIsBatching() {\r\n return isBatching;\r\n}\r\n","import { batchUpdates, isBatching } from './batch.js';\r\nimport { HookContext } from './types.js';\r\n\r\nlet currentRender: number = 0;\r\nconst states = new Map<number, any[]>();\r\nconst stateIndices = new Map<number, number>();\r\nconst effects = new Map<number, Effect[]>();\r\nconst memos = new Map<number, { value: any; deps: any[] }[]>();\r\nconst refs = new Map<number, any[]>();\r\n\r\n// Current hook context for the current render\r\nconst currentContext: HookContext = {\r\n hooks: [],\r\n currentHook: 0\r\n};\r\n\r\ninterface Effect {\r\n cleanup?: () => void;\r\n deps?: any[];\r\n}\r\n\r\n// Add at the top with other declarations\r\nlet globalRenderCallback: ((element: any, container: HTMLElement) => void) | null = null;\r\nlet globalContainer: HTMLElement | null = null;\r\nlet currentElement: any = null;\r\n\r\nconst isServer = typeof window === 'undefined';\r\nconst serverStates = new Map<number, any>();\r\n\r\nexport function setRenderCallback(\r\n callback: (element: any, container: HTMLElement) => void,\r\n element: any,\r\n container: HTMLElement\r\n) {\r\n globalRenderCallback = callback;\r\n globalContainer = container;\r\n currentElement = element;\r\n}\r\n\r\nexport function prepareRender() {\r\n // Reset hook index but preserve the hook state\r\n currentContext.currentHook = 0;\r\n currentRender++;\r\n stateIndices.set(currentRender, 0);\r\n return currentRender;\r\n}\r\n\r\nexport function finishRender() {\r\n // Any cleanup needed after rendering\r\n if (isServer) {\r\n serverStates.delete(currentRender);\r\n }\r\n currentRender = 0;\r\n}\r\n\r\nexport function useState<T>(initial: T): [T, (value: T | ((prev: T) => T)) => void] {\r\n if (!currentRender) {\r\n throw new Error('useState must be called within a render');\r\n }\r\n\r\n if (isServer) {\r\n // Server-side state handling\r\n if (!serverStates.has(currentRender)) {\r\n serverStates.set(currentRender, new Map());\r\n }\r\n const componentState = serverStates.get(currentRender)!;\r\n const index = stateIndices.get(currentRender) || 0;\r\n \r\n if (!componentState.has(index)) {\r\n componentState.set(index, initial);\r\n }\r\n\r\n const state = componentState.get(index);\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n // No-op for server-side\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n }\r\n\r\n if (!states.has(currentRender)) {\r\n states.set(currentRender, []);\r\n }\r\n\r\n const componentStates = states.get(currentRender)!;\r\n const index = stateIndices.get(currentRender)!;\r\n \r\n if (index >= componentStates.length) {\r\n componentStates.push(initial);\r\n }\r\n\r\n const state = componentStates[index];\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n const nextValue = typeof newValue === 'function' \r\n ? (newValue as Function)(componentStates[index])\r\n : newValue;\r\n\r\n if (componentStates[index] === nextValue) return; // Skip if value hasn't changed\r\n \r\n componentStates[index] = nextValue;\r\n \r\n if (isBatching) {\r\n batchUpdates(() => rerender(currentRender));\r\n } else {\r\n rerender(currentRender);\r\n }\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n}\r\n\r\nexport function useEffect(callback: () => (() => void) | void, deps?: any[]) {\r\n if (!currentRender) throw new Error('useEffect must be called within a render');\r\n \r\n const effectIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!effects.has(currentRender)) {\r\n effects.set(currentRender, []);\r\n }\r\n\r\n const componentEffects = effects.get(currentRender)!;\r\n const prevEffect = componentEffects[effectIndex];\r\n \r\n // Run effect if deps changed\r\n if (!prevEffect || !deps || !prevEffect.deps || \r\n deps.some((dep, i) => dep !== prevEffect.deps![i])) {\r\n \r\n // Cleanup previous effect\r\n if (prevEffect?.cleanup) {\r\n prevEffect.cleanup();\r\n }\r\n\r\n // Schedule new effect\r\n queueMicrotask(() => {\r\n const cleanup = callback() || undefined;\r\n componentEffects[effectIndex] = { cleanup: cleanup, deps };\r\n });\r\n }\r\n \r\n stateIndices.set(currentRender, effectIndex + 1);\r\n}\r\n\r\nexport function useMemo<T>(factory: () => T, deps: any[]): T {\r\n if (!currentRender) throw new Error('useMemo must be called within a render');\r\n \r\n const memoIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!memos.has(currentRender)) {\r\n memos.set(currentRender, []);\r\n }\r\n\r\n const componentMemos = memos.get(currentRender)!;\r\n const prevMemo = componentMemos[memoIndex];\r\n \r\n if (!prevMemo || (deps && deps.some((dep, i) => !Object.is(dep, prevMemo.deps[i])))) {\r\n const value = factory();\r\n componentMemos[memoIndex] = { value, deps };\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return value;\r\n }\r\n\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return prevMemo.value;\r\n}\r\n\r\nexport function useRef<T>(initial: T) {\r\n if (!currentRender) throw new Error('useRef must be called within a render');\r\n \r\n const refIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!refs.has(currentRender)) {\r\n refs.set(currentRender, []);\r\n }\r\n\r\n const componentRefs = refs.get(currentRender)!;\r\n if (refIndex >= componentRefs.length) {\r\n // Initialize with an object that has a current property\r\n const ref = { current: initial };\r\n componentRefs.push(ref);\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n }\r\n\r\n const ref = componentRefs[refIndex];\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n}\r\n\r\n// Add a map to track component DOM nodes\r\nconst componentNodes = new Map<Function, Node>();\r\n\r\nasync function rerender(rendererId: number) {\r\n try {\r\n // Clean up effects\r\n const componentEffects = effects.get(rendererId);\r\n if (componentEffects) {\r\n componentEffects.forEach(effect => {\r\n if (effect.cleanup) effect.cleanup();\r\n });\r\n effects.set(rendererId, []);\r\n }\r\n\r\n if (globalRenderCallback && globalContainer && currentElement) {\r\n await globalRenderCallback(currentElement, globalContainer);\r\n }\r\n } catch (error) {\r\n console.error('Error during rerender:', error);\r\n }\r\n}\r\n\r\n// Add new hook for error boundaries\r\nexport function useErrorBoundary(): [Error | null, () => void] {\r\n const [error, setError] = useState<Error | null>(null);\r\n return [error, () => setError(null)];\r\n}\r\n\r\n// Remove withHooks export\r\n","/**\r\n * Context API for state sharing between components\r\n */\r\n\r\nconst contexts = new Map<symbol, any>();\r\nlet currentRender: Function | null = null;\r\n\r\n/**\r\n * Interface for context objects\r\n */\r\nexport interface Context<T = any> {\r\n /** \r\n * The display name of the context \r\n */\r\n displayName?: string;\r\n \r\n /** \r\n * The current context value \r\n */\r\n currentValue: T;\r\n \r\n /**\r\n * Providers using this context\r\n */\r\n providers: Set<any>;\r\n}\r\n\r\n/**\r\n * Creates a context object with the specified default value\r\n * @param defaultValue The default value for the context\r\n */\r\nexport function createContext<T>(defaultValue: T): Context<T> {\r\n const context: Context<T> = {\r\n currentValue: defaultValue,\r\n providers: new Set()\r\n };\r\n \r\n return context;\r\n}\r\n\r\n/**\r\n * Get the current value of a context\r\n * @param context The context object\r\n */\r\nexport function useContext<T>(context: Context<T>): T {\r\n // In a real implementation, this would check for providers up the component tree\r\n return context.currentValue;\r\n}\r\n","// src/hooks.ts\r\ninterface VNode {\r\n type: string | Function;\r\n props: Record<string, any>;\r\n}\r\n\r\nfunction jsx(type: string | Function, props: any): VNode {\r\n console.log('JSX Transform:', { type, props });\r\n const processedProps = { ...props };\r\n \r\n // Handle children properly\r\n if (arguments.length > 2) {\r\n processedProps.children = Array.prototype.slice.call(arguments, 2);\r\n }\r\n \r\n return { type, props: processedProps };\r\n}\r\n\r\nconst Fragment = ({ children }: { children: any }) => children;\r\n\r\nasync function createElement(vnode: VNode | any): Promise<Node> {\r\n console.log('Creating element from:', vnode);\r\n\r\n // Handle primitives and null\r\n if (vnode == null) {\r\n return document.createTextNode('');\r\n }\r\n \r\n if (typeof vnode === 'boolean') {\r\n return document.createTextNode('');\r\n }\r\n\r\n if (typeof vnode === 'number' || typeof vnode === 'string') {\r\n return document.createTextNode(String(vnode));\r\n }\r\n\r\n // Handle arrays\r\n if (Array.isArray(vnode)) {\r\n const fragment = document.createDocumentFragment();\r\n for (const child of vnode) {\r\n const node = await createElement(child);\r\n fragment.appendChild(node);\r\n }\r\n return fragment;\r\n }\r\n\r\n // Handle VNode\r\n if ('type' in vnode && vnode.props !== undefined) {\r\n const { type, props } = vnode;\r\n \r\n // Handle function components\r\n if (typeof type === 'function') {\r\n try {\r\n const result = await type(props || {});\r\n const node = await createElement(result);\r\n if (node instanceof Element) {\r\n node.setAttribute('data-component-id', type.name || type.toString());\r\n }\r\n return node;\r\n } catch (error) {\r\n console.error('Error rendering component:', error);\r\n return document.createTextNode('');\r\n }\r\n }\r\n\r\n // Create DOM element\r\n const element = document.createElement(type as string);\r\n \r\n // Handle props\r\n for (const [key, value] of Object.entries(props || {})) {\r\n if (key === 'children') continue;\r\n if (key.startsWith('on') && typeof value === 'function') {\r\n const eventName = key.toLowerCase().slice(2);\r\n // Remove existing event listener if any\r\n const existingHandler = (element as any).__events?.[eventName];\r\n if (existingHandler) {\r\n element.removeEventListener(eventName, existingHandler);\r\n }\r\n \r\n // Add new event listener\r\n element.addEventListener(eventName, value as EventListener);\r\n if (!(element as any).__events) {\r\n (element as any).__events = {};\r\n }\r\n (element as any).__events[eventName] = value;\r\n } else if (key === 'style' && typeof value === 'object') {\r\n Object.assign(element.style, value);\r\n } else if (key === 'className') {\r\n element.setAttribute('class', String(value));\r\n } else if (key !== 'key' && key !== 'ref') {\r\n element.setAttribute(key, String(value));\r\n }\r\n }\r\n\r\n // Handle children\r\n const children = props?.children;\r\n if (children != null) {\r\n const childArray = Array.isArray(children) ? children.flat() : [children];\r\n for (const child of childArray) {\r\n const childNode = await createElement(child);\r\n element.appendChild(childNode);\r\n }\r\n }\r\n\r\n return element;\r\n }\r\n\r\n // Handle other objects by converting to string\r\n return document.createTextNode(String(vnode));\r\n}\r\n\r\n// Export named functions and aliases without duplicates\r\nexport {\r\n jsx,\r\n jsx as jsxs,\r\n jsx as jsxDEV,\r\n Fragment,\r\n createElement\r\n};\r\n\r\n// Named exports object\r\nconst jsxRuntime = {\r\n jsx,\r\n jsxs: jsx,\r\n jsxDEV: jsx,\r\n Fragment,\r\n createElement\r\n};\r\n\r\nexport default jsxRuntime;\r\n","import { createElement } from './jsx-runtime.js';\r\nimport { prepareRender, finishRender, setRenderCallback } from './hooks.js';\r\nimport { batchUpdates } from './batch.js';\r\n\r\nlet isHydrating = false;\r\n\r\nexport async function hydrate(element: any, container: HTMLElement) {\r\n isHydrating = true;\r\n try {\r\n await render(element, container);\r\n } finally {\r\n isHydrating = false;\r\n }\r\n}\r\n\r\nexport async function render(element: any, container: HTMLElement) {\r\n console.log('Rendering to:', container.id);\r\n \r\n batchUpdates(async () => {\r\n const rendererId = prepareRender();\r\n try {\r\n setRenderCallback(render, element, container);\r\n const domNode = await createElement(element);\r\n \r\n if (!isHydrating) {\r\n container.innerHTML = '';\r\n }\r\n container.appendChild(domNode);\r\n \r\n } finally {\r\n finishRender();\r\n }\r\n });\r\n}\r\n","import { VNode, Component } from './types.js';\r\nimport { prepareRender, finishRender } from './hooks.js';\r\n\r\n/**\r\n * Renders a virtual DOM tree to an HTML string\r\n */\r\nexport function renderToString(vnode: VNode): string {\r\n // Reset hook state for this render\r\n prepareRender();\r\n \r\n // Render the tree to HTML\r\n const html = renderNodeToString(vnode);\r\n \r\n // Clean up after rendering\r\n finishRender();\r\n \r\n return html;\r\n}\r\n\r\n/**\r\n * Internal function to convert a virtual node to an HTML string\r\n */\r\nfunction renderNodeToString(vnode: VNode | string | number | boolean | null | undefined): string {\r\n // Handle primitive values\r\n if (vnode === null || vnode === undefined) return '';\r\n if (typeof vnode === 'boolean') return '';\r\n if (typeof vnode === 'number' || typeof vnode === 'string') return escapeHtml(String(vnode));\r\n \r\n // Handle function components\r\n if (typeof vnode.type === 'function') {\r\n const Component = vnode.type as Component;\r\n const renderedNode = Component(vnode.props || {});\r\n return renderNodeToString(renderedNode);\r\n }\r\n \r\n // Handle intrinsic elements (regular HTML tags)\r\n if (typeof vnode.type === 'string') {\r\n const tag = vnode.type;\r\n let attrs = '';\r\n let children = '';\r\n \r\n // Convert props to HTML attributes\r\n if (vnode.props) {\r\n for (const [key, value] of Object.entries(vnode.props)) {\r\n // Skip children prop as we handle it separately\r\n if (key === 'children') continue;\r\n \r\n // Skip event handlers (they start with 'on')\r\n if (key.startsWith('on')) continue;\r\n \r\n // Handle the className prop specially\r\n if (key === 'className') {\r\n attrs += ` class=\"${escapeHtml(value as string)}\"`;\r\n continue;\r\n }\r\n \r\n // Handle other attributes\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n attrs += ` ${key}=\"${escapeHtml(String(value))}\"`;\r\n } else if (value === true) {\r\n // Boolean attributes\r\n attrs += ` ${key}`;\r\n }\r\n }\r\n }\r\n \r\n // Process children\r\n const childrenArray = (vnode.props?.children) \r\n ? Array.isArray(vnode.props.children) \r\n ? vnode.props.children \r\n : [vnode.props.children]\r\n : [];\r\n \r\n for (const child of childrenArray) {\r\n children += renderNodeToString(child);\r\n }\r\n \r\n // Self-closing tags\r\n const selfClosing = [\r\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\r\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\r\n ];\r\n \r\n if (selfClosing.includes(tag)) {\r\n return `<${tag}${attrs}/>`;\r\n }\r\n \r\n // Regular tags with closing\r\n return `<${tag}${attrs}>${children}</${tag}>`;\r\n }\r\n \r\n // Handle fragments\r\n if (vnode.type === Symbol.for('react.fragment')) {\r\n let fragmentOutput = '';\r\n const children = Array.isArray(vnode.props?.children)\r\n ? vnode.props.children\r\n : vnode.props?.children ? [vnode.props.children] : [];\r\n \r\n for (const child of children) {\r\n fragmentOutput += renderNodeToString(child);\r\n }\r\n \r\n return fragmentOutput;\r\n }\r\n \r\n // Fallback for unknown node types\r\n console.warn('Unknown vnode type:', vnode.type);\r\n return '';\r\n}\r\n\r\n/**\r\n * Escape HTML special characters to prevent XSS\r\n */\r\nfunction escapeHtml(text: string): string {\r\n return text\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n}\r\n","\r\nexport { \r\n useState, \r\n useEffect, \r\n useMemo, \r\n useRef,\r\n useErrorBoundary \r\n} from './hooks.js';\r\n\r\nexport { createContext, useContext } from './context.js';\r\nexport { batchUpdates } from './batch.js';\r\nexport { jsx, jsxs, Fragment } from './jsx-runtime.js';\r\nexport { render, hydrate } from './renderer.js';\r\nexport { renderToString } from './server-renderer.js';\r\n\r\n// Re-export types for client-side usage\r\nexport type { Context } from './context.js';\r\nexport type { VNode } from './types.js';\r\n\r\n// Export server types for type checking\r\nexport type {\r\n Server,\r\n ServerConfig,\r\n User,\r\n DbConfig,\r\n MiddlewareFunction\r\n} from './server-types.js';\r\n\r\n// Provide placeholder server functionality\r\nexport const server = {\r\n async getServer() {\r\n throw new Error('Server module can only be used in Node.js environment');\r\n }\r\n};\r\n\r\nlet isHydrating = false;\r\n"],"names":["index","state","setState","ref","Component"],"mappings":"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"}
|
package/dist/index.mjs.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/batch.ts","../src/hooks.ts","../src/context.ts","../src/jsx-runtime.ts","../src/renderer.ts","../src/server-renderer.ts","../src/index.client.ts"],"sourcesContent":["export let isBatching = false;\r\nconst queue: Function[] = [];\r\n\r\nexport function batchUpdates(fn: Function) {\r\n if (isBatching) {\r\n queue.push(fn);\r\n return;\r\n }\r\n\r\n isBatching = true;\r\n try {\r\n fn();\r\n while (queue.length > 0) {\r\n const nextFn = queue.shift();\r\n nextFn?.();\r\n }\r\n } finally {\r\n isBatching = false;\r\n }\r\n}\r\n\r\nexport function getIsBatching() {\r\n return isBatching;\r\n}\r\n","import { batchUpdates, isBatching } from './batch.js';\r\nimport { HookContext } from './types.js';\r\n\r\nlet currentRender: number = 0;\r\nconst states = new Map<number, any[]>();\r\nconst stateIndices = new Map<number, number>();\r\nconst effects = new Map<number, Effect[]>();\r\nconst memos = new Map<number, { value: any; deps: any[] }[]>();\r\nconst refs = new Map<number, any[]>();\r\n\r\n// Current hook context for the current render\r\nconst currentContext: HookContext = {\r\n hooks: [],\r\n currentHook: 0\r\n};\r\n\r\ninterface Effect {\r\n cleanup?: () => void;\r\n deps?: any[];\r\n}\r\n\r\n// Add at the top with other declarations\r\nlet globalRenderCallback: ((element: any, container: HTMLElement) => void) | null = null;\r\nlet globalContainer: HTMLElement | null = null;\r\nlet currentElement: any = null;\r\n\r\nconst isServer = typeof window === 'undefined';\r\nconst serverStates = new Map<number, any>();\r\n\r\nexport function setRenderCallback(\r\n callback: (element: any, container: HTMLElement) => void,\r\n element: any,\r\n container: HTMLElement\r\n) {\r\n globalRenderCallback = callback;\r\n globalContainer = container;\r\n currentElement = element;\r\n}\r\n\r\nexport function prepareRender() {\r\n // Reset hook index but preserve the hook state\r\n currentContext.currentHook = 0;\r\n currentRender++;\r\n stateIndices.set(currentRender, 0);\r\n return currentRender;\r\n}\r\n\r\nexport function finishRender() {\r\n // Any cleanup needed after rendering\r\n if (isServer) {\r\n serverStates.delete(currentRender);\r\n }\r\n currentRender = 0;\r\n}\r\n\r\nexport function useState<T>(initial: T): [T, (value: T | ((prev: T) => T)) => void] {\r\n if (!currentRender) {\r\n throw new Error('useState must be called within a render');\r\n }\r\n\r\n if (isServer) {\r\n // Server-side state handling\r\n if (!serverStates.has(currentRender)) {\r\n serverStates.set(currentRender, new Map());\r\n }\r\n const componentState = serverStates.get(currentRender)!;\r\n const index = stateIndices.get(currentRender) || 0;\r\n \r\n if (!componentState.has(index)) {\r\n componentState.set(index, initial);\r\n }\r\n\r\n const state = componentState.get(index);\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n // No-op for server-side\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n }\r\n\r\n if (!states.has(currentRender)) {\r\n states.set(currentRender, []);\r\n }\r\n\r\n const componentStates = states.get(currentRender)!;\r\n const index = stateIndices.get(currentRender)!;\r\n \r\n if (index >= componentStates.length) {\r\n componentStates.push(initial);\r\n }\r\n\r\n const state = componentStates[index];\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n const nextValue = typeof newValue === 'function' \r\n ? (newValue as Function)(componentStates[index])\r\n : newValue;\r\n\r\n if (componentStates[index] === nextValue) return; // Skip if value hasn't changed\r\n \r\n componentStates[index] = nextValue;\r\n \r\n if (isBatching) {\r\n batchUpdates(() => rerender(currentRender));\r\n } else {\r\n rerender(currentRender);\r\n }\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n}\r\n\r\nexport function useEffect(callback: () => (() => void) | void, deps?: any[]) {\r\n if (!currentRender) throw new Error('useEffect must be called within a render');\r\n \r\n const effectIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!effects.has(currentRender)) {\r\n effects.set(currentRender, []);\r\n }\r\n\r\n const componentEffects = effects.get(currentRender)!;\r\n const prevEffect = componentEffects[effectIndex];\r\n \r\n // Run effect if deps changed\r\n if (!prevEffect || !deps || !prevEffect.deps || \r\n deps.some((dep, i) => dep !== prevEffect.deps![i])) {\r\n \r\n // Cleanup previous effect\r\n if (prevEffect?.cleanup) {\r\n prevEffect.cleanup();\r\n }\r\n\r\n // Schedule new effect\r\n queueMicrotask(() => {\r\n const cleanup = callback() || undefined;\r\n componentEffects[effectIndex] = { cleanup: cleanup, deps };\r\n });\r\n }\r\n \r\n stateIndices.set(currentRender, effectIndex + 1);\r\n}\r\n\r\nexport function useMemo<T>(factory: () => T, deps: any[]): T {\r\n if (!currentRender) throw new Error('useMemo must be called within a render');\r\n \r\n const memoIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!memos.has(currentRender)) {\r\n memos.set(currentRender, []);\r\n }\r\n\r\n const componentMemos = memos.get(currentRender)!;\r\n const prevMemo = componentMemos[memoIndex];\r\n \r\n if (!prevMemo || (deps && deps.some((dep, i) => !Object.is(dep, prevMemo.deps[i])))) {\r\n const value = factory();\r\n componentMemos[memoIndex] = { value, deps };\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return value;\r\n }\r\n\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return prevMemo.value;\r\n}\r\n\r\nexport function useRef<T>(initial: T) {\r\n if (!currentRender) throw new Error('useRef must be called within a render');\r\n \r\n const refIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!refs.has(currentRender)) {\r\n refs.set(currentRender, []);\r\n }\r\n\r\n const componentRefs = refs.get(currentRender)!;\r\n if (refIndex >= componentRefs.length) {\r\n // Initialize with an object that has a current property\r\n const ref = { current: initial };\r\n componentRefs.push(ref);\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n }\r\n\r\n const ref = componentRefs[refIndex];\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n}\r\n\r\n// Add a map to track component DOM nodes\r\nconst componentNodes = new Map<Function, Node>();\r\n\r\nasync function rerender(rendererId: number) {\r\n try {\r\n // Clean up effects\r\n const componentEffects = effects.get(rendererId);\r\n if (componentEffects) {\r\n componentEffects.forEach(effect => {\r\n if (effect.cleanup) effect.cleanup();\r\n });\r\n effects.set(rendererId, []);\r\n }\r\n\r\n if (globalRenderCallback && globalContainer && currentElement) {\r\n await globalRenderCallback(currentElement, globalContainer);\r\n }\r\n } catch (error) {\r\n console.error('Error during rerender:', error);\r\n }\r\n}\r\n\r\n// Add new hook for error boundaries\r\nexport function useErrorBoundary(): [Error | null, () => void] {\r\n const [error, setError] = useState<Error | null>(null);\r\n return [error, () => setError(null)];\r\n}\r\n\r\n// Remove withHooks export\r\n","/**\r\n * Context API for state sharing between components\r\n */\r\n\r\nconst contexts = new Map<symbol, any>();\r\nlet currentRender: Function | null = null;\r\n\r\n/**\r\n * Interface for context objects\r\n */\r\nexport interface Context<T = any> {\r\n /** \r\n * The display name of the context \r\n */\r\n displayName?: string;\r\n \r\n /** \r\n * The current context value \r\n */\r\n currentValue: T;\r\n \r\n /**\r\n * Providers using this context\r\n */\r\n providers: Set<any>;\r\n}\r\n\r\n/**\r\n * Creates a context object with the specified default value\r\n * @param defaultValue The default value for the context\r\n */\r\nexport function createContext<T>(defaultValue: T): Context<T> {\r\n const context: Context<T> = {\r\n currentValue: defaultValue,\r\n providers: new Set()\r\n };\r\n \r\n return context;\r\n}\r\n\r\n/**\r\n * Get the current value of a context\r\n * @param context The context object\r\n */\r\nexport function useContext<T>(context: Context<T>): T {\r\n // In a real implementation, this would check for providers up the component tree\r\n return context.currentValue;\r\n}\r\n","// src/hooks.ts\r\ninterface VNode {\r\n type: string | Function;\r\n props: Record<string, any>;\r\n}\r\n\r\nfunction jsx(type: string | Function, props: any): VNode {\r\n console.log('JSX Transform:', { type, props });\r\n const processedProps = { ...props };\r\n \r\n // Handle children properly\r\n if (arguments.length > 2) {\r\n processedProps.children = Array.prototype.slice.call(arguments, 2);\r\n }\r\n \r\n return { type, props: processedProps };\r\n}\r\n\r\nconst Fragment = ({ children }: { children: any }) => children;\r\n\r\nasync function createElement(vnode: VNode | any): Promise<Node> {\r\n console.log('Creating element from:', vnode);\r\n\r\n // Handle primitives and null\r\n if (vnode == null) {\r\n return document.createTextNode('');\r\n }\r\n \r\n if (typeof vnode === 'boolean') {\r\n return document.createTextNode('');\r\n }\r\n\r\n if (typeof vnode === 'number' || typeof vnode === 'string') {\r\n return document.createTextNode(String(vnode));\r\n }\r\n\r\n // Handle arrays\r\n if (Array.isArray(vnode)) {\r\n const fragment = document.createDocumentFragment();\r\n for (const child of vnode) {\r\n const node = await createElement(child);\r\n fragment.appendChild(node);\r\n }\r\n return fragment;\r\n }\r\n\r\n // Handle VNode\r\n if ('type' in vnode && vnode.props !== undefined) {\r\n const { type, props } = vnode;\r\n \r\n // Handle function components\r\n if (typeof type === 'function') {\r\n try {\r\n const result = await type(props || {});\r\n const node = await createElement(result);\r\n if (node instanceof Element) {\r\n node.setAttribute('data-component-id', type.name || type.toString());\r\n }\r\n return node;\r\n } catch (error) {\r\n console.error('Error rendering component:', error);\r\n return document.createTextNode('');\r\n }\r\n }\r\n\r\n // Create DOM element\r\n const element = document.createElement(type as string);\r\n \r\n // Handle props\r\n for (const [key, value] of Object.entries(props || {})) {\r\n if (key === 'children') continue;\r\n if (key.startsWith('on') && typeof value === 'function') {\r\n const eventName = key.toLowerCase().slice(2);\r\n // Remove existing event listener if any\r\n const existingHandler = (element as any).__events?.[eventName];\r\n if (existingHandler) {\r\n element.removeEventListener(eventName, existingHandler);\r\n }\r\n \r\n // Add new event listener\r\n element.addEventListener(eventName, value as EventListener);\r\n if (!(element as any).__events) {\r\n (element as any).__events = {};\r\n }\r\n (element as any).__events[eventName] = value;\r\n } else if (key === 'style' && typeof value === 'object') {\r\n Object.assign(element.style, value);\r\n } else if (key === 'className') {\r\n element.setAttribute('class', String(value));\r\n } else if (key !== 'key' && key !== 'ref') {\r\n element.setAttribute(key, String(value));\r\n }\r\n }\r\n\r\n // Handle children\r\n const children = props?.children;\r\n if (children != null) {\r\n const childArray = Array.isArray(children) ? children.flat() : [children];\r\n for (const child of childArray) {\r\n const childNode = await createElement(child);\r\n element.appendChild(childNode);\r\n }\r\n }\r\n\r\n return element;\r\n }\r\n\r\n // Handle other objects by converting to string\r\n return document.createTextNode(String(vnode));\r\n}\r\n\r\n// Export named functions and aliases without duplicates\r\nexport {\r\n jsx,\r\n jsx as jsxs,\r\n jsx as jsxDEV,\r\n Fragment,\r\n createElement\r\n};\r\n\r\n// Named exports object\r\nconst jsxRuntime = {\r\n jsx,\r\n jsxs: jsx,\r\n jsxDEV: jsx,\r\n Fragment,\r\n createElement\r\n};\r\n\r\nexport default jsxRuntime;\r\n","import { createElement } from './jsx-runtime.js';\r\nimport { prepareRender, finishRender, setRenderCallback } from './hooks.js';\r\nimport { batchUpdates } from './batch.js';\r\n\r\nlet isHydrating = false;\r\n\r\nexport async function hydrate(element: any, container: HTMLElement) {\r\n isHydrating = true;\r\n try {\r\n await render(element, container);\r\n } finally {\r\n isHydrating = false;\r\n }\r\n}\r\n\r\nexport async function render(element: any, container: HTMLElement) {\r\n console.log('Rendering to:', container.id);\r\n \r\n batchUpdates(async () => {\r\n const rendererId = prepareRender();\r\n try {\r\n setRenderCallback(render, element, container);\r\n const domNode = await createElement(element);\r\n \r\n if (!isHydrating) {\r\n container.innerHTML = '';\r\n }\r\n container.appendChild(domNode);\r\n \r\n } finally {\r\n finishRender();\r\n }\r\n });\r\n}\r\n","import { VNode, Component } from './types.js';\r\nimport { prepareRender, finishRender } from './hooks.js';\r\n\r\n/**\r\n * Renders a virtual DOM tree to an HTML string\r\n */\r\nexport function renderToString(vnode: VNode): string {\r\n // Reset hook state for this render\r\n prepareRender();\r\n \r\n // Render the tree to HTML\r\n const html = renderNodeToString(vnode);\r\n \r\n // Clean up after rendering\r\n finishRender();\r\n \r\n return html;\r\n}\r\n\r\n/**\r\n * Internal function to convert a virtual node to an HTML string\r\n */\r\nfunction renderNodeToString(vnode: VNode | string | number | boolean | null | undefined): string {\r\n // Handle primitive values\r\n if (vnode === null || vnode === undefined) return '';\r\n if (typeof vnode === 'boolean') return '';\r\n if (typeof vnode === 'number' || typeof vnode === 'string') return escapeHtml(String(vnode));\r\n \r\n // Handle function components\r\n if (typeof vnode.type === 'function') {\r\n const Component = vnode.type as Component;\r\n const renderedNode = Component(vnode.props || {});\r\n return renderNodeToString(renderedNode);\r\n }\r\n \r\n // Handle intrinsic elements (regular HTML tags)\r\n if (typeof vnode.type === 'string') {\r\n const tag = vnode.type;\r\n let attrs = '';\r\n let children = '';\r\n \r\n // Convert props to HTML attributes\r\n if (vnode.props) {\r\n for (const [key, value] of Object.entries(vnode.props)) {\r\n // Skip children prop as we handle it separately\r\n if (key === 'children') continue;\r\n \r\n // Skip event handlers (they start with 'on')\r\n if (key.startsWith('on')) continue;\r\n \r\n // Handle the className prop specially\r\n if (key === 'className') {\r\n attrs += ` class=\"${escapeHtml(value as string)}\"`;\r\n continue;\r\n }\r\n \r\n // Handle other attributes\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n attrs += ` ${key}=\"${escapeHtml(String(value))}\"`;\r\n } else if (value === true) {\r\n // Boolean attributes\r\n attrs += ` ${key}`;\r\n }\r\n }\r\n }\r\n \r\n // Process children\r\n const childrenArray = (vnode.props?.children) \r\n ? Array.isArray(vnode.props.children) \r\n ? vnode.props.children \r\n : [vnode.props.children]\r\n : [];\r\n \r\n for (const child of childrenArray) {\r\n children += renderNodeToString(child);\r\n }\r\n \r\n // Self-closing tags\r\n const selfClosing = [\r\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\r\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\r\n ];\r\n \r\n if (selfClosing.includes(tag)) {\r\n return `<${tag}${attrs}/>`;\r\n }\r\n \r\n // Regular tags with closing\r\n return `<${tag}${attrs}>${children}</${tag}>`;\r\n }\r\n \r\n // Handle fragments\r\n if (vnode.type === Symbol.for('react.fragment')) {\r\n let fragmentOutput = '';\r\n const children = Array.isArray(vnode.props?.children)\r\n ? vnode.props.children\r\n : vnode.props?.children ? [vnode.props.children] : [];\r\n \r\n for (const child of children) {\r\n fragmentOutput += renderNodeToString(child);\r\n }\r\n \r\n return fragmentOutput;\r\n }\r\n \r\n // Fallback for unknown node types\r\n console.warn('Unknown vnode type:', vnode.type);\r\n return '';\r\n}\r\n\r\n/**\r\n * Escape HTML special characters to prevent XSS\r\n */\r\nfunction escapeHtml(text: string): string {\r\n return text\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n}\r\n","\r\nexport { \r\n useState, \r\n useEffect, \r\n useMemo, \r\n useRef,\r\n useErrorBoundary \r\n} from './hooks.js';\r\n\r\nexport { createContext, useContext } from './context.js';\r\nexport { batchUpdates } from './batch.js';\r\nexport { jsx, jsxs, Fragment } from './jsx-runtime.js';\r\nexport { render, hydrate } from './renderer.js';\r\nexport { renderToString } from './server-renderer.js';\r\n\r\n// Re-export types for client-side usage\r\nexport type { Context } from './context.js';\r\nexport type { VNode } from './types.js';\r\n\r\n// Export server types for type checking\r\nexport type {\r\n Server,\r\n ServerConfig,\r\n User,\r\n DbConfig,\r\n MiddlewareFunction\r\n} from './server-types.js';\r\n\r\n// Provide placeholder server functionality\r\nexport const server = {\r\n async getServer() {\r\n throw new Error('Server module can only be used in Node.js environment');\r\n }\r\n};\r\n\r\nlet isHydrating = false;\r\n"],"names":["index","state","setState","ref","Component"],"mappings":"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"}
|