baraqex 1.0.76 → 2.0.0
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 +2592 -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,60 @@
|
|
|
1
|
+
import { jsx } from 'frontend-hamroun';
|
|
2
|
+
import Layout from '../components/Layout';
|
|
3
|
+
import { UserApi } from '../data/api';
|
|
4
|
+
|
|
5
|
+
const UsersPage = ({ initialState }) => {
|
|
6
|
+
const users = initialState.data?.users || [];
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<Layout title="User Management">
|
|
10
|
+
<div className="max-w-4xl mx-auto">
|
|
11
|
+
<div className="bg-blue-50 p-6 rounded-lg mb-8 border border-blue-100">
|
|
12
|
+
<h2 className="text-xl font-semibold text-blue-800 mb-2">Data Fetching Demo</h2>
|
|
13
|
+
<p className="text-blue-700">This page demonstrates dynamic data fetching with the Users API.</p>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div className="bg-white shadow-md rounded-lg overflow-hidden">
|
|
17
|
+
<div className="px-6 py-4 border-b border-gray-200">
|
|
18
|
+
<h2 className="text-xl font-semibold text-gray-800">User List</h2>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
{users.length === 0 ? (
|
|
22
|
+
<div className="p-6 text-center text-gray-500">
|
|
23
|
+
<p>No users found.</p>
|
|
24
|
+
</div>
|
|
25
|
+
) : (
|
|
26
|
+
<div className="overflow-x-auto">
|
|
27
|
+
<table className="w-full">
|
|
28
|
+
<thead>
|
|
29
|
+
<tr className="bg-gray-50">
|
|
30
|
+
<th className="text-left py-3 px-6 font-medium text-gray-600 text-sm uppercase tracking-wider border-b">ID</th>
|
|
31
|
+
<th className="text-left py-3 px-6 font-medium text-gray-600 text-sm uppercase tracking-wider border-b">Name</th>
|
|
32
|
+
<th className="text-left py-3 px-6 font-medium text-gray-600 text-sm uppercase tracking-wider border-b">Email</th>
|
|
33
|
+
</tr>
|
|
34
|
+
</thead>
|
|
35
|
+
<tbody className="divide-y divide-gray-200">
|
|
36
|
+
{users.map(user => (
|
|
37
|
+
<tr key={user.id} className="hover:bg-gray-50">
|
|
38
|
+
<td className="py-4 px-6 text-sm text-gray-900">{user.id}</td>
|
|
39
|
+
<td className="py-4 px-6 text-sm font-medium text-gray-900">{user.name}</td>
|
|
40
|
+
<td className="py-4 px-6 text-sm text-gray-500">{user.email}</td>
|
|
41
|
+
</tr>
|
|
42
|
+
))}
|
|
43
|
+
</tbody>
|
|
44
|
+
</table>
|
|
45
|
+
</div>
|
|
46
|
+
)}
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</Layout>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Static method to fetch initial data for this page
|
|
54
|
+
UsersPage.getInitialData = async () => {
|
|
55
|
+
return {
|
|
56
|
+
users: await UserApi.getAll()
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default UsersPage;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// This file will be removed as it contains WASM functionality
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { jsx } from 'frontend-hamroun';
|
|
2
|
+
// Use dynamic import to ensure it's available
|
|
3
|
+
// import UsersPage from './pages/users';
|
|
4
|
+
|
|
5
|
+
// Type definitions for page components
|
|
6
|
+
export interface PageProps {
|
|
7
|
+
initialState: any;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface PageComponent {
|
|
11
|
+
(props: PageProps): any;
|
|
12
|
+
getInitialData?: (path: string) => Promise<any>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Define router interface for type safety
|
|
16
|
+
interface RouteParams {
|
|
17
|
+
[key: string]: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Define router class for handling routes
|
|
21
|
+
export class Router {
|
|
22
|
+
private routes: Record<string, PageComponent> = {};
|
|
23
|
+
private notFoundComponent: PageComponent | null = null;
|
|
24
|
+
|
|
25
|
+
// Register a component for a specific route
|
|
26
|
+
register(path: string, component: PageComponent): Router {
|
|
27
|
+
const normalizedPath = path === '/' ? 'index' : path.replace(/^\//, '');
|
|
28
|
+
this.routes[normalizedPath] = component;
|
|
29
|
+
console.log(`[Router] Registered component for path: ${normalizedPath}`);
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Set the not found component
|
|
34
|
+
setNotFound(component: PageComponent): Router {
|
|
35
|
+
this.notFoundComponent = component;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Get the not found component
|
|
40
|
+
getNotFound(): PageComponent | null {
|
|
41
|
+
return this.notFoundComponent;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Get all registered routes
|
|
45
|
+
getAllRoutes(): Record<string, PageComponent> {
|
|
46
|
+
return this.routes;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Find component for a given path
|
|
50
|
+
async resolve(path: string): Promise<PageComponent | null> {
|
|
51
|
+
const normalizedPath = path === '/' ? 'index' : path.replace(/^\//, '');
|
|
52
|
+
|
|
53
|
+
console.log(`[Router] Resolving component for path: ${normalizedPath}`);
|
|
54
|
+
|
|
55
|
+
// Check for exact match first
|
|
56
|
+
if (this.routes[normalizedPath]) {
|
|
57
|
+
return this.routes[normalizedPath];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Check for nested routes (e.g., "users/123" should match a "users/[id]" route)
|
|
61
|
+
const pathSegments = normalizedPath.split('/');
|
|
62
|
+
const registeredRoutes = Object.keys(this.routes);
|
|
63
|
+
|
|
64
|
+
// Try to find dynamic route matches
|
|
65
|
+
for (const route of registeredRoutes) {
|
|
66
|
+
const routeSegments = route.split('/');
|
|
67
|
+
|
|
68
|
+
// Skip routes with different segment count
|
|
69
|
+
if (routeSegments.length !== pathSegments.length) continue;
|
|
70
|
+
|
|
71
|
+
let isMatch = true;
|
|
72
|
+
const params: RouteParams = {};
|
|
73
|
+
|
|
74
|
+
// Compare each segment
|
|
75
|
+
for (let i = 0; i < routeSegments.length; i++) {
|
|
76
|
+
const routeSegment = routeSegments[i];
|
|
77
|
+
const pathSegment = pathSegments[i];
|
|
78
|
+
|
|
79
|
+
// Handle dynamic segments (e.g., [id])
|
|
80
|
+
if (routeSegment.startsWith('[') && routeSegment.endsWith(']')) {
|
|
81
|
+
const paramName = routeSegment.slice(1, -1);
|
|
82
|
+
params[paramName] = pathSegment;
|
|
83
|
+
}
|
|
84
|
+
// Regular segment, must match exactly
|
|
85
|
+
else if (routeSegment !== pathSegment) {
|
|
86
|
+
isMatch = false;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (isMatch) {
|
|
92
|
+
console.log(`[Router] Found dynamic route match: ${route}`);
|
|
93
|
+
// Return the component with params
|
|
94
|
+
return this.routes[route];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// If no match found yet, try to dynamically import the component
|
|
99
|
+
try {
|
|
100
|
+
let component = null;
|
|
101
|
+
let resolvedPath = normalizedPath;
|
|
102
|
+
|
|
103
|
+
// Next.js-style dynamic route resolution
|
|
104
|
+
try {
|
|
105
|
+
// First, try direct file match (e.g., ./pages/users.tsx)
|
|
106
|
+
// Focus on .tsx since that's what this project uses
|
|
107
|
+
try {
|
|
108
|
+
console.log(`[Router] Trying direct import: ./pages/${resolvedPath}.tsx`);
|
|
109
|
+
const directModule = await import(/* @vite-ignore */ `./pages/${resolvedPath}.tsx`)
|
|
110
|
+
.catch(() => null);
|
|
111
|
+
|
|
112
|
+
if (directModule) {
|
|
113
|
+
component = directModule.default || directModule;
|
|
114
|
+
}
|
|
115
|
+
} catch (e) {
|
|
116
|
+
console.warn(`[Router] Error importing ./pages/${resolvedPath}.tsx:`, e);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Next, try index file in directory (e.g., ./pages/about/index.tsx)
|
|
120
|
+
if (!component && !resolvedPath.endsWith('index')) {
|
|
121
|
+
try {
|
|
122
|
+
console.log(`[Router] Trying index file: ./pages/${resolvedPath}/index.tsx`);
|
|
123
|
+
const indexModule = await import(/* @vite-ignore */ `./pages/${resolvedPath}/index.tsx`)
|
|
124
|
+
.catch(() => null);
|
|
125
|
+
|
|
126
|
+
if (indexModule) {
|
|
127
|
+
component = indexModule.default || indexModule;
|
|
128
|
+
}
|
|
129
|
+
} catch (e) {
|
|
130
|
+
console.warn(`[Router] Error importing ./pages/${resolvedPath}/index.tsx:`, e);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
} catch (routeError) {
|
|
134
|
+
console.warn(`[Router] Error resolving Next.js style route:`, routeError);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Register and return component if found
|
|
138
|
+
if (component) {
|
|
139
|
+
this.routes[normalizedPath] = component;
|
|
140
|
+
return component;
|
|
141
|
+
}
|
|
142
|
+
} catch (error) {
|
|
143
|
+
console.warn(`[Router] Error importing component for ${normalizedPath}:`, error);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// If we reach here, no component was found
|
|
147
|
+
console.warn(`[Router] No component found for path: ${normalizedPath}`);
|
|
148
|
+
return this.notFoundComponent;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Auto-discover components in the pages directory
|
|
152
|
+
async discoverRoutes(): Promise<Record<string, PageComponent>> {
|
|
153
|
+
console.log('[Router] Auto-discovering routes from pages directory...');
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
// Use a more conventional approach instead of relying on import.meta.glob
|
|
157
|
+
await this.tryLoadCoreRoutes();
|
|
158
|
+
|
|
159
|
+
console.log('[Router] Route discovery complete. Available routes:', Object.keys(this.routes));
|
|
160
|
+
return this.routes;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
console.error('[Router] Error discovering routes:', error);
|
|
163
|
+
await this.tryLoadCoreRoutes();
|
|
164
|
+
return this.routes;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Fallback method to load core routes
|
|
169
|
+
async tryLoadCoreRoutes(): Promise<void> {
|
|
170
|
+
// First try the auto-discovery approach with dynamic imports
|
|
171
|
+
const pageModules = [
|
|
172
|
+
{ path: './pages/index', route: 'index' },
|
|
173
|
+
{ path: './pages/about/index', route: 'about' },
|
|
174
|
+
{ path: './pages/users', route: 'users' }
|
|
175
|
+
];
|
|
176
|
+
|
|
177
|
+
// Try importing each module dynamically - focus on .tsx files
|
|
178
|
+
for (const { path, route } of pageModules) {
|
|
179
|
+
if (!this.routes[route]) {
|
|
180
|
+
try {
|
|
181
|
+
console.log(`[Router] Attempting to load route: ${route}`);
|
|
182
|
+
|
|
183
|
+
// Only try .tsx imports since that's what the project uses
|
|
184
|
+
const module = await import(/* @vite-ignore */ `${path}.tsx`)
|
|
185
|
+
.catch(() => null);
|
|
186
|
+
|
|
187
|
+
if (module && module.default) {
|
|
188
|
+
this.routes[route] = module.default;
|
|
189
|
+
console.log(`[Router] Registered route: ${route}`);
|
|
190
|
+
}
|
|
191
|
+
} catch (error) {
|
|
192
|
+
console.warn(`[Router] Could not load route: ${route}`, error);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Create and export a router instance
|
|
200
|
+
export const router = new Router();
|
|
201
|
+
|
|
202
|
+
// NotFound component as fallback (using jsx function instead of JSX syntax)
|
|
203
|
+
export const NotFound: PageComponent = ({ initialState }) => {
|
|
204
|
+
return jsx('div', { className: 'container mx-auto px-4 py-12 max-w-4xl' }, [
|
|
205
|
+
jsx('div', { className: 'bg-white shadow-lg rounded-lg overflow-hidden p-8' }, [
|
|
206
|
+
jsx('h1', { className: 'text-3xl font-bold text-gray-800 mb-4' }, ['Page Not Found']),
|
|
207
|
+
jsx('p', { className: 'text-gray-600 mb-6' }, [`No component found for path: ${initialState?.route || 'unknown'}`]),
|
|
208
|
+
jsx('a', { href: '/', className: 'text-blue-600 hover:text-blue-800 hover:underline transition-colors' }, ['Go to Home']),
|
|
209
|
+
jsx('div', { className: 'mt-8 p-6 bg-gray-50 rounded-lg border border-gray-200' }, [
|
|
210
|
+
jsx('h3', { className: 'text-lg font-medium text-gray-700 mb-3' }, ['Available Routes']),
|
|
211
|
+
jsx('ul', { className: 'space-y-2' }, [
|
|
212
|
+
jsx('li', {}, [jsx('a', { href: '/', className: 'text-blue-600 hover:text-blue-800 hover:underline' }, ['Home'])]),
|
|
213
|
+
jsx('li', {}, [jsx('a', { href: '/about', className: 'text-blue-600 hover:text-blue-800 hover:underline' }, ['About'])]),
|
|
214
|
+
jsx('li', {}, [jsx('a', { href: '/users', className: 'text-blue-600 hover:text-blue-800 hover:underline' }, ['Users'])])
|
|
215
|
+
])
|
|
216
|
+
])
|
|
217
|
+
])
|
|
218
|
+
]);
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// Set NotFound as the default fallback
|
|
222
|
+
router.setNotFound(NotFound);
|
|
223
|
+
|
|
224
|
+
// Improved router initialization with auto-discovery
|
|
225
|
+
export async function initializeRouter(): Promise<Router> {
|
|
226
|
+
try {
|
|
227
|
+
console.log('[Router] Initializing router with auto-discovery...');
|
|
228
|
+
|
|
229
|
+
// Auto-discover routes
|
|
230
|
+
await router.discoverRoutes();
|
|
231
|
+
|
|
232
|
+
// Register fallback pages for key routes if they weren't discovered
|
|
233
|
+
const routes = router.getAllRoutes();
|
|
234
|
+
|
|
235
|
+
if (!routes['index']) {
|
|
236
|
+
router.register('index', ({ initialState }: PageProps) => jsx('div', {}, [
|
|
237
|
+
jsx('h1', {}, ['Welcome']),
|
|
238
|
+
jsx('p', {}, ['This is the home page.'])
|
|
239
|
+
]));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (!routes['about']) {
|
|
243
|
+
router.register('about', ({ initialState }: PageProps) => jsx('div', {}, [
|
|
244
|
+
jsx('h1', {}, ['About']),
|
|
245
|
+
jsx('p', {}, ['This is the about page.'])
|
|
246
|
+
]));
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
console.log('[Router] Router initialized with routes:', Object.keys(router.getAllRoutes()));
|
|
250
|
+
return router;
|
|
251
|
+
} catch (error) {
|
|
252
|
+
console.error('[Router] Error initializing router:', error);
|
|
253
|
+
return router;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"sourceMap": true,
|
|
8
|
+
"outDir": "dist",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"lib": ["ES2020"],
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"allowSyntheticDefaultImports": true,
|
|
14
|
+
"resolveJsonModule": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["**/*.ts"],
|
|
17
|
+
"exclude": ["node_modules", "dist"]
|
|
18
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
// Server configuration
|
|
6
|
+
server: {
|
|
7
|
+
port: 5173,
|
|
8
|
+
proxy: {
|
|
9
|
+
'/api': 'http://localhost:3000',
|
|
10
|
+
'/socket.io': {
|
|
11
|
+
target: 'http://localhost:3000',
|
|
12
|
+
ws: true
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
// Using jsx transform with frontend-hamroun's jsx function
|
|
18
|
+
esbuild: {
|
|
19
|
+
jsxFactory: 'jsx',
|
|
20
|
+
jsxFragment: 'Fragment',
|
|
21
|
+
jsxInject: `import { jsx, Fragment } from 'frontend-hamroun'`
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
// Build configuration
|
|
25
|
+
build: {
|
|
26
|
+
outDir: 'dist',
|
|
27
|
+
assetsDir: 'assets',
|
|
28
|
+
// Generate SPA-friendly build that works with client-side routing
|
|
29
|
+
rollupOptions: {
|
|
30
|
+
input: {
|
|
31
|
+
main: resolve(__dirname, 'index.html')
|
|
32
|
+
},
|
|
33
|
+
output: {
|
|
34
|
+
manualChunks: {
|
|
35
|
+
vendor: ['frontend-hamroun']
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
// Make sure CSS is properly processed
|
|
40
|
+
cssCodeSplit: true
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
// CSS preprocessing
|
|
44
|
+
css: {
|
|
45
|
+
postcss: './postcss.config.js',
|
|
46
|
+
// Include module CSS as well as global CSS
|
|
47
|
+
modules: {
|
|
48
|
+
scopeBehaviour: 'local',
|
|
49
|
+
localsConvention: 'camelCaseOnly',
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
// Resolve aliases
|
|
54
|
+
resolve: {
|
|
55
|
+
alias: {
|
|
56
|
+
'@': resolve(__dirname, 'src'),
|
|
57
|
+
'@components': resolve(__dirname, 'src/components'),
|
|
58
|
+
'@pages': resolve(__dirname, 'src/pages'),
|
|
59
|
+
'@utils': resolve(__dirname, 'src/utils')
|
|
60
|
+
},
|
|
61
|
+
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json']
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
// Optimize dependencies
|
|
65
|
+
optimizeDeps: {
|
|
66
|
+
include: ['frontend-hamroun']
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
// This is a critical plugin for SPA routing - much simpler than before
|
|
70
|
+
plugins: [{
|
|
71
|
+
name: 'spa-fallback',
|
|
72
|
+
configureServer(server) {
|
|
73
|
+
return () => {
|
|
74
|
+
server.middlewares.use((req, res, next) => {
|
|
75
|
+
if (req.url.includes('.') || req.url.startsWith('/api/') || req.url.startsWith('/socket.io/')) {
|
|
76
|
+
next();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
console.log(`[SPA] Handling route: ${req.url}`);
|
|
81
|
+
req.url = '/'; // Rewrite all routes to root
|
|
82
|
+
next();
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}]
|
|
87
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
echo Building Go WASM module...
|
|
3
|
+
|
|
4
|
+
REM Check if Go is installed
|
|
5
|
+
where go >nul 2>&1
|
|
6
|
+
if %ERRORLEVEL% NEQ 0 (
|
|
7
|
+
echo Error: Go is not installed
|
|
8
|
+
exit /b 1
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
REM Build WASM module
|
|
12
|
+
set GOOS=js
|
|
13
|
+
set GOARCH=wasm
|
|
14
|
+
go build -o example.wasm example.go
|
|
15
|
+
if %ERRORLEVEL% NEQ 0 (
|
|
16
|
+
echo Error: Failed to build Go WASM module
|
|
17
|
+
exit /b 1
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
REM Copy wasm_exec.js files
|
|
21
|
+
for /f "tokens=*" %%g in ('go env GOROOT') do (set GOROOT=%%g)
|
|
22
|
+
|
|
23
|
+
echo Copying WASM runtime files from %GOROOT%\misc\wasm\
|
|
24
|
+
copy "%GOROOT%\misc\wasm\wasm_exec.js" .
|
|
25
|
+
copy "%GOROOT%\misc\wasm\wasm_exec_node.js" .
|
|
26
|
+
|
|
27
|
+
echo Build complete!
|
|
28
|
+
echo Files created:
|
|
29
|
+
echo - example.wasm - WebAssembly module
|
|
30
|
+
echo - wasm_exec.js - Browser runtime
|
|
31
|
+
echo - wasm_exec_node.js - Node.js runtime
|
|
32
|
+
|
|
33
|
+
echo.
|
|
34
|
+
echo Usage:
|
|
35
|
+
echo 1. Copy these files to your project's public directory
|
|
36
|
+
echo 2. Load the WASM module using the provided utilities
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Build script for Go WASM modules
|
|
4
|
+
|
|
5
|
+
# Ensure Go is installed
|
|
6
|
+
if ! command -v go &> /dev/null; then
|
|
7
|
+
echo "Error: Go is not installed"
|
|
8
|
+
exit 1
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
# Check Go version
|
|
12
|
+
GO_VERSION=$(go version | cut -d ' ' -f 3 | sed 's/go//')
|
|
13
|
+
GO_VERSION_MAJOR=$(echo $GO_VERSION | cut -d '.' -f 1)
|
|
14
|
+
GO_VERSION_MINOR=$(echo $GO_VERSION | cut -d '.' -f 2)
|
|
15
|
+
|
|
16
|
+
if [ $GO_VERSION_MAJOR -lt 1 ] || ([ $GO_VERSION_MAJOR -eq 1 ] && [ $GO_VERSION_MINOR -lt 16 ]); then
|
|
17
|
+
echo "Warning: Go version 1.16+ recommended for WebAssembly, detected $GO_VERSION"
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Build example WASM module
|
|
21
|
+
echo "Building example Go WASM module..."
|
|
22
|
+
GOOS=js GOARCH=wasm go build -o example.wasm example.go
|
|
23
|
+
if [ $? -ne 0 ]; then
|
|
24
|
+
echo "Error: Failed to build Go WASM module"
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Copy wasm_exec.js files for browser and Node.js from Go installation
|
|
29
|
+
GO_ROOT=$(go env GOROOT)
|
|
30
|
+
echo "Copying wasm_exec.js files from $GO_ROOT/misc/wasm/"
|
|
31
|
+
cp "$GO_ROOT/misc/wasm/wasm_exec.js" ./
|
|
32
|
+
cp "$GO_ROOT/misc/wasm/wasm_exec_node.js" ./
|
|
33
|
+
|
|
34
|
+
echo "Build complete!"
|
|
35
|
+
echo "Files created:"
|
|
36
|
+
echo "- example.wasm - WebAssembly module"
|
|
37
|
+
echo "- wasm_exec.js - Browser runtime"
|
|
38
|
+
echo "- wasm_exec_node.js - Node.js runtime"
|
|
39
|
+
|
|
40
|
+
echo ""
|
|
41
|
+
echo "Usage:"
|
|
42
|
+
echo "1. Copy these files to your project's public directory"
|
|
43
|
+
echo "2. Load the WASM module using the provided utilities"
|