frontend-hamroun 1.2.80 → 1.2.83
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/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.client.cjs +1 -1
- package/dist/index.client.js +2 -2
- package/dist/index.js +11 -7
- package/dist/index.js.map +1 -1
- package/dist/{renderer-Din1y3YM.cjs → renderer-BL3gq8cW.cjs} +2 -2
- package/dist/{renderer-Din1y3YM.cjs.map → renderer-BL3gq8cW.cjs.map} +1 -1
- package/dist/{renderer-Bo9zkUZ_.js → renderer-Dyy-o05F.js} +2 -2
- package/dist/{renderer-Bo9zkUZ_.js.map → renderer-Dyy-o05F.js.map} +1 -1
- package/dist/{server-renderer-QHt45Ip2.js → server-renderer-C1WXH-zV.js} +99 -73
- package/dist/server-renderer-C1WXH-zV.js.map +1 -0
- package/dist/server-renderer-Chs-nmJm.cjs +2 -0
- package/dist/server-renderer-Chs-nmJm.cjs.map +1 -0
- package/dist/server-renderer.cjs +1 -1
- package/dist/server-renderer.js +1 -1
- package/package.json +1 -1
- package/templates/basic-app/src/App.jsx +16 -0
- package/templates/basic-app/src/client.jsx +5 -0
- package/templates/basic-app/src/components/Counter.jsx +13 -0
- package/templates/basic-app/src/jsx-shim.js +3 -0
- package/templates/basic-app/src/jsx-shim.ts +7 -0
- package/templates/basic-app/src/main.jsx +98 -0
- package/templates/basic-app/src/server.js +47 -0
- package/templates/complete-app/api/hello.js +0 -0
- package/templates/complete-app/lib/frontend-hamroun.js +182 -0
- package/templates/complete-app/package.json +18 -0
- package/templates/complete-app/pages/about.js +119 -0
- package/templates/complete-app/pages/about.jsx +0 -0
- package/templates/complete-app/pages/index.js +157 -0
- package/templates/complete-app/pages/index.jsx +0 -0
- package/templates/complete-app/pages/wasm-demo.js +290 -0
- package/templates/complete-app/pages/wasm-demo.jsx +0 -0
- package/templates/complete-app/public/client.js +89 -0
- package/templates/complete-app/public/index.html +118 -0
- package/templates/complete-app/public/styles.css +76 -0
- package/templates/complete-app/server.js +226 -0
- package/templates/complete-app/src/App.tsx +59 -0
- package/templates/complete-app/src/client.tsx +18 -0
- package/templates/complete-app/src/server.ts +218 -0
- package/templates/complete-app/tsconfig.json +22 -0
- package/templates/complete-app/tsconfig.server.json +19 -0
- package/templates/{ssr-template → complete-app}/vite.config.js +16 -5
- package/templates/complete-app/vite.config.ts +30 -0
- package/templates/complete-app/wasm/build.bat +0 -0
- package/templates/complete-app/wasm/build.sh +0 -0
- package/templates/complete-app/wasm/example.go +0 -0
- package/templates/fullstack-app/build/main.css +874 -874
- package/templates/fullstack-app/build/main.css.map +7 -7
- package/templates/fullstack-app/build/main.js +996 -967
- package/templates/fullstack-app/build/main.js.map +7 -7
- package/templates/fullstack-app/package-lock.json +6301 -0
- package/templates/fullstack-app/public/styles.css +768 -768
- package/templates/go/example.go +154 -99
- package/templates/ssr-template/dist/client/assets/main-D-VH3xOb.js +1 -0
- package/templates/ssr-template/dist/client/index.html +23 -0
- package/templates/ssr-template/dist/client.js +951 -0
- package/templates/ssr-template/dist/server.js +739 -0
- package/templates/ssr-template/esbuild.config.js +33 -0
- package/templates/ssr-template/jsx-shim.js +1 -0
- package/templates/ssr-template/package.json +14 -8
- package/templates/ssr-template/src/App.tsx +847 -49
- package/templates/ssr-template/src/client.tsx +3 -17
- package/templates/ssr-template/src/server.ts +21 -204
- package/templates/ssr-template/tsconfig.json +9 -8
- package/templates/ssr-template/tsconfig.server.json +6 -14
- package/templates/ssr-template/vite.config.ts +19 -17
- package/templates/wasm/build-wasm.js +228 -0
- package/templates/wasm/dist/assets/index-BNqTDBdE.js +295 -0
- package/templates/wasm/dist/example.wasm +0 -0
- package/templates/wasm/dist/index.html +53 -0
- package/templates/{go-wasm-app/public/wasm → wasm/dist}/wasm_exec.js +572 -561
- package/templates/wasm/esbuild.config.js +63 -0
- package/templates/wasm/go/main.go +256 -0
- package/templates/wasm/go/wasm_exec.js +0 -0
- package/templates/wasm/index.html +97 -0
- package/templates/wasm/jsx-shim.js +9 -0
- package/templates/wasm/package-lock.json +4577 -0
- package/templates/wasm/package.json +25 -0
- package/templates/wasm/public/example.wasm +0 -0
- package/templates/wasm/public/wasm_exec.js +572 -0
- package/templates/wasm/src/App.tsx +550 -0
- package/templates/wasm/src/client.tsx +220 -0
- package/templates/wasm/src/index.tsx +21 -0
- package/templates/wasm/src/server.ts +145 -0
- package/templates/wasm/tsconfig.json +21 -0
- package/templates/wasm/tsconfig.node.json +13 -0
- package/templates/wasm/tsconfig.server.json +23 -0
- package/templates/wasm/vite.config.ts +38 -0
- package/templates/wasm/wasm-loader.js +103 -0
- package/dist/server-renderer-CqIpQ-od.cjs +0 -2
- package/dist/server-renderer-CqIpQ-od.cjs.map +0 -1
- package/dist/server-renderer-QHt45Ip2.js.map +0 -1
- package/templates/basic-app/bun.lock +0 -196
- package/templates/basic-app/docs/rapport_pfe.aux +0 -27
- package/templates/basic-app/docs/rapport_pfe.out +0 -10
- package/templates/basic-app/docs/rapport_pfe.pdf +0 -0
- package/templates/basic-app/docs/rapport_pfe.tex +0 -68
- package/templates/basic-app/docs/rapport_pfe.toc +0 -14
- package/templates/basic-app/package-lock.json +0 -4185
- package/templates/go-wasm-app/README.md +0 -38
- package/templates/go-wasm-app/babel.config.js +0 -15
- package/templates/go-wasm-app/build-client.js +0 -49
- package/templates/go-wasm-app/build-wasm.js +0 -237
- package/templates/go-wasm-app/package.json +0 -23
- package/templates/go-wasm-app/public/index.html +0 -128
- package/templates/go-wasm-app/public/styles.css +0 -197
- package/templates/go-wasm-app/public/wasm/example.wasm +0 -0
- package/templates/go-wasm-app/public/wasm/wasm_exec_node.js +0 -39
- package/templates/go-wasm-app/server.js +0 -521
- package/templates/go-wasm-app/src/App.jsx +0 -38
- package/templates/go-wasm-app/src/app.js +0 -153
- package/templates/go-wasm-app/src/client.js +0 -57
- package/templates/go-wasm-app/src/components/Footer.jsx +0 -13
- package/templates/go-wasm-app/src/components/Header.jsx +0 -19
- package/templates/go-wasm-app/src/components/WasmDemo.jsx +0 -120
- package/templates/go-wasm-app/src/main.jsx +0 -12
- package/templates/go-wasm-app/src/wasm/example.go +0 -75
- package/templates/go-wasm-app/tsconfig.server.json +0 -18
- package/templates/go-wasm-app/vite.config.js +0 -34
- package/templates/ssr-template/package-lock.json +0 -2478
- package/templates/ssr-template/public/index.html +0 -47
- package/templates/ssr-template/server.js +0 -369
- /package/templates/{ssr-template → complete-app}/client.js +0 -0
- /package/templates/{ssr-template → complete-app}/readme.md +0 -0
- /package/templates/{ssr-template → complete-app}/server.ts +0 -0
- /package/templates/{ssr-template → complete-app}/src/client.ts +0 -0
- /package/templates/{ssr-template → complete-app}/src/pages/index.tsx +0 -0
@@ -0,0 +1,220 @@
|
|
1
|
+
import { jsx, render } from 'frontend-hamroun';
|
2
|
+
import { loadGoWasm } from '../wasm-loader.js';
|
3
|
+
|
4
|
+
// WASM Demo Component
|
5
|
+
function WasmDemo() {
|
6
|
+
const [wasmReady, setWasmReady] = useState(false);
|
7
|
+
const [result, setResult] = useState('');
|
8
|
+
const [input1, setInput1] = useState('5');
|
9
|
+
const [input2, setInput2] = useState('3');
|
10
|
+
const [fibInput, setFibInput] = useState('10');
|
11
|
+
|
12
|
+
useEffect(() => {
|
13
|
+
loadWasm();
|
14
|
+
}, []);
|
15
|
+
|
16
|
+
const loadWasm = async () => {
|
17
|
+
try {
|
18
|
+
await loadGoWasm('/example.wasm');
|
19
|
+
setWasmReady(true);
|
20
|
+
setResult('✅ Go WASM module loaded successfully!');
|
21
|
+
} catch (error) {
|
22
|
+
setResult(`❌ Failed to load WASM: ${error.message}`);
|
23
|
+
}
|
24
|
+
};
|
25
|
+
|
26
|
+
const testAdd = () => {
|
27
|
+
if (!wasmReady) return;
|
28
|
+
try {
|
29
|
+
const num1 = parseFloat(input1);
|
30
|
+
const num2 = parseFloat(input2);
|
31
|
+
const result = (window as any).add(num1, num2);
|
32
|
+
setResult(`Add result: ${num1} + ${num2} = ${result}`);
|
33
|
+
} catch (error) {
|
34
|
+
setResult(`Error: ${error.message}`);
|
35
|
+
}
|
36
|
+
};
|
37
|
+
|
38
|
+
const testFibonacci = () => {
|
39
|
+
if (!wasmReady) return;
|
40
|
+
try {
|
41
|
+
const n = parseInt(fibInput);
|
42
|
+
const result = (window as any).fibonacci(n);
|
43
|
+
setResult(`Fibonacci(${n}) = ${result}`);
|
44
|
+
} catch (error) {
|
45
|
+
setResult(`Error: ${error.message}`);
|
46
|
+
}
|
47
|
+
};
|
48
|
+
|
49
|
+
const testProcessArray = () => {
|
50
|
+
if (!wasmReady) return;
|
51
|
+
try {
|
52
|
+
const testArray = [1, 2, 3, 4, 5];
|
53
|
+
const result = (window as any).processArray(testArray);
|
54
|
+
const resultArray = Array.from(result);
|
55
|
+
setResult(`Process array [${testArray.join(', ')}] = [${resultArray.join(', ')}]`);
|
56
|
+
} catch (error) {
|
57
|
+
setResult(`Error: ${error.message}`);
|
58
|
+
}
|
59
|
+
};
|
60
|
+
|
61
|
+
const testFormatMessage = () => {
|
62
|
+
if (!wasmReady) return;
|
63
|
+
try {
|
64
|
+
const message = 'Hello from JavaScript!';
|
65
|
+
const result = (window as any).formatMessage(message);
|
66
|
+
setResult(`Formatted: ${result}`);
|
67
|
+
} catch (error) {
|
68
|
+
setResult(`Error: ${error.message}`);
|
69
|
+
}
|
70
|
+
};
|
71
|
+
|
72
|
+
const testPerformance = () => {
|
73
|
+
if (!wasmReady) return;
|
74
|
+
try {
|
75
|
+
const iterations = 100000;
|
76
|
+
const startTime = performance.now();
|
77
|
+
const result = (window as any).performanceBenchmark(iterations);
|
78
|
+
const endTime = performance.now();
|
79
|
+
|
80
|
+
setResult(
|
81
|
+
`Performance test: ${result.message}\n` +
|
82
|
+
`Result: ${result.result}\n` +
|
83
|
+
`Time: ${(endTime - startTime).toFixed(2)}ms`
|
84
|
+
);
|
85
|
+
} catch (error) {
|
86
|
+
setResult(`Error: ${error.message}`);
|
87
|
+
}
|
88
|
+
};
|
89
|
+
|
90
|
+
const testTypeDemo = () => {
|
91
|
+
if (!wasmReady) return;
|
92
|
+
try {
|
93
|
+
const result = (window as any).typeDemo();
|
94
|
+
setResult(
|
95
|
+
`Type demo results:\n` +
|
96
|
+
`String: ${result.string}\n` +
|
97
|
+
`Number: ${result.number}\n` +
|
98
|
+
`Boolean: ${result.boolean}\n` +
|
99
|
+
`Array: [${Array.from(result.array).join(', ')}]`
|
100
|
+
);
|
101
|
+
} catch (error) {
|
102
|
+
setResult(`Error: ${error.message}`);
|
103
|
+
}
|
104
|
+
};
|
105
|
+
|
106
|
+
return jsx('div', {
|
107
|
+
className: 'wasm-demo',
|
108
|
+
children: [
|
109
|
+
jsx('h1', { children: '🚀 Frontend Hamroun + Go WASM Demo' }),
|
110
|
+
|
111
|
+
jsx('div', {
|
112
|
+
className: 'status',
|
113
|
+
children: jsx('p', {
|
114
|
+
className: wasmReady ? 'ready' : 'loading',
|
115
|
+
children: wasmReady ? '✅ WASM Ready' : '⏳ Loading WASM...'
|
116
|
+
})
|
117
|
+
}),
|
118
|
+
|
119
|
+
jsx('div', {
|
120
|
+
className: 'controls',
|
121
|
+
children: [
|
122
|
+
jsx('h2', { children: '🧮 Arithmetic Operations' }),
|
123
|
+
jsx('div', {
|
124
|
+
className: 'input-group',
|
125
|
+
children: [
|
126
|
+
jsx('input', {
|
127
|
+
type: 'number',
|
128
|
+
value: input1,
|
129
|
+
onChange: (e: any) => setInput1(e.target.value),
|
130
|
+
placeholder: 'First number'
|
131
|
+
}),
|
132
|
+
jsx('span', { children: ' + ' }),
|
133
|
+
jsx('input', {
|
134
|
+
type: 'number',
|
135
|
+
value: input2,
|
136
|
+
onChange: (e: any) => setInput2(e.target.value),
|
137
|
+
placeholder: 'Second number'
|
138
|
+
}),
|
139
|
+
jsx('button', {
|
140
|
+
onClick: testAdd,
|
141
|
+
disabled: !wasmReady,
|
142
|
+
children: 'Calculate'
|
143
|
+
})
|
144
|
+
]
|
145
|
+
}),
|
146
|
+
|
147
|
+
jsx('h2', { children: '🔢 Fibonacci Sequence' }),
|
148
|
+
jsx('div', {
|
149
|
+
className: 'input-group',
|
150
|
+
children: [
|
151
|
+
jsx('input', {
|
152
|
+
type: 'number',
|
153
|
+
value: fibInput,
|
154
|
+
onChange: (e: any) => setFibInput(e.target.value),
|
155
|
+
placeholder: 'Fibonacci number'
|
156
|
+
}),
|
157
|
+
jsx('button', {
|
158
|
+
onClick: testFibonacci,
|
159
|
+
disabled: !wasmReady,
|
160
|
+
children: 'Calculate Fibonacci'
|
161
|
+
})
|
162
|
+
]
|
163
|
+
}),
|
164
|
+
|
165
|
+
jsx('h2', { children: '🔧 Advanced Functions' }),
|
166
|
+
jsx('div', {
|
167
|
+
className: 'button-group',
|
168
|
+
children: [
|
169
|
+
jsx('button', {
|
170
|
+
onClick: testProcessArray,
|
171
|
+
disabled: !wasmReady,
|
172
|
+
children: 'Process Array'
|
173
|
+
}),
|
174
|
+
jsx('button', {
|
175
|
+
onClick: testFormatMessage,
|
176
|
+
disabled: !wasmReady,
|
177
|
+
children: 'Format Message'
|
178
|
+
}),
|
179
|
+
jsx('button', {
|
180
|
+
onClick: testPerformance,
|
181
|
+
disabled: !wasmReady,
|
182
|
+
children: 'Performance Test'
|
183
|
+
}),
|
184
|
+
jsx('button', {
|
185
|
+
onClick: testTypeDemo,
|
186
|
+
disabled: !wasmReady,
|
187
|
+
children: 'Type Demo'
|
188
|
+
})
|
189
|
+
]
|
190
|
+
})
|
191
|
+
]
|
192
|
+
}),
|
193
|
+
|
194
|
+
jsx('div', {
|
195
|
+
className: 'result',
|
196
|
+
children: [
|
197
|
+
jsx('h3', { children: '📋 Result:' }),
|
198
|
+
jsx('pre', { children: result })
|
199
|
+
]
|
200
|
+
})
|
201
|
+
]
|
202
|
+
});
|
203
|
+
}
|
204
|
+
|
205
|
+
// App Component
|
206
|
+
function App() {
|
207
|
+
return jsx('div', {
|
208
|
+
className: 'app',
|
209
|
+
children: jsx(WasmDemo, {})
|
210
|
+
});
|
211
|
+
}
|
212
|
+
|
213
|
+
// Render the app
|
214
|
+
const appElement = document.getElementById('app');
|
215
|
+
if (appElement) {
|
216
|
+
render(jsx(App, {}), appElement);
|
217
|
+
}
|
218
|
+
|
219
|
+
// Import statements for hooks
|
220
|
+
import { useState, useEffect } from 'frontend-hamroun';
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { jsx, render } from 'frontend-hamroun';
|
2
|
+
import App from './App.tsx';
|
3
|
+
|
4
|
+
// Simple render without infinite loops
|
5
|
+
function startApp() {
|
6
|
+
const appElement = jsx(App, {});
|
7
|
+
const rootElement = document.getElementById('app');
|
8
|
+
|
9
|
+
if (rootElement) {
|
10
|
+
render(appElement, rootElement);
|
11
|
+
} else {
|
12
|
+
console.error('Root element not found');
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
// Start when DOM is ready
|
17
|
+
if (document.readyState === 'loading') {
|
18
|
+
document.addEventListener('DOMContentLoaded', startApp);
|
19
|
+
} else {
|
20
|
+
startApp();
|
21
|
+
}
|
@@ -0,0 +1,145 @@
|
|
1
|
+
import { createServer } from 'frontend-hamroun';
|
2
|
+
import { loadGoWasmFromFile } from 'frontend-hamroun';
|
3
|
+
import path from 'path';
|
4
|
+
import { fileURLToPath } from 'url';
|
5
|
+
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
7
|
+
const __dirname = path.dirname(__filename);
|
8
|
+
|
9
|
+
// Create server instance
|
10
|
+
const server = createServer({
|
11
|
+
port: 3000,
|
12
|
+
staticDir: './public',
|
13
|
+
pagesDir: './src/pages',
|
14
|
+
apiDir: './src/api'
|
15
|
+
});
|
16
|
+
|
17
|
+
// Server-side WASM integration example
|
18
|
+
async function initServerWasm() {
|
19
|
+
try {
|
20
|
+
console.log('🔄 Initializing server-side Go WASM...');
|
21
|
+
|
22
|
+
const wasmPath = path.join(__dirname, '..', 'public', 'example.wasm');
|
23
|
+
const wasmInstance = await loadGoWasmFromFile(wasmPath, {
|
24
|
+
debug: true,
|
25
|
+
onLoad: (instance) => {
|
26
|
+
console.log('✅ Go WASM loaded on server side');
|
27
|
+
|
28
|
+
// Test server-side WASM functions
|
29
|
+
try {
|
30
|
+
if (instance.functions.add) {
|
31
|
+
const result = instance.functions.add(5, 3);
|
32
|
+
console.log('Server WASM test - add(5, 3):', result);
|
33
|
+
}
|
34
|
+
|
35
|
+
if (instance.functions.fibonacci) {
|
36
|
+
const fibResult = instance.functions.fibonacci(10);
|
37
|
+
console.log('Server WASM test - fibonacci(10):', fibResult);
|
38
|
+
}
|
39
|
+
} catch (error) {
|
40
|
+
console.log('Server WASM test functions not available:', error.message);
|
41
|
+
}
|
42
|
+
}
|
43
|
+
});
|
44
|
+
|
45
|
+
// Make WASM instance available to API routes
|
46
|
+
server.getExpressApp().locals.wasm = wasmInstance;
|
47
|
+
|
48
|
+
} catch (error) {
|
49
|
+
console.error('❌ Failed to initialize server-side WASM:', error);
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
// API route example using server-side WASM
|
54
|
+
server.getExpressApp().get('/api/wasm/compute', async (req, res) => {
|
55
|
+
try {
|
56
|
+
const { operation, a, b } = req.query;
|
57
|
+
const wasmInstance = req.app.locals.wasm;
|
58
|
+
|
59
|
+
if (!wasmInstance) {
|
60
|
+
return res.status(500).json({ error: 'WASM not initialized' });
|
61
|
+
}
|
62
|
+
|
63
|
+
let result;
|
64
|
+
switch (operation) {
|
65
|
+
case 'add':
|
66
|
+
if (wasmInstance.functions.add) {
|
67
|
+
result = wasmInstance.functions.add(Number(a), Number(b));
|
68
|
+
} else {
|
69
|
+
throw new Error('Add function not available');
|
70
|
+
}
|
71
|
+
break;
|
72
|
+
case 'fibonacci':
|
73
|
+
if (wasmInstance.functions.fibonacci) {
|
74
|
+
result = wasmInstance.functions.fibonacci(Number(a));
|
75
|
+
} else {
|
76
|
+
throw new Error('Fibonacci function not available');
|
77
|
+
}
|
78
|
+
break;
|
79
|
+
default:
|
80
|
+
throw new Error('Unknown operation');
|
81
|
+
}
|
82
|
+
|
83
|
+
res.json({
|
84
|
+
success: true,
|
85
|
+
operation,
|
86
|
+
result,
|
87
|
+
serverTime: new Date().toISOString()
|
88
|
+
});
|
89
|
+
} catch (error) {
|
90
|
+
res.status(400).json({
|
91
|
+
success: false,
|
92
|
+
error: error.message
|
93
|
+
});
|
94
|
+
}
|
95
|
+
});
|
96
|
+
|
97
|
+
// Health check endpoint
|
98
|
+
server.getExpressApp().get('/api/health', (req, res) => {
|
99
|
+
res.json({
|
100
|
+
status: 'healthy',
|
101
|
+
wasm: !!req.app.locals.wasm,
|
102
|
+
timestamp: new Date().toISOString()
|
103
|
+
});
|
104
|
+
});
|
105
|
+
|
106
|
+
// Start server
|
107
|
+
async function startServer() {
|
108
|
+
try {
|
109
|
+
// Initialize WASM first
|
110
|
+
await initServerWasm();
|
111
|
+
|
112
|
+
// Start the server
|
113
|
+
await server.start();
|
114
|
+
|
115
|
+
console.log('🚀 Server started successfully!');
|
116
|
+
console.log('📋 Available endpoints:');
|
117
|
+
console.log(' • http://localhost:3000 - Main app');
|
118
|
+
console.log(' • http://localhost:3000/api/health - Health check');
|
119
|
+
console.log(' • http://localhost:3000/api/wasm/compute - WASM compute API');
|
120
|
+
console.log('');
|
121
|
+
console.log('💡 Example API calls:');
|
122
|
+
console.log(' • /api/wasm/compute?operation=add&a=5&b=3');
|
123
|
+
console.log(' • /api/wasm/compute?operation=fibonacci&a=10');
|
124
|
+
|
125
|
+
} catch (error) {
|
126
|
+
console.error('❌ Failed to start server:', error);
|
127
|
+
process.exit(1);
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
// Graceful shutdown
|
132
|
+
process.on('SIGTERM', async () => {
|
133
|
+
console.log('🛑 Received SIGTERM, shutting down gracefully...');
|
134
|
+
await server.stop();
|
135
|
+
process.exit(0);
|
136
|
+
});
|
137
|
+
|
138
|
+
process.on('SIGINT', async () => {
|
139
|
+
console.log('🛑 Received SIGINT, shutting down gracefully...');
|
140
|
+
await server.stop();
|
141
|
+
process.exit(0);
|
142
|
+
});
|
143
|
+
|
144
|
+
// Start the server
|
145
|
+
startServer();
|
@@ -0,0 +1,21 @@
|
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"target": "ES2020",
|
4
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
5
|
+
"module": "ESNext",
|
6
|
+
"skipLibCheck": true,
|
7
|
+
"moduleResolution": "bundler",
|
8
|
+
"allowImportingTsExtensions": true,
|
9
|
+
"resolveJsonModule": true,
|
10
|
+
"isolatedModules": true,
|
11
|
+
"noEmit": true,
|
12
|
+
"jsx": "preserve",
|
13
|
+
"jsxImportSource": "frontend-hamroun",
|
14
|
+
"strict": true,
|
15
|
+
"noUnusedLocals": true,
|
16
|
+
"noUnusedParameters": true,
|
17
|
+
"noFallthroughCasesInSwitch": true
|
18
|
+
},
|
19
|
+
"include": ["src"],
|
20
|
+
"references": [{ "path": "./tsconfig.node.json" }]
|
21
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"composite": true,
|
4
|
+
"skipLibCheck": true,
|
5
|
+
"module": "ESNext",
|
6
|
+
"moduleResolution": "bundler",
|
7
|
+
"allowSyntheticDefaultImports": true,
|
8
|
+
"strict": true,
|
9
|
+
"noEmit": true,
|
10
|
+
"types": ["node"]
|
11
|
+
},
|
12
|
+
"include": ["vite.config.*", "vitest.config.*", "build-wasm.js", "esbuild.config.js"]
|
13
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
{
|
2
|
+
"extends": "./tsconfig.json",
|
3
|
+
"compilerOptions": {
|
4
|
+
"module": "ESNext",
|
5
|
+
"outDir": "dist",
|
6
|
+
"noEmit": false,
|
7
|
+
"jsx": "preserve",
|
8
|
+
"moduleResolution": "bundler",
|
9
|
+
"composite": true,
|
10
|
+
"skipLibCheck": true,
|
11
|
+
"allowSyntheticDefaultImports": true,
|
12
|
+
"strict": true,
|
13
|
+
"target": "ES2020",
|
14
|
+
"lib": ["ES2020"],
|
15
|
+
"types": ["node"],
|
16
|
+
"esModuleInterop": true,
|
17
|
+
"allowImportingTsExtensions": true,
|
18
|
+
"resolveJsonModule": true,
|
19
|
+
"isolatedModules": true
|
20
|
+
},
|
21
|
+
"include": ["src/server.ts", "**/*.ts", "**/*.js"],
|
22
|
+
"exclude": ["node_modules", "dist"]
|
23
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import { defineConfig } from 'vite';
|
2
|
+
import path from 'path';
|
3
|
+
|
4
|
+
export default defineConfig({
|
5
|
+
esbuild: {
|
6
|
+
jsx: 'transform',
|
7
|
+
jsxFactory: 'jsx',
|
8
|
+
jsxFragment: 'Fragment',
|
9
|
+
jsxImportSource: 'frontend-hamroun',
|
10
|
+
},
|
11
|
+
optimizeDeps: {
|
12
|
+
include: ['frontend-hamroun'],
|
13
|
+
exclude: []
|
14
|
+
},
|
15
|
+
server: {
|
16
|
+
fs: {
|
17
|
+
allow: ['..', '../..']
|
18
|
+
},
|
19
|
+
headers: {
|
20
|
+
'Cross-Origin-Embedder-Policy': 'require-corp',
|
21
|
+
'Cross-Origin-Opener-Policy': 'same-origin'
|
22
|
+
}
|
23
|
+
},
|
24
|
+
build: {
|
25
|
+
target: 'esnext',
|
26
|
+
rollupOptions: {
|
27
|
+
output: {
|
28
|
+
format: 'es'
|
29
|
+
}
|
30
|
+
}
|
31
|
+
},
|
32
|
+
resolve: {
|
33
|
+
alias: {
|
34
|
+
'frontend-hamroun/jsx-dev-runtime': 'frontend-hamroun',
|
35
|
+
'frontend-hamroun/jsx-runtime': 'frontend-hamroun'
|
36
|
+
}
|
37
|
+
}
|
38
|
+
});
|
@@ -0,0 +1,103 @@
|
|
1
|
+
/**
|
2
|
+
* WASM Loader for Frontend Hamroun Go WASM integration
|
3
|
+
*/
|
4
|
+
|
5
|
+
let wasmInstance = null;
|
6
|
+
let wasmReady = false;
|
7
|
+
|
8
|
+
export async function loadGoWasm(wasmPath, options = {}) {
|
9
|
+
if (wasmReady) {
|
10
|
+
return wasmInstance;
|
11
|
+
}
|
12
|
+
|
13
|
+
try {
|
14
|
+
console.log('🔄 Loading Go WASM module from:', wasmPath);
|
15
|
+
|
16
|
+
// Load the Go WASM runtime
|
17
|
+
if (!window.Go) {
|
18
|
+
await loadWasmExecJs();
|
19
|
+
}
|
20
|
+
|
21
|
+
// Create Go instance
|
22
|
+
const go = new window.Go();
|
23
|
+
|
24
|
+
// Fetch and instantiate WASM
|
25
|
+
const wasmModule = await WebAssembly.instantiateStreaming(
|
26
|
+
fetch(wasmPath),
|
27
|
+
go.importObject
|
28
|
+
);
|
29
|
+
|
30
|
+
// Run the Go program
|
31
|
+
go.run(wasmModule.instance);
|
32
|
+
|
33
|
+
wasmInstance = {
|
34
|
+
instance: wasmModule.instance,
|
35
|
+
module: wasmModule.module,
|
36
|
+
go: go
|
37
|
+
};
|
38
|
+
|
39
|
+
wasmReady = true;
|
40
|
+
|
41
|
+
console.log('✅ Go WASM module loaded successfully!');
|
42
|
+
|
43
|
+
if (options.onLoad) {
|
44
|
+
options.onLoad(wasmInstance);
|
45
|
+
}
|
46
|
+
|
47
|
+
return wasmInstance;
|
48
|
+
|
49
|
+
} catch (error) {
|
50
|
+
console.error('❌ Failed to load Go WASM module:', error);
|
51
|
+
throw error;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
async function loadWasmExecJs() {
|
56
|
+
return new Promise((resolve, reject) => {
|
57
|
+
const script = document.createElement('script');
|
58
|
+
script.src = '/wasm_exec.js';
|
59
|
+
script.onload = resolve;
|
60
|
+
script.onerror = () => reject(new Error('Failed to load wasm_exec.js'));
|
61
|
+
document.head.appendChild(script);
|
62
|
+
});
|
63
|
+
}
|
64
|
+
|
65
|
+
export function isWasmReady() {
|
66
|
+
return wasmReady;
|
67
|
+
}
|
68
|
+
|
69
|
+
export function getWasmInstance() {
|
70
|
+
return wasmInstance;
|
71
|
+
}
|
72
|
+
|
73
|
+
// Utility functions for calling Go functions safely
|
74
|
+
export function callGoFunction(functionName, ...args) {
|
75
|
+
if (!wasmReady) {
|
76
|
+
throw new Error('WASM module not ready');
|
77
|
+
}
|
78
|
+
|
79
|
+
if (typeof window[functionName] !== 'function') {
|
80
|
+
throw new Error(`Go function '${functionName}' not found`);
|
81
|
+
}
|
82
|
+
|
83
|
+
return window[functionName](...args);
|
84
|
+
}
|
85
|
+
|
86
|
+
export async function waitForWasm(timeout = 10000) {
|
87
|
+
if (wasmReady) return wasmInstance;
|
88
|
+
|
89
|
+
return new Promise((resolve, reject) => {
|
90
|
+
const checkInterval = setInterval(() => {
|
91
|
+
if (wasmReady) {
|
92
|
+
clearInterval(checkInterval);
|
93
|
+
clearTimeout(timeoutId);
|
94
|
+
resolve(wasmInstance);
|
95
|
+
}
|
96
|
+
}, 100);
|
97
|
+
|
98
|
+
const timeoutId = setTimeout(() => {
|
99
|
+
clearInterval(checkInterval);
|
100
|
+
reject(new Error('WASM loading timeout'));
|
101
|
+
}, timeout);
|
102
|
+
});
|
103
|
+
}
|
@@ -1,2 +0,0 @@
|
|
1
|
-
"use strict";exports.isBatching=!1;const e=[];function t(t){if(exports.isBatching)e.push(t);else{exports.isBatching=!0;try{for(t();e.length>0;){const t=e.shift();t?.()}}finally{exports.isBatching=!1}}}let r=0;const n=new Map,s=new Map,o=new Map,c=new Map,i=new Map,p="undefined"==typeof window,u=new Map;let a=null,l=null,f=null;function h(){return r++,s.set(r,0),r}function d(){p&&u.delete(r),r=0}function g(e){if(!r)throw new Error("useState must be called within a render");if(p){u.has(r)||u.set(r,new Map);const t=u.get(r),n=s.get(r)||0;t.has(n)||t.set(n,e);const o=t.get(n),c=e=>{};return s.set(r,n+1),[o,c]}n.has(r)||n.set(r,[]);const o=n.get(r),c=s.get(r)||0;c>=o.length&&o.push(e);const i=o[c];return s.set(r,c+1),[i,e=>{const n="function"==typeof e?e(o[c]):e;o[c]!==n&&(o[c]=n,exports.isBatching?t((()=>y(r))):y(r))}]}async function y(e){try{const t=o.get(e);t&&(t.forEach((e=>{e.cleanup&&e.cleanup()})),o.set(e,[])),a&&l&&f&&await a(f,l)}catch(t){console.error("Error during rerender:",t)}}function w(e){if(null==e)return"";if("boolean"==typeof e)return"";if("number"==typeof e||"string"==typeof e)return m(String(e));if("function"==typeof e.type){return w((0,e.type)(e.props||{}))}if("string"==typeof e.type){const t=e.type;let r="",n="";if(e.props)for(const[o,c]of Object.entries(e.props))"children"!==o&&(o.startsWith("on")||("className"!==o?"string"==typeof c||"number"==typeof c?r+=` ${o}="${m(String(c))}"`:!0===c&&(r+=` ${o}`):r+=` class="${m(c)}"`));const s=e.props?.children?Array.isArray(e.props.children)?e.props.children:[e.props.children]:[];for(const e of s)n+=w(e);return["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"].includes(t)?`<${t}${r}/>`:`<${t}${r}>${n}</${t}>`}if(e.type===Symbol.for("react.fragment")){let t="";const r=Array.isArray(e.props?.children)?e.props.children:e.props?.children?[e.props.children]:[];for(const e of r)t+=w(e);return t}return console.warn("Unknown vnode type:",e.type),""}function m(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}exports.batchUpdates=t,exports.finishRender=d,exports.getIsBatching=function(){return exports.isBatching},exports.prepareRender=h,exports.renderToString=function(e){h();const t=w(e);return d(),t},exports.setRenderCallback=function(e,t,r){a=e,l=r,f=t},exports.useEffect=function(e,t){if(!r)throw new Error("useEffect must be called within a render");if(p){const e=s.get(r)||0;return void s.set(r,e+1)}const n=s.get(r)||0;o.has(r)||o.set(r,[]);const c=o.get(r),i=c[n];i&&t&&i.deps&&!t.some(((e,t)=>e!==i.deps[t]))||(i?.cleanup&&i.cleanup(),queueMicrotask((()=>{const r=e()||void 0;c[n]={cleanup:r,deps:t||[]}}))),s.set(r,n+1)},exports.useErrorBoundary=function(){const[e,t]=g(null);return[e,()=>t(null)]},exports.useMemo=function(e,t){if(!r)throw new Error("useMemo must be called within a render");const n=s.get(r)||0;c.has(r)||c.set(r,[]);const o=c.get(r),i=o[n];if(!i||t&&t.some(((e,t)=>!Object.is(e,i.deps[t])))){const c=e();return o[n]={value:c,deps:t||[]},s.set(r,n+1),c}return s.set(r,n+1),i.value},exports.useRef=function(e){if(!r)throw new Error("useRef must be called within a render");const t=s.get(r)||0;i.has(r)||i.set(r,[]);const n=i.get(r);if(t>=n.length){const o={current:e};return n.push(o),s.set(r,t+1),o}const o=n[t];return s.set(r,t+1),o},exports.useState=g;
|
2
|
-
//# sourceMappingURL=server-renderer-CqIpQ-od.cjs.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"server-renderer-CqIpQ-od.cjs","sources":["../src/batch.ts","../src/hooks.ts","../src/server-renderer.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 { createElement } from './jsx-runtime.js';\r\nimport { batchUpdates, isBatching } from './batch.js';\r\nimport { diff } from './vdom.js';\r\nimport { createContext, useContext } from './context.js';\r\n\r\n// Current render ID counter\r\nlet currentRender = 0;\r\n\r\n// State storage\r\nconst states = new Map<number, any[]>();\r\nconst stateIndices = new Map<number, number>();\r\nconst effects = new Map<number, any[]>();\r\nconst memos = new Map<number, any[]>();\r\nconst refs = new Map<number, any[]>();\r\n\r\n// Server-side rendering detection\r\nconst isServer = typeof window === 'undefined';\r\nconst serverStates = new Map<number, Map<number, any>>();\r\n\r\n// Rendering callbacks\r\nlet globalRenderCallback: any = null;\r\nlet globalContainer: any = null;\r\nlet currentElement: any = null;\r\n\r\nexport function setRenderCallback(callback: any, element: any, container: any): void {\r\n globalRenderCallback = callback;\r\n globalContainer = container;\r\n currentElement = element;\r\n}\r\n\r\nexport function prepareRender(): number {\r\n currentRender++;\r\n stateIndices.set(currentRender, 0);\r\n return currentRender;\r\n}\r\n\r\nexport function finishRender(): void {\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, (newValue: 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 // Handle server-side rendering separately\r\n if (isServer) {\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 // In SSR, setState is a no-op\r\n const setState = (_newValue: T | ((prev: T) => T)) => {};\r\n \r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n }\r\n\r\n // Client-side implementation\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) || 0;\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 \r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n const nextValue = typeof newValue === 'function'\r\n ? (newValue as ((prev: T) => T))(componentStates[index])\r\n : newValue;\r\n \r\n if (componentStates[index] === nextValue) return;\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[]): void {\r\n if (!currentRender) throw new Error(\"useEffect must be called within a render\");\r\n\r\n // Skip effects on server\r\n if (isServer) {\r\n const effectIndex = stateIndices.get(currentRender) || 0;\r\n stateIndices.set(currentRender, effectIndex + 1);\r\n return;\r\n }\r\n\r\n const effectIndex = stateIndices.get(currentRender) || 0;\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 if (!prevEffect || !deps || !prevEffect.deps || deps.some((dep, i) => dep !== prevEffect.deps[i])) {\r\n if (prevEffect?.cleanup) {\r\n prevEffect.cleanup();\r\n }\r\n \r\n // Schedule effect execution after render is complete\r\n queueMicrotask(() => {\r\n const cleanup = callback() || undefined;\r\n componentEffects[effectIndex] = { cleanup, deps: 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) || 0;\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: 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): { current: T } {\r\n if (!currentRender) throw new Error(\"useRef must be called within a render\");\r\n \r\n const refIndex = stateIndices.get(currentRender) || 0;\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 \r\n if (refIndex >= componentRefs.length) {\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\nasync function rerender(rendererId: number): Promise<void> {\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 // Trigger re-render\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\nexport function useErrorBoundary() {\r\n const [error, setError] = useState(null);\r\n return [error, () => setError(null)];\r\n}\r\n\r\n// Re-export from context to match index.js\r\nexport { createContext, useContext };\r\n","import { VNode } from './types.js';\r\nimport { prepareRender, finishRender } from './hooks.js';\r\n\r\ntype Component = (props: any) => any;\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"],"names":["isBatching","queue","batchUpdates","fn","push","length","nextFn","shift","currentRender","states","Map","stateIndices","effects","memos","refs","isServer","window","serverStates","globalRenderCallback","globalContainer","currentElement","prepareRender","set","finishRender","delete","useState","initial","Error","has","componentState","get","index","state","setState","_newValue","componentStates","newValue","nextValue","rerender","async","rendererId","componentEffects","forEach","effect","cleanup","error","console","renderNodeToString","vnode","escapeHtml","String","type","Component","props","tag","attrs","children","key","value","Object","entries","startsWith","childrenArray","Array","isArray","child","includes","Symbol","for","fragmentOutput","warn","text","replace","html","callback","element","container","deps","effectIndex","prevEffect","some","dep","i","queueMicrotask","setError","factory","memoIndex","componentMemos","prevMemo","is","refIndex","componentRefs","ref","current"],"mappings":"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"}
|