frontend-hamroun 1.2.75 → 1.2.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/batch/package.json +16 -0
  2. package/dist/client-router/package.json +16 -0
  3. package/dist/component/package.json +16 -0
  4. package/dist/context/package.json +16 -0
  5. package/dist/event-bus/package.json +16 -0
  6. package/dist/forms/package.json +16 -0
  7. package/dist/hooks/package.json +16 -0
  8. package/dist/jsx-runtime/package.json +16 -0
  9. package/dist/lifecycle-events/package.json +16 -0
  10. package/dist/package.json +71 -0
  11. package/dist/render-component/package.json +16 -0
  12. package/dist/renderer/package.json +16 -0
  13. package/dist/router/package.json +16 -0
  14. package/dist/server/package.json +17 -0
  15. package/dist/server/src/client-router.d.ts +60 -0
  16. package/dist/server/src/client-router.js +210 -0
  17. package/dist/server/src/client-router.js.map +1 -0
  18. package/dist/server/src/component.js +1 -1
  19. package/dist/server/src/event-bus.d.ts +23 -0
  20. package/dist/server/src/event-bus.js +75 -0
  21. package/dist/server/src/event-bus.js.map +1 -0
  22. package/dist/server/src/forms.d.ts +40 -0
  23. package/dist/server/src/forms.js +148 -0
  24. package/dist/server/src/forms.js.map +1 -0
  25. package/dist/server/src/hooks.js +2 -2
  26. package/dist/server/src/index.js +19 -11
  27. package/dist/server/src/lifecycle-events.d.ts +108 -0
  28. package/dist/server/src/lifecycle-events.js +177 -0
  29. package/dist/server/src/lifecycle-events.js.map +1 -0
  30. package/dist/server/src/renderComponent.js +1 -1
  31. package/dist/server/src/renderer.js +3 -3
  32. package/dist/server/src/router.d.ts +55 -0
  33. package/dist/server/src/router.js +166 -0
  34. package/dist/server/src/router.js.map +1 -0
  35. package/dist/server/src/server/index.d.ts +75 -2
  36. package/dist/server/src/server/index.js +224 -8
  37. package/dist/server/src/server/index.js.map +1 -1
  38. package/dist/server/src/server/server.js +1 -1
  39. package/dist/server/src/server/templates.d.ts +28 -0
  40. package/dist/server/src/server/templates.js +204 -0
  41. package/dist/server/src/server/templates.js.map +1 -0
  42. package/dist/server/src/server/utils.d.ts +70 -0
  43. package/dist/server/src/server/utils.js +156 -0
  44. package/dist/server/src/server/utils.js.map +1 -0
  45. package/dist/server/src/server-renderer.js +1 -1
  46. package/dist/server/src/store.d.ts +41 -0
  47. package/dist/server/src/store.js +99 -0
  48. package/dist/server/src/store.js.map +1 -0
  49. package/dist/server/src/utils.d.ts +46 -0
  50. package/dist/server/src/utils.js +144 -0
  51. package/dist/server/src/utils.js.map +1 -0
  52. package/dist/server/tsconfig.server.tsbuildinfo +1 -1
  53. package/dist/server-renderer/package.json +16 -0
  54. package/dist/store/package.json +16 -0
  55. package/dist/types/package.json +16 -0
  56. package/dist/utils/package.json +16 -0
  57. package/dist/vdom/package.json +16 -0
  58. package/dist/wasm/package.json +16 -0
  59. package/package.json +14 -13
  60. package/templates/complete-app/build.js +284 -0
  61. package/templates/complete-app/package.json +40 -0
  62. package/templates/complete-app/public/styles.css +345 -0
  63. package/templates/complete-app/src/api/index.js +31 -0
  64. package/templates/complete-app/src/client.js +93 -0
  65. package/templates/complete-app/src/components/App.js +66 -0
  66. package/templates/complete-app/src/components/Footer.js +19 -0
  67. package/templates/complete-app/src/components/Header.js +38 -0
  68. package/templates/complete-app/src/pages/About.js +59 -0
  69. package/templates/complete-app/src/pages/Home.js +54 -0
  70. package/templates/complete-app/src/pages/WasmDemo.js +136 -0
  71. package/templates/complete-app/src/server.js +186 -0
  72. package/templates/complete-app/src/wasm/build.bat +16 -0
  73. package/templates/complete-app/src/wasm/build.sh +16 -0
  74. package/templates/complete-app/src/wasm/example.go +101 -0
  75. package/templates/fullstack-app/build/main.css +225 -15
  76. package/templates/fullstack-app/build/main.css.map +2 -2
  77. package/templates/fullstack-app/build/main.js +657 -372
  78. package/templates/fullstack-app/build/main.js.map +4 -4
  79. package/templates/fullstack-app/build.ts +3 -4
  80. package/templates/fullstack-app/public/styles.css +222 -15
  81. package/templates/fullstack-app/server.ts +46 -12
  82. package/templates/fullstack-app/src/components/ClientHome.tsx +0 -0
  83. package/templates/fullstack-app/src/components/ErrorBoundary.tsx +36 -0
  84. package/templates/fullstack-app/src/components/Layout.tsx +23 -26
  85. package/templates/fullstack-app/src/components/StateDemo.tsx +207 -0
  86. package/templates/fullstack-app/src/components/UserList.tsx +30 -13
  87. package/templates/fullstack-app/src/data/api.ts +173 -38
  88. package/templates/fullstack-app/src/main.tsx +88 -154
  89. package/templates/fullstack-app/src/middleware.ts +28 -0
  90. package/templates/fullstack-app/src/pages/404.tsx +28 -0
  91. package/templates/fullstack-app/src/pages/[id].tsx +0 -0
  92. package/templates/fullstack-app/src/pages/_app.tsx +11 -0
  93. package/templates/fullstack-app/src/pages/_document.tsx +25 -0
  94. package/templates/fullstack-app/src/pages/_error.tsx +45 -0
  95. package/templates/fullstack-app/src/pages/about.tsx +71 -0
  96. package/templates/fullstack-app/src/pages/api/users/[id].ts +73 -0
  97. package/templates/fullstack-app/src/pages/api/users/index.ts +43 -0
  98. package/templates/fullstack-app/src/pages/index.tsx +97 -20
  99. package/templates/fullstack-app/src/pages/users/[id].tsx +153 -0
  100. package/templates/fullstack-app/src/pages/wasm-demo.tsx +1 -0
  101. package/templates/go/example.go +99 -86
  102. package/templates/go-wasm-app/babel.config.js +8 -2
  103. package/templates/go-wasm-app/build.config.js +62 -0
  104. package/templates/go-wasm-app/build.js +218 -0
  105. package/templates/go-wasm-app/package.json +21 -12
  106. package/templates/go-wasm-app/server.js +59 -510
  107. package/templates/go-wasm-app/src/app.js +173 -0
  108. package/templates/go-wasm-app/vite.config.js +16 -5
  109. package/templates/ssr-template/client.js +54 -26
  110. package/templates/ssr-template/server.js +5 -28
  111. package/templates/ssr-template/vite.config.js +21 -5
  112. package/dist/server/wasm.d.ts +0 -7
  113. package/dist/wasm.d.ts +0 -37
@@ -1,33 +1,110 @@
1
- import { jsx } from 'frontend-hamroun';
2
- import Layout from '../components/Layout';
1
+ import { jsx, useState, useEffect, batchUpdates } from 'frontend-hamroun';
3
2
  import UserList from '../components/UserList';
3
+ import StateDemo from '../components/StateDemo';
4
+ import { ErrorBoundary } from '../components/ErrorBoundary';
4
5
  import { UserApi } from '../data/api';
5
6
 
6
- const HomePage = ({ initialState }) => (
7
- <Layout title="Home">
7
+ // Home Page Component with Server Side Props
8
+ export default function HomePage({ users, posts, initialState }) {
9
+ const [state, setState] = useState(initialState || {});
10
+ const [refreshTrigger, setRefreshTrigger] = useState(0);
11
+
12
+ // Fetch data when refresh is triggered
13
+ useEffect(() => {
14
+ if (refreshTrigger === 0) return; // Skip initial render
15
+
16
+ async function fetchData() {
17
+ try {
18
+ const [users, posts] = await Promise.all([
19
+ UserApi.getAll(),
20
+ UserApi.getPosts()
21
+ ]);
22
+
23
+ // Use batch updates for efficiency
24
+ batchUpdates(() => {
25
+ setState(prev => ({
26
+ ...prev,
27
+ data: {
28
+ ...prev.data,
29
+ users,
30
+ posts
31
+ },
32
+ lastUpdate: new Date().toISOString()
33
+ }));
34
+ });
35
+ } catch (error) {
36
+ console.error('Error fetching data:', error);
37
+ }
38
+ }
39
+
40
+ fetchData();
41
+ }, [refreshTrigger]);
42
+
43
+ const handleRefresh = () => {
44
+ setRefreshTrigger(t => t + 1);
45
+ };
46
+
47
+ return (
8
48
  <div className="max-w-4xl mx-auto py-8">
9
- <h1 className="text-3xl font-bold text-blue-600 mb-6">Welcome to your Frontend Hamroun application!</h1>
49
+ <h1 className="text-3xl font-bold text-blue-600 mb-6">
50
+ Welcome to your Next-style Frontend Hamroun application!
51
+ </h1>
10
52
 
11
- <div className="bg-white shadow-lg rounded-lg p-6 mb-8">
12
- <h2 className="text-xl font-semibold text-gray-800 mb-4">User List</h2>
13
- <UserList users={initialState.data?.users || []} />
53
+ <div className="mb-8">
54
+ <button
55
+ className="mb-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
56
+ onClick={handleRefresh}
57
+ >
58
+ Refresh Data
59
+ </button>
60
+
61
+ <div className="bg-blue-50 p-4 rounded-lg border border-blue-100 mb-6">
62
+ <p className="text-blue-700">
63
+ Last updated: {state.lastUpdate || 'Never'}
64
+ </p>
65
+ </div>
14
66
  </div>
15
67
 
16
- <div className="bg-gray-50 rounded-lg p-6 border border-gray-200">
68
+ <ErrorBoundary>
69
+ <div className="bg-white shadow-lg rounded-lg p-6 mb-8">
70
+ <h2 className="text-xl font-semibold text-gray-800 mb-4">User List</h2>
71
+ <UserList users={users || state.data?.users || []} />
72
+ </div>
73
+ </ErrorBoundary>
74
+
75
+ <ErrorBoundary>
76
+ <StateDemo />
77
+ </ErrorBoundary>
78
+
79
+ <div className="bg-gray-50 rounded-lg p-6 border border-gray-200 mt-8">
17
80
  <h3 className="text-lg font-medium text-gray-700 mb-3">Application State</h3>
18
81
  <pre className="overflow-auto p-4 bg-gray-100 rounded-md text-sm text-gray-800">
19
- {JSON.stringify(initialState, null, 2)}
82
+ {JSON.stringify({ users, posts, ...state }, null, 2)}
20
83
  </pre>
21
84
  </div>
22
85
  </div>
23
- </Layout>
24
- );
25
-
26
- // Static method to fetch initial data for this page
27
- HomePage.getInitialData = async () => {
28
- return {
29
- users: await UserApi.getAll()
30
- };
31
- };
86
+ );
87
+ }
32
88
 
33
- export default HomePage;
89
+ // Server-side data fetching (Next.js style)
90
+ export async function getServerSideProps() {
91
+ try {
92
+ const users = await UserApi.getAll();
93
+ const posts = await UserApi.getPosts();
94
+
95
+ return {
96
+ props: {
97
+ users,
98
+ posts
99
+ }
100
+ };
101
+ } catch (error) {
102
+ console.error('Error fetching initial data:', error);
103
+ return {
104
+ props: {
105
+ users: [],
106
+ posts: []
107
+ }
108
+ };
109
+ }
110
+ }
@@ -0,0 +1,153 @@
1
+ import { jsx, useState, useEffect } from 'frontend-hamroun';
2
+ import { UserApi } from '../../data/api';
3
+
4
+ export default function UserDetail({ user, posts, initialState }) {
5
+ // State for client-side data fetching when needed
6
+ const [userData, setUserData] = useState(user);
7
+ const [userPosts, setUserPosts] = useState(posts || []);
8
+ const [loading, setLoading] = useState(false);
9
+ const [error, setError] = useState(null);
10
+
11
+ // Get user ID from route params
12
+ const { id } = initialState?.params || {};
13
+
14
+ // Fetch user data if not provided from server
15
+ useEffect(() => {
16
+ if (!userData && id) {
17
+ setLoading(true);
18
+
19
+ Promise.all([
20
+ UserApi.getById(id),
21
+ UserApi.getPosts(id)
22
+ ])
23
+ .then(([userData, postsData]) => {
24
+ setUserData(userData);
25
+ setUserPosts(postsData);
26
+ setLoading(false);
27
+ })
28
+ .catch(err => {
29
+ console.error('Error fetching user data:', err);
30
+ setError(err.message || 'Failed to load user data');
31
+ setLoading(false);
32
+ });
33
+ }
34
+ }, [userData, id]);
35
+
36
+ if (loading) {
37
+ return (
38
+ <div className="max-w-4xl mx-auto p-4">
39
+ <div className="animate-pulse rounded-md bg-gray-100 p-8">
40
+ <div className="h-8 bg-gray-200 rounded w-1/4 mb-4"></div>
41
+ <div className="h-4 bg-gray-200 rounded w-1/2 mb-2"></div>
42
+ <div className="h-4 bg-gray-200 rounded w-3/4 mb-4"></div>
43
+ <div className="h-40 bg-gray-200 rounded mb-4"></div>
44
+ </div>
45
+ </div>
46
+ );
47
+ }
48
+
49
+ if (error) {
50
+ return (
51
+ <div className="max-w-4xl mx-auto p-4">
52
+ <div className="rounded-md bg-red-50 p-4 border border-red-200">
53
+ <h2 className="text-lg font-bold text-red-700">Error Loading User</h2>
54
+ <p className="text-red-600">{error}</p>
55
+ </div>
56
+ </div>
57
+ );
58
+ }
59
+
60
+ if (!userData) {
61
+ return (
62
+ <div className="max-w-4xl mx-auto p-4">
63
+ <div className="rounded-md bg-yellow-50 p-4 border border-yellow-200">
64
+ <h2 className="text-lg font-bold text-yellow-700">User Not Found</h2>
65
+ <p className="text-yellow-600">Could not find user with ID: {id}</p>
66
+ <a href="/users" className="text-blue-600 hover:underline mt-2 block">
67
+ Back to Users List
68
+ </a>
69
+ </div>
70
+ </div>
71
+ );
72
+ }
73
+
74
+ return (
75
+ <div className="max-w-4xl mx-auto p-4">
76
+ <div className="bg-white shadow-lg rounded-lg p-6 mb-6">
77
+ <h1 className="text-2xl font-bold text-gray-800 mb-4">{userData.name}</h1>
78
+ <div className="user-info mb-6">
79
+ <p className="text-gray-600">
80
+ <span className="font-bold">ID:</span> {userData.id}
81
+ </p>
82
+ <p className="text-gray-600">
83
+ <span className="font-bold">Email:</span> {userData.email}
84
+ </p>
85
+ </div>
86
+
87
+ <a href="/users" className="text-blue-600 hover:underline">
88
+ Back to Users List
89
+ </a>
90
+ </div>
91
+
92
+ {userPosts && userPosts.length > 0 ? (
93
+ <div className="bg-white shadow-lg rounded-lg p-6">
94
+ <h2 className="text-xl font-bold text-gray-800 mb-4">Posts by {userData.name}</h2>
95
+ <div className="space-y-4">
96
+ {userPosts.map(post => (
97
+ <div key={post.id} className="border-b pb-4">
98
+ <h3 className="text-lg font-semibold">{post.title}</h3>
99
+ <p className="text-gray-600">{post.content}</p>
100
+ </div>
101
+ ))}
102
+ </div>
103
+ </div>
104
+ ) : (
105
+ <div className="bg-white shadow-lg rounded-lg p-6">
106
+ <h2 className="text-xl font-bold text-gray-800 mb-4">Posts by {userData.name}</h2>
107
+ <p className="text-gray-500 italic">No posts found for this user.</p>
108
+ </div>
109
+ )}
110
+ </div>
111
+ );
112
+ }
113
+
114
+ // Next.js style server-side data fetching
115
+ export async function getServerSideProps({ params }) {
116
+ try {
117
+ const userId = params.id;
118
+
119
+ // Parallel data fetching
120
+ const [user, posts] = await Promise.all([
121
+ UserApi.getById(parseInt(userId)),
122
+ UserApi.getPosts(parseInt(userId))
123
+ ]);
124
+
125
+ // Handle user not found
126
+ if (!user) {
127
+ return {
128
+ notFound: true
129
+ };
130
+ }
131
+
132
+ return {
133
+ props: {
134
+ user,
135
+ posts
136
+ }
137
+ };
138
+ } catch (error) {
139
+ console.error(`Error fetching user ${params.id}:`, error);
140
+
141
+ // Pass the error for client-side handling
142
+ return {
143
+ props: {
144
+ error: {
145
+ message: error.message,
146
+ status: error.status || 500
147
+ },
148
+ user: null,
149
+ posts: []
150
+ }
151
+ };
152
+ }
153
+ }
@@ -0,0 +1 @@
1
+ // This file will be removed as it contains WASM functionality
@@ -9,10 +9,10 @@ import (
9
9
  "syscall/js"
10
10
  )
11
11
 
12
- // Example Go function to be called from JavaScript
12
+ // Basic arithmetic functions
13
13
  func add(this js.Value, args []js.Value) interface{} {
14
14
  if len(args) != 2 {
15
- return js.ValueOf("Error: Expected two arguments")
15
+ return js.ValueOf("Error: add requires 2 arguments")
16
16
  }
17
17
 
18
18
  a := args[0].Int()
@@ -20,118 +20,131 @@ func add(this js.Value, args []js.Value) interface{} {
20
20
  return js.ValueOf(a + b)
21
21
  }
22
22
 
23
- // Helper to convert Go string to JS string
24
- func stringToJS(s string) js.Value {
25
- return js.ValueOf(s)
26
- }
23
+ func subtract(this js.Value, args []js.Value) interface{} {
24
+ if len(args) != 2 {
25
+ return js.ValueOf("Error: subtract requires 2 arguments")
26
+ }
27
27
 
28
- // Helper to convert JS string to Go string
29
- func stringFromJS(jsStr js.Value) string {
30
- return jsStr.String()
28
+ a := args[0].Int()
29
+ b := args[1].Int()
30
+ return js.ValueOf(a - b)
31
31
  }
32
32
 
33
- // Helper to convert Go object to JS object (via JSON)
34
- func objectToJS(obj interface{}) js.Value {
35
- data, err := json.Marshal(obj)
36
- if err != nil {
37
- return js.ValueOf("Error: Failed to marshal JSON")
33
+ func multiply(this js.Value, args []js.Value) interface{} {
34
+ if len(args) != 2 {
35
+ return js.ValueOf("Error: multiply requires 2 arguments")
38
36
  }
39
- return stringToJS(string(data))
40
- }
41
37
 
42
- // Helper to convert JS object to Go object (via JSON)
43
- func objectFromJS(jsObj js.Value) (interface{}, error) {
44
- jsonStr := jsObj.String()
45
- var result interface{}
46
- err := json.Unmarshal([]byte(jsonStr), &result)
47
- return result, err
38
+ a := args[0].Int()
39
+ b := args[1].Int()
40
+ return js.ValueOf(a * b)
48
41
  }
49
42
 
50
- // Complex example: process data in Go
51
- func processData(this js.Value, args []js.Value) interface{} {
52
- if len(args) == 0 {
53
- return js.ValueOf("Error: Expected at least one argument")
43
+ // String operations
44
+ func concat(this js.Value, args []js.Value) interface{} {
45
+ if len(args) < 1 {
46
+ return js.ValueOf("")
54
47
  }
55
48
 
56
- // Get input data
57
- data := args[0]
58
- if data.Type() != js.TypeObject {
59
- return js.ValueOf("Error: Expected JSON object")
60
- }
61
-
62
- // Convert JS object to Go map
63
- jsonStr := js.Global().Get("JSON").Call("stringify", data).String()
64
- var inputMap map[string]interface{}
65
- if err := json.Unmarshal([]byte(jsonStr), &inputMap); err != nil {
66
- return js.ValueOf(fmt.Sprintf("Error parsing JSON: %s", err.Error()))
49
+ result := ""
50
+ for _, arg := range args {
51
+ result += arg.String()
67
52
  }
53
+ return js.ValueOf(result)
54
+ }
68
55
 
69
- // Add new fields
70
- inputMap["processed"] = true
71
- inputMap["processor"] = "Go WASM"
72
-
73
- // Add some computed fields
74
- if values, ok := inputMap["values"].([]interface{}); ok {
75
- sum := 0.0
76
- for _, v := range values {
77
- if num, ok := v.(float64); ok {
78
- sum += num
79
- }
80
- }
81
- inputMap["sum"] = sum
56
+ // JSON operations
57
+ func parseJSON(this js.Value, args []js.Value) interface{} {
58
+ if len(args) != 1 {
59
+ return js.ValueOf("Error: parseJSON requires 1 argument")
82
60
  }
83
61
 
84
- // Convert back to JS
85
- resultJSON, err := json.Marshal(inputMap)
62
+ jsonStr := args[0].String()
63
+ var result interface{}
64
+ err := json.Unmarshal([]byte(jsonStr), &result)
86
65
  if err != nil {
87
- return js.ValueOf(fmt.Sprintf("Error generating JSON: %s", err.Error()))
66
+ return js.ValueOf("Error parsing JSON: " + err.Error())
88
67
  }
89
68
 
90
- return js.ValueOf(string(resultJSON))
69
+ // Convert result to JS value
70
+ return mapToJSValue(result)
91
71
  }
92
72
 
93
- // Helper functions exposed to JavaScript
94
- func registerHelperFunctions() {
95
- js.Global().Set("__stringToGo", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
96
- if len(args) != 1 {
97
- return nil
73
+ // Helper functions for JSON conversion
74
+ func mapToJSValue(value interface{}) js.Value {
75
+ switch v := value.(type) {
76
+ case map[string]interface{}:
77
+ result := js.Global().Get("Object").New()
78
+ for key, val := range v {
79
+ result.Set(key, mapToJSValue(val))
98
80
  }
99
- return stringToJS(stringFromJS(args[0]))
100
- }))
101
-
102
- js.Global().Set("__stringFromGo", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
103
- if len(args) != 1 {
104
- return nil
81
+ return result
82
+ case []interface{}:
83
+ result := js.Global().Get("Array").New(len(v))
84
+ for i, val := range v {
85
+ result.SetIndex(i, mapToJSValue(val))
105
86
  }
106
- return stringToJS(stringFromJS(args[0]))
107
- }))
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
+ }
99
+ }
108
100
 
109
- js.Global().Set("__objectToGo", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
110
- if len(args) != 1 {
111
- return nil
112
- }
113
- obj, _ := objectFromJS(args[0])
114
- return objectToJS(obj)
115
- }))
101
+ // Special utility functions for string handling between Go and JS
102
+ func __stringToGo(this js.Value, args []js.Value) interface{} {
103
+ if len(args) != 1 {
104
+ return js.ValueOf(-1)
105
+ }
106
+ return args[0] // Pass through
107
+ }
116
108
 
117
- js.Global().Set("__objectFromGo", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
118
- if len(args) != 1 {
119
- return nil
120
- }
121
- return stringToJS(stringFromJS(args[0]))
122
- }))
109
+ func __stringFromGo(this js.Value, args []js.Value) interface{} {
110
+ if len(args) != 1 {
111
+ return js.ValueOf("")
112
+ }
113
+ return args[0] // Pass through
114
+ }
115
+
116
+ func __objectToGo(this js.Value, args []js.Value) interface{} {
117
+ if len(args) != 1 {
118
+ return js.ValueOf(-1)
119
+ }
120
+ return args[0] // Pass through
121
+ }
122
+
123
+ func __objectFromGo(this js.Value, args []js.Value) interface{} {
124
+ if len(args) != 1 {
125
+ return js.ValueOf("")
126
+ }
127
+ return args[0] // Pass through
123
128
  }
124
129
 
125
130
  func main() {
126
- fmt.Println("Go WASM Module initialized")
131
+ fmt.Println("Go WebAssembly module initialized")
127
132
 
128
- // Register functions to be callable from JavaScript
133
+ // Register functions to make available to JavaScript
129
134
  js.Global().Set("goAdd", js.FuncOf(add))
130
- js.Global().Set("goProcessData", js.FuncOf(processData))
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))
131
139
 
132
- // Register helper functions
133
- registerHelperFunctions()
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))
134
145
 
135
146
  // Keep the program running
136
- <-make(chan bool)
147
+ c := make(chan struct{}, 0)
148
+ fmt.Println("Go WebAssembly module ready")
149
+ <-c
137
150
  }
@@ -1,9 +1,11 @@
1
- export default {
1
+ const config = {
2
2
  presets: [
3
3
  ['@babel/preset-env', {
4
4
  targets: {
5
5
  node: 'current'
6
- }
6
+ },
7
+ // Enable dynamic imports for both ESM and CommonJS
8
+ modules: false
7
9
  }]
8
10
  ],
9
11
  plugins: [
@@ -13,3 +15,7 @@ export default {
13
15
  }]
14
16
  ]
15
17
  };
18
+
19
+ // Support both ESM and CommonJS
20
+ export default config;
21
+ module.exports = config;
@@ -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;