hightjs 0.3.3 → 0.3.4
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/dist/adapters/factory.js +8 -8
- package/dist/adapters/native.js +3 -3
- package/dist/auth/client.js +5 -5
- package/dist/auth/components.js +2 -2
- package/dist/auth/core.js +2 -2
- package/dist/auth/react.js +4 -4
- package/dist/auth/routes.js +1 -1
- package/dist/bin/hightjs.js +29 -328
- package/dist/builder.js +7 -19
- package/dist/client/DefaultNotFound.js +1 -1
- package/dist/client/entry.client.js +3 -3
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +90 -28
- package/dist/hotReload.js +12 -12
- package/dist/index.d.ts +1 -1
- package/dist/index.js +16 -30
- package/dist/router.js +133 -62
- package/dist/types.d.ts +42 -0
- package/docs/config.md +201 -0
- package/example/hightjs.config.ts +81 -0
- package/example/package-lock.json +633 -3054
- package/example/package.json +1 -1
- package/package.json +1 -1
- package/src/adapters/factory.ts +8 -8
- package/src/adapters/native.ts +3 -3
- package/src/auth/client.ts +5 -5
- package/src/auth/components.tsx +2 -2
- package/src/auth/core.ts +2 -2
- package/src/auth/react.tsx +4 -4
- package/src/auth/routes.ts +1 -1
- package/src/bin/hightjs.js +30 -391
- package/src/builder.js +7 -20
- package/src/client/DefaultNotFound.tsx +1 -1
- package/src/client/entry.client.tsx +3 -3
- package/src/helpers.ts +105 -29
- package/src/hotReload.ts +12 -12
- package/src/index.ts +20 -33
- package/src/router.ts +140 -63
- package/src/types.ts +52 -0
- package/example/.hweb/entry.client.js +0 -24
- package/example/hweb-dist/main-5KKAYNUU.js +0 -1137
package/src/helpers.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
1
3
|
/*
|
|
2
4
|
* This file is part of the HightJS Project.
|
|
3
5
|
* Copyright (c) 2025 itsmuzin
|
|
@@ -19,9 +21,10 @@
|
|
|
19
21
|
import http, {IncomingMessage, Server, ServerResponse} from 'http';
|
|
20
22
|
import os from 'os';
|
|
21
23
|
import {URLSearchParams} from 'url'; // API moderna, substitui 'querystring'
|
|
24
|
+
import path from 'path';
|
|
22
25
|
// Helpers para integração com diferentes frameworks
|
|
23
26
|
import hweb, {FrameworkAdapterFactory} from './index'; // Importando o tipo
|
|
24
|
-
import type {HightJSOptions} from './types';
|
|
27
|
+
import type {HightJSOptions, HightConfig, HightConfigFunction} from './types';
|
|
25
28
|
import Console, {Colors} from "./api/console";
|
|
26
29
|
import https, { Server as HttpsServer } from 'https'; // <-- ADICIONAR
|
|
27
30
|
import fs from 'fs'; // <-- ADICIONAR
|
|
@@ -66,7 +69,7 @@ function getLocalExternalIp(): string {
|
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
const sendBox = (options: HightJSOptions) => {
|
|
69
|
-
const isDev = options.dev ? "
|
|
72
|
+
const isDev = options.dev ? "Running in development mode" : null;
|
|
70
73
|
|
|
71
74
|
// 1. Verifica se o SSL está ativado (baseado na mesma lógica do initNativeServer)
|
|
72
75
|
const isSSL = options.ssl && options.ssl.key && options.ssl.cert;
|
|
@@ -75,12 +78,12 @@ const sendBox = (options: HightJSOptions) => {
|
|
|
75
78
|
|
|
76
79
|
// 2. Monta as mensagens com o protocolo correto
|
|
77
80
|
const messages = [
|
|
78
|
-
` ${Colors.FgGray}┃${Colors.Reset} Local:
|
|
81
|
+
` ${Colors.FgGray}┃${Colors.Reset} Local: ${Colors.FgGreen}${protocol}://localhost:${options.port}${Colors.Reset}`,
|
|
79
82
|
];
|
|
80
83
|
|
|
81
84
|
// Só adiciona a rede se o IP local for encontrado
|
|
82
85
|
if (localIp) {
|
|
83
|
-
messages.push(` ${Colors.FgGray}┃${Colors.Reset}
|
|
86
|
+
messages.push(` ${Colors.FgGray}┃${Colors.Reset} Network: ${Colors.FgGreen}${protocol}://${localIp}:${options.port}${Colors.Reset}`);
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
if (isDev) {
|
|
@@ -89,10 +92,78 @@ const sendBox = (options: HightJSOptions) => {
|
|
|
89
92
|
|
|
90
93
|
// Adiciona aviso de redirecionamento se estiver em modo SSL
|
|
91
94
|
if (isSSL && options.ssl?.redirectPort) {
|
|
92
|
-
messages.push(` ${Colors.FgGray}┃${Colors.Reset} HTTP (
|
|
95
|
+
messages.push(` ${Colors.FgGray}┃${Colors.Reset} HTTP (port ${options.ssl?.redirectPort}) is redirecting to HTTPS.`);
|
|
93
96
|
}
|
|
94
97
|
|
|
95
|
-
Console.box(messages.join("\n"), { title: "
|
|
98
|
+
Console.box(messages.join("\n"), { title: "Access on:" });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Carrega o arquivo de configuração hightjs.config.ts ou hightjs.config.js do projeto
|
|
103
|
+
* @param projectDir Diretório raiz do projeto
|
|
104
|
+
* @param phase Fase de execução ('development' ou 'production')
|
|
105
|
+
* @returns Configuração mesclada com os valores padrão
|
|
106
|
+
*/
|
|
107
|
+
async function loadHightConfig(projectDir: string, phase: string): Promise<HightConfig> {
|
|
108
|
+
const defaultConfig: HightConfig = {
|
|
109
|
+
maxHeadersCount: 100,
|
|
110
|
+
headersTimeout: 60000,
|
|
111
|
+
requestTimeout: 30000,
|
|
112
|
+
serverTimeout: 35000,
|
|
113
|
+
individualRequestTimeout: 30000,
|
|
114
|
+
maxUrlLength: 2048,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
// Tenta primeiro .ts, depois .js
|
|
119
|
+
const possiblePaths = [
|
|
120
|
+
path.join(projectDir, 'hightjs.config.ts'),
|
|
121
|
+
path.join(projectDir, 'hightjs.config.js'),
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
let configPath: string | null = null;
|
|
125
|
+
for (const p of possiblePaths) {
|
|
126
|
+
if (fs.existsSync(p)) {
|
|
127
|
+
configPath = p;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (!configPath) {
|
|
133
|
+
return defaultConfig;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Remove do cache para permitir hot reload da configuração em dev
|
|
137
|
+
delete require.cache[require.resolve(configPath)];
|
|
138
|
+
|
|
139
|
+
const configModule = require(configPath);
|
|
140
|
+
const configExport = configModule.default || configModule;
|
|
141
|
+
|
|
142
|
+
let userConfig: HightConfig;
|
|
143
|
+
|
|
144
|
+
if (typeof configExport === 'function') {
|
|
145
|
+
// Suporta tanto função síncrona quanto assíncrona
|
|
146
|
+
userConfig = await Promise.resolve(
|
|
147
|
+
(configExport as HightConfigFunction)(phase, { defaultConfig })
|
|
148
|
+
);
|
|
149
|
+
} else {
|
|
150
|
+
userConfig = configExport;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Mescla a configuração do usuário com a padrão
|
|
154
|
+
const mergedConfig = { ...defaultConfig, ...userConfig };
|
|
155
|
+
|
|
156
|
+
const configFileName = path.basename(configPath);
|
|
157
|
+
Console.info(`${Colors.FgCyan}[Config]${Colors.Reset} Loaded ${configFileName}`);
|
|
158
|
+
|
|
159
|
+
return mergedConfig;
|
|
160
|
+
} catch (error) {
|
|
161
|
+
if (error instanceof Error) {
|
|
162
|
+
Console.warn(`${Colors.FgYellow}[Config]${Colors.Reset} Error loading hightjs.config: ${error.message}`);
|
|
163
|
+
Console.warn(`${Colors.FgYellow}[Config]${Colors.Reset} Using default configuration`);
|
|
164
|
+
}
|
|
165
|
+
return defaultConfig;
|
|
166
|
+
}
|
|
96
167
|
}
|
|
97
168
|
|
|
98
169
|
/**
|
|
@@ -181,8 +252,14 @@ async function initNativeServer(hwebApp: HWebApp, options: HightJSOptions, port:
|
|
|
181
252
|
const time = Date.now();
|
|
182
253
|
|
|
183
254
|
await hwebApp.prepare();
|
|
255
|
+
|
|
256
|
+
// Carrega a configuração do arquivo hightjs.config.js
|
|
257
|
+
const projectDir = options.dir || process.cwd();
|
|
258
|
+
const phase = options.dev ? 'development' : 'production';
|
|
259
|
+
const hightConfig = await loadHightConfig(projectDir, phase);
|
|
260
|
+
|
|
184
261
|
const handler = hwebApp.getRequestHandler();
|
|
185
|
-
const msg = Console.dynamicLine(` ${Colors.BgYellow} ready ${Colors.Reset} ${Colors.Bright}
|
|
262
|
+
const msg = Console.dynamicLine(` ${Colors.BgYellow} ready ${Colors.Reset} ${Colors.Bright}Starting HightJS on port ${options.port}${Colors.Reset}`);
|
|
186
263
|
|
|
187
264
|
// --- LÓGICA DO LISTENER (REUTILIZÁVEL) ---
|
|
188
265
|
// Extraímos a lógica principal para uma variável
|
|
@@ -200,16 +277,17 @@ async function initNativeServer(hwebApp: HWebApp, options: HightJSOptions, port:
|
|
|
200
277
|
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
|
|
201
278
|
}
|
|
202
279
|
|
|
203
|
-
// Timeout por requisição
|
|
204
|
-
req.setTimeout(30000, () => {
|
|
280
|
+
// Timeout por requisição (usa configuração personalizada)
|
|
281
|
+
req.setTimeout(hightConfig.individualRequestTimeout || 30000, () => {
|
|
205
282
|
res.statusCode = 408; // Request Timeout
|
|
206
283
|
res.end('Request timeout');
|
|
207
284
|
});
|
|
208
285
|
|
|
209
286
|
try {
|
|
210
|
-
// Validação básica de URL
|
|
287
|
+
// Validação básica de URL (usa configuração personalizada)
|
|
211
288
|
const url = req.url || '/';
|
|
212
|
-
|
|
289
|
+
const maxUrlLength = hightConfig.maxUrlLength || 2048;
|
|
290
|
+
if (url.length > maxUrlLength) {
|
|
213
291
|
res.statusCode = 414; // URI Too Long
|
|
214
292
|
res.end('URL too long');
|
|
215
293
|
return;
|
|
@@ -227,9 +305,9 @@ async function initNativeServer(hwebApp: HWebApp, options: HightJSOptions, port:
|
|
|
227
305
|
} catch (error) {
|
|
228
306
|
// Log do erro no servidor
|
|
229
307
|
if (error instanceof Error) {
|
|
230
|
-
Console.error(`
|
|
308
|
+
Console.error(`Native server error: ${error.message}`);
|
|
231
309
|
} else {
|
|
232
|
-
Console.error('
|
|
310
|
+
Console.error('Unknown native server error:', error);
|
|
233
311
|
}
|
|
234
312
|
|
|
235
313
|
// Tratamento de erro (idêntico ao seu original)
|
|
@@ -297,15 +375,15 @@ async function initNativeServer(hwebApp: HWebApp, options: HightJSOptions, port:
|
|
|
297
375
|
server = http.createServer(requestListener as any); // (any para contornar HWebIncomingMessage)
|
|
298
376
|
}
|
|
299
377
|
|
|
300
|
-
// Configurações de segurança do servidor (
|
|
301
|
-
server.setTimeout(35000); // Timeout geral do servidor
|
|
302
|
-
server.maxHeadersCount = 100; // Limita número de headers
|
|
303
|
-
server.headersTimeout = 60000; // Timeout para headers
|
|
304
|
-
server.requestTimeout = 30000; // Timeout para requisições
|
|
378
|
+
// Configurações de segurança do servidor (usa configuração personalizada)
|
|
379
|
+
server.setTimeout(hightConfig.serverTimeout || 35000); // Timeout geral do servidor
|
|
380
|
+
server.maxHeadersCount = hightConfig.maxHeadersCount || 100; // Limita número de headers
|
|
381
|
+
server.headersTimeout = hightConfig.headersTimeout || 60000; // Timeout para headers
|
|
382
|
+
server.requestTimeout = hightConfig.requestTimeout || 30000; // Timeout para requisições
|
|
305
383
|
|
|
306
384
|
server.listen(port, hostname, () => {
|
|
307
385
|
sendBox({ ...options, port });
|
|
308
|
-
msg.end(` ${Colors.BgGreen} ready ${Colors.Reset} ${Colors.Bright}
|
|
386
|
+
msg.end(` ${Colors.BgGreen} ready ${Colors.Reset} ${Colors.Bright}Ready on port ${Colors.BgGreen} ${options.port} ${Colors.Reset}${Colors.Bright} in ${Date.now() - time}ms${Colors.Reset}\n`);
|
|
309
387
|
});
|
|
310
388
|
|
|
311
389
|
// Configura WebSocket para hot reload (Comum a ambos)
|
|
@@ -344,7 +422,7 @@ export function app(options: HightJSOptions = {}) {
|
|
|
344
422
|
const cookieParser = require('cookie-parser');
|
|
345
423
|
serverApp.use(cookieParser());
|
|
346
424
|
} catch (e) {
|
|
347
|
-
Console.error("
|
|
425
|
+
Console.error("Could not find cookie-parser");
|
|
348
426
|
}
|
|
349
427
|
serverApp.use(express.json());
|
|
350
428
|
serverApp.use(express.urlencoded({ extended: true }));
|
|
@@ -355,12 +433,12 @@ export function app(options: HightJSOptions = {}) {
|
|
|
355
433
|
try {
|
|
356
434
|
await serverApp.register(require('@fastify/cookie'));
|
|
357
435
|
} catch (e) {
|
|
358
|
-
Console.error("
|
|
436
|
+
Console.error("Could not find @fastify/cookie");
|
|
359
437
|
}
|
|
360
438
|
try {
|
|
361
439
|
await serverApp.register(require('@fastify/formbody'));
|
|
362
440
|
} catch (e) {
|
|
363
|
-
Console.error("
|
|
441
|
+
Console.error("Could not find @fastify/formbody");
|
|
364
442
|
}
|
|
365
443
|
await serverApp.register(async (fastify: any) => {
|
|
366
444
|
fastify.all('*', handler);
|
|
@@ -390,7 +468,7 @@ export function app(options: HightJSOptions = {}) {
|
|
|
390
468
|
const data = await response.json();
|
|
391
469
|
return data.version;
|
|
392
470
|
} catch (error) {
|
|
393
|
-
Console.error('
|
|
471
|
+
Console.error('Could not check for the latest HightJS version:', error);
|
|
394
472
|
return currentVersion; // Retorna a versão atual em caso de erro
|
|
395
473
|
}
|
|
396
474
|
}
|
|
@@ -398,23 +476,21 @@ export function app(options: HightJSOptions = {}) {
|
|
|
398
476
|
const isUpToDate = latestVersion === currentVersion;
|
|
399
477
|
let message;
|
|
400
478
|
if (!isUpToDate) {
|
|
401
|
-
message = `${Colors.FgGreen}
|
|
479
|
+
message = `${Colors.FgGreen} A new version is available (v${latestVersion})${Colors.FgMagenta}`
|
|
402
480
|
} else {
|
|
403
|
-
message = `${Colors.FgGreen}
|
|
481
|
+
message = `${Colors.FgGreen} You are on the latest version${Colors.FgMagenta}`
|
|
404
482
|
}
|
|
405
483
|
console.log(`${Colors.FgMagenta}
|
|
406
484
|
__ ___ ${Colors.FgGreen} __ ${Colors.FgMagenta}
|
|
407
485
|
|__| | / _\` |__| | ${Colors.FgGreen} | /__\` ${Colors.FgMagenta} ${Colors.FgMagenta}HightJS ${Colors.FgGray}(v${require('../package.json').version}) - itsmuzin${Colors.FgMagenta}
|
|
408
|
-
| | | \\__> | | | ${Colors.FgGreen}\\__/ .__/ ${message}
|
|
409
|
-
|
|
410
|
-
|
|
486
|
+
| | | \\__> | | | ${Colors.FgGreen}\\__/ .__/ ${message}
|
|
411
487
|
${Colors.Reset}`);
|
|
412
488
|
|
|
413
489
|
const actualPort = options.port || 3000;
|
|
414
490
|
const actualHostname = options.hostname || "0.0.0.0";
|
|
415
491
|
|
|
416
492
|
if (framework !== 'native') {
|
|
417
|
-
Console.warn(`
|
|
493
|
+
Console.warn(`The "${framework}" framework was selected, but the init() method only works with the "native" framework. Starting native server...`);
|
|
418
494
|
}
|
|
419
495
|
|
|
420
496
|
|
package/src/hotReload.ts
CHANGED
|
@@ -204,7 +204,7 @@ export class HotReloadManager {
|
|
|
204
204
|
|
|
205
205
|
// Se for arquivo de frontend, aguarda o build terminar antes de recarregar
|
|
206
206
|
if (isFrontendFile) {
|
|
207
|
-
Console.logWithout(Levels.INFO, Colors.BgRed,`📄
|
|
207
|
+
Console.logWithout(Levels.INFO, Colors.BgRed,`📄 Waiting for frontend build...`);
|
|
208
208
|
|
|
209
209
|
// Marca que estamos esperando um build
|
|
210
210
|
this.isBuilding = true;
|
|
@@ -221,11 +221,11 @@ export class HotReloadManager {
|
|
|
221
221
|
|
|
222
222
|
try {
|
|
223
223
|
await Promise.race([buildPromise, timeoutPromise]);
|
|
224
|
-
Console.logWithout(Levels.INFO, Colors.BgRed,`✅ Build
|
|
224
|
+
Console.logWithout(Levels.INFO, Colors.BgRed,`✅ Build complete, reloading frontend...`);
|
|
225
225
|
this.frontendChangeCallback?.();
|
|
226
226
|
this.notifyClients('frontend-reload', { file: filePath, event: 'change' });
|
|
227
227
|
} catch (error) {
|
|
228
|
-
Console.logWithout(Levels.ERROR, Colors.BgRed,`⚠️ Timeout
|
|
228
|
+
Console.logWithout(Levels.ERROR, Colors.BgRed,`⚠️ Timeout in build, reloading anyway...`);
|
|
229
229
|
this.frontendChangeCallback?.();
|
|
230
230
|
this.notifyClients('frontend-reload', { file: filePath, event: 'change' });
|
|
231
231
|
} finally {
|
|
@@ -236,14 +236,14 @@ export class HotReloadManager {
|
|
|
236
236
|
|
|
237
237
|
// Se for arquivo de backend, recarrega o módulo e notifica
|
|
238
238
|
if (isBackendFile) {
|
|
239
|
-
Console.logWithout(Levels.INFO, Colors.BgRed,`⚙️
|
|
239
|
+
Console.logWithout(Levels.INFO, Colors.BgRed,`⚙️ Reloading backend...`);
|
|
240
240
|
this.backendApiChangeCallback?.();
|
|
241
241
|
this.notifyClients('backend-api-reload', { file: filePath, event: 'change' });
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
// Fallback: se não for nem frontend nem backend detectado, recarrega tudo
|
|
245
245
|
if (!isFrontendFile && !isBackendFile) {
|
|
246
|
-
Console.logWithout(Levels.INFO, Colors.BgRed,`🔄
|
|
246
|
+
Console.logWithout(Levels.INFO, Colors.BgRed,`🔄 Reloading application...`);
|
|
247
247
|
this.frontendChangeCallback?.();
|
|
248
248
|
this.backendApiChangeCallback?.();
|
|
249
249
|
this.notifyClients('src-reload', { file: filePath, event: 'change' });
|
|
@@ -255,7 +255,7 @@ export class HotReloadManager {
|
|
|
255
255
|
await this.customHotReloadListener(filePath);
|
|
256
256
|
} catch (error) {
|
|
257
257
|
// @ts-ignore
|
|
258
|
-
Console.logWithout(Levels.ERROR, `
|
|
258
|
+
Console.logWithout(Levels.ERROR, `Error in custom listener: ${error.message}`);
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
261
|
}
|
|
@@ -273,7 +273,7 @@ export class HotReloadManager {
|
|
|
273
273
|
try {
|
|
274
274
|
ws.send(message);
|
|
275
275
|
} catch (error) {
|
|
276
|
-
Console.logWithout(Levels.ERROR, Colors.BgRed, `
|
|
276
|
+
Console.logWithout(Levels.ERROR, Colors.BgRed, `Error sending WebSocket message: ${error}`);
|
|
277
277
|
deadClients.push(ws);
|
|
278
278
|
}
|
|
279
279
|
} else {
|
|
@@ -342,7 +342,7 @@ export class HotReloadManager {
|
|
|
342
342
|
ws = new WebSocket('ws://localhost:3000/hweb-hotreload/');
|
|
343
343
|
|
|
344
344
|
ws.onopen = function() {
|
|
345
|
-
console.log('🔌 Hot-reload
|
|
345
|
+
console.log('🔌 Hot-reload connected');
|
|
346
346
|
isConnected = true;
|
|
347
347
|
reconnectAttempts = 0;
|
|
348
348
|
reconnectInterval = 1000;
|
|
@@ -362,13 +362,13 @@ export class HotReloadManager {
|
|
|
362
362
|
window.location.reload();
|
|
363
363
|
break;
|
|
364
364
|
case 'server-restart':
|
|
365
|
-
console.log('🔄
|
|
365
|
+
console.log('🔄 Server restarting...');
|
|
366
366
|
break;
|
|
367
367
|
case 'server-ready':
|
|
368
368
|
setTimeout(() => window.location.reload(), 500);
|
|
369
369
|
break;
|
|
370
370
|
case 'frontend-error':
|
|
371
|
-
console.error('❌
|
|
371
|
+
console.error('❌ Frontend error:', message.data);
|
|
372
372
|
break;
|
|
373
373
|
}
|
|
374
374
|
} catch (e) {
|
|
@@ -393,7 +393,7 @@ export class HotReloadManager {
|
|
|
393
393
|
};
|
|
394
394
|
|
|
395
395
|
} catch (error) {
|
|
396
|
-
console.error('
|
|
396
|
+
console.error('Error creating WebSocket:', error);
|
|
397
397
|
scheduleReconnect();
|
|
398
398
|
}
|
|
399
399
|
}
|
|
@@ -463,7 +463,7 @@ export class HotReloadManager {
|
|
|
463
463
|
|
|
464
464
|
setHotReloadListener(listener: (file: string) => Promise<void> | void) {
|
|
465
465
|
this.customHotReloadListener = listener;
|
|
466
|
-
Console.info('🔌 Hot reload listener
|
|
466
|
+
Console.info('🔌 Hot reload custom listener registered');
|
|
467
467
|
}
|
|
468
468
|
|
|
469
469
|
removeHotReloadListener() {
|
package/src/index.ts
CHANGED
|
@@ -61,6 +61,9 @@ export { app } from './helpers';
|
|
|
61
61
|
// Exporta o sistema de WebSocket
|
|
62
62
|
export type { WebSocketContext, WebSocketHandler } from './types';
|
|
63
63
|
|
|
64
|
+
// Exporta os tipos de configuração
|
|
65
|
+
export type { HightConfig, HightConfigFunction } from './types';
|
|
66
|
+
|
|
64
67
|
// Função para verificar se o projeto é grande o suficiente para se beneficiar de chunks
|
|
65
68
|
function isLargeProject(projectDir: string): boolean {
|
|
66
69
|
try {
|
|
@@ -254,7 +257,7 @@ export default function hweb(options: HightJSOptions) {
|
|
|
254
257
|
|
|
255
258
|
// Adiciona callback para recarregar TUDO quando qualquer arquivo mudar
|
|
256
259
|
hotReloadManager.onBackendApiChange(() => {
|
|
257
|
-
|
|
260
|
+
|
|
258
261
|
|
|
259
262
|
loadBackendRoutes(userBackendRoutesDir);
|
|
260
263
|
processWebSocketRoutes(); // Processa rotas WS após recarregar backend
|
|
@@ -262,18 +265,16 @@ export default function hweb(options: HightJSOptions) {
|
|
|
262
265
|
|
|
263
266
|
// Adiciona callback para regenerar entry file quando frontend mudar
|
|
264
267
|
hotReloadManager.onFrontendChange(() => {
|
|
265
|
-
Console.info('🔄 Regenerando frontend...');
|
|
266
268
|
regenerateEntryFile();
|
|
267
269
|
});
|
|
268
270
|
}
|
|
269
271
|
const now = Date.now();
|
|
270
|
-
const timee = Console.dynamicLine(` ${Colors.BgYellow} router ${Colors.Reset}
|
|
272
|
+
const timee = Console.dynamicLine(` ${Colors.BgYellow} router ${Colors.Reset} Loading routes and components`);
|
|
271
273
|
const spinnerFrames1 = ['|', '/', '-', '\\'];
|
|
272
274
|
let frameIndex1 = 0;
|
|
273
275
|
|
|
274
276
|
const spinner1 = setInterval(() => {
|
|
275
|
-
|
|
276
|
-
timee.update(` ${Colors.FgYellow}${spinnerFrames1[frameIndex1]}${Colors.Reset} Carregando rotas e componentes...`);
|
|
277
|
+
timee.update(` ${Colors.FgYellow}${spinnerFrames1[frameIndex1]}${Colors.Reset} Loading routes and components...`);
|
|
277
278
|
frameIndex1 = (frameIndex1 + 1) % spinnerFrames1.length;
|
|
278
279
|
}, 100); // muda a cada 100ms
|
|
279
280
|
// ORDEM IMPORTANTE: Carrega TUDO antes de criar o arquivo de entrada
|
|
@@ -293,18 +294,18 @@ export default function hweb(options: HightJSOptions) {
|
|
|
293
294
|
|
|
294
295
|
entryPoint = createEntryFile(dir, frontendRoutes);
|
|
295
296
|
clearInterval(spinner1)
|
|
296
|
-
timee.end(` ${Colors.BgGreen} router ${Colors.Reset}
|
|
297
|
+
timee.end(` ${Colors.BgGreen} router ${Colors.Reset} Routes and components loaded in ${Date.now() - now}ms`);
|
|
297
298
|
|
|
298
299
|
|
|
299
300
|
if (isProduction) {
|
|
300
|
-
const time = Console.dynamicLine(` ${Colors.BgYellow} build ${Colors.Reset}
|
|
301
|
+
const time = Console.dynamicLine(` ${Colors.BgYellow} build ${Colors.Reset} Starting client build`);
|
|
301
302
|
|
|
302
303
|
// Spinner
|
|
303
304
|
const spinnerFrames = ['|', '/', '-', '\\'];
|
|
304
305
|
let frameIndex = 0;
|
|
305
306
|
|
|
306
307
|
const spinner = setInterval(() => {
|
|
307
|
-
time.update(` ${Colors.FgYellow}${spinnerFrames[frameIndex]}${Colors.Reset}
|
|
308
|
+
time.update(` ${Colors.FgYellow}${spinnerFrames[frameIndex]}${Colors.Reset} Building...`);
|
|
308
309
|
frameIndex = (frameIndex + 1) % spinnerFrames.length;
|
|
309
310
|
}, 100); // muda a cada 100ms
|
|
310
311
|
|
|
@@ -314,14 +315,14 @@ export default function hweb(options: HightJSOptions) {
|
|
|
314
315
|
|
|
315
316
|
clearInterval(spinner); // para o spinner
|
|
316
317
|
time.update(""); // limpa a linha
|
|
317
|
-
time.end(` ${Colors.BgGreen} build ${Colors.Reset}
|
|
318
|
+
time.end(` ${Colors.BgGreen} build ${Colors.Reset} Client build completed in ${elapsed}ms`);
|
|
318
319
|
|
|
319
320
|
} else {
|
|
320
|
-
const time = Console.dynamicLine(` ${Colors.BgYellow} watcher ${Colors.Reset}
|
|
321
|
+
const time = Console.dynamicLine(` ${Colors.BgYellow} watcher ${Colors.Reset} Starting client watch`);
|
|
321
322
|
watchWithChunks(entryPoint, outDir, hotReloadManager!).catch(err => {
|
|
322
|
-
Console.error(`
|
|
323
|
+
Console.error(`Error starting watch`, err);
|
|
323
324
|
});
|
|
324
|
-
time.end(` ${Colors.BgGreen} watcher ${Colors.Reset} Watch
|
|
325
|
+
time.end(` ${Colors.BgGreen} watcher ${Colors.Reset} Client Watch started`);
|
|
325
326
|
}
|
|
326
327
|
|
|
327
328
|
},
|
|
@@ -339,7 +340,6 @@ export default function hweb(options: HightJSOptions) {
|
|
|
339
340
|
if (instrumentation.hotReloadListener && typeof instrumentation.hotReloadListener === 'function') {
|
|
340
341
|
if (hotReloadManager) {
|
|
341
342
|
hotReloadManager.setHotReloadListener(instrumentation.hotReloadListener);
|
|
342
|
-
Console.info('✅ Hot reload listener registrado');
|
|
343
343
|
}
|
|
344
344
|
}
|
|
345
345
|
|
|
@@ -348,7 +348,7 @@ export default function hweb(options: HightJSOptions) {
|
|
|
348
348
|
} else if (typeof instrumentation.default === 'function') {
|
|
349
349
|
instrumentation.default();
|
|
350
350
|
} else {
|
|
351
|
-
Console.warn(`
|
|
351
|
+
Console.warn(`The instrumentation file ${instrumentationFile} does not export a default function.`);
|
|
352
352
|
}
|
|
353
353
|
}
|
|
354
354
|
},
|
|
@@ -470,8 +470,8 @@ export default function hweb(options: HightJSOptions) {
|
|
|
470
470
|
return;
|
|
471
471
|
}
|
|
472
472
|
} catch (error) {
|
|
473
|
-
Console.error(`
|
|
474
|
-
genericRes.status(500).text('
|
|
473
|
+
Console.error(`API route error ${pathname}:`, error);
|
|
474
|
+
genericRes.status(500).text('Internal server error in API');
|
|
475
475
|
return;
|
|
476
476
|
}
|
|
477
477
|
}
|
|
@@ -498,8 +498,8 @@ export default function hweb(options: HightJSOptions) {
|
|
|
498
498
|
genericRes.status(404).header('Content-Type', 'text/html').send(html);
|
|
499
499
|
return;
|
|
500
500
|
} catch (error) {
|
|
501
|
-
Console.error(`
|
|
502
|
-
genericRes.status(404).text('
|
|
501
|
+
Console.error(`Error rendering page 404:`, error);
|
|
502
|
+
genericRes.status(404).text('Page not found');
|
|
503
503
|
return;
|
|
504
504
|
}
|
|
505
505
|
}
|
|
@@ -513,8 +513,8 @@ export default function hweb(options: HightJSOptions) {
|
|
|
513
513
|
});
|
|
514
514
|
genericRes.status(200).header('Content-Type', 'text/html').send(html);
|
|
515
515
|
} catch (error) {
|
|
516
|
-
Console.error(`
|
|
517
|
-
genericRes.status(500).text('
|
|
516
|
+
Console.error(`Error rendering page ${pathname}:`, error);
|
|
517
|
+
genericRes.status(500).text('Internal server error');
|
|
518
518
|
}
|
|
519
519
|
};
|
|
520
520
|
},
|
|
@@ -529,19 +529,6 @@ export default function hweb(options: HightJSOptions) {
|
|
|
529
529
|
setupWebSocketUpgrade(actualServer, hotReloadManager);
|
|
530
530
|
},
|
|
531
531
|
|
|
532
|
-
build: async () => {
|
|
533
|
-
const msg = Console.dynamicLine(` ${Colors.FgYellow}● ${Colors.Reset}Iniciando build do cliente para produção`);
|
|
534
|
-
const outDir = path.join(dir, 'hweb-dist');
|
|
535
|
-
fs.mkdirSync(outDir, {recursive: true});
|
|
536
|
-
|
|
537
|
-
const routes = loadRoutes(userWebRoutesDir);
|
|
538
|
-
const entryPoint = createEntryFile(dir, routes);
|
|
539
|
-
const outfile = path.join(outDir, 'main.js');
|
|
540
|
-
|
|
541
|
-
await build(entryPoint, outfile, true); // Força produção no build manual
|
|
542
|
-
|
|
543
|
-
msg.end(` ${Colors.FgGreen}● ${Colors.Reset}Build do cliente concluído: ${outfile}`);
|
|
544
|
-
},
|
|
545
532
|
|
|
546
533
|
stop: () => {
|
|
547
534
|
if (hotReloadManager) {
|