frontend-hamroun 1.2.22 → 1.2.24

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.
@@ -1,46 +1,123 @@
1
- import { Server, renderComponent } from 'frontend-hamroun/server';
2
- import { join } from 'path';
3
1
  import express from 'express';
2
+ import { fileURLToPath } from 'url';
3
+ import { dirname, join } from 'path';
4
+ import { renderToString } from 'frontend-hamroun';
4
5
 
5
- async function startServer() {
6
+ // Get directory name in ESM
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = dirname(__filename);
9
+
10
+ // Create Express app
11
+ const app = express();
12
+ const port = process.env.PORT ? parseInt(process.env.PORT) : 3000;
13
+
14
+ // Serve static files from public directory
15
+ app.use(express.static(join(__dirname, 'public')));
16
+
17
+ // API endpoint example
18
+ app.get('/api/page-data', (req, res) => {
19
+ res.json({
20
+ title: 'Server-side Data',
21
+ content: 'This data was fetched from the server',
22
+ timestamp: new Date().toISOString()
23
+ });
24
+ });
25
+
26
+ // Implement basic SSR without relying on complex server functionality
27
+ app.get('*', async (req, res) => {
6
28
  try {
7
- // Create and configure the server
8
- const app = new Server({
9
- port: process.env.PORT ? parseInt(process.env.PORT) : 3000,
10
- pagesDir: './src/pages',
11
- staticDir: './public',
12
-
13
- // Enable CORS for API endpoints
14
- enableCors: true
15
- });
29
+ // Import the page component
30
+ const pagesDir = join(__dirname, 'src', 'pages');
31
+ let componentPath;
16
32
 
17
- // Add server-side data endpoints (optional)
18
- const expressApp = app.getExpressApp();
33
+ // Map URL path to component file
34
+ if (req.path === '/') {
35
+ componentPath = join(pagesDir, 'index.js');
36
+ } else {
37
+ componentPath = join(pagesDir, `${req.path}.js`);
38
+ // Check if it's a directory with index.js
39
+ if (!await fileExists(componentPath)) {
40
+ componentPath = join(pagesDir, req.path, 'index.js');
41
+ }
42
+ }
19
43
 
20
- // Example API endpoint that provides data to SSR pages
21
- expressApp.get('/api/page-data', (req, res) => {
22
- res.json({
23
- title: 'Server-side Data',
24
- content: 'This data was fetched from the server',
25
- timestamp: new Date().toISOString()
26
- });
27
- });
44
+ // If component doesn't exist, return 404
45
+ if (!await fileExists(componentPath)) {
46
+ return res.status(404).send(`
47
+ <!DOCTYPE html>
48
+ <html>
49
+ <head>
50
+ <title>404 - Page Not Found</title>
51
+ </head>
52
+ <body>
53
+ <h1>404 - Page Not Found</h1>
54
+ <p>The page you requested does not exist.</p>
55
+ </body>
56
+ </html>
57
+ `);
58
+ }
28
59
 
29
- // Start the server
30
- await app.start();
60
+ // Import the component
61
+ const { default: PageComponent } = await import(componentPath);
31
62
 
32
- console.log(`Server running at http://localhost:${process.env.PORT || 3000}`);
63
+ // Render the component to string
64
+ const content = renderToString(PageComponent());
33
65
 
34
- // Handle graceful shutdown
35
- process.on('SIGINT', async () => {
36
- console.log('Shutting down server...');
37
- await app.stop();
38
- process.exit(0);
39
- });
66
+ // Send the HTML response
67
+ res.send(`
68
+ <!DOCTYPE html>
69
+ <html lang="en">
70
+ <head>
71
+ <meta charset="UTF-8">
72
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
73
+ <title>Frontend Hamroun SSR</title>
74
+ <!-- Import Tailwind-like styles for quick styling -->
75
+ <link href="https://cdn.jsdelivr.net/npm/daisyui@3.7.4/dist/full.css" rel="stylesheet" type="text/css" />
76
+ <script src="https://cdn.tailwindcss.com"></script>
77
+ <!-- Client-side script for hydration -->
78
+ <script type="module" src="/assets/client.js"></script>
79
+ </head>
80
+ <body>
81
+ <div id="app">${content}</div>
82
+ </body>
83
+ </html>
84
+ `);
40
85
  } catch (error) {
41
- console.error('Failed to start server:', error);
42
- process.exit(1);
86
+ console.error('Error rendering page:', error);
87
+ res.status(500).send(`
88
+ <!DOCTYPE html>
89
+ <html>
90
+ <head>
91
+ <title>500 - Server Error</title>
92
+ </head>
93
+ <body>
94
+ <h1>500 - Server Error</h1>
95
+ <p>There was an error processing your request.</p>
96
+ ${process.env.NODE_ENV === 'development' ? `<pre>${error.stack}</pre>` : ''}
97
+ </body>
98
+ </html>
99
+ `);
100
+ }
101
+ });
102
+
103
+ // Helper function to check if file exists
104
+ async function fileExists(path) {
105
+ try {
106
+ const fs = await import('fs/promises');
107
+ await fs.access(path);
108
+ return true;
109
+ } catch {
110
+ return false;
43
111
  }
44
112
  }
45
113
 
46
- startServer();
114
+ // Start the server
115
+ app.listen(port, () => {
116
+ console.log(`Server running at http://localhost:${port}`);
117
+ });
118
+
119
+ // Handle graceful shutdown
120
+ process.on('SIGINT', () => {
121
+ console.log('Shutting down server...');
122
+ process.exit(0);
123
+ });
@@ -0,0 +1,29 @@
1
+ import { hydrate } from 'frontend-hamroun';
2
+
3
+ // Dynamically import the appropriate page component
4
+ async function hydratePage() {
5
+ try {
6
+ // Get current path
7
+ const path = window.location.pathname === '/' ? '/index' : window.location.pathname;
8
+
9
+ // Dynamically import the component
10
+ const module = await import(`./pages${path}.js`);
11
+ const PageComponent = module.default;
12
+
13
+ // Find the root element
14
+ const rootElement = document.getElementById('app');
15
+
16
+ if (rootElement && PageComponent) {
17
+ // Hydrate the application
18
+ hydrate(PageComponent(), rootElement);
19
+ console.log('Hydration complete');
20
+ } else {
21
+ console.error('Could not find root element or page component');
22
+ }
23
+ } catch (error) {
24
+ console.error('Hydration error:', error);
25
+ }
26
+ }
27
+
28
+ // Hydrate when DOM is ready
29
+ document.addEventListener('DOMContentLoaded', hydratePage);
@@ -11,34 +11,31 @@ export default defineConfig({
11
11
 
12
12
  // Configure build
13
13
  build: {
14
- outDir: 'dist/client',
14
+ outDir: 'dist/public',
15
15
  emptyOutDir: true,
16
- minify: process.env.NODE_ENV === 'production',
17
16
  rollupOptions: {
18
17
  input: {
19
- client: resolve(__dirname, 'src/client.tsx')
18
+ client: resolve(__dirname, 'src/client.ts')
20
19
  },
21
20
  output: {
22
- entryFileNames: 'assets/[name]-[hash].js',
21
+ entryFileNames: 'assets/[name].js',
23
22
  chunkFileNames: 'assets/[name]-[hash].js',
24
23
  assetFileNames: 'assets/[name]-[hash].[ext]'
25
24
  }
26
25
  }
27
26
  },
28
27
 
29
- // Optimize dependencies
30
- optimizeDeps: {
31
- include: ['frontend-hamroun']
28
+ // Resolve aliases for better imports
29
+ resolve: {
30
+ alias: {
31
+ '@': resolve(__dirname, 'src')
32
+ }
32
33
  },
33
34
 
34
35
  // Development server
35
36
  server: {
36
37
  proxy: {
37
- // Forward API requests to the actual Node.js server during development
38
- '/api': {
39
- target: 'http://localhost:3000',
40
- changeOrigin: true
41
- }
38
+ '/api': 'http://localhost:3000'
42
39
  }
43
40
  }
44
41
  });