baraqex 1.0.76 → 2.0.1
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/CHANGELOG.md +73 -0
- package/README.md +268 -315
- package/bin/baraqex.js +150 -12
- package/dist/browser.d.ts +1 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +2319 -205
- package/dist/browser.js.map +4 -4
- package/dist/core/batch.d.ts +10 -0
- package/dist/core/batch.d.ts.map +1 -0
- package/dist/core/component.d.ts +69 -0
- package/dist/core/component.d.ts.map +1 -0
- package/dist/core/context.d.ts +22 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/errors.d.ts +125 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/event-bus.d.ts +29 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/forms.d.ts +128 -0
- package/dist/core/forms.d.ts.map +1 -0
- package/dist/core/hooks.d.ts +84 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/index.d.ts +23 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/jsx-runtime.d.ts +45 -0
- package/dist/core/jsx-runtime.d.ts.map +1 -0
- package/dist/core/lifecycle-events.d.ts +71 -0
- package/dist/core/lifecycle-events.d.ts.map +1 -0
- package/dist/core/renderer.d.ts +39 -0
- package/dist/core/renderer.d.ts.map +1 -0
- package/dist/core/router.d.ts +108 -0
- package/dist/core/router.d.ts.map +1 -0
- package/dist/core/server-renderer.d.ts +26 -0
- package/dist/core/server-renderer.d.ts.map +1 -0
- package/dist/core/store.d.ts +102 -0
- package/dist/core/store.d.ts.map +1 -0
- package/dist/core/types.d.ts +66 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/utils.d.ts +153 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/core/vdom.d.ts +29 -0
- package/dist/core/vdom.d.ts.map +1 -0
- package/dist/index.d.ts +39 -35
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2596 -508
- package/dist/index.js.map +4 -4
- package/dist/server/auth.d.ts +8 -3
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +173 -112
- package/dist/server/index.js.map +4 -4
- package/dist/server/middleware.d.ts +10 -1
- package/dist/server/middleware.d.ts.map +1 -1
- package/package.json +224 -124
- package/templates/basic-app/src/main.jsx +336 -0
- package/templates/complete-app/api/hello.js +0 -0
- package/templates/complete-app/client.js +58 -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/readme.md +188 -0
- package/templates/complete-app/server.js +226 -0
- package/templates/complete-app/server.ts +275 -0
- package/templates/complete-app/src/App.tsx +59 -0
- package/templates/complete-app/src/client.ts +61 -0
- package/templates/complete-app/src/client.tsx +18 -0
- package/templates/complete-app/src/pages/index.tsx +51 -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/complete-app/vite.config.js +57 -0
- 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/README.md +37 -0
- package/templates/fullstack-app/api/hello.js +11 -0
- package/templates/fullstack-app/api/hello.ts +18 -0
- package/templates/fullstack-app/api/users/[id].ts +73 -0
- package/templates/fullstack-app/api/users/index.ts +32 -0
- package/templates/fullstack-app/build/main.css +874 -0
- package/templates/fullstack-app/build/main.css.map +7 -0
- package/templates/fullstack-app/build/main.js +967 -0
- package/templates/fullstack-app/build/main.js.map +7 -0
- package/templates/fullstack-app/build.ts +210 -0
- package/templates/fullstack-app/index.html +36 -0
- package/templates/fullstack-app/package.json +35 -0
- package/templates/fullstack-app/postcss.config.js +6 -0
- package/templates/fullstack-app/process-tailwind.js +45 -0
- package/templates/fullstack-app/public/_redirects +1 -0
- package/templates/fullstack-app/public/route-handler.js +47 -0
- package/templates/fullstack-app/public/spa-fix.html +17 -0
- package/templates/fullstack-app/public/styles.css +975 -0
- package/templates/fullstack-app/public/tailwind.css +15 -0
- package/templates/fullstack-app/server.js +267 -0
- package/templates/fullstack-app/server.ts +474 -0
- package/templates/fullstack-app/src/README.md +55 -0
- package/templates/fullstack-app/src/client.js +87 -0
- 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 +42 -0
- package/templates/fullstack-app/src/components/StateDemo.tsx +207 -0
- package/templates/fullstack-app/src/components/UserList.tsx +44 -0
- package/templates/fullstack-app/src/config.ts +42 -0
- package/templates/fullstack-app/src/data/api.ts +206 -0
- package/templates/fullstack-app/src/main.tsx +155 -0
- 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/index.tsx +67 -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 +110 -0
- package/templates/fullstack-app/src/pages/users/[id].tsx +153 -0
- package/templates/fullstack-app/src/pages/users.tsx +60 -0
- package/templates/fullstack-app/src/pages/wasm-demo.tsx +1 -0
- package/templates/fullstack-app/src/router.ts +255 -0
- package/templates/fullstack-app/src/styles.css +5 -0
- package/templates/fullstack-app/tailwind.config.js +11 -0
- package/templates/fullstack-app/tsconfig.json +18 -0
- package/templates/fullstack-app/vite.config.js +87 -0
- package/templates/go/build.bat +36 -0
- package/templates/go/build.sh +43 -0
- package/templates/go/example.go +205 -0
- package/templates/go-wasm-app/README.md +38 -0
- package/templates/go-wasm-app/babel.config.js +21 -0
- package/templates/go-wasm-app/build-client.js +49 -0
- package/templates/go-wasm-app/build-wasm.js +237 -0
- 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 +32 -0
- package/templates/go-wasm-app/public/index.html +128 -0
- 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 +70 -0
- package/templates/go-wasm-app/src/App.jsx +38 -0
- package/templates/go-wasm-app/src/app.js +173 -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 +45 -0
- package/dist/forms/index.d.ts +0 -2
- package/dist/forms/index.d.ts.map +0 -1
- package/dist/forms/types.d.ts +0 -2
- package/dist/forms/types.d.ts.map +0 -1
- package/dist/frontend/components/WasmLoader.d.ts +0 -2
- package/dist/frontend/components/WasmLoader.d.ts.map +0 -1
- package/dist/frontend/hooks/useWasm.d.ts +0 -2
- package/dist/frontend/hooks/useWasm.d.ts.map +0 -1
- package/dist/frontend/index.d.ts +0 -2
- package/dist/frontend/index.d.ts.map +0 -1
- package/dist/router/index.d.ts +0 -2
- package/dist/router/index.d.ts.map +0 -1
- package/dist/router/types.d.ts +0 -2
- package/dist/router/types.d.ts.map +0 -1
- package/dist/store/index.d.ts +0 -2
- package/dist/store/index.d.ts.map +0 -1
- package/dist/store/types.d.ts +0 -2
- package/dist/store/types.d.ts.map +0 -1
- package/templates/basic-app/package-lock.json +0 -7173
- package/templates/fullstack-template/package-lock.json +0 -3558
- package/templates/ssr-template/package-lock.json +0 -5380
- package/templates/wasm/package-lock.json +0 -5347
- package/templates/wasm/public/example.wasm +0 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
//go:build js && wasm
|
|
2
|
+
// +build js,wasm
|
|
3
|
+
|
|
4
|
+
package main
|
|
5
|
+
|
|
6
|
+
import (
|
|
7
|
+
"fmt"
|
|
8
|
+
"strconv"
|
|
9
|
+
"strings"
|
|
10
|
+
"syscall/js"
|
|
11
|
+
)
|
|
12
|
+
|
|
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{} {
|
|
31
|
+
if len(args) != 2 {
|
|
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
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Return the result
|
|
49
|
+
return fmt.Sprintf("%g", a+b)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// goSubtract subtracts the second number from the first
|
|
53
|
+
func goSubtract(this js.Value, args []js.Value) interface{} {
|
|
54
|
+
if len(args) != 2 {
|
|
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
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Return the result
|
|
72
|
+
return fmt.Sprintf("%g", a-b)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// goMultiply multiplies two numbers
|
|
76
|
+
func goMultiply(this js.Value, args []js.Value) interface{} {
|
|
77
|
+
if len(args) != 2 {
|
|
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
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Return the result
|
|
95
|
+
return fmt.Sprintf("%g", a*b)
|
|
96
|
+
}
|
|
97
|
+
|
|
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
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Check for division by zero
|
|
118
|
+
if b == 0 {
|
|
119
|
+
return map[string]interface{}{
|
|
120
|
+
"error": "Division by zero is not allowed",
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Return the result
|
|
125
|
+
return fmt.Sprintf("%g", a/b)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// goReverseString reverses a string
|
|
129
|
+
func goReverseString(this js.Value, args []js.Value) interface{} {
|
|
130
|
+
if len(args) != 1 {
|
|
131
|
+
return map[string]interface{}{
|
|
132
|
+
"error": "Expected 1 argument: string",
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
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]
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return string(runes)
|
|
145
|
+
}
|
|
146
|
+
|
|
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",
|
|
152
|
+
}
|
|
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",
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Check for negative numbers
|
|
166
|
+
if n < 0 {
|
|
167
|
+
return map[string]interface{}{
|
|
168
|
+
"error": "Factorial is not defined for negative numbers",
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Calculate factorial
|
|
173
|
+
result := int64(1)
|
|
174
|
+
for i := int64(2); i <= n; i++ {
|
|
175
|
+
result *= i
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return fmt.Sprintf("%d", result)
|
|
179
|
+
}
|
|
180
|
+
|
|
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
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
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))
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Join the processed parts with commas
|
|
204
|
+
return strings.Join(results, ",")
|
|
205
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Frontend Hamroun - Go WebAssembly Template with SSR
|
|
2
|
+
|
|
3
|
+
This template demonstrates integration between Frontend Hamroun, Go WebAssembly, and Server-Side Rendering for high-performance web applications.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔄 Go + WebAssembly integration
|
|
8
|
+
- 🌐 Server-Side Rendering with client hydration
|
|
9
|
+
- ⚡ High-performance computation in both browser and server
|
|
10
|
+
- 🚀 Same Go code runs in both environments
|
|
11
|
+
- 🔍 SEO-friendly with pre-rendered HTML
|
|
12
|
+
|
|
13
|
+
## Prerequisites
|
|
14
|
+
|
|
15
|
+
- [Node.js](https://nodejs.org/) (v14+)
|
|
16
|
+
- [Go](https://golang.org/dl/) (v1.16+)
|
|
17
|
+
|
|
18
|
+
## Getting Started
|
|
19
|
+
|
|
20
|
+
1. Install dependencies:
|
|
21
|
+
```
|
|
22
|
+
npm install
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
2. Start the development server:
|
|
26
|
+
```
|
|
27
|
+
npm run dev
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
3. Open your browser and navigate to `http://localhost:3000`
|
|
31
|
+
|
|
32
|
+
The development server includes:
|
|
33
|
+
- Automatic WASM compilation from Go source
|
|
34
|
+
- Server-side rendering with Express
|
|
35
|
+
- Hot reloading of server code with Node's `--watch` flag
|
|
36
|
+
- Client-side hydration for interactivity
|
|
37
|
+
|
|
38
|
+
## Project Structure
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const config = {
|
|
2
|
+
presets: [
|
|
3
|
+
['@babel/preset-env', {
|
|
4
|
+
targets: {
|
|
5
|
+
node: 'current'
|
|
6
|
+
},
|
|
7
|
+
// Enable dynamic imports for both ESM and CommonJS
|
|
8
|
+
modules: false
|
|
9
|
+
}]
|
|
10
|
+
],
|
|
11
|
+
plugins: [
|
|
12
|
+
['@babel/plugin-transform-react-jsx', {
|
|
13
|
+
pragma: 'createElement',
|
|
14
|
+
pragmaFrag: 'Fragment'
|
|
15
|
+
}]
|
|
16
|
+
]
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Support both ESM and CommonJS
|
|
20
|
+
export default config;
|
|
21
|
+
module.exports = config;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
// Get __dirname equivalent in ESM
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = path.dirname(__filename);
|
|
8
|
+
|
|
9
|
+
// Output directory
|
|
10
|
+
const outputDir = path.join(__dirname, 'dist');
|
|
11
|
+
|
|
12
|
+
// Ensure output directory exists
|
|
13
|
+
fs.ensureDirSync(outputDir);
|
|
14
|
+
|
|
15
|
+
// Copy necessary files for production
|
|
16
|
+
console.log('Copying files for production...');
|
|
17
|
+
|
|
18
|
+
// Copy HTML template
|
|
19
|
+
fs.copySync(path.join(__dirname, 'public', 'index.html'), path.join(outputDir, 'index.html'));
|
|
20
|
+
|
|
21
|
+
// Copy WASM files
|
|
22
|
+
const wasmDir = path.join(__dirname, 'public', 'wasm');
|
|
23
|
+
const distWasmDir = path.join(outputDir, 'wasm');
|
|
24
|
+
fs.ensureDirSync(distWasmDir);
|
|
25
|
+
|
|
26
|
+
if (fs.existsSync(wasmDir)) {
|
|
27
|
+
fs.copySync(wasmDir, distWasmDir);
|
|
28
|
+
console.log('Copied WASM files to:', distWasmDir);
|
|
29
|
+
} else {
|
|
30
|
+
console.warn('WASM directory not found:', wasmDir);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Copy client.js for hydration
|
|
34
|
+
const srcDir = path.join(__dirname, 'src');
|
|
35
|
+
const distSrcDir = path.join(outputDir, 'src');
|
|
36
|
+
fs.ensureDirSync(distSrcDir);
|
|
37
|
+
fs.copySync(path.join(srcDir, 'client.js'), path.join(distSrcDir, 'client.js'));
|
|
38
|
+
|
|
39
|
+
// Copy any other static assets
|
|
40
|
+
const publicDir = path.join(__dirname, 'public');
|
|
41
|
+
fs.readdirSync(publicDir).forEach(file => {
|
|
42
|
+
if (file !== 'index.html' && file !== 'wasm') {
|
|
43
|
+
const srcPath = path.join(publicDir, file);
|
|
44
|
+
const destPath = path.join(outputDir, file);
|
|
45
|
+
fs.copySync(srcPath, destPath);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
console.log('Build completed successfully.');
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import { dirname, resolve, join } from 'path';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import os from 'os';
|
|
6
|
+
|
|
7
|
+
// Get __dirname equivalent in ESM
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
|
|
11
|
+
// Check if running on Windows
|
|
12
|
+
const isWindows = os.platform() === 'win32';
|
|
13
|
+
|
|
14
|
+
// Check if Go is installed
|
|
15
|
+
function checkGoInstallation() {
|
|
16
|
+
try {
|
|
17
|
+
const output = execSync('go version', { encoding: 'utf8' });
|
|
18
|
+
console.log(`✓ Found Go: ${output.trim()}`);
|
|
19
|
+
return true;
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.error('✗ Go is not installed or not in PATH');
|
|
22
|
+
console.error('Please install Go from https://golang.org/dl/');
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Ensure directory exists
|
|
28
|
+
function ensureDir(dir) {
|
|
29
|
+
if (!fs.existsSync(dir)) {
|
|
30
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
31
|
+
console.log(`Created directory: ${dir}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Build Go WASM modules
|
|
36
|
+
async function buildWasmModules() {
|
|
37
|
+
// Check if Go is installed
|
|
38
|
+
if (!checkGoInstallation()) {
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Directory containing Go source files
|
|
43
|
+
const goSourceDir = resolve(__dirname, 'src', 'wasm');
|
|
44
|
+
|
|
45
|
+
// Output directory for WASM files
|
|
46
|
+
const wasmOutputDir = resolve(__dirname, 'public', 'wasm');
|
|
47
|
+
|
|
48
|
+
// Create directories if they don't exist
|
|
49
|
+
ensureDir(goSourceDir);
|
|
50
|
+
ensureDir(wasmOutputDir);
|
|
51
|
+
|
|
52
|
+
// Get the Go root directory
|
|
53
|
+
const goRoot = execSync('go env GOROOT', { encoding: 'utf8' }).trim();
|
|
54
|
+
|
|
55
|
+
// Copy the wasm_exec.js files to the output directory (for both browser and Node.js)
|
|
56
|
+
const wasmExecJsPath = join(goRoot, 'misc', 'wasm', 'wasm_exec.js');
|
|
57
|
+
const wasmExecJsDest = join(wasmOutputDir, 'wasm_exec.js');
|
|
58
|
+
|
|
59
|
+
const wasmExecNodeJsPath = join(goRoot, 'misc', 'wasm', 'wasm_exec_node.js');
|
|
60
|
+
const wasmExecNodeJsDest = join(wasmOutputDir, 'wasm_exec_node.js');
|
|
61
|
+
|
|
62
|
+
console.log(`Copying ${wasmExecJsPath} to ${wasmExecJsDest}`);
|
|
63
|
+
fs.copyFileSync(wasmExecJsPath, wasmExecJsDest);
|
|
64
|
+
|
|
65
|
+
console.log(`Copying ${wasmExecNodeJsPath} to ${wasmExecNodeJsDest}`);
|
|
66
|
+
fs.copyFileSync(wasmExecNodeJsPath, wasmExecNodeJsDest);
|
|
67
|
+
|
|
68
|
+
// Build all Go files in the WASM directory
|
|
69
|
+
const goFiles = fs.readdirSync(goSourceDir).filter(file => file.endsWith('.go'));
|
|
70
|
+
|
|
71
|
+
if (goFiles.length === 0) {
|
|
72
|
+
console.log('No Go files found in src/wasm');
|
|
73
|
+
|
|
74
|
+
// Create an example Go file
|
|
75
|
+
const exampleGoFile = join(goSourceDir, 'example.go');
|
|
76
|
+
const exampleGoContent = `//go:build js && wasm
|
|
77
|
+
// +build js,wasm
|
|
78
|
+
|
|
79
|
+
package main
|
|
80
|
+
|
|
81
|
+
import (
|
|
82
|
+
"encoding/json"
|
|
83
|
+
"fmt"
|
|
84
|
+
"syscall/js"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
// Example Go function to be called from JavaScript
|
|
88
|
+
func add(this js.Value, args []js.Value) interface{} {
|
|
89
|
+
if len(args) != 2 {
|
|
90
|
+
return js.ValueOf("Error: Expected two arguments")
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
a := args[0].Int()
|
|
94
|
+
b := args[1].Int()
|
|
95
|
+
return js.ValueOf(a + b)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Process complex data in Go
|
|
99
|
+
func processData(this js.Value, args []js.Value) interface{} {
|
|
100
|
+
if len(args) == 0 {
|
|
101
|
+
return js.ValueOf("Error: Expected at least one argument")
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Get input data
|
|
105
|
+
data := args[0]
|
|
106
|
+
if data.Type() != js.TypeObject {
|
|
107
|
+
return js.ValueOf("Error: Expected JSON object")
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Convert JS object to Go map
|
|
111
|
+
jsonStr := js.Global().Get("JSON").Call("stringify", data).String()
|
|
112
|
+
var inputMap map[string]interface{}
|
|
113
|
+
if err := json.Unmarshal([]byte(jsonStr), &inputMap); err != nil {
|
|
114
|
+
return js.ValueOf(fmt.Sprintf("Error parsing JSON: %s", err.Error()))
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Add new fields
|
|
118
|
+
inputMap["processed"] = true
|
|
119
|
+
inputMap["processor"] = "Go WASM"
|
|
120
|
+
|
|
121
|
+
// Add some computed fields
|
|
122
|
+
if values, ok := inputMap["values"].([]interface{}); ok {
|
|
123
|
+
sum := 0.0
|
|
124
|
+
for _, v := range values {
|
|
125
|
+
if num, ok := v.(float64); ok {
|
|
126
|
+
sum += num
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
inputMap["sum"] = sum
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Convert back to JS
|
|
133
|
+
resultJSON, err := json.Marshal(inputMap)
|
|
134
|
+
if err != nil {
|
|
135
|
+
return js.ValueOf(fmt.Sprintf("Error generating JSON: %s", err.Error()))
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return js.ValueOf(string(resultJSON))
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
func main() {
|
|
142
|
+
fmt.Println("Go WASM Module initialized")
|
|
143
|
+
|
|
144
|
+
// Register functions to be callable from JavaScript
|
|
145
|
+
js.Global().Set("goAdd", js.FuncOf(add))
|
|
146
|
+
js.Global().Set("goProcessData", js.FuncOf(processData))
|
|
147
|
+
|
|
148
|
+
// Keep the program running
|
|
149
|
+
<-make(chan bool)
|
|
150
|
+
}
|
|
151
|
+
`;
|
|
152
|
+
|
|
153
|
+
fs.writeFileSync(exampleGoFile, exampleGoContent);
|
|
154
|
+
console.log(`Created example Go file at ${exampleGoFile}`);
|
|
155
|
+
|
|
156
|
+
// Add the new file to the list
|
|
157
|
+
goFiles.push('example.go');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Build each Go file
|
|
161
|
+
for (const goFile of goFiles) {
|
|
162
|
+
const goFilePath = join(goSourceDir, goFile);
|
|
163
|
+
const wasmFileName = goFile.replace('.go', '.wasm');
|
|
164
|
+
const wasmFilePath = join(wasmOutputDir, wasmFileName);
|
|
165
|
+
|
|
166
|
+
console.log(`Building ${goFile} to ${wasmFilePath}`);
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
// Create a unique temporary directory with timestamp
|
|
170
|
+
const timestamp = Date.now();
|
|
171
|
+
const tempDir = join(os.tmpdir(), `go-wasm-build-${timestamp}`);
|
|
172
|
+
|
|
173
|
+
// Ensure the directory is clean (doesn't exist from previous builds)
|
|
174
|
+
if (fs.existsSync(tempDir)) {
|
|
175
|
+
if (isWindows) {
|
|
176
|
+
// On Windows, we need to handle directory removal differently
|
|
177
|
+
execSync(`rmdir /s /q "${tempDir}"`, { shell: true });
|
|
178
|
+
} else {
|
|
179
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Create the temporary directory
|
|
184
|
+
ensureDir(tempDir);
|
|
185
|
+
|
|
186
|
+
// Copy the Go file to the temp directory
|
|
187
|
+
const tempGoFile = join(tempDir, goFile);
|
|
188
|
+
fs.copyFileSync(goFilePath, tempGoFile);
|
|
189
|
+
|
|
190
|
+
// Initialize Go module
|
|
191
|
+
console.log(`Initializing Go module in ${tempDir}`);
|
|
192
|
+
execSync(`go mod init wasmapp`, { cwd: tempDir });
|
|
193
|
+
|
|
194
|
+
// Build the WASM module with OS-specific command
|
|
195
|
+
if (isWindows) {
|
|
196
|
+
// Fix: Use Windows-specific environment variable setting
|
|
197
|
+
execSync(`go build -o "${wasmFilePath}" "${tempGoFile}"`, {
|
|
198
|
+
cwd: tempDir,
|
|
199
|
+
env: {
|
|
200
|
+
...process.env,
|
|
201
|
+
GOOS: 'js',
|
|
202
|
+
GOARCH: 'wasm'
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
} else {
|
|
206
|
+
// Unix/Linux/Mac command
|
|
207
|
+
execSync(`GOOS=js GOARCH=wasm go build -o "${wasmFilePath}" "${tempGoFile}"`, {
|
|
208
|
+
cwd: tempDir
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Clean up temporary directory
|
|
213
|
+
try {
|
|
214
|
+
if (isWindows) {
|
|
215
|
+
execSync(`rmdir /s /q "${tempDir}"`, { shell: true });
|
|
216
|
+
} else {
|
|
217
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
218
|
+
}
|
|
219
|
+
} catch (cleanupError) {
|
|
220
|
+
console.warn(`Warning: Failed to clean up temp directory ${tempDir}:`, cleanupError);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
console.log(`✓ Successfully built ${wasmFileName}`);
|
|
224
|
+
} catch (error) {
|
|
225
|
+
console.error(`✗ Error building ${goFile}:`);
|
|
226
|
+
console.error(error.message);
|
|
227
|
+
if (error.stdout) console.error(error.stdout.toString());
|
|
228
|
+
if (error.stderr) console.error(error.stderr.toString());
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Run the build process
|
|
234
|
+
buildWasmModules().catch(error => {
|
|
235
|
+
console.error('Build failed:', error);
|
|
236
|
+
process.exit(1);
|
|
237
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// CommonJS/ESM compatible build configuration
|
|
2
|
+
const buildConfig = {
|
|
3
|
+
/**
|
|
4
|
+
* Determines if we should build for dual module support
|
|
5
|
+
*/
|
|
6
|
+
dualModuleSupport: true,
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Entry points for both client and server
|
|
10
|
+
*/
|
|
11
|
+
entryPoints: {
|
|
12
|
+
client: 'src/client.js',
|
|
13
|
+
server: 'src/server.js'
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Output formats to generate
|
|
18
|
+
*/
|
|
19
|
+
outputFormats: ['esm', 'cjs'],
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Output directory configuration
|
|
23
|
+
*/
|
|
24
|
+
output: {
|
|
25
|
+
dir: 'dist',
|
|
26
|
+
client: {
|
|
27
|
+
esm: 'assets/[name].mjs',
|
|
28
|
+
cjs: 'assets/[name].js'
|
|
29
|
+
},
|
|
30
|
+
server: {
|
|
31
|
+
esm: 'server/[name].mjs',
|
|
32
|
+
cjs: 'server/[name].js'
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* WebAssembly configuration
|
|
38
|
+
*/
|
|
39
|
+
wasm: {
|
|
40
|
+
enabled: true,
|
|
41
|
+
goBinaryPath: 'go',
|
|
42
|
+
sourceDir: 'src/wasm',
|
|
43
|
+
outputDir: 'public/wasm',
|
|
44
|
+
copyGoRuntime: true
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Additional build options
|
|
49
|
+
*/
|
|
50
|
+
options: {
|
|
51
|
+
minify: process.env.NODE_ENV === 'production',
|
|
52
|
+
sourcemap: true,
|
|
53
|
+
target: 'es2020'
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Make it work in both ESM and CommonJS environments
|
|
58
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
59
|
+
module.exports = buildConfig;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default buildConfig;
|