hightjs 0.3.2 → 0.3.3
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/builder.js +40 -2
- package/dist/hotReload.d.ts +3 -1
- package/dist/hotReload.js +34 -42
- package/package.json +1 -1
- package/src/builder.js +40 -2
- package/src/hotReload.ts +36 -46
package/dist/builder.js
CHANGED
|
@@ -234,6 +234,25 @@ async function watchWithChunks(entryPoint, outdir, hotReloadManager = null) {
|
|
|
234
234
|
// limpar diretorio
|
|
235
235
|
fs.rmSync(outdir, { recursive: true, force: true });
|
|
236
236
|
try {
|
|
237
|
+
// Plugin para notificar quando o build termina
|
|
238
|
+
const buildCompletePlugin = {
|
|
239
|
+
name: 'build-complete',
|
|
240
|
+
setup(build) {
|
|
241
|
+
let isFirstBuild = true;
|
|
242
|
+
build.onEnd((result) => {
|
|
243
|
+
if (hotReloadManager) {
|
|
244
|
+
if (isFirstBuild) {
|
|
245
|
+
isFirstBuild = false;
|
|
246
|
+
hotReloadManager.onBuildComplete(true);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
// Notifica o hot reload manager que o build foi concluído
|
|
250
|
+
hotReloadManager.onBuildComplete(result.errors.length === 0);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
};
|
|
237
256
|
const context = await esbuild.context({
|
|
238
257
|
entryPoints: [entryPoint],
|
|
239
258
|
bundle: true,
|
|
@@ -243,7 +262,7 @@ async function watchWithChunks(entryPoint, outdir, hotReloadManager = null) {
|
|
|
243
262
|
outdir: outdir,
|
|
244
263
|
loader: { '.js': 'jsx', '.ts': 'tsx' },
|
|
245
264
|
external: nodeBuiltIns,
|
|
246
|
-
plugins: [postcssPlugin, npmDependenciesPlugin, reactResolvePlugin],
|
|
265
|
+
plugins: [postcssPlugin, npmDependenciesPlugin, reactResolvePlugin, buildCompletePlugin],
|
|
247
266
|
format: 'esm',
|
|
248
267
|
jsx: 'automatic',
|
|
249
268
|
define: {
|
|
@@ -327,6 +346,25 @@ async function build(entryPoint, outfile, isProduction = false) {
|
|
|
327
346
|
*/
|
|
328
347
|
async function watch(entryPoint, outfile, hotReloadManager = null) {
|
|
329
348
|
try {
|
|
349
|
+
// Plugin para notificar quando o build termina
|
|
350
|
+
const buildCompletePlugin = {
|
|
351
|
+
name: 'build-complete',
|
|
352
|
+
setup(build) {
|
|
353
|
+
let isFirstBuild = true;
|
|
354
|
+
build.onEnd((result) => {
|
|
355
|
+
if (hotReloadManager) {
|
|
356
|
+
if (isFirstBuild) {
|
|
357
|
+
isFirstBuild = false;
|
|
358
|
+
hotReloadManager.onBuildComplete(true);
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
// Notifica o hot reload manager que o build foi concluído
|
|
362
|
+
hotReloadManager.onBuildComplete(result.errors.length === 0);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
};
|
|
330
368
|
const context = await esbuild.context({
|
|
331
369
|
entryPoints: [entryPoint],
|
|
332
370
|
bundle: true,
|
|
@@ -336,7 +374,7 @@ async function watch(entryPoint, outfile, hotReloadManager = null) {
|
|
|
336
374
|
outfile: outfile,
|
|
337
375
|
loader: { '.js': 'jsx', '.ts': 'tsx' },
|
|
338
376
|
external: nodeBuiltIns,
|
|
339
|
-
plugins: [postcssPlugin, npmDependenciesPlugin, reactResolvePlugin],
|
|
377
|
+
plugins: [postcssPlugin, npmDependenciesPlugin, reactResolvePlugin, buildCompletePlugin],
|
|
340
378
|
format: 'iife',
|
|
341
379
|
globalName: 'HwebApp',
|
|
342
380
|
jsx: 'automatic',
|
package/dist/hotReload.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export declare class HotReloadManager {
|
|
|
9
9
|
private isShuttingDown;
|
|
10
10
|
private debounceTimers;
|
|
11
11
|
private customHotReloadListener;
|
|
12
|
+
private isBuilding;
|
|
13
|
+
private buildCompleteResolve;
|
|
12
14
|
constructor(projectDir: string);
|
|
13
15
|
start(): Promise<void>;
|
|
14
16
|
handleUpgrade(request: IncomingMessage, socket: any, head: Buffer): void;
|
|
@@ -26,5 +28,5 @@ export declare class HotReloadManager {
|
|
|
26
28
|
onFrontendChange(callback: () => void): void;
|
|
27
29
|
setHotReloadListener(listener: (file: string) => Promise<void> | void): void;
|
|
28
30
|
removeHotReloadListener(): void;
|
|
29
|
-
|
|
31
|
+
onBuildComplete(success: boolean): void;
|
|
30
32
|
}
|
package/dist/hotReload.js
CHANGED
|
@@ -65,6 +65,8 @@ class HotReloadManager {
|
|
|
65
65
|
this.isShuttingDown = false;
|
|
66
66
|
this.debounceTimers = new Map();
|
|
67
67
|
this.customHotReloadListener = null;
|
|
68
|
+
this.isBuilding = false;
|
|
69
|
+
this.buildCompleteResolve = null;
|
|
68
70
|
this.projectDir = projectDir;
|
|
69
71
|
}
|
|
70
72
|
async start() {
|
|
@@ -198,20 +200,34 @@ class HotReloadManager {
|
|
|
198
200
|
// Limpa o cache do arquivo alterado
|
|
199
201
|
(0, router_1.clearFileCache)(filePath);
|
|
200
202
|
this.clearBackendCache(filePath);
|
|
201
|
-
//
|
|
202
|
-
const ext = path.extname(filePath);
|
|
203
|
-
if ([".ts", ".tsx", ".js", ".jsx"].includes(ext)) {
|
|
204
|
-
const result = await this.checkFrontendBuild(filePath);
|
|
205
|
-
if (result.error) {
|
|
206
|
-
this.notifyClients('src-error', { file: filePath, error: result.error });
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
// Se for arquivo de frontend, notifica o cliente para recarregar a página
|
|
203
|
+
// Se for arquivo de frontend, aguarda o build terminar antes de recarregar
|
|
211
204
|
if (isFrontendFile) {
|
|
212
|
-
console_1.default.logWithout(console_1.Levels.INFO, console_1.Colors.BgRed, `📄
|
|
213
|
-
|
|
214
|
-
this.
|
|
205
|
+
console_1.default.logWithout(console_1.Levels.INFO, console_1.Colors.BgRed, `📄 Aguardando build do frontend...`);
|
|
206
|
+
// Marca que estamos esperando um build
|
|
207
|
+
this.isBuilding = true;
|
|
208
|
+
// Cria uma promise que será resolvida quando o build terminar
|
|
209
|
+
const buildPromise = new Promise((resolve) => {
|
|
210
|
+
this.buildCompleteResolve = resolve;
|
|
211
|
+
});
|
|
212
|
+
// Aguarda o build terminar (com timeout de 30 segundos)
|
|
213
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
214
|
+
setTimeout(() => reject(new Error('Build timeout')), 30000);
|
|
215
|
+
});
|
|
216
|
+
try {
|
|
217
|
+
await Promise.race([buildPromise, timeoutPromise]);
|
|
218
|
+
console_1.default.logWithout(console_1.Levels.INFO, console_1.Colors.BgRed, `✅ Build concluído, recarregando frontend...`);
|
|
219
|
+
this.frontendChangeCallback?.();
|
|
220
|
+
this.notifyClients('frontend-reload', { file: filePath, event: 'change' });
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
console_1.default.logWithout(console_1.Levels.ERROR, console_1.Colors.BgRed, `⚠️ Timeout no build, recarregando mesmo assim...`);
|
|
224
|
+
this.frontendChangeCallback?.();
|
|
225
|
+
this.notifyClients('frontend-reload', { file: filePath, event: 'change' });
|
|
226
|
+
}
|
|
227
|
+
finally {
|
|
228
|
+
this.isBuilding = false;
|
|
229
|
+
this.buildCompleteResolve = null;
|
|
230
|
+
}
|
|
215
231
|
}
|
|
216
232
|
// Se for arquivo de backend, recarrega o módulo e notifica
|
|
217
233
|
if (isBackendFile) {
|
|
@@ -432,36 +448,12 @@ class HotReloadManager {
|
|
|
432
448
|
removeHotReloadListener() {
|
|
433
449
|
this.customHotReloadListener = null;
|
|
434
450
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
return new Promise((resolve) => {
|
|
440
|
-
const proc = spawn(process.execPath, [tsNodePath, '--transpile-only', filePath], {
|
|
441
|
-
cwd: this.projectDir,
|
|
442
|
-
env: process.env,
|
|
443
|
-
timeout: 10000 // Timeout de 10 segundos
|
|
444
|
-
});
|
|
445
|
-
let errorMsg = '';
|
|
446
|
-
proc.stderr.on('data', (data) => {
|
|
447
|
-
errorMsg += data.toString();
|
|
448
|
-
});
|
|
449
|
-
proc.on('close', (code) => {
|
|
450
|
-
if (code !== 0 && errorMsg) {
|
|
451
|
-
resolve({ error: errorMsg });
|
|
452
|
-
}
|
|
453
|
-
else {
|
|
454
|
-
resolve({});
|
|
455
|
-
}
|
|
456
|
-
});
|
|
457
|
-
proc.on('error', (error) => {
|
|
458
|
-
resolve({ error: error.message });
|
|
459
|
-
});
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
catch (error) {
|
|
463
|
-
return { error: `Erro ao verificar build: ${error}` };
|
|
451
|
+
onBuildComplete(success) {
|
|
452
|
+
if (this.buildCompleteResolve) {
|
|
453
|
+
this.buildCompleteResolve();
|
|
454
|
+
this.buildCompleteResolve = null;
|
|
464
455
|
}
|
|
456
|
+
this.isBuilding = false;
|
|
465
457
|
}
|
|
466
458
|
}
|
|
467
459
|
exports.HotReloadManager = HotReloadManager;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hightjs",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "HightJS is a high-level framework for building web applications with ease and speed. It provides a robust set of tools and features to streamline development and enhance productivity.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
package/src/builder.js
CHANGED
|
@@ -251,6 +251,25 @@ async function watchWithChunks(entryPoint, outdir, hotReloadManager = null) {
|
|
|
251
251
|
// limpar diretorio
|
|
252
252
|
fs.rmSync(outdir, { recursive: true, force: true });
|
|
253
253
|
try {
|
|
254
|
+
// Plugin para notificar quando o build termina
|
|
255
|
+
const buildCompletePlugin = {
|
|
256
|
+
name: 'build-complete',
|
|
257
|
+
setup(build) {
|
|
258
|
+
let isFirstBuild = true;
|
|
259
|
+
build.onEnd((result) => {
|
|
260
|
+
if (hotReloadManager) {
|
|
261
|
+
if (isFirstBuild) {
|
|
262
|
+
isFirstBuild = false;
|
|
263
|
+
hotReloadManager.onBuildComplete(true);
|
|
264
|
+
} else {
|
|
265
|
+
// Notifica o hot reload manager que o build foi concluído
|
|
266
|
+
hotReloadManager.onBuildComplete(result.errors.length === 0);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
|
|
254
273
|
const context = await esbuild.context({
|
|
255
274
|
entryPoints: [entryPoint],
|
|
256
275
|
bundle: true,
|
|
@@ -260,7 +279,7 @@ async function watchWithChunks(entryPoint, outdir, hotReloadManager = null) {
|
|
|
260
279
|
outdir: outdir,
|
|
261
280
|
loader: { '.js': 'jsx', '.ts': 'tsx' },
|
|
262
281
|
external: nodeBuiltIns,
|
|
263
|
-
plugins: [postcssPlugin, npmDependenciesPlugin, reactResolvePlugin],
|
|
282
|
+
plugins: [postcssPlugin, npmDependenciesPlugin, reactResolvePlugin, buildCompletePlugin],
|
|
264
283
|
format: 'esm',
|
|
265
284
|
jsx: 'automatic',
|
|
266
285
|
define: {
|
|
@@ -347,6 +366,25 @@ async function build(entryPoint, outfile, isProduction = false) {
|
|
|
347
366
|
*/
|
|
348
367
|
async function watch(entryPoint, outfile, hotReloadManager = null) {
|
|
349
368
|
try {
|
|
369
|
+
// Plugin para notificar quando o build termina
|
|
370
|
+
const buildCompletePlugin = {
|
|
371
|
+
name: 'build-complete',
|
|
372
|
+
setup(build) {
|
|
373
|
+
let isFirstBuild = true;
|
|
374
|
+
build.onEnd((result) => {
|
|
375
|
+
if (hotReloadManager) {
|
|
376
|
+
if (isFirstBuild) {
|
|
377
|
+
isFirstBuild = false;
|
|
378
|
+
hotReloadManager.onBuildComplete(true);
|
|
379
|
+
} else {
|
|
380
|
+
// Notifica o hot reload manager que o build foi concluído
|
|
381
|
+
hotReloadManager.onBuildComplete(result.errors.length === 0);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
|
|
350
388
|
const context = await esbuild.context({
|
|
351
389
|
entryPoints: [entryPoint],
|
|
352
390
|
bundle: true,
|
|
@@ -356,7 +394,7 @@ async function watch(entryPoint, outfile, hotReloadManager = null) {
|
|
|
356
394
|
outfile: outfile,
|
|
357
395
|
loader: { '.js': 'jsx', '.ts': 'tsx' },
|
|
358
396
|
external: nodeBuiltIns,
|
|
359
|
-
plugins: [postcssPlugin, npmDependenciesPlugin, reactResolvePlugin],
|
|
397
|
+
plugins: [postcssPlugin, npmDependenciesPlugin, reactResolvePlugin, buildCompletePlugin],
|
|
360
398
|
format: 'iife',
|
|
361
399
|
globalName: 'HwebApp',
|
|
362
400
|
jsx: 'automatic',
|
package/src/hotReload.ts
CHANGED
|
@@ -39,6 +39,8 @@ export class HotReloadManager {
|
|
|
39
39
|
private isShuttingDown: boolean = false;
|
|
40
40
|
private debounceTimers: Map<string, NodeJS.Timeout> = new Map();
|
|
41
41
|
private customHotReloadListener: ((file: string) => Promise<void> | void) | null = null;
|
|
42
|
+
private isBuilding: boolean = false;
|
|
43
|
+
private buildCompleteResolve: (() => void) | null = null;
|
|
42
44
|
|
|
43
45
|
constructor(projectDir: string) {
|
|
44
46
|
this.projectDir = projectDir;
|
|
@@ -200,21 +202,36 @@ export class HotReloadManager {
|
|
|
200
202
|
clearFileCache(filePath);
|
|
201
203
|
this.clearBackendCache(filePath);
|
|
202
204
|
|
|
203
|
-
//
|
|
204
|
-
const ext = path.extname(filePath);
|
|
205
|
-
if ([".ts", ".tsx", ".js", ".jsx"].includes(ext)) {
|
|
206
|
-
const result = await this.checkFrontendBuild(filePath);
|
|
207
|
-
if (result.error) {
|
|
208
|
-
this.notifyClients('src-error', { file: filePath, error: result.error });
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Se for arquivo de frontend, notifica o cliente para recarregar a página
|
|
205
|
+
// Se for arquivo de frontend, aguarda o build terminar antes de recarregar
|
|
214
206
|
if (isFrontendFile) {
|
|
215
|
-
Console.logWithout(Levels.INFO, Colors.BgRed,`📄
|
|
216
|
-
|
|
217
|
-
|
|
207
|
+
Console.logWithout(Levels.INFO, Colors.BgRed,`📄 Aguardando build do frontend...`);
|
|
208
|
+
|
|
209
|
+
// Marca que estamos esperando um build
|
|
210
|
+
this.isBuilding = true;
|
|
211
|
+
|
|
212
|
+
// Cria uma promise que será resolvida quando o build terminar
|
|
213
|
+
const buildPromise = new Promise<void>((resolve) => {
|
|
214
|
+
this.buildCompleteResolve = resolve;
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Aguarda o build terminar (com timeout de 30 segundos)
|
|
218
|
+
const timeoutPromise = new Promise<void>((_, reject) => {
|
|
219
|
+
setTimeout(() => reject(new Error('Build timeout')), 30000);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
try {
|
|
223
|
+
await Promise.race([buildPromise, timeoutPromise]);
|
|
224
|
+
Console.logWithout(Levels.INFO, Colors.BgRed,`✅ Build concluído, recarregando frontend...`);
|
|
225
|
+
this.frontendChangeCallback?.();
|
|
226
|
+
this.notifyClients('frontend-reload', { file: filePath, event: 'change' });
|
|
227
|
+
} catch (error) {
|
|
228
|
+
Console.logWithout(Levels.ERROR, Colors.BgRed,`⚠️ Timeout no build, recarregando mesmo assim...`);
|
|
229
|
+
this.frontendChangeCallback?.();
|
|
230
|
+
this.notifyClients('frontend-reload', { file: filePath, event: 'change' });
|
|
231
|
+
} finally {
|
|
232
|
+
this.isBuilding = false;
|
|
233
|
+
this.buildCompleteResolve = null;
|
|
234
|
+
}
|
|
218
235
|
}
|
|
219
236
|
|
|
220
237
|
// Se for arquivo de backend, recarrega o módulo e notifica
|
|
@@ -453,38 +470,11 @@ export class HotReloadManager {
|
|
|
453
470
|
this.customHotReloadListener = null;
|
|
454
471
|
}
|
|
455
472
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
return new Promise<{ error?: string }>((resolve) => {
|
|
462
|
-
const proc = spawn(process.execPath, [tsNodePath, '--transpile-only', filePath], {
|
|
463
|
-
cwd: this.projectDir,
|
|
464
|
-
env: process.env,
|
|
465
|
-
timeout: 10000 // Timeout de 10 segundos
|
|
466
|
-
});
|
|
467
|
-
|
|
468
|
-
let errorMsg = '';
|
|
469
|
-
|
|
470
|
-
proc.stderr.on('data', (data: Buffer) => {
|
|
471
|
-
errorMsg += data.toString();
|
|
472
|
-
});
|
|
473
|
-
|
|
474
|
-
proc.on('close', (code: number) => {
|
|
475
|
-
if (code !== 0 && errorMsg) {
|
|
476
|
-
resolve({ error: errorMsg });
|
|
477
|
-
} else {
|
|
478
|
-
resolve({});
|
|
479
|
-
}
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
proc.on('error', (error: Error) => {
|
|
483
|
-
resolve({ error: error.message });
|
|
484
|
-
});
|
|
485
|
-
});
|
|
486
|
-
} catch (error) {
|
|
487
|
-
return { error: `Erro ao verificar build: ${error}` };
|
|
473
|
+
onBuildComplete(success: boolean) {
|
|
474
|
+
if (this.buildCompleteResolve) {
|
|
475
|
+
this.buildCompleteResolve();
|
|
476
|
+
this.buildCompleteResolve = null;
|
|
488
477
|
}
|
|
478
|
+
this.isBuilding = false;
|
|
489
479
|
}
|
|
490
480
|
}
|