frontend-hamroun 1.2.69 → 1.2.71
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/package.json +1 -1
- package/templates/go-wasm-app/README.md +38 -0
- package/templates/go-wasm-app/babel.config.js +15 -0
- package/templates/go-wasm-app/build-client.js +49 -0
- package/templates/go-wasm-app/build-wasm.js +95 -73
- package/templates/go-wasm-app/package-lock.json +6459 -0
- package/templates/go-wasm-app/package.json +9 -8
- package/templates/go-wasm-app/public/index.html +118 -3
- package/templates/go-wasm-app/public/styles.css +197 -0
- package/templates/go-wasm-app/public/wasm/example.wasm +0 -0
- package/templates/go-wasm-app/public/wasm/wasm_exec.js +561 -0
- package/templates/go-wasm-app/public/wasm/wasm_exec_node.js +39 -0
- package/templates/go-wasm-app/server.js +521 -0
- package/templates/go-wasm-app/src/App.jsx +38 -0
- package/templates/go-wasm-app/src/client.js +57 -0
- package/templates/go-wasm-app/src/components/Footer.jsx +13 -0
- package/templates/go-wasm-app/src/components/Header.jsx +19 -0
- package/templates/go-wasm-app/src/components/WasmDemo.jsx +120 -0
- package/templates/go-wasm-app/src/main.jsx +12 -0
- package/templates/go-wasm-app/src/wasm/example.go +75 -0
- package/templates/go-wasm-app/tsconfig.server.json +18 -0
- package/templates/go-wasm-app/vite.config.js +10 -4
@@ -0,0 +1,120 @@
|
|
1
|
+
import { jsx, useState } from 'frontend-hamroun';
|
2
|
+
|
3
|
+
export default function WasmDemo({ wasm }) {
|
4
|
+
// Addition demo state
|
5
|
+
const [num1, setNum1] = useState(5);
|
6
|
+
const [num2, setNum2] = useState(7);
|
7
|
+
const [sum, setSum] = useState(null);
|
8
|
+
|
9
|
+
// Data processing demo state
|
10
|
+
const [processInput, setProcessInput] = useState(JSON.stringify({
|
11
|
+
name: 'Test data',
|
12
|
+
source: 'client',
|
13
|
+
values: [10, 20, 30, 40, 50],
|
14
|
+
timestamp: new Date().toISOString()
|
15
|
+
}, null, 2));
|
16
|
+
const [processResult, setProcessResult] = useState(null);
|
17
|
+
|
18
|
+
// Error state
|
19
|
+
const [error, setError] = useState(null);
|
20
|
+
|
21
|
+
// Handle addition with Go WASM
|
22
|
+
const handleCalculate = () => {
|
23
|
+
try {
|
24
|
+
setError(null);
|
25
|
+
// Get the goAdd function from the WASM instance
|
26
|
+
const goAdd = wasm.functions.goAdd;
|
27
|
+
// Call the Go function and get the result
|
28
|
+
const result = goAdd(parseInt(num1), parseInt(num2));
|
29
|
+
setSum(result);
|
30
|
+
} catch (err) {
|
31
|
+
console.error('Error calling Go function:', err);
|
32
|
+
setError(`Error: ${err.message}`);
|
33
|
+
}
|
34
|
+
};
|
35
|
+
|
36
|
+
// Handle complex data processing with Go WASM
|
37
|
+
const handleProcessData = () => {
|
38
|
+
try {
|
39
|
+
setError(null);
|
40
|
+
// Parse the input JSON
|
41
|
+
const inputData = JSON.parse(processInput);
|
42
|
+
// Get the goProcessData function from the WASM instance
|
43
|
+
const goProcessData = wasm.functions.goProcessData;
|
44
|
+
// Call the Go function with the data
|
45
|
+
const result = goProcessData(inputData);
|
46
|
+
// Parse the returned JSON and format it
|
47
|
+
setProcessResult(JSON.parse(result));
|
48
|
+
} catch (err) {
|
49
|
+
console.error('Error processing data with Go:', err);
|
50
|
+
setError(`Error: ${err.message}`);
|
51
|
+
}
|
52
|
+
};
|
53
|
+
|
54
|
+
return (
|
55
|
+
<div className="wasm-demo">
|
56
|
+
{error && (
|
57
|
+
<div className="error-message">
|
58
|
+
{error}
|
59
|
+
</div>
|
60
|
+
)}
|
61
|
+
|
62
|
+
<section className="demo-section">
|
63
|
+
<h2>Simple Addition with Go</h2>
|
64
|
+
<p>Call a Go WASM function to add two numbers:</p>
|
65
|
+
<div className="input-row">
|
66
|
+
<input
|
67
|
+
type="number"
|
68
|
+
value={num1}
|
69
|
+
onChange={(e) => setNum1(e.target.value)}
|
70
|
+
/>
|
71
|
+
<span className="operator">+</span>
|
72
|
+
<input
|
73
|
+
type="number"
|
74
|
+
value={num2}
|
75
|
+
onChange={(e) => setNum2(e.target.value)}
|
76
|
+
/>
|
77
|
+
<button onClick={handleCalculate}>Calculate</button>
|
78
|
+
</div>
|
79
|
+
|
80
|
+
{sum !== null && (
|
81
|
+
<div className="result">
|
82
|
+
<h3>Result:</h3>
|
83
|
+
<pre>{sum}</pre>
|
84
|
+
</div>
|
85
|
+
)}
|
86
|
+
</section>
|
87
|
+
|
88
|
+
<section className="demo-section">
|
89
|
+
<h2>Complex Data Processing with Go</h2>
|
90
|
+
<p>Process JSON data using a Go WASM function:</p>
|
91
|
+
<div className="json-editor">
|
92
|
+
<textarea
|
93
|
+
value={processInput}
|
94
|
+
onChange={(e) => setProcessInput(e.target.value)}
|
95
|
+
rows={10}
|
96
|
+
/>
|
97
|
+
<button onClick={handleProcessData}>Process Data</button>
|
98
|
+
</div>
|
99
|
+
|
100
|
+
{processResult && (
|
101
|
+
<div className="result">
|
102
|
+
<h3>Processed Result:</h3>
|
103
|
+
<pre>{JSON.stringify(processResult, null, 2)}</pre>
|
104
|
+
</div>
|
105
|
+
)}
|
106
|
+
</section>
|
107
|
+
|
108
|
+
<section className="info-section">
|
109
|
+
<h2>How It Works</h2>
|
110
|
+
<p>This demo demonstrates the integration between Frontend Hamroun and Go WebAssembly with SSR:</p>
|
111
|
+
<ol>
|
112
|
+
<li>Server renders the initial HTML using the same React-like components</li>
|
113
|
+
<li>Server can process data with Go WASM before sending the response</li>
|
114
|
+
<li>Browser hydrates the app and loads its own WASM module</li>
|
115
|
+
<li>The same Go code runs in both server and browser environments</li>
|
116
|
+
</ol>
|
117
|
+
</section>
|
118
|
+
</div>
|
119
|
+
);
|
120
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { hydrate } from 'frontend-hamroun';
|
2
|
+
import App from './App';
|
3
|
+
|
4
|
+
// Get initial state from server
|
5
|
+
const initialState = window.__INITIAL_STATE__ || {
|
6
|
+
path: window.location.pathname,
|
7
|
+
ssrRendered: false,
|
8
|
+
wasmAvailable: false
|
9
|
+
};
|
10
|
+
|
11
|
+
// Hydrate the application
|
12
|
+
hydrate(<App initialState={initialState} />, document.getElementById('root'));
|
@@ -0,0 +1,75 @@
|
|
1
|
+
//go:build js && wasm
|
2
|
+
// +build js,wasm
|
3
|
+
|
4
|
+
package main
|
5
|
+
|
6
|
+
import (
|
7
|
+
"encoding/json"
|
8
|
+
"fmt"
|
9
|
+
"syscall/js"
|
10
|
+
)
|
11
|
+
|
12
|
+
// Example Go function to be called from JavaScript
|
13
|
+
func add(this js.Value, args []js.Value) interface{} {
|
14
|
+
if len(args) != 2 {
|
15
|
+
return js.ValueOf("Error: Expected two arguments")
|
16
|
+
}
|
17
|
+
|
18
|
+
a := args[0].Int()
|
19
|
+
b := args[1].Int()
|
20
|
+
return js.ValueOf(a + b)
|
21
|
+
}
|
22
|
+
|
23
|
+
// Process complex data in Go
|
24
|
+
func processData(this js.Value, args []js.Value) interface{} {
|
25
|
+
if len(args) == 0 {
|
26
|
+
return js.ValueOf("Error: Expected at least one argument")
|
27
|
+
}
|
28
|
+
|
29
|
+
// Get input data
|
30
|
+
data := args[0]
|
31
|
+
if data.Type() != js.TypeObject {
|
32
|
+
return js.ValueOf("Error: Expected JSON object")
|
33
|
+
}
|
34
|
+
|
35
|
+
// Convert JS object to Go map
|
36
|
+
jsonStr := js.Global().Get("JSON").Call("stringify", data).String()
|
37
|
+
var inputMap map[string]interface{}
|
38
|
+
if err := json.Unmarshal([]byte(jsonStr), &inputMap); err != nil {
|
39
|
+
return js.ValueOf(fmt.Sprintf("Error parsing JSON: %s", err.Error()))
|
40
|
+
}
|
41
|
+
|
42
|
+
// Add new fields
|
43
|
+
inputMap["processed"] = true
|
44
|
+
inputMap["processor"] = "Go WASM"
|
45
|
+
|
46
|
+
// Add some computed fields
|
47
|
+
if values, ok := inputMap["values"].([]interface{}); ok {
|
48
|
+
sum := 0.0
|
49
|
+
for _, v := range values {
|
50
|
+
if num, ok := v.(float64); ok {
|
51
|
+
sum += num
|
52
|
+
}
|
53
|
+
}
|
54
|
+
inputMap["sum"] = sum
|
55
|
+
}
|
56
|
+
|
57
|
+
// Convert back to JS
|
58
|
+
resultJSON, err := json.Marshal(inputMap)
|
59
|
+
if err != nil {
|
60
|
+
return js.ValueOf(fmt.Sprintf("Error generating JSON: %s", err.Error()))
|
61
|
+
}
|
62
|
+
|
63
|
+
return js.ValueOf(string(resultJSON))
|
64
|
+
}
|
65
|
+
|
66
|
+
func main() {
|
67
|
+
fmt.Println("Go WASM Module initialized")
|
68
|
+
|
69
|
+
// Register functions to be callable from JavaScript
|
70
|
+
js.Global().Set("goAdd", js.FuncOf(add))
|
71
|
+
js.Global().Set("goProcessData", js.FuncOf(processData))
|
72
|
+
|
73
|
+
// Keep the program running
|
74
|
+
<-make(chan bool)
|
75
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"target": "ESNext",
|
4
|
+
"module": "ESNext",
|
5
|
+
"moduleResolution": "Node",
|
6
|
+
"esModuleInterop": true,
|
7
|
+
"strict": true,
|
8
|
+
"skipLibCheck": true,
|
9
|
+
"outDir": "dist/server",
|
10
|
+
"jsx": "react",
|
11
|
+
"jsxFactory": "jsx",
|
12
|
+
"jsxFragmentFactory": "Fragment",
|
13
|
+
"allowJs": true,
|
14
|
+
"declaration": false
|
15
|
+
},
|
16
|
+
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx"],
|
17
|
+
"exclude": ["node_modules"]
|
18
|
+
}
|
@@ -4,8 +4,9 @@ import { resolve } from 'path';
|
|
4
4
|
export default defineConfig({
|
5
5
|
// Configure JSX
|
6
6
|
esbuild: {
|
7
|
-
jsxFactory: '
|
8
|
-
jsxFragment: 'Fragment'
|
7
|
+
jsxFactory: 'createElement',
|
8
|
+
jsxFragment: 'Fragment',
|
9
|
+
jsxInject: `import { createElement, Fragment } from 'frontend-hamroun'`
|
9
10
|
},
|
10
11
|
|
11
12
|
// Configure build
|
@@ -14,12 +15,17 @@ export default defineConfig({
|
|
14
15
|
emptyOutDir: true,
|
15
16
|
rollupOptions: {
|
16
17
|
input: {
|
17
|
-
|
18
|
+
client: resolve(__dirname, 'src/client.js')
|
19
|
+
},
|
20
|
+
output: {
|
21
|
+
entryFileNames: 'assets/[name].js',
|
22
|
+
chunkFileNames: 'assets/[name]-[hash].js',
|
23
|
+
assetFileNames: 'assets/[name]-[hash].[ext]'
|
18
24
|
}
|
19
25
|
}
|
20
26
|
},
|
21
27
|
|
22
|
-
// Resolve aliases
|
28
|
+
// Resolve aliases for better imports
|
23
29
|
resolve: {
|
24
30
|
alias: {
|
25
31
|
'@': resolve(__dirname, 'src')
|