frontend-hamroun 1.2.80 → 1.2.82
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/bin/cli.js +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +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/esbuild.config.js +33 -0
- package/templates/ssr-template/jsx-shim.js +1 -0
- package/templates/ssr-template/package.json +22 -16
- package/templates/ssr-template/src/App.tsx +12 -52
- package/templates/ssr-template/src/client.tsx +3 -17
- package/templates/ssr-template/src/server.ts +21 -204
- package/templates/ssr-template/tsconfig.json +10 -13
- package/templates/ssr-template/tsconfig.server.json +6 -14
- package/templates/wasm/build-wasm.js +228 -0
- 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 +5307 -0
- package/templates/wasm/package.json +42 -0
- package/templates/wasm/public/example.wasm +0 -0
- package/templates/{go-wasm-app/public/wasm → wasm/public}/wasm_exec.js +561 -561
- package/templates/wasm/src/App.tsx +564 -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 +56 -0
- package/templates/wasm/wasm-loader.js +103 -0
- 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
package/templates/go/example.go
CHANGED
@@ -4,147 +4,202 @@
|
|
4
4
|
package main
|
5
5
|
|
6
6
|
import (
|
7
|
-
"encoding/json"
|
8
7
|
"fmt"
|
8
|
+
"strconv"
|
9
|
+
"strings"
|
9
10
|
"syscall/js"
|
10
11
|
)
|
11
12
|
|
12
|
-
//
|
13
|
-
func
|
13
|
+
// Main function required for Go WebAssembly
|
14
|
+
func main() {
|
15
|
+
// Set up global functions that will be accessible from JavaScript
|
16
|
+
js.Global().Set("goAdd", js.FuncOf(goAdd))
|
17
|
+
js.Global().Set("goSubtract", js.FuncOf(goSubtract))
|
18
|
+
js.Global().Set("goMultiply", js.FuncOf(goMultiply))
|
19
|
+
js.Global().Set("goDivide", js.FuncOf(goDivide))
|
20
|
+
js.Global().Set("goReverseString", js.FuncOf(goReverseString))
|
21
|
+
js.Global().Set("goCalculateFactorial", js.FuncOf(goCalculateFactorial))
|
22
|
+
js.Global().Set("goProcessArray", js.FuncOf(goProcessArray))
|
23
|
+
|
24
|
+
// Keep the Go program running until the context is done
|
25
|
+
// This is necessary for WebAssembly modules
|
26
|
+
<-make(chan bool)
|
27
|
+
}
|
28
|
+
|
29
|
+
// goAdd adds two numbers and returns the result
|
30
|
+
func goAdd(this js.Value, args []js.Value) interface{} {
|
14
31
|
if len(args) != 2 {
|
15
|
-
return
|
32
|
+
return map[string]interface{}{
|
33
|
+
"error": "Expected 2 arguments: number, number",
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
// Parse string arguments as numbers
|
38
|
+
a, errA := strconv.ParseFloat(args[0].String(), 64)
|
39
|
+
b, errB := strconv.ParseFloat(args[1].String(), 64)
|
40
|
+
|
41
|
+
// Check for parsing errors
|
42
|
+
if errA != nil || errB != nil {
|
43
|
+
return map[string]interface{}{
|
44
|
+
"error": "Arguments must be valid numbers",
|
45
|
+
}
|
16
46
|
}
|
17
47
|
|
18
|
-
|
19
|
-
|
20
|
-
return js.ValueOf(a + b)
|
48
|
+
// Return the result
|
49
|
+
return fmt.Sprintf("%g", a+b)
|
21
50
|
}
|
22
51
|
|
23
|
-
|
52
|
+
// goSubtract subtracts the second number from the first
|
53
|
+
func goSubtract(this js.Value, args []js.Value) interface{} {
|
24
54
|
if len(args) != 2 {
|
25
|
-
return
|
55
|
+
return map[string]interface{}{
|
56
|
+
"error": "Expected 2 arguments: number, number",
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
// Parse string arguments as numbers
|
61
|
+
a, errA := strconv.ParseFloat(args[0].String(), 64)
|
62
|
+
b, errB := strconv.ParseFloat(args[1].String(), 64)
|
63
|
+
|
64
|
+
// Check for parsing errors
|
65
|
+
if errA != nil || errB != nil {
|
66
|
+
return map[string]interface{}{
|
67
|
+
"error": "Arguments must be valid numbers",
|
68
|
+
}
|
26
69
|
}
|
27
70
|
|
28
|
-
|
29
|
-
|
30
|
-
return js.ValueOf(a - b)
|
71
|
+
// Return the result
|
72
|
+
return fmt.Sprintf("%g", a-b)
|
31
73
|
}
|
32
74
|
|
33
|
-
|
75
|
+
// goMultiply multiplies two numbers
|
76
|
+
func goMultiply(this js.Value, args []js.Value) interface{} {
|
34
77
|
if len(args) != 2 {
|
35
|
-
return
|
78
|
+
return map[string]interface{}{
|
79
|
+
"error": "Expected 2 arguments: number, number",
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
// Parse string arguments as numbers
|
84
|
+
a, errA := strconv.ParseFloat(args[0].String(), 64)
|
85
|
+
b, errB := strconv.ParseFloat(args[1].String(), 64)
|
86
|
+
|
87
|
+
// Check for parsing errors
|
88
|
+
if errA != nil || errB != nil {
|
89
|
+
return map[string]interface{}{
|
90
|
+
"error": "Arguments must be valid numbers",
|
91
|
+
}
|
36
92
|
}
|
37
93
|
|
38
|
-
|
39
|
-
|
40
|
-
return js.ValueOf(a * b)
|
94
|
+
// Return the result
|
95
|
+
return fmt.Sprintf("%g", a*b)
|
41
96
|
}
|
42
97
|
|
43
|
-
//
|
44
|
-
func
|
45
|
-
if len(args)
|
46
|
-
return
|
98
|
+
// goDivide divides the first number by the second
|
99
|
+
func goDivide(this js.Value, args []js.Value) interface{} {
|
100
|
+
if len(args) != 2 {
|
101
|
+
return map[string]interface{}{
|
102
|
+
"error": "Expected 2 arguments: number, number",
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
// Parse string arguments as numbers
|
107
|
+
a, errA := strconv.ParseFloat(args[0].String(), 64)
|
108
|
+
b, errB := strconv.ParseFloat(args[1].String(), 64)
|
109
|
+
|
110
|
+
// Check for parsing errors
|
111
|
+
if errA != nil || errB != nil {
|
112
|
+
return map[string]interface{}{
|
113
|
+
"error": "Arguments must be valid numbers",
|
114
|
+
}
|
47
115
|
}
|
48
116
|
|
49
|
-
|
50
|
-
|
51
|
-
|
117
|
+
// Check for division by zero
|
118
|
+
if b == 0 {
|
119
|
+
return map[string]interface{}{
|
120
|
+
"error": "Division by zero is not allowed",
|
121
|
+
}
|
52
122
|
}
|
53
|
-
|
123
|
+
|
124
|
+
// Return the result
|
125
|
+
return fmt.Sprintf("%g", a/b)
|
54
126
|
}
|
55
127
|
|
56
|
-
//
|
57
|
-
func
|
128
|
+
// goReverseString reverses a string
|
129
|
+
func goReverseString(this js.Value, args []js.Value) interface{} {
|
58
130
|
if len(args) != 1 {
|
59
|
-
return
|
131
|
+
return map[string]interface{}{
|
132
|
+
"error": "Expected 1 argument: string",
|
133
|
+
}
|
60
134
|
}
|
61
135
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
136
|
+
input := args[0].String()
|
137
|
+
runes := []rune(input)
|
138
|
+
|
139
|
+
// Reverse the string
|
140
|
+
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
|
141
|
+
runes[i], runes[j] = runes[j], runes[i]
|
67
142
|
}
|
68
143
|
|
69
|
-
|
70
|
-
return mapToJSValue(result)
|
144
|
+
return string(runes)
|
71
145
|
}
|
72
146
|
|
73
|
-
//
|
74
|
-
func
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
for key, val := range v {
|
79
|
-
result.Set(key, mapToJSValue(val))
|
147
|
+
// goCalculateFactorial calculates the factorial of a number
|
148
|
+
func goCalculateFactorial(this js.Value, args []js.Value) interface{} {
|
149
|
+
if len(args) != 1 {
|
150
|
+
return map[string]interface{}{
|
151
|
+
"error": "Expected 1 argument: number",
|
80
152
|
}
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
153
|
+
}
|
154
|
+
|
155
|
+
// Parse string argument as number
|
156
|
+
n, err := strconv.ParseInt(args[0].String(), 10, 64)
|
157
|
+
|
158
|
+
// Check for parsing errors
|
159
|
+
if err != nil {
|
160
|
+
return map[string]interface{}{
|
161
|
+
"error": "Argument must be a valid integer",
|
86
162
|
}
|
87
|
-
return result
|
88
|
-
case string:
|
89
|
-
return js.ValueOf(v)
|
90
|
-
case float64:
|
91
|
-
return js.ValueOf(v)
|
92
|
-
case bool:
|
93
|
-
return js.ValueOf(v)
|
94
|
-
case nil:
|
95
|
-
return js.ValueOf(nil)
|
96
|
-
default:
|
97
|
-
return js.ValueOf(fmt.Sprint(v))
|
98
163
|
}
|
99
|
-
}
|
100
164
|
|
101
|
-
//
|
102
|
-
|
103
|
-
|
104
|
-
|
165
|
+
// Check for negative numbers
|
166
|
+
if n < 0 {
|
167
|
+
return map[string]interface{}{
|
168
|
+
"error": "Factorial is not defined for negative numbers",
|
169
|
+
}
|
105
170
|
}
|
106
|
-
return args[0] // Pass through
|
107
|
-
}
|
108
171
|
|
109
|
-
|
110
|
-
|
111
|
-
|
172
|
+
// Calculate factorial
|
173
|
+
result := int64(1)
|
174
|
+
for i := int64(2); i <= n; i++ {
|
175
|
+
result *= i
|
112
176
|
}
|
113
|
-
|
177
|
+
|
178
|
+
return fmt.Sprintf("%d", result)
|
114
179
|
}
|
115
180
|
|
116
|
-
|
117
|
-
|
118
|
-
|
181
|
+
// goProcessArray processes an array of values
|
182
|
+
func goProcessArray(this js.Value, args []js.Value) interface{} {
|
183
|
+
if len(args) != 1 || args[0].Type() != js.TypeString {
|
184
|
+
return map[string]interface{}{
|
185
|
+
"error": "Expected 1 argument: comma-separated string",
|
186
|
+
}
|
119
187
|
}
|
120
|
-
return args[0] // Pass through
|
121
|
-
}
|
122
188
|
|
123
|
-
|
124
|
-
|
125
|
-
|
189
|
+
// Split the input string by commas
|
190
|
+
input := args[0].String()
|
191
|
+
parts := strings.Split(input, ",")
|
192
|
+
|
193
|
+
// Process each part
|
194
|
+
var results []string
|
195
|
+
for _, part := range parts {
|
196
|
+
// Trim whitespace
|
197
|
+
trimmed := strings.TrimSpace(part)
|
198
|
+
|
199
|
+
// Convert to uppercase and add to results
|
200
|
+
results = append(results, strings.ToUpper(trimmed))
|
126
201
|
}
|
127
|
-
return args[0] // Pass through
|
128
|
-
}
|
129
202
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
// Register functions to make available to JavaScript
|
134
|
-
js.Global().Set("goAdd", js.FuncOf(add))
|
135
|
-
js.Global().Set("goSubtract", js.FuncOf(subtract))
|
136
|
-
js.Global().Set("goMultiply", js.FuncOf(multiply))
|
137
|
-
js.Global().Set("goConcat", js.FuncOf(concat))
|
138
|
-
js.Global().Set("goParseJSON", js.FuncOf(parseJSON))
|
139
|
-
|
140
|
-
// Register special utility functions for frontend-hamroun integration
|
141
|
-
js.Global().Set("__stringToGo", js.FuncOf(__stringToGo))
|
142
|
-
js.Global().Set("__stringFromGo", js.FuncOf(__stringFromGo))
|
143
|
-
js.Global().Set("__objectToGo", js.FuncOf(__objectToGo))
|
144
|
-
js.Global().Set("__objectFromGo", js.FuncOf(__objectFromGo))
|
145
|
-
|
146
|
-
// Keep the program running
|
147
|
-
c := make(chan struct{}, 0)
|
148
|
-
fmt.Println("Go WebAssembly module ready")
|
149
|
-
<-c
|
203
|
+
// Join the processed parts with commas
|
204
|
+
return strings.Join(results, ",")
|
150
205
|
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import { build } from 'esbuild';
|
2
|
+
|
3
|
+
// Build client
|
4
|
+
await build({
|
5
|
+
entryPoints: ['src/client.tsx'],
|
6
|
+
bundle: true,
|
7
|
+
outfile: 'dist/client.js',
|
8
|
+
platform: 'browser',
|
9
|
+
format: 'esm',
|
10
|
+
minify: false,
|
11
|
+
jsx: 'transform',
|
12
|
+
jsxFactory: 'jsx',
|
13
|
+
jsxFragment: 'Fragment',
|
14
|
+
inject: ['./jsx-shim.js'],
|
15
|
+
});
|
16
|
+
|
17
|
+
// Build server
|
18
|
+
await build({
|
19
|
+
entryPoints: ['src/server.ts'],
|
20
|
+
bundle: true,
|
21
|
+
outfile: 'dist/server.js',
|
22
|
+
platform: 'node',
|
23
|
+
format: 'esm',
|
24
|
+
external: ['frontend-hamroun'],
|
25
|
+
packages: 'external',
|
26
|
+
minify: false,
|
27
|
+
jsx: 'transform',
|
28
|
+
jsxFactory: 'jsx',
|
29
|
+
jsxFragment: 'Fragment',
|
30
|
+
inject: ['./jsx-shim.js'],
|
31
|
+
});
|
32
|
+
|
33
|
+
console.log('Build completed successfully!');
|
@@ -0,0 +1 @@
|
|
1
|
+
export { jsx, Fragment } from 'frontend-hamroun';
|
@@ -1,16 +1,22 @@
|
|
1
|
-
{
|
2
|
-
"name": "ssr-
|
3
|
-
"
|
4
|
-
"
|
5
|
-
"
|
6
|
-
|
7
|
-
"
|
8
|
-
"build": "
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
"
|
14
|
-
"
|
15
|
-
}
|
16
|
-
|
1
|
+
{
|
2
|
+
"name": "ssr-version",
|
3
|
+
"private": true,
|
4
|
+
"version": "0.0.0",
|
5
|
+
"type": "module",
|
6
|
+
"scripts": {
|
7
|
+
"build:client": "esbuild src/client.tsx --bundle --outfile=dist/client.js --platform=browser --format=esm",
|
8
|
+
"build:server": "esbuild src/server.ts --bundle --outfile=dist/server.js --platform=node --format=esm --external:frontend-hamroun --packages=external",
|
9
|
+
"build": "node esbuild.config.js",
|
10
|
+
"start": "node dist/server.js"
|
11
|
+
},
|
12
|
+
"dependencies": {
|
13
|
+
"express": "^4.18.2",
|
14
|
+
"frontend-hamroun": "latest"
|
15
|
+
},
|
16
|
+
"devDependencies": {
|
17
|
+
"@types/express": "^4.17.17",
|
18
|
+
"@types/node": "^20.5.0",
|
19
|
+
"esbuild": "^0.19.12",
|
20
|
+
"typescript": "^5.0.0"
|
21
|
+
}
|
22
|
+
}
|
@@ -1,59 +1,19 @@
|
|
1
|
-
import { useState
|
2
|
-
|
3
|
-
// Create a theme context
|
4
|
-
const ThemeContext = createContext('light');
|
1
|
+
import { useState } from 'frontend-hamroun';
|
5
2
|
|
6
3
|
export function App() {
|
7
|
-
// Initialize with a default state that works on both server and client
|
8
4
|
const [count, setCount] = useState(0);
|
9
|
-
|
10
|
-
const
|
11
|
-
|
12
|
-
|
13
|
-
useEffect(() => {
|
14
|
-
if (typeof window !== 'undefined') {
|
15
|
-
renderCount.current += 1;
|
16
|
-
console.log('Component rendered', renderCount.current, 'times');
|
17
|
-
}
|
18
|
-
return () => console.log('Component unmounting');
|
19
|
-
}, [count]);
|
20
|
-
|
21
|
-
// Memoized value
|
22
|
-
const doubled = useMemo(() => count * 2, [count]);
|
23
|
-
|
5
|
+
|
6
|
+
const increment = () => setCount(count + 1);
|
7
|
+
const decrement = () => setCount(count - 1);
|
8
|
+
|
24
9
|
return (
|
25
|
-
<
|
26
|
-
<
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
<h1>Server-Side Rendered App</h1>
|
32
|
-
<div>
|
33
|
-
<button
|
34
|
-
onClick={() => setCount(count - 1)}
|
35
|
-
data-action="decrement"
|
36
|
-
>-</button>
|
37
|
-
<span style={{ margin: '0 10px' }}>{count}</span>
|
38
|
-
<button
|
39
|
-
onClick={() => setCount(count + 1)}
|
40
|
-
data-action="increment"
|
41
|
-
>+</button>
|
42
|
-
</div>
|
43
|
-
<p>Doubled value: {doubled}</p>
|
44
|
-
{typeof window !== 'undefined' && (
|
45
|
-
<p>Render count: {renderCount.current}</p>
|
46
|
-
)}
|
47
|
-
<button
|
48
|
-
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
|
49
|
-
style={{ marginTop: '10px' }}
|
50
|
-
>
|
51
|
-
Toggle Theme ({theme})
|
52
|
-
</button>
|
53
|
-
<script dangerouslySetInnerHTML={{
|
54
|
-
__html: `window.__INITIAL_STATE__ = ${JSON.stringify({ count: 0, theme: 'light' })};`
|
55
|
-
}} />
|
10
|
+
<div>
|
11
|
+
<h1>Server-Side Rendered App</h1>
|
12
|
+
<div>
|
13
|
+
<button onClick={decrement} data-action="decrement">-</button>
|
14
|
+
<span style={{ margin: '0 10px' }}>{count}</span>
|
15
|
+
<button onClick={increment} data-action="increment">+</button>
|
56
16
|
</div>
|
57
|
-
</
|
17
|
+
</div>
|
58
18
|
);
|
59
19
|
}
|
@@ -1,18 +1,4 @@
|
|
1
|
-
import { hydrate,
|
1
|
+
import { hydrate, jsx } from 'frontend-hamroun';
|
2
|
+
import { App } from './App.js';
|
2
3
|
|
3
|
-
|
4
|
-
// In a more complex app, you might use a router
|
5
|
-
import HomePage from './pages/index';
|
6
|
-
|
7
|
-
// When the DOM is ready, hydrate the server-rendered HTML
|
8
|
-
document.addEventListener('DOMContentLoaded', () => {
|
9
|
-
const rootElement = document.getElementById('app');
|
10
|
-
|
11
|
-
if (rootElement) {
|
12
|
-
// Hydrate the app with the same component that was rendered on the server
|
13
|
-
hydrate(<HomePage />, rootElement);
|
14
|
-
console.log('Hydration complete');
|
15
|
-
} else {
|
16
|
-
console.error('Could not find root element with id "app"');
|
17
|
-
}
|
18
|
-
});
|
4
|
+
hydrate(jsx(App, {}), document.getElementById('root')!);
|