frontend-hamroun 1.2.72 → 1.2.74

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.
@@ -5,19 +5,18 @@
5
5
  "type": "module",
6
6
  "main": "server.js",
7
7
  "scripts": {
8
+ "build:dirs": "node -e \"const fs=require('fs');const dirs=['public/wasm','src/wasm','dist'];dirs.forEach(d=>!fs.existsSync(d)&&fs.mkdirSync(d,{recursive:true}))\"",
8
9
  "build:wasm": "node build-wasm.js",
9
- "prepare": "node -e \"if (!require('fs').existsSync('public/wasm')) { require('fs').mkdirSync('public/wasm', {recursive: true}); }\"",
10
- "dev": "npm run build:wasm && node --watch server.js",
11
- "build": "npm run build:wasm && node -e \"require('fs').mkdirSync('dist', {recursive: true}); require('fs-extra').copySync('public', 'dist')\"",
10
+ "dev": "npm run build:dirs && npm run build:wasm && node --watch server.js",
11
+ "build": "npm run build:dirs && npm run build:wasm && node -e \"require('fs-extra').copySync('public', 'dist')\"",
12
12
  "start": "cross-env NODE_ENV=production node server.js"
13
13
  },
14
14
  "dependencies": {
15
15
  "express": "^4.18.2",
16
- "frontend-hamroun": "^1.2.71",
17
- "fs-extra": "^10.0.0"
16
+ "frontend-hamroun": "^1.2.72",
17
+ "fs-extra": "^11.1.1"
18
18
  },
19
19
  "devDependencies": {
20
- "@babel/core": "^7.22.9",
21
20
  "cross-env": "^7.0.3"
22
21
  }
23
22
  }
@@ -21,12 +21,12 @@
21
21
  }
22
22
 
23
23
  body {
24
- font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
25
- max-width: 800px;
26
- margin: 0 auto;
27
- padding: 2rem;
24
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
25
+ background-color: var(--background);
26
+ color: var(--text-color);
27
+ margin: 0;
28
+ padding: 0;
28
29
  line-height: 1.6;
29
- color: #333;
30
30
  }
31
31
 
32
32
  .app {
@@ -45,8 +45,25 @@
45
45
  color: var(--primary-color);
46
46
  }
47
47
 
48
- header p {
48
+ .rendering-info {
49
+ display: flex;
50
+ gap: 10px;
51
+ justify-content: center;
52
+ margin-top: 10px;
53
+ }
54
+
55
+ .badge {
56
+ display: inline-block;
57
+ padding: 4px 8px;
58
+ border-radius: 4px;
59
+ background-color: #eaeaea;
49
60
  color: #666;
61
+ font-size: 0.8rem;
62
+ }
63
+
64
+ .badge.active {
65
+ background-color: var(--success-color);
66
+ color: white;
50
67
  }
51
68
 
52
69
  .card {
@@ -58,11 +75,23 @@
58
75
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
59
76
  }
60
77
 
61
- pre {
62
- background-color: #f5f5f5;
78
+ .result {
79
+ background-color: #f0f7ff;
63
80
  padding: 1rem;
64
81
  border-radius: 4px;
82
+ margin-top: 1rem;
83
+ white-space: pre-wrap;
65
84
  overflow-x: auto;
85
+ font-family: monospace;
86
+ font-size: 0.9rem;
87
+ }
88
+
89
+ .error {
90
+ background-color: #ffebee;
91
+ color: #c62828;
92
+ padding: 0.75rem;
93
+ border-radius: 4px;
94
+ margin-top: 0.5rem;
66
95
  }
67
96
 
68
97
  footer {
@@ -73,56 +102,31 @@
73
102
  border-top: 1px solid var(--border-color);
74
103
  }
75
104
 
76
- .warning {
77
- display: none;
78
- background-color: #fff3cd;
79
- border: 1px solid #ffecb5;
80
- color: #856404;
81
- padding: 1rem;
82
- border-radius: 4px;
83
- margin-bottom: 1rem;
84
- }
85
-
86
- code {
87
- background-color: #f5f5f5;
88
- padding: 0.2rem 0.4rem;
89
- border-radius: 3px;
105
+ footer a {
106
+ color: var(--primary-color);
107
+ text-decoration: none;
90
108
  }
91
109
 
92
- .loading {
93
- text-align: center;
94
- padding: 3rem 1rem;
95
- color: #666;
110
+ @media (max-width: 768px) {
111
+ .app {
112
+ padding: 10px;
113
+ }
114
+
115
+ .card {
116
+ padding: 1rem;
117
+ }
96
118
  }
97
119
  </style>
98
- <script src="/wasm/wasm_exec.js" defer></script>
120
+ <!-- WASM runtime will be loaded by server -->
121
+ <script src="/wasm/wasm_exec.js"></script>
99
122
  </head>
100
123
  <body>
101
124
  <div id="root">
102
- <!-- Server-rendered content will be inserted here -->
103
- <div class="loading">
125
+ <!-- Server-rendered content will replace this -->
126
+ <div class="loading" style="text-align:center;padding:3rem;">
104
127
  <h2>Loading...</h2>
105
- <p>Please wait while the server starts.</p>
106
- <p>If this message persists, there might be an issue with the server.</p>
128
+ <p>Please wait while the application initializes.</p>
107
129
  </div>
108
130
  </div>
109
- <script type="module" src="/src/client.js"></script>
110
- <script>
111
- // The server should replace this entire page with server-rendered content
112
- // If you're seeing this, something is wrong with the server-side rendering
113
- setTimeout(() => {
114
- if (document.querySelector('.loading')) {
115
- document.querySelector('#root').innerHTML = `
116
- <div class="warning" style="display:block; background-color: #fff3cd; border: 1px solid #ffecb5; color: #856404; padding: 1rem; border-radius: 4px; margin-bottom: 1rem;">
117
- <h2>Server Not Responding</h2>
118
- <p>The server is not responding with the expected server-rendered content.</p>
119
- <p>Please make sure the server is running properly with:</p>
120
- <code>npm run dev</code>
121
- <p>This static HTML file should be replaced by server-rendered content.</p>
122
- </div>
123
- `;
124
- }
125
- }, 2000);
126
- </script>
127
131
  </body>
128
132
  </html>
@@ -514,6 +514,194 @@ function renderPage(req, res) {
514
514
  }
515
515
  }
516
516
 
517
+ // Configure Express file serving
518
+ app.get('/wasm/wasm_exec.js', (req, res) => {
519
+ res.sendFile(WASM_EXEC_NODE_PATH);
520
+ });
521
+
522
+ app.get('/wasm/example.wasm', (req, res) => {
523
+ res.sendFile(WASM_PATH);
524
+ });
525
+
526
+ // Dynamic Go code generation endpoint
527
+ app.post('/api/generate-wasm', async (req, res) => {
528
+ try {
529
+ const { functionName, functionBody, inputTypes, returnType } = req.body;
530
+
531
+ if (!functionName || !functionBody) {
532
+ return res.status(400).json({ error: 'Missing required fields: functionName and functionBody' });
533
+ }
534
+
535
+ // Create Go source directory if it doesn't exist
536
+ const goSourceDir = path.join(__dirname, 'src', 'wasm');
537
+ if (!fs.existsSync(goSourceDir)) {
538
+ fs.mkdirSync(goSourceDir, { recursive: true });
539
+ }
540
+
541
+ // Create the Go file with the user-provided function
542
+ const goFilePath = path.join(goSourceDir, `${functionName}.go`);
543
+
544
+ // Generate Go code with the user's function
545
+ const goCode = generateGoCode(functionName, functionBody, inputTypes, returnType);
546
+
547
+ // Write Go file
548
+ fs.writeFileSync(goFilePath, goCode);
549
+ console.log(`Created Go file: ${goFilePath}`);
550
+
551
+ // Build the WASM module
552
+ const wasmOutputDir = path.join(__dirname, 'public', 'wasm');
553
+ if (!fs.existsSync(wasmOutputDir)) {
554
+ fs.mkdirSync(wasmOutputDir, { recursive: true });
555
+ }
556
+
557
+ const wasmFilePath = path.join(wasmOutputDir, `${functionName}.wasm`);
558
+
559
+ // Import the build function from build-wasm.js
560
+ const { buildGoFile } = await import('./build-wasm.js');
561
+
562
+ // Build the Go file to WASM
563
+ const result = await buildGoFile(goFilePath, wasmFilePath);
564
+
565
+ if (result.success) {
566
+ res.json({
567
+ success: true,
568
+ message: 'WebAssembly module generated successfully',
569
+ function: functionName,
570
+ wasmPath: `/wasm/${functionName}.wasm`,
571
+ jsUsage: `
572
+ // Load and use the WASM module:
573
+ const wasm = await loadGoWasm('/wasm/${functionName}.wasm');
574
+ const result = wasm.functions.${functionName}(...args);
575
+ `
576
+ });
577
+ } else {
578
+ res.status(500).json({
579
+ success: false,
580
+ error: result.error,
581
+ message: 'Failed to build WebAssembly module'
582
+ });
583
+ }
584
+ } catch (error) {
585
+ console.error('Error generating WASM:', error);
586
+ res.status(500).json({ error: error.message });
587
+ }
588
+ });
589
+
590
+ // Helper function to generate Go code
591
+ function generateGoCode(functionName, functionBody, inputTypes = [], returnType = 'int') {
592
+ // Default input types to interface{} (any) if not provided
593
+ const goInputTypes = inputTypes.length > 0
594
+ ? inputTypes.map(t => mapJsTypeToGo(t)).join(', ')
595
+ : 'interface{}, interface{}';
596
+
597
+ // Default return type to int if not provided
598
+ const goReturnType = mapJsTypeToGo(returnType);
599
+
600
+ return `//go:build js && wasm
601
+ // +build js,wasm
602
+
603
+ package main
604
+
605
+ import (
606
+ "encoding/json"
607
+ "fmt"
608
+ "syscall/js"
609
+ )
610
+
611
+ // Generated ${functionName} function from template
612
+ func ${functionName}(this js.Value, args []js.Value) interface{} {
613
+ // Validate input arguments
614
+ if len(args) < ${inputTypes.length || 1} {
615
+ return js.ValueOf("Error: Not enough arguments")
616
+ }
617
+
618
+ // Implementation
619
+ ${functionBody}
620
+ }
621
+
622
+ // Example Go function to be called from JavaScript
623
+ func goAdd(this js.Value, args []js.Value) interface{} {
624
+ if len(args) != 2 {
625
+ return js.ValueOf("Error: Expected two arguments")
626
+ }
627
+
628
+ a := args[0].Int()
629
+ b := args[1].Int()
630
+ return js.ValueOf(a + b)
631
+ }
632
+
633
+ // Process complex data in Go
634
+ func goProcessData(this js.Value, args []js.Value) interface{} {
635
+ if len(args) == 0 {
636
+ return js.ValueOf("Error: Expected at least one argument")
637
+ }
638
+
639
+ // Get input data
640
+ data := args[0]
641
+ if data.Type() != js.TypeObject {
642
+ return js.ValueOf("Error: Expected JSON object")
643
+ }
644
+
645
+ // Convert JS object to Go map
646
+ jsonStr := js.Global().Get("JSON").Call("stringify", data).String()
647
+ var inputMap map[string]interface{}
648
+ if err := json.Unmarshal([]byte(jsonStr), &inputMap); err != nil {
649
+ return js.ValueOf(fmt.Sprintf("Error parsing JSON: %s", err.Error()))
650
+ }
651
+
652
+ // Add new fields
653
+ inputMap["processed"] = true
654
+ inputMap["processor"] = "Go WASM"
655
+
656
+ // Add some computed fields
657
+ if values, ok := inputMap["values"].([]interface{}); ok {
658
+ sum := 0.0
659
+ for _, v := range values {
660
+ if num, ok := v.(float64); ok {
661
+ sum += num
662
+ }
663
+ }
664
+ inputMap["sum"] = sum
665
+ }
666
+
667
+ // Convert back to JS
668
+ resultJSON, err := json.Marshal(inputMap)
669
+ if err != nil {
670
+ return js.ValueOf(fmt.Sprintf("Error generating JSON: %s", err.Error()))
671
+ }
672
+
673
+ return js.ValueOf(string(resultJSON))
674
+ }
675
+
676
+ func main() {
677
+ fmt.Println("Go WASM Module initialized")
678
+
679
+ // Register functions to be callable from JavaScript
680
+ js.Global().Set("goAdd", js.FuncOf(goAdd))
681
+ js.Global().Set("goProcessData", js.FuncOf(goProcessData))
682
+ js.Global().Set("${functionName}", js.FuncOf(${functionName}))
683
+
684
+ // Keep the program running
685
+ <-make(chan bool)
686
+ }
687
+ `;
688
+ }
689
+
690
+ // Map JavaScript types to Go types
691
+ function mapJsTypeToGo(jsType) {
692
+ const typeMap = {
693
+ 'string': 'string',
694
+ 'number': 'float64',
695
+ 'integer': 'int',
696
+ 'boolean': 'bool',
697
+ 'object': 'map[string]interface{}',
698
+ 'array': '[]interface{}',
699
+ 'any': 'interface{}'
700
+ };
701
+
702
+ return typeMap[jsType] || 'interface{}';
703
+ }
704
+
517
705
  // Start the server
518
706
  startServer().catch(err => {
519
707
  console.error('Failed to start server:', err);
package/dist/batch.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export declare let isBatching: boolean;
2
- export declare function batchUpdates(fn: Function): void;
3
- export declare function getIsBatching(): boolean;
@@ -1,14 +0,0 @@
1
- export declare class Component {
2
- state: any;
3
- props: any;
4
- element: HTMLElement | null;
5
- private _mounted;
6
- constructor(props?: any);
7
- componentDidMount(): void;
8
- setState(newState: any): Promise<void>;
9
- private _replayEvents;
10
- private _deepCloneWithEvents;
11
- update(): Promise<HTMLElement | Text>;
12
- private _updateElement;
13
- render(): any;
14
- }
File without changes
package/dist/context.d.ts DELETED
@@ -1,13 +0,0 @@
1
- export interface Context<T> {
2
- Provider: (props: {
3
- value: T;
4
- children?: any;
5
- }) => any;
6
- Consumer: (props: {
7
- children: (value: T) => any;
8
- }) => any;
9
- _id: symbol;
10
- useSelector: <S>(selector: (state: T) => S) => S;
11
- }
12
- export declare function createContext<T>(defaultValue: T): Context<T>;
13
- export declare function useContext<T>(context: any): T;
package/dist/hooks.d.ts DELETED
@@ -1,8 +0,0 @@
1
- export declare function setRenderCallback(callback: (element: any, container: HTMLElement) => void, element: any, container: HTMLElement): void;
2
- export declare function prepareRender(): number;
3
- export declare function finishRender(): void;
4
- export declare function useState<T>(initial: T): [T, (value: T | ((prev: T) => T)) => void];
5
- export declare function useEffect(callback: () => (() => void) | void, deps?: any[]): void;
6
- export declare function useMemo<T>(factory: () => T, deps: any[]): T;
7
- export declare function useRef<T>(initial: T): any;
8
- export declare function useErrorBoundary(): [Error | null, () => void];
@@ -1,12 +0,0 @@
1
- export { useState, useEffect, useMemo, useRef, useErrorBoundary } from './hooks';
2
- export { createContext, useContext } from './context';
3
- export { batchUpdates } from './batch';
4
- export { jsx, jsxs, Fragment } from './jsx-runtime';
5
- export { render, hydrate } from './renderer';
6
- export { renderToString } from './server-renderer';
7
- export type { Context } from './context';
8
- export type { VNode } from './types';
9
- export type { Server, ServerConfig, User, DbConfig, MiddlewareFunction } from './server-types';
10
- export declare const server: {
11
- getServer(): Promise<never>;
12
- };
File without changes
@@ -1,4 +0,0 @@
1
- export declare function jsx(type: string | Function, props: any, key?: string): any;
2
- export declare function jsxs(type: string | Function, props: any, key?: string): any;
3
- export declare function createElement(vnode: any): HTMLElement | Text;
4
- export declare const Fragment: unique symbol;
@@ -1,20 +0,0 @@
1
- interface VNode {
2
- type: string | Function;
3
- props: Record<string, any>;
4
- }
5
- declare function jsx(type: string | Function, props: any): VNode;
6
- declare const Fragment: ({ children }: {
7
- children: any;
8
- }) => any;
9
- declare function createElement(vnode: VNode | any): Promise<Node>;
10
- export { jsx, jsx as jsxs, jsx as jsxDEV, Fragment, createElement };
11
- declare const jsxRuntime: {
12
- jsx: typeof jsx;
13
- jsxs: typeof jsx;
14
- jsxDEV: typeof jsx;
15
- Fragment: ({ children }: {
16
- children: any;
17
- }) => any;
18
- createElement: typeof createElement;
19
- };
20
- export default jsxRuntime;
@@ -1,2 +0,0 @@
1
- export declare function hydrate(element: any, container: HTMLElement): Promise<void>;
2
- export declare function render(element: any, container: HTMLElement): Promise<void>;
@@ -1,5 +0,0 @@
1
- import { VNode } from './types';
2
- /**
3
- * Renders a virtual DOM tree to an HTML string
4
- */
5
- export declare function renderToString(vnode: VNode): string;
@@ -1,42 +0,0 @@
1
- /**
2
- * Public type definitions for server functionality
3
- * These types are safe to import in any environment
4
- */
5
- export interface ServerConfig {
6
- port?: number;
7
- apiDir?: string;
8
- pagesDir?: string;
9
- staticDir?: string;
10
- enableCors?: boolean;
11
- corsOptions?: any;
12
- db?: {
13
- url: string;
14
- type: 'mongodb' | 'mysql' | 'postgres';
15
- };
16
- auth?: {
17
- secret: string;
18
- expiresIn?: string;
19
- };
20
- }
21
- export interface Server {
22
- start(): Promise<void>;
23
- stop(): Promise<void>;
24
- getExpressApp(): any;
25
- getDatabase(): any;
26
- getAuth(): any;
27
- }
28
- export interface User {
29
- id: string | number;
30
- username: string;
31
- password?: string;
32
- email?: string;
33
- roles?: string[];
34
- [key: string]: any;
35
- }
36
- export interface DbConfig {
37
- url: string;
38
- type: 'mongodb' | 'mysql' | 'postgres';
39
- }
40
- export interface MiddlewareFunction {
41
- (req: any, res: any, next: any): void | Promise<void>;
42
- }
package/dist/types.d.ts DELETED
@@ -1,18 +0,0 @@
1
- export type { Context } from './context';
2
- export interface VNode {
3
- type: string | Function;
4
- props: Record<string, any>;
5
- key?: string | number;
6
- }
7
- declare global {
8
- namespace JSX {
9
- interface Element {
10
- type: string | Function;
11
- props: Record<string, any>;
12
- key?: string | number;
13
- }
14
- interface IntrinsicElements {
15
- [elemName: string]: any;
16
- }
17
- }
18
- }
package/dist/vdom.d.ts DELETED
@@ -1,8 +0,0 @@
1
- interface VNode {
2
- type: string | Function;
3
- props: Record<string, any>;
4
- key?: string | number;
5
- }
6
- export declare function diff(oldNode: VNode | any, newNode: VNode | any): boolean;
7
- export declare function shouldComponentUpdate(oldProps: any, newProps: any): boolean;
8
- export {};
package/dist/wasm.d.ts DELETED
@@ -1,36 +0,0 @@
1
- /**
2
- * Go WebAssembly Integration Utilities
3
- *
4
- * This module provides tools for loading and interacting with Go WASM modules
5
- * in browser and server environments.
6
- */
7
- export interface GoWasmInstance {
8
- instance: WebAssembly.Instance;
9
- module: WebAssembly.Module;
10
- exports: any;
11
- functions: Record<string, Function>;
12
- }
13
- export interface GoWasmOptions {
14
- importObject?: WebAssembly.Imports;
15
- goWasmPath?: string;
16
- loadGo?: boolean;
17
- onLoad?: (instance: GoWasmInstance) => void;
18
- debug?: boolean;
19
- }
20
- /**
21
- * Load a Go WASM module from a URL
22
- */
23
- export declare function loadGoWasm(wasmUrl: string, options?: GoWasmOptions): Promise<GoWasmInstance>;
24
- /**
25
- * Create a TypeScript-friendly wrapper for Go WASM functions
26
- */
27
- export declare function createTypedWasmFunction<T extends (...args: any[]) => any>(instance: GoWasmInstance, functionName: string): T;
28
- /**
29
- * Helper to convert JavaScript values to Go-compatible formats
30
- */
31
- export declare const goValues: {
32
- stringToGo: (instance: GoWasmInstance, str: string) => number;
33
- stringFromGo: (instance: GoWasmInstance, ptr: number) => string;
34
- objectToGo: (instance: GoWasmInstance, obj: any) => number;
35
- objectFromGo: (instance: GoWasmInstance, ptr: number) => any;
36
- };