bertui 0.2.4 → 0.2.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.
package/index.js CHANGED
@@ -32,5 +32,5 @@ export default {
32
32
  buildCSS,
33
33
  copyCSS,
34
34
  program,
35
- version: "0.2.1"
35
+ version: "0.2.5"
36
36
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bertui",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "Lightning-fast React dev server powered by Bun and Elysia",
5
5
  "type": "module",
6
6
  "main": "./index.js",
@@ -4,12 +4,15 @@ import { join, extname } from 'path';
4
4
  import { existsSync } from 'fs';
5
5
  import logger from '../logger/logger.js';
6
6
  import { compileProject } from '../client/compiler.js';
7
+ import { loadConfig } from '../config/loadConfig.js';
7
8
 
8
9
  export async function startDevServer(options = {}) {
9
10
  const port = parseInt(options.port) || 3000;
10
11
  const root = options.root || process.cwd();
11
12
  const compiledDir = join(root, '.bertui', 'compiled');
12
13
 
14
+ const config = await loadConfig(root);
15
+
13
16
  const clients = new Set();
14
17
  let hasRouter = false;
15
18
 
@@ -21,7 +24,7 @@ export async function startDevServer(options = {}) {
21
24
 
22
25
  const app = new Elysia()
23
26
  .get('/', async () => {
24
- return serveHTML(root, hasRouter);
27
+ return serveHTML(root, hasRouter, config);
25
28
  })
26
29
 
27
30
  .get('/*', async ({ params, set }) => {
@@ -45,11 +48,21 @@ export async function startDevServer(options = {}) {
45
48
  }
46
49
  }
47
50
 
51
+ if (path.startsWith('public/')) {
52
+ const publicDir = join(root, 'public');
53
+ const filepath = join(publicDir, path.replace('public/', ''));
54
+ const file = Bun.file(filepath);
55
+
56
+ if (await file.exists()) {
57
+ return new Response(file);
58
+ }
59
+ }
60
+
48
61
  set.status = 404;
49
62
  return 'File not found';
50
63
  }
51
64
 
52
- return serveHTML(root, hasRouter);
65
+ return serveHTML(root, hasRouter, config);
53
66
  })
54
67
 
55
68
  .get('/hmr-client.js', () => {
@@ -141,21 +154,34 @@ ws.onclose = () => {
141
154
  logger.success(`🚀 Server running at http://localhost:${port}`);
142
155
  logger.info(`📁 Serving: ${root}`);
143
156
 
144
- setupWatcher(root, compiledDir, clients, () => {
157
+ setupWatcher(root, compiledDir, clients, async () => {
145
158
  hasRouter = existsSync(join(compiledDir, 'router.js'));
146
159
  });
147
160
 
148
161
  return app;
149
162
  }
150
163
 
151
- function serveHTML(root, hasRouter) {
164
+ function serveHTML(root, hasRouter, config) {
165
+ const meta = config.meta || {};
166
+
152
167
  const html = `
153
168
  <!DOCTYPE html>
154
- <html lang="en">
169
+ <html lang="${meta.lang || 'en'}">
155
170
  <head>
156
171
  <meta charset="UTF-8">
157
172
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
158
- <title>BertUI App - Dev</title>
173
+ <title>${meta.title || 'BertUI App'}</title>
174
+
175
+ ${meta.description ? `<meta name="description" content="${meta.description}">` : ''}
176
+ ${meta.keywords ? `<meta name="keywords" content="${meta.keywords}">` : ''}
177
+ ${meta.author ? `<meta name="author" content="${meta.author}">` : ''}
178
+ ${meta.themeColor ? `<meta name="theme-color" content="${meta.themeColor}">` : ''}
179
+
180
+ ${meta.ogTitle ? `<meta property="og:title" content="${meta.ogTitle || meta.title}">` : ''}
181
+ ${meta.ogDescription ? `<meta property="og:description" content="${meta.ogDescription || meta.description}">` : ''}
182
+ ${meta.ogImage ? `<meta property="og:image" content="${meta.ogImage}">` : ''}
183
+
184
+ <link rel="icon" type="image/svg+xml" href="/public/favicon.svg">
159
185
 
160
186
  <script type="importmap">
161
187
  {
@@ -182,10 +208,7 @@ function serveHTML(root, hasRouter) {
182
208
  <body>
183
209
  <div id="root"></div>
184
210
  <script type="module" src="/hmr-client.js"></script>
185
- ${hasRouter
186
- ? '<script type="module" src="/compiled/main.js"></script>'
187
- : '<script type="module" src="/compiled/main.js"></script>'
188
- }
211
+ <script type="module" src="/compiled/main.js"></script>
189
212
  </body>
190
213
  </html>`;
191
214
 
@@ -214,6 +237,7 @@ function getContentType(ext) {
214
237
 
215
238
  function setupWatcher(root, compiledDir, clients, onRecompile) {
216
239
  const srcDir = join(root, 'src');
240
+ const configPath = join(root, 'bertui.config.js');
217
241
 
218
242
  if (!existsSync(srcDir)) {
219
243
  logger.warn('src/ directory not found');
@@ -241,7 +265,7 @@ function setupWatcher(root, compiledDir, clients, onRecompile) {
241
265
  await compileProject(root);
242
266
 
243
267
  if (onRecompile) {
244
- onRecompile();
268
+ await onRecompile();
245
269
  }
246
270
 
247
271
  for (const client of clients) {
@@ -256,4 +280,20 @@ function setupWatcher(root, compiledDir, clients, onRecompile) {
256
280
  }
257
281
  }
258
282
  });
283
+
284
+ if (existsSync(configPath)) {
285
+ watch(configPath, async (eventType) => {
286
+ if (eventType === 'change') {
287
+ logger.info('📝 Config changed, reloading...');
288
+
289
+ for (const client of clients) {
290
+ try {
291
+ client.send(JSON.stringify({ type: 'reload', file: 'bertui.config.js' }));
292
+ } catch (e) {
293
+ clients.delete(client);
294
+ }
295
+ }
296
+ }
297
+ });
298
+ }
259
299
  }