baraqex 2.0.3 → 2.0.5

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 (65) hide show
  1. package/dist/browser.js +11 -9
  2. package/dist/browser.js.map +2 -2
  3. package/dist/core/jsx-runtime.d.ts +1 -1
  4. package/dist/core/jsx-runtime.d.ts.map +1 -1
  5. package/dist/index.js +11 -9
  6. package/dist/index.js.map +2 -2
  7. package/package.json +1 -1
  8. package/templates/fullstack-app/README.md +62 -37
  9. package/templates/fullstack-app/build-wasm.js +80 -0
  10. package/templates/fullstack-app/build.mjs +133 -0
  11. package/templates/fullstack-app/go/main.go +53 -0
  12. package/templates/fullstack-app/index.html +17 -36
  13. package/templates/fullstack-app/package.json +41 -35
  14. package/templates/fullstack-app/postcss.config.js +6 -6
  15. package/templates/fullstack-app/public/wasm/.gitkeep +1 -0
  16. package/templates/fullstack-app/server.ts +239 -474
  17. package/templates/fullstack-app/src/App.tsx +77 -0
  18. package/templates/fullstack-app/src/main.tsx +31 -155
  19. package/templates/fullstack-app/src/pages/About.tsx +40 -0
  20. package/templates/fullstack-app/src/pages/Home.tsx +67 -0
  21. package/templates/fullstack-app/src/pages/WasmDemo.tsx +81 -0
  22. package/templates/fullstack-app/src/styles.css +12 -5
  23. package/templates/fullstack-app/tailwind.config.js +8 -11
  24. package/templates/fullstack-app/tsconfig.json +20 -18
  25. package/templates/fullstack-app/api/hello.js +0 -11
  26. package/templates/fullstack-app/api/hello.ts +0 -18
  27. package/templates/fullstack-app/api/users/[id].ts +0 -73
  28. package/templates/fullstack-app/api/users/index.ts +0 -32
  29. package/templates/fullstack-app/build/main.css +0 -874
  30. package/templates/fullstack-app/build/main.css.map +0 -7
  31. package/templates/fullstack-app/build/main.js +0 -967
  32. package/templates/fullstack-app/build/main.js.map +0 -7
  33. package/templates/fullstack-app/build.ts +0 -210
  34. package/templates/fullstack-app/process-tailwind.js +0 -45
  35. package/templates/fullstack-app/public/_redirects +0 -1
  36. package/templates/fullstack-app/public/route-handler.js +0 -47
  37. package/templates/fullstack-app/public/spa-fix.html +0 -17
  38. package/templates/fullstack-app/public/styles.css +0 -975
  39. package/templates/fullstack-app/public/tailwind.css +0 -15
  40. package/templates/fullstack-app/server.js +0 -267
  41. package/templates/fullstack-app/src/README.md +0 -55
  42. package/templates/fullstack-app/src/client.js +0 -87
  43. package/templates/fullstack-app/src/components/ClientHome.tsx +0 -0
  44. package/templates/fullstack-app/src/components/ErrorBoundary.tsx +0 -36
  45. package/templates/fullstack-app/src/components/Layout.tsx +0 -42
  46. package/templates/fullstack-app/src/components/StateDemo.tsx +0 -207
  47. package/templates/fullstack-app/src/components/UserList.tsx +0 -44
  48. package/templates/fullstack-app/src/config.ts +0 -42
  49. package/templates/fullstack-app/src/data/api.ts +0 -206
  50. package/templates/fullstack-app/src/middleware.ts +0 -28
  51. package/templates/fullstack-app/src/pages/404.tsx +0 -28
  52. package/templates/fullstack-app/src/pages/[id].tsx +0 -0
  53. package/templates/fullstack-app/src/pages/_app.tsx +0 -11
  54. package/templates/fullstack-app/src/pages/_document.tsx +0 -25
  55. package/templates/fullstack-app/src/pages/_error.tsx +0 -45
  56. package/templates/fullstack-app/src/pages/about/index.tsx +0 -67
  57. package/templates/fullstack-app/src/pages/about.tsx +0 -71
  58. package/templates/fullstack-app/src/pages/api/users/[id].ts +0 -73
  59. package/templates/fullstack-app/src/pages/api/users/index.ts +0 -43
  60. package/templates/fullstack-app/src/pages/index.tsx +0 -110
  61. package/templates/fullstack-app/src/pages/users/[id].tsx +0 -153
  62. package/templates/fullstack-app/src/pages/users.tsx +0 -60
  63. package/templates/fullstack-app/src/pages/wasm-demo.tsx +0 -1
  64. package/templates/fullstack-app/src/router.ts +0 -255
  65. package/templates/fullstack-app/vite.config.js +0 -87
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baraqex",
3
- "version": "2.0.3",
3
+ "version": "2.0.5",
4
4
  "description": "A full-stack WebAssembly framework for building fast, modern web applications.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -1,37 +1,62 @@
1
- # Frontend Hamroun Fullstack Template
2
-
3
- A dynamic, customizable fullstack template with automatic routing.
4
-
5
- ## Getting Started
6
-
7
- 1. Install dependencies:
8
- ```
9
- npm install
10
- ```
11
-
12
- 2. Run the development server:
13
- ```
14
- npm run dev
15
- ```
16
-
17
- 3. Build for production:
18
- ```
19
- npm run build
20
- ```
21
-
22
- 4. Run in production mode:
23
- ```
24
- npm start
25
- ```
26
-
27
- ## Customizing Without Touching Core Files
28
-
29
- This template is designed to be customized without modifying the core server or app files:
30
-
31
- 1. **Configuration**: Edit `src/config.ts` to change app settings
32
- 2. **Pages**: Add new pages in `src/pages` - they become routes automatically
33
- 3. **Components**: Create reusable components in `src/components`
34
- 4. **API Endpoints**: Add new API endpoints in `src/data/api.ts`
35
-
36
- ## File Structure
37
-
1
+ # Baraqex Full-Stack Template
2
+
3
+ A complete starter that brings together the full Baraqex stack in one project:
4
+
5
+ - **Frontend** — JSX components with hooks in `src/`
6
+ - **Backend** — Express REST API in `server.ts` under `/api/*`
7
+ - **SSR** — the same `<App/>` is server-rendered with Baraqex and hydrated on the client
8
+ - **WebAssembly (Go)** — `go/main.go` compiles to WASM and runs in the browser
9
+ - **Live reload** — esbuild rebuild + Socket.IO reload in dev mode
10
+
11
+ ## Prerequisites
12
+
13
+ - Node.js >= 18
14
+ - Go >= 1.21 (only needed for the WASM demo)
15
+
16
+ ## Quick start
17
+
18
+ ```bash
19
+ # 1. Install dependencies
20
+ npm install
21
+
22
+ # 2. Compile the Go WASM module (produces public/wasm/example.wasm + wasm_exec.js)
23
+ npm run build:wasm
24
+
25
+ # 3. Run in development (esbuild bundles src/, live reload over Socket.IO)
26
+ npm run dev
27
+ ```
28
+
29
+ Open `http://localhost:3000`.
30
+
31
+ ## Production build
32
+
33
+ ```bash
34
+ npm run build:wasm # compile Go -> WASM
35
+ npm run build # bundle client + server to dist/
36
+ npm run start # node dist/server.js
37
+ ```
38
+
39
+ ## What's where
40
+
41
+ | Path | Purpose |
42
+ | ----------------- | ------------------------------------------ |
43
+ | `src/App.tsx` | Shared app component (SSR + client) |
44
+ | `src/pages/*` | Home, About, and WASM demo pages |
45
+ | `src/main.tsx` | Client entry — hydrates the SSR markup |
46
+ | `server.ts` | Express server: API, static, SSR |
47
+ | `go/main.go` | Go source compiled to WebAssembly |
48
+ | `build-wasm.js` | Compiles `go/` to `public/wasm/` |
49
+ | `build.mjs` | esbuild bundle for client + server |
50
+
51
+ ## The WASM demo
52
+
53
+ The **WASM (Go)** page loads `public/wasm/example.wasm` through Baraqex's `loadGoWasm`
54
+ and exposes these Go functions in the browser:
55
+
56
+ - `goAdd(a, b)`
57
+ - `goMultiply(a, b)`
58
+ - `goFibonacci(n)`
59
+ - `goProcessArray([...])`
60
+
61
+ If the page shows a load error, run `npm run build:wasm` and confirm
62
+ `/wasm/example.wasm` is served.
@@ -0,0 +1,80 @@
1
+ import { execSync } from 'child_process';
2
+ import { existsSync, mkdirSync, copyFileSync } from 'fs';
3
+ import path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ const goDir = path.join(__dirname, 'go');
10
+ const outputDir = path.join(__dirname, 'public', 'wasm');
11
+ const wasmFile = path.join(outputDir, 'example.wasm');
12
+
13
+ function checkGo() {
14
+ try {
15
+ execSync('go version', { stdio: 'pipe' });
16
+ } catch {
17
+ console.error(
18
+ '❌ Go is not installed or not on PATH.\n' +
19
+ 'Install Go from https://go.dev/dl/ then re-run `npm run build:wasm`.'
20
+ );
21
+ process.exit(1);
22
+ }
23
+ }
24
+
25
+ function goRoot() {
26
+ return execSync('go env GOROOT', { encoding: 'utf8' }).trim();
27
+ }
28
+
29
+ function buildWasm() {
30
+ if (!existsSync(goDir)) {
31
+ console.error(`❌ Go source directory not found: ${goDir}`);
32
+ process.exit(1);
33
+ }
34
+
35
+ if (!existsSync(outputDir)) {
36
+ mkdirSync(outputDir, { recursive: true });
37
+ }
38
+
39
+ console.log('🔥 Compiling Go WASM module...');
40
+ const isWindows = process.platform === 'win32';
41
+ const goMod = path.join(goDir, 'go.mod');
42
+ if (!existsSync(goMod)) {
43
+ execSync('go mod init wasm-example', { cwd: goDir, stdio: 'inherit' });
44
+ }
45
+
46
+ // Compile with the js/wasm target
47
+ execSync(
48
+ `go build -o "${wasmFile}" main.go`,
49
+ {
50
+ cwd: goDir,
51
+ stdio: 'inherit',
52
+ env: {
53
+ ...process.env,
54
+ GOOS: 'js',
55
+ GOARCH: 'wasm',
56
+ CGO_ENABLED: '0'
57
+ },
58
+ shell: isWindows
59
+ }
60
+ );
61
+ console.log(`✅ WASM compiled: ${wasmFile}`);
62
+ }
63
+
64
+ function copyRuntime() {
65
+ const root = goRoot();
66
+ const wasmExec = path.join(root, 'lib', 'wasm', 'wasm_exec.js');
67
+ const dest = path.join(outputDir, 'wasm_exec.js');
68
+
69
+ if (!existsSync(wasmExec)) {
70
+ console.warn(`⚠️ wasm_exec.js not found at ${wasmExec}. You must copy it manually.`);
71
+ return;
72
+ }
73
+
74
+ copyFileSync(wasmExec, dest);
75
+ console.log(`✅ Runtime copied: ${dest}`);
76
+ }
77
+
78
+ buildWasm();
79
+ copyRuntime();
80
+ console.log('🎉 Go WASM build complete. Serve /wasm/example.wasm + /wasm/wasm_exec.js.');
@@ -0,0 +1,133 @@
1
+ import * as esbuild from 'esbuild';
2
+ import path from 'path';
3
+ import fs from 'fs/promises';
4
+ import { existsSync } from 'fs';
5
+ import { fileURLToPath } from 'url';
6
+ import postcss from 'postcss';
7
+ import tailwindcss from 'tailwindcss';
8
+ import autoprefixer from 'autoprefixer';
9
+
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = path.dirname(__filename);
12
+
13
+ const clientEntry = path.join(__dirname, 'src', 'main.tsx');
14
+ const serverEntry = path.join(__dirname, 'server.ts');
15
+ const outdir = path.join(__dirname, 'dist');
16
+ const buildDir = path.join(outdir, 'build');
17
+
18
+ async function ensureDir(dir) {
19
+ if (!existsSync(dir)) {
20
+ await fs.mkdir(dir, { recursive: true });
21
+ }
22
+ }
23
+
24
+ // Tailwind + Autoprefixer postcss plugin for esbuild
25
+ const cssPlugin = {
26
+ name: 'css-processor',
27
+ setup(build) {
28
+ build.onLoad({ filter: /\.css$/ }, async (args) => {
29
+ const css = await fs.readFile(args.path, 'utf8');
30
+ if (!args.path.includes('styles')) {
31
+ return { contents: css, loader: 'css' };
32
+ }
33
+ try {
34
+ const result = await postcss([tailwindcss, autoprefixer]).process(css, {
35
+ from: args.path
36
+ });
37
+ return { contents: result.css, loader: 'css' };
38
+ } catch (error) {
39
+ console.error('Error processing CSS:', error);
40
+ return { errors: [{ text: 'CSS processing error: ' + error.message }], loader: 'css' };
41
+ }
42
+ });
43
+ }
44
+ };
45
+
46
+ async function copyPublicFiles() {
47
+ const publicDir = path.join(__dirname, 'public');
48
+ if (!existsSync(publicDir)) return;
49
+ const dest = path.join(outdir, 'public');
50
+ await ensureDir(dest);
51
+ await fs.cp(publicDir, dest, { recursive: true });
52
+ console.log('✅ Public assets copied to dist/public');
53
+ }
54
+
55
+ async function buildClient() {
56
+ console.log('🚀 Building client...');
57
+ await ensureDir(buildDir);
58
+ await esbuild.build({
59
+ entryPoints: [clientEntry],
60
+ bundle: true,
61
+ minify: process.env.NODE_ENV === 'production',
62
+ format: 'esm',
63
+ outfile: path.join(buildDir, 'main.js'),
64
+ jsx: 'transform',
65
+ jsxFactory: 'jsx',
66
+ jsxFragment: 'Fragment',
67
+ loader: { '.tsx': 'tsx', '.ts': 'ts', '.jsx': 'jsx', '.js': 'js', '.css': 'css', '.json': 'json' },
68
+ plugins: [
69
+ {
70
+ name: 'baraqex-jsx',
71
+ setup(build) {
72
+ build.onLoad({ filter: /\.(tsx|jsx)$/ }, async (args) => {
73
+ const source = await fs.readFile(args.path, 'utf8');
74
+ const content = `import { jsx, Fragment } from 'baraqex';\n${source}`;
75
+ return { contents: content, loader: args.path.endsWith('tsx') ? 'tsx' : 'jsx' };
76
+ });
77
+ }
78
+ }
79
+ ],
80
+ define: { 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development') },
81
+ sourcemap: true,
82
+ target: ['es2020']
83
+ });
84
+
85
+ // Build the Tailwind styles as a separate CSS file for SSR initial paint
86
+ await esbuild.build({
87
+ entryPoints: [path.join(__dirname, 'src', 'styles.css')],
88
+ bundle: true,
89
+ outfile: path.join(buildDir, 'styles.css'),
90
+ plugins: [cssPlugin],
91
+ define: { 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development') },
92
+ minify: process.env.NODE_ENV === 'production'
93
+ });
94
+
95
+ console.log('✅ Client build complete');
96
+ }
97
+
98
+ async function buildServer() {
99
+ console.log('🚀 Building server...');
100
+ await esbuild.build({
101
+ entryPoints: [serverEntry],
102
+ bundle: true,
103
+ platform: 'node',
104
+ target: ['node18'],
105
+ format: 'esm',
106
+ outfile: path.join(outdir, 'server.js'),
107
+ external: ['express', 'cors', 'compression', 'socket.io', 'dotenv'],
108
+ plugins: [
109
+ {
110
+ name: 'external-all',
111
+ setup(build) {
112
+ build.onResolve({ filter: /^baraqex/ }, () => ({ external: true }));
113
+ }
114
+ }
115
+ ],
116
+ define: { 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development') },
117
+ sourcemap: false
118
+ });
119
+ console.log('✅ Server build complete');
120
+ }
121
+
122
+ async function build() {
123
+ console.log('🔨 Starting fullstack build...');
124
+ await ensureDir(outdir);
125
+ await Promise.all([copyPublicFiles(), buildClient(), buildServer()]);
126
+ await fs.copyFile(path.join(__dirname, 'index.html'), path.join(outdir, 'index.html'));
127
+ console.log('🎉 Build complete! Run `npm run start` to launch.');
128
+ }
129
+
130
+ build().catch((err) => {
131
+ console.error('Build failed:', err);
132
+ process.exit(1);
133
+ });
@@ -0,0 +1,53 @@
1
+ package main
2
+
3
+ import (
4
+ "syscall/js"
5
+ )
6
+
7
+ // goAdd returns the sum of two numbers.
8
+ func goAdd(this js.Value, args []js.Value) interface{} {
9
+ a := args[0].Float()
10
+ b := args[1].Float()
11
+ return a + b
12
+ }
13
+
14
+ // goMultiply returns the product of two numbers.
15
+ func goMultiply(this js.Value, args []js.Value) interface{} {
16
+ a := args[0].Float()
17
+ b := args[1].Float()
18
+ return a * b
19
+ }
20
+
21
+ // goFibonacci returns the nth Fibonacci number (0-indexed).
22
+ func goFibonacci(this js.Value, args []js.Value) interface{} {
23
+ n := args[0].Int()
24
+ if n <= 1 {
25
+ return n
26
+ }
27
+ a, b := 0, 1
28
+ for i := 2; i <= n; i++ {
29
+ a, b = b, a+b
30
+ }
31
+ return b
32
+ }
33
+
34
+ // goProcessArray doubles each element of a JS array.
35
+ func goProcessArray(this js.Value, args []js.Value) interface{} {
36
+ src := args[0]
37
+ length := src.Length()
38
+ result := make([]interface{}, length)
39
+ for i := 0; i < length; i++ {
40
+ val := src.Index(i).Float()
41
+ result[i] = val * 2
42
+ }
43
+ return result
44
+ }
45
+
46
+ func main() {
47
+ c := make(chan struct{}, 0)
48
+ js.Global().Set("goAdd", js.FuncOf(goAdd))
49
+ js.Global().Set("goMultiply", js.FuncOf(goMultiply))
50
+ js.Global().Set("goFibonacci", js.FuncOf(goFibonacci))
51
+ js.Global().Set("goProcessArray", js.FuncOf(goProcessArray))
52
+ <-c
53
+ }
@@ -1,36 +1,17 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Frontend Hamroun SSR App</title>
7
- <!-- Include the processed Tailwind CSS file -->
8
- <link rel="stylesheet" href="/styles.css">
9
- <!-- Fallback styles if Tailwind isn't loaded correctly -->
10
- <style>
11
- body {
12
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
13
- line-height: 1.6;
14
- color: #333;
15
- }
16
- a {
17
- color: #0066cc;
18
- text-decoration: none;
19
- }
20
- a:hover {
21
- text-decoration: underline;
22
- }
23
- pre {
24
- background: #f5f5f5;
25
- padding: 10px;
26
- border-radius: 4px;
27
- overflow: auto;
28
- }
29
- </style>
30
- </head>
31
- <body>
32
- <div id="root"></div>
33
- <script src="/build/main.js" type="module"></script>
34
- <script src="/socket.io/socket.io.js"></script>
35
- </body>
36
- </html>
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Baraqex Full-Stack App</title>
7
+ <link rel="icon" href="data:,">
8
+ <link rel="stylesheet" href="/build/styles.css">
9
+ <script>window.__INITIAL_STATE__ = {};</script>
10
+ </head>
11
+ <body>
12
+ <div id="root"></div>
13
+ <script src="/wasm/wasm_exec.js"></script>
14
+ <script src="/socket.io/socket.io.js"></script>
15
+ <script src="/build/main.js" type="module"></script>
16
+ </body>
17
+ </html>
@@ -1,35 +1,41 @@
1
- {
2
- "name": "fullstack-app",
3
- "version": "1.0.0",
4
- "description": "Frontend Hamroun Fullstack App with esbuild",
5
- "type": "module",
6
- "scripts": {
7
- "start": "node server.js",
8
- "dev": "node process-tailwind.js && cross-env NODE_ENV=development tsx server.ts",
9
- "build": "node process-tailwind.js && cross-env NODE_ENV=production tsx build.ts",
10
- "serve": "cross-env NODE_ENV=production node dist/server.js",
11
- "tailwind": "node process-tailwind.js"
12
- },
13
- "dependencies": {
14
- "compression": "^1.7.4",
15
- "cors": "^2.8.5",
16
- "dotenv": "^16.3.1",
17
- "express": "^4.18.2",
18
- "frontend-hamroun": "latest",
19
- "socket.io": "^4.7.2"
20
- },
21
- "devDependencies": {
22
- "@types/compression": "^1.7.3",
23
- "@types/cors": "^2.8.14",
24
- "@types/express": "^4.17.18",
25
- "@types/node": "^20.8.2",
26
- "autoprefixer": "^10.4.14",
27
- "chokidar": "^3.5.3",
28
- "cross-env": "^7.0.3",
29
- "esbuild": "^0.19.5",
30
- "postcss": "^8.4.27",
31
- "tailwindcss": "^3.3.3",
32
- "tsx": "^3.13.0",
33
- "typescript": "^5.2.2"
34
- }
35
- }
1
+ {
2
+ "name": "fullstack-app",
3
+ "version": "1.0.0",
4
+ "description": "Baraqex full-stack template: frontend + backend + SSR + WebAssembly (Go)",
5
+ "private": true,
6
+ "type": "module",
7
+ "scripts": {
8
+ "start": "node dist/server.js",
9
+ "prod": "npm run build && npm run start",
10
+ "dev": "tsx server.ts",
11
+ "build": "node build.mjs",
12
+ "build:wasm": "node build-wasm.js",
13
+ "build:all": "node build-wasm.js && node build.mjs"
14
+ },
15
+ "dependencies": {
16
+ "baraqex": "latest",
17
+ "compression": "^1.7.4",
18
+ "cors": "^2.8.5",
19
+ "dotenv": "^16.3.1",
20
+ "express": "^4.18.2",
21
+ "socket.io": "^4.7.2"
22
+ },
23
+ "devDependencies": {
24
+ "@types/compression": "^1.7.3",
25
+ "@types/cors": "^2.8.14",
26
+ "@types/express": "^4.17.18",
27
+ "@types/node": "^20.8.2",
28
+ "autoprefixer": "^10.4.14",
29
+ "chokidar": "^3.5.3",
30
+ "cross-env": "^7.0.3",
31
+ "esbuild": "^0.19.5",
32
+ "postcss": "^8.4.27",
33
+ "rimraf": "^5.0.0",
34
+ "tailwindcss": "^3.3.3",
35
+ "tsx": "^3.13.0",
36
+ "typescript": "^5.2.2"
37
+ },
38
+ "engines": {
39
+ "node": ">=18.0.0"
40
+ }
41
+ }
@@ -1,6 +1,6 @@
1
- module.exports = {
2
- plugins: {
3
- tailwindcss: {},
4
- autoprefixer: {},
5
- },
6
- }
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {}
5
+ }
6
+ };