opticore-webapp 1.0.68 → 1.0.69
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/index.cjs +778 -560
- package/dist/index.d.cts +462 -148
- package/dist/index.d.ts +462 -148
- package/dist/index.js +780 -558
- package/dist/utils/translations/message.translation.en.json +20 -1
- package/dist/utils/translations/message.translation.fr.json +1 -1
- package/package.json +6 -7
package/dist/index.cjs
CHANGED
|
@@ -39,8 +39,9 @@ module.exports = __toCommonJS(index_exports);
|
|
|
39
39
|
var path2 = __toESM(require("path"), 1);
|
|
40
40
|
var import_node_process3 = __toESM(require("process"), 1);
|
|
41
41
|
var import_cors = __toESM(require("cors"), 1);
|
|
42
|
+
var import_express = __toESM(require("express"), 1);
|
|
43
|
+
var import_chokidar = __toESM(require("chokidar"), 1);
|
|
42
44
|
var import_opticore_catch_exception_error3 = require("opticore-catch-exception-error");
|
|
43
|
-
var import_opticore_express = require("opticore-express");
|
|
44
45
|
var import_opticore_env_access2 = require("opticore-env-access");
|
|
45
46
|
var import_opticore_request_call_event = require("opticore-request-call-event");
|
|
46
47
|
var import_opticore_dependency_inject2 = require("opticore-dependency-inject");
|
|
@@ -476,55 +477,149 @@ var SServerStartError = (err, environmentPath) => {
|
|
|
476
477
|
};
|
|
477
478
|
|
|
478
479
|
// src/core/webServer.core.ts
|
|
479
|
-
var import_opticore_watcher = require("opticore-watcher");
|
|
480
480
|
var WebServerCore = class {
|
|
481
481
|
serverUtility;
|
|
482
|
-
expressApp
|
|
483
|
-
fileWatcher;
|
|
482
|
+
expressApp;
|
|
484
483
|
localLanguage;
|
|
485
484
|
loggerConfig;
|
|
486
|
-
routerExpressApp;
|
|
487
485
|
getEnvironment;
|
|
488
486
|
environmentPath;
|
|
489
487
|
serverListenEvent;
|
|
488
|
+
// Existing properties
|
|
490
489
|
currentRoutes = [];
|
|
491
490
|
currentDependencies = [];
|
|
492
491
|
server = void 0;
|
|
493
492
|
errorEmitter;
|
|
494
|
-
isWatcherEnabled = true;
|
|
495
493
|
serverStatus = "STARTING";
|
|
496
494
|
serverStartTime = /* @__PURE__ */ new Date();
|
|
495
|
+
// HMR properties
|
|
496
|
+
fileWatcher = null;
|
|
497
|
+
hmrRestartPending = false;
|
|
498
|
+
hmrDebounceTimeout = null;
|
|
499
|
+
hmrRestartCount = 0;
|
|
500
|
+
lastHmrRestartTime = 0;
|
|
501
|
+
/**
|
|
502
|
+
* Creates a new WebServerCore instance.
|
|
503
|
+
*
|
|
504
|
+
* @constructor
|
|
505
|
+
* @param {WebServerConstructorInterface} paramsConstructor - Configuration parameters
|
|
506
|
+
*
|
|
507
|
+
* @param {express.Application} paramsConstructor.app - Express application instance
|
|
508
|
+
* @param {LoggerCore} paramsConstructor.loggerConfig - Logger configuration
|
|
509
|
+
* @param {string} paramsConstructor.environmentPath - Path to environment file
|
|
510
|
+
* @param {string} paramsConstructor.localLanguage - Default language for translations
|
|
511
|
+
* @param {CorsOptions} paramsConstructor.corsOriginOptions - CORS configuration
|
|
512
|
+
*
|
|
513
|
+
* @returns {WebServerCore} New WebServerCore instance
|
|
514
|
+
*
|
|
515
|
+
* @throws {Error} If environment file cannot be loaded
|
|
516
|
+
*
|
|
517
|
+
* @example
|
|
518
|
+
* ```typescript
|
|
519
|
+
* const server = new WebServerCore({
|
|
520
|
+
* app: express(),
|
|
521
|
+
* loggerConfig: new LoggerCore(config),
|
|
522
|
+
* environmentPath: ".env",
|
|
523
|
+
* localLanguage: "fr",
|
|
524
|
+
* corsOriginOptions: { origin: "http://localhost:3000" }
|
|
525
|
+
* });
|
|
526
|
+
* ```
|
|
527
|
+
*/
|
|
497
528
|
constructor(paramsConstructor) {
|
|
498
|
-
this.getEnvironment = (0, import_opticore_env_access2.
|
|
499
|
-
this.routerExpressApp = paramsConstructor.app;
|
|
529
|
+
this.getEnvironment = (0, import_opticore_env_access2.getEnvironmentValue)(paramsConstructor.environmentPath);
|
|
500
530
|
this.loggerConfig = paramsConstructor.loggerConfig;
|
|
501
531
|
this.localLanguage = paramsConstructor.localLanguage;
|
|
502
532
|
this.environmentPath = paramsConstructor.environmentPath;
|
|
503
|
-
this.expressApp
|
|
504
|
-
this.expressApp.use(import_opticore_express.express.raw());
|
|
505
|
-
this.expressApp.use(import_opticore_express.express.text());
|
|
506
|
-
this.expressApp.use(import_opticore_express.express.urlencoded({ extended: true }));
|
|
507
|
-
this.expressApp.use((0, import_cors.default)(paramsConstructor.corsOriginOptions));
|
|
533
|
+
this.expressApp = (0, import_express.default)();
|
|
508
534
|
this.serverListenEvent = new import_opticore_catch_exception_error3.ServerListenEventError(paramsConstructor.localLanguage);
|
|
535
|
+
this.expressApp.use(import_express.default.json());
|
|
536
|
+
this.expressApp.use(import_express.default.raw());
|
|
537
|
+
this.expressApp.use(import_express.default.text());
|
|
538
|
+
this.expressApp.use(import_express.default.urlencoded({ extended: true }));
|
|
539
|
+
this.expressApp.use((0, import_cors.default)(paramsConstructor.corsOriginOptions));
|
|
509
540
|
this.serverUtility = new CoreService(paramsConstructor.localLanguage, paramsConstructor.environmentPath);
|
|
541
|
+
this.serverStatus = "STARTING";
|
|
542
|
+
this.serverStartTime = /* @__PURE__ */ new Date();
|
|
543
|
+
this.setupProcessEventListeners();
|
|
510
544
|
}
|
|
545
|
+
/**
|
|
546
|
+
* Starts the HTTP server and initializes all components including HMR if enabled.
|
|
547
|
+
*
|
|
548
|
+
* @method onStartServer
|
|
549
|
+
* @public
|
|
550
|
+
*
|
|
551
|
+
* @param {TFeatureRoutes[]} routers - Array of feature routes to register
|
|
552
|
+
* @param {(env: IEnvVariables) => void} [databaseCallback] - Optional database connection callback
|
|
553
|
+
* @param {TDependency[]} [dependenciesProvider] - Optional dependency injection providers
|
|
554
|
+
*
|
|
555
|
+
* @returns {serverWebApp | undefined} HTTP server instance or undefined if startup fails
|
|
556
|
+
*
|
|
557
|
+
* @throws {ServerListenEventError} If port/host configuration is invalid
|
|
558
|
+
* @throws {Error} If server initialization fails
|
|
559
|
+
*
|
|
560
|
+
* @fires WebServerCore#startHttpServer - When server successfully starts
|
|
561
|
+
* @fires WebServerCore#startHMR - When HMR is started (if enabled)
|
|
562
|
+
* @fires WebServerCore#serverError - When server fails to start
|
|
563
|
+
*
|
|
564
|
+
* @example
|
|
565
|
+
* ```typescript
|
|
566
|
+
* const server = app.onStartServer(
|
|
567
|
+
* routes,
|
|
568
|
+
* (env) => connectToDatabase(env),
|
|
569
|
+
* dependencies
|
|
570
|
+
* );
|
|
571
|
+
*
|
|
572
|
+
* if (server) {
|
|
573
|
+
* console.log("Server started successfully");
|
|
574
|
+
* }
|
|
575
|
+
* ```
|
|
576
|
+
*/
|
|
511
577
|
onStartServer(routers, databaseCallback, dependenciesProvider) {
|
|
578
|
+
try {
|
|
579
|
+
loaderTranslationFile(this.localLanguage);
|
|
580
|
+
this.currentRoutes = routers;
|
|
581
|
+
this.currentDependencies = dependenciesProvider || [];
|
|
582
|
+
this.serverStartTime = /* @__PURE__ */ new Date();
|
|
583
|
+
this.serverStatus = "STARTING";
|
|
584
|
+
if (!this.validateServerParameters()) {
|
|
585
|
+
return void 0;
|
|
586
|
+
}
|
|
587
|
+
const server = this.startHttpServer(databaseCallback);
|
|
588
|
+
if (this.getEnvironment.hmrEnabled) {
|
|
589
|
+
this.startHMR();
|
|
590
|
+
}
|
|
591
|
+
return server;
|
|
592
|
+
} catch (error) {
|
|
593
|
+
this.handleStartupError(error);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Validates server configuration parameters.
|
|
598
|
+
*
|
|
599
|
+
* @method validateServerParameters
|
|
600
|
+
* @private
|
|
601
|
+
*
|
|
602
|
+
* @returns {boolean} True if all parameters are valid, false otherwise
|
|
603
|
+
*
|
|
604
|
+
* @remarks
|
|
605
|
+
* Validates:
|
|
606
|
+
* - Port number is valid and positive
|
|
607
|
+
* - Host is not empty
|
|
608
|
+
* - Local language is specified
|
|
609
|
+
* - HMR configuration (if enabled)
|
|
610
|
+
*/
|
|
611
|
+
validateServerParameters() {
|
|
512
612
|
loaderTranslationFile(this.localLanguage);
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
return void 0;
|
|
613
|
+
const port = Number(this.getEnvironment.appPort);
|
|
614
|
+
if (isNaN(port) || port <= 0) {
|
|
615
|
+
this.serverListenEvent.portUndefined();
|
|
616
|
+
return false;
|
|
518
617
|
}
|
|
519
|
-
if (this.getEnvironment.appHost === "") {
|
|
618
|
+
if (!this.getEnvironment.appHost || this.getEnvironment.appHost.trim() === "") {
|
|
520
619
|
this.serverListenEvent.hostUndefined(this.getEnvironment.appHost);
|
|
521
|
-
return
|
|
522
|
-
}
|
|
523
|
-
if (Number(this.getEnvironment.appPort) === 0) {
|
|
524
|
-
this.serverListenEvent.portUndefined();
|
|
525
|
-
return void 0;
|
|
620
|
+
return false;
|
|
526
621
|
}
|
|
527
|
-
if (this.localLanguage === "") {
|
|
622
|
+
if (!this.localLanguage || this.localLanguage.trim() === "") {
|
|
528
623
|
SLogger(this.localLanguage).logger.error({
|
|
529
624
|
message: import_opticore_translator2.TranslationLoader.t("noDefaultLocalLang", this.localLanguage),
|
|
530
625
|
title: import_opticore_translator2.TranslationLoader.t("noLocalLang", this.localLanguage),
|
|
@@ -532,81 +627,225 @@ var WebServerCore = class {
|
|
|
532
627
|
stackTrace: void 0,
|
|
533
628
|
httpCodeValue: import_opticore_http_response3.HttpStatusCode.NOT_FOUND
|
|
534
629
|
});
|
|
535
|
-
return
|
|
630
|
+
return false;
|
|
536
631
|
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
632
|
+
if (this.getEnvironment.hmrEnabled) {
|
|
633
|
+
if (!this.getEnvironment.hmrWatchPatterns || this.getEnvironment.hmrWatchPatterns.length === 0) {
|
|
634
|
+
SLogger(this.localLanguage).logger.warn({
|
|
635
|
+
title: import_opticore_translator2.TranslationLoader.t("HMR_CONFIG_WARNING", this.localLanguage),
|
|
636
|
+
message: "HMR enabled but no watch patterns defined"
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
return true;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Starts the HTTP server and sets up event listeners.
|
|
644
|
+
*
|
|
645
|
+
* @method startHttpServer
|
|
646
|
+
* @private
|
|
647
|
+
*
|
|
648
|
+
* @param {(env: IEnvVariables) => void} [databaseCallback] - Database connection callback
|
|
649
|
+
*
|
|
650
|
+
* @returns {serverWebApp | undefined} HTTP server instance or undefined if startup fails
|
|
651
|
+
*
|
|
652
|
+
* @throws {Error} If server fails to start
|
|
653
|
+
*/
|
|
654
|
+
startHttpServer(databaseCallback) {
|
|
655
|
+
try {
|
|
656
|
+
loaderTranslationFile(this.localLanguage);
|
|
657
|
+
const port = Number(this.getEnvironment.appPort);
|
|
658
|
+
const host = this.getEnvironment.appHost;
|
|
659
|
+
this.server = this.expressApp.listen(port, host, () => {
|
|
541
660
|
try {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
if (this.isWatcherEnabled) {
|
|
551
|
-
this.initializeFileWatcher();
|
|
552
|
-
}
|
|
553
|
-
this.infoWebApp();
|
|
554
|
-
} catch (err) {
|
|
555
|
-
SLogger(this.localLanguage).logger.error({
|
|
556
|
-
title: import_opticore_translator2.TranslationLoader.t("STARTUP_ERROR", this.localLanguage),
|
|
557
|
-
message: err.message,
|
|
558
|
-
errorType: err.code,
|
|
559
|
-
stackTrace: err.stackTrace,
|
|
560
|
-
httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
661
|
+
this.configureServerComponents(databaseCallback);
|
|
662
|
+
this.serverStatus = "READY";
|
|
663
|
+
SLogger(this.localLanguage).logger.info({
|
|
664
|
+
title: import_opticore_translator2.TranslationLoader.t("SERVER_RUNNING_TITLE", this.localLanguage),
|
|
665
|
+
message: import_opticore_translator2.TranslationLoader.t("SERVER_RUNNING_AT", this.localLanguage, {
|
|
666
|
+
server: `${host}:${port}`,
|
|
667
|
+
hmrEnabled: this.getEnvironment.hmrEnabled ? "with HMR" : "without HMR"
|
|
668
|
+
})
|
|
561
669
|
});
|
|
562
|
-
|
|
670
|
+
} catch (err) {
|
|
671
|
+
this.handleServerConfigurationError(err);
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
this.setupServerEventListeners();
|
|
675
|
+
return this.server;
|
|
676
|
+
} catch (error) {
|
|
677
|
+
this.serverListenEvent.onEventError(
|
|
678
|
+
new Error(import_opticore_translator2.TranslationLoader.t(
|
|
679
|
+
"HTTP_SERVER_FAILED",
|
|
680
|
+
this.localLanguage,
|
|
681
|
+
{ errorMessage: error.message }
|
|
682
|
+
))
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Configures server components (database, dependencies, routes, etc.).
|
|
688
|
+
*
|
|
689
|
+
* @method configureServerComponents
|
|
690
|
+
* @private
|
|
691
|
+
*
|
|
692
|
+
* @param {(env: IEnvVariables) => void} [databaseCallback] - Database connection callback
|
|
693
|
+
*
|
|
694
|
+
* @returns {void}
|
|
695
|
+
*
|
|
696
|
+
* @throws {Error} If component configuration fails
|
|
697
|
+
*/
|
|
698
|
+
configureServerComponents(databaseCallback) {
|
|
699
|
+
try {
|
|
700
|
+
loaderTranslationFile(this.localLanguage);
|
|
701
|
+
if (databaseCallback && typeof databaseCallback === "function") {
|
|
702
|
+
try {
|
|
703
|
+
databaseCallback(this.getEnvironment);
|
|
704
|
+
} catch (dbError) {
|
|
705
|
+
this.serverListenEvent.listenerError(
|
|
706
|
+
new Error(import_opticore_translator2.TranslationLoader.t("DB_CON_FAILED", this.localLanguage, { dbErrorMessage: dbError.message }))
|
|
707
|
+
);
|
|
563
708
|
}
|
|
564
709
|
}
|
|
565
|
-
|
|
566
|
-
|
|
710
|
+
try {
|
|
711
|
+
new import_opticore_dependency_inject2.SContainer(this.localLanguage, this.currentDependencies);
|
|
712
|
+
} catch (depError) {
|
|
713
|
+
this.serverListenEvent.listenerError(
|
|
714
|
+
new Error(import_opticore_translator2.TranslationLoader.t("DEPENDENCY_INJECTION_FAILED", this.localLanguage, { depErrorMessage: depError.message }))
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
this.expressApp.use(import_express.default.static(path2.join(import_node_process3.default.cwd(), "public/template")));
|
|
718
|
+
this.registerRoutes(this.currentRoutes);
|
|
719
|
+
this.setupErrorHandling();
|
|
720
|
+
this.infoWebApp();
|
|
721
|
+
} catch (error) {
|
|
722
|
+
this.serverListenEvent.listenerError(
|
|
723
|
+
new Error(import_opticore_translator2.TranslationLoader.t("SERVER_COMPONENT_CONFIG_FAILED", this.localLanguage, { errorMessage: error.message }))
|
|
724
|
+
);
|
|
725
|
+
throw error;
|
|
726
|
+
}
|
|
567
727
|
}
|
|
568
728
|
/**
|
|
569
|
-
*
|
|
729
|
+
* Handles server configuration errors.
|
|
730
|
+
*
|
|
731
|
+
* @method handleServerConfigurationError
|
|
732
|
+
* @private
|
|
733
|
+
*
|
|
734
|
+
* @param {any} err - The error that occurred
|
|
735
|
+
*
|
|
736
|
+
* @returns {void}
|
|
570
737
|
*/
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
this.
|
|
579
|
-
SLogger(this.localLanguage).logger.error({
|
|
580
|
-
title: import_opticore_translator2.TranslationLoader.t("TRANSFORM_ERROR", this.localLanguage),
|
|
581
|
-
message: error.message,
|
|
582
|
-
errorType: error.name,
|
|
583
|
-
stackTrace: error.stackTrace,
|
|
584
|
-
httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
585
|
-
});
|
|
586
|
-
});
|
|
587
|
-
this.errorEmitter.on("error", (error) => {
|
|
588
|
-
SLogger(this.localLanguage).logger.info({
|
|
589
|
-
title: import_opticore_translator2.TranslationLoader.t("ERROR_EMITTED", this.localLanguage),
|
|
590
|
-
message: error.message
|
|
591
|
-
});
|
|
592
|
-
});
|
|
593
|
-
this.errorEmitter.on("hotReload", (data) => {
|
|
594
|
-
SLogger(this.localLanguage).logger.info({
|
|
595
|
-
title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_EVENT", this.localLanguage),
|
|
596
|
-
message: `Hot reload triggered for ${data.file}`
|
|
597
|
-
});
|
|
598
|
-
});
|
|
738
|
+
handleServerConfigurationError(err) {
|
|
739
|
+
loaderTranslationFile(this.localLanguage);
|
|
740
|
+
this.serverStatus = "ERROR";
|
|
741
|
+
this.serverListenEvent.onEventError(err);
|
|
742
|
+
try {
|
|
743
|
+
SServerStartError(err, this.environmentPath);
|
|
744
|
+
} catch (startError) {
|
|
745
|
+
this.serverListenEvent.listenerError(startError);
|
|
599
746
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Handles general startup errors.
|
|
750
|
+
*
|
|
751
|
+
* @method handleStartupError
|
|
752
|
+
* @private
|
|
753
|
+
*
|
|
754
|
+
* @param {any} error - The startup error
|
|
755
|
+
*
|
|
756
|
+
* @returns {void}
|
|
757
|
+
*/
|
|
758
|
+
handleStartupError(error) {
|
|
759
|
+
loaderTranslationFile(this.localLanguage);
|
|
760
|
+
this.serverStatus = "ERROR";
|
|
761
|
+
this.serverListenEvent.listenerError(error);
|
|
762
|
+
SLogger(this.localLanguage).logger.error({
|
|
763
|
+
title: import_opticore_translator2.TranslationLoader.t("GLOBAL_STARTUP_ERROR", this.localLanguage),
|
|
764
|
+
message: error.message,
|
|
765
|
+
errorType: error.name || "StartupError",
|
|
766
|
+
stackTrace: error.stack,
|
|
767
|
+
httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
603
768
|
});
|
|
604
769
|
}
|
|
605
770
|
/**
|
|
606
|
-
*
|
|
771
|
+
* Sets up Node.js process event listeners.
|
|
772
|
+
*
|
|
773
|
+
* @method setupProcessEventListeners
|
|
774
|
+
* @private
|
|
775
|
+
*
|
|
776
|
+
* @returns {void}
|
|
777
|
+
*
|
|
778
|
+
* @remarks
|
|
779
|
+
* Listens for:
|
|
780
|
+
* - Process exit events
|
|
781
|
+
* - Uncaught exceptions
|
|
782
|
+
* - Unhandled rejections
|
|
783
|
+
* - System signals (SIGINT, SIGTERM)
|
|
607
784
|
*/
|
|
608
|
-
|
|
609
|
-
|
|
785
|
+
setupProcessEventListeners() {
|
|
786
|
+
loaderTranslationFile(this.localLanguage);
|
|
787
|
+
import_node_process3.default.on(import_opticore_catch_exception_error3.CEvent.beforeExit, (code) => {
|
|
788
|
+
this.serverListenEvent.processBeforeExit(code);
|
|
789
|
+
});
|
|
790
|
+
import_node_process3.default.on(import_opticore_catch_exception_error3.CEvent.disconnect, () => {
|
|
791
|
+
this.serverListenEvent.processDisconnected();
|
|
792
|
+
});
|
|
793
|
+
import_node_process3.default.on(import_opticore_catch_exception_error3.CEvent.exit, (code) => {
|
|
794
|
+
this.serverListenEvent.exited(code);
|
|
795
|
+
});
|
|
796
|
+
import_node_process3.default.on(import_opticore_catch_exception_error3.CEvent.message, (message) => {
|
|
797
|
+
this.serverListenEvent.message(message);
|
|
798
|
+
});
|
|
799
|
+
import_node_process3.default.on(import_opticore_catch_exception_error3.CEvent.multipleResolves, (type, promise, reason) => {
|
|
800
|
+
this.serverListenEvent.multipleResolves(type, promise, reason);
|
|
801
|
+
});
|
|
802
|
+
import_node_process3.default.on(import_opticore_catch_exception_error3.CEvent.rejectionHandled, (promise) => {
|
|
803
|
+
this.serverListenEvent.promiseRejectionHandled(promise);
|
|
804
|
+
});
|
|
805
|
+
import_node_process3.default.on(import_opticore_catch_exception_error3.CEvent.uncaughtException, (error) => {
|
|
806
|
+
this.serverListenEvent.uncaughtException(error);
|
|
807
|
+
});
|
|
808
|
+
import_node_process3.default.on(import_opticore_catch_exception_error3.CEvent.uncaughtExceptionMonitor, (error) => {
|
|
809
|
+
this.serverListenEvent.uncaughtExceptionMonitor(error);
|
|
810
|
+
});
|
|
811
|
+
import_node_process3.default.on(import_opticore_catch_exception_error3.CEvent.unhandledRejection, (reason, promise) => {
|
|
812
|
+
this.serverListenEvent.unhandledRejection(reason, promise);
|
|
813
|
+
});
|
|
814
|
+
import_node_process3.default.on(import_opticore_catch_exception_error3.CEvent.warning, (warning) => {
|
|
815
|
+
this.serverListenEvent.warning(warning);
|
|
816
|
+
});
|
|
817
|
+
import_node_process3.default.on(import_opticore_catch_exception_error3.CEvent.sigint, () => {
|
|
818
|
+
this.serverListenEvent.processInterrupted();
|
|
819
|
+
});
|
|
820
|
+
import_node_process3.default.on(import_opticore_catch_exception_error3.CEvent.sigterm, (signal) => {
|
|
821
|
+
this.serverListenEvent.sigtermSignalReceived(signal);
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Sets up HTTP server event listeners.
|
|
826
|
+
*
|
|
827
|
+
* @method setupServerEventListeners
|
|
828
|
+
* @private
|
|
829
|
+
*
|
|
830
|
+
* @returns {void}
|
|
831
|
+
*
|
|
832
|
+
* @remarks
|
|
833
|
+
* Configures listeners for:
|
|
834
|
+
* - Server errors
|
|
835
|
+
* - Connection closing
|
|
836
|
+
* - Connection dropping
|
|
837
|
+
* - HTTP requests (for logging)
|
|
838
|
+
*
|
|
839
|
+
* @listens Server#error - Server error events
|
|
840
|
+
* @listens Server#close - Server closing events
|
|
841
|
+
* @listens Server#drop - Connection drop events
|
|
842
|
+
* @listens Server#request - HTTP request events
|
|
843
|
+
*/
|
|
844
|
+
setupServerEventListeners() {
|
|
845
|
+
loaderTranslationFile(this.localLanguage);
|
|
846
|
+
if (!this.server) {
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
610
849
|
this.server.on(import_opticore_catch_exception_error3.CEventNameError.error, (err) => {
|
|
611
850
|
this.serverListenEvent.onEventError(err);
|
|
612
851
|
});
|
|
@@ -629,544 +868,509 @@ var WebServerCore = class {
|
|
|
629
868
|
});
|
|
630
869
|
}
|
|
631
870
|
/**
|
|
632
|
-
*
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
this.fileWatcher.startWatching();
|
|
639
|
-
this.fileWatcher.setHotReload(true);
|
|
640
|
-
SLogger(this.localLanguage).logger.info({
|
|
641
|
-
title: import_opticore_translator2.TranslationLoader.t("WATCHER_INITIALIZED", this.localLanguage),
|
|
642
|
-
message: "File watcher has been initialized successfully"
|
|
643
|
-
});
|
|
644
|
-
} catch (error) {
|
|
645
|
-
SLogger(this.localLanguage).logger.error({
|
|
646
|
-
title: import_opticore_translator2.TranslationLoader.t("WATCHER_INIT_ERROR", this.localLanguage),
|
|
647
|
-
message: `Failed to initialize file watcher: ${error.message}`,
|
|
648
|
-
errorType: "WatcherInitializationError",
|
|
649
|
-
httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
650
|
-
});
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
/**
|
|
654
|
-
* Setup watcher events
|
|
871
|
+
* Sets up error handling middleware and event emitters.
|
|
872
|
+
*
|
|
873
|
+
* @method setupErrorHandling
|
|
874
|
+
* @private
|
|
875
|
+
*
|
|
876
|
+
* @returns {void}
|
|
655
877
|
*/
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
878
|
+
setupErrorHandling() {
|
|
879
|
+
loaderTranslationFile(this.localLanguage);
|
|
880
|
+
SLogger(this.localLanguage).logger.info({
|
|
881
|
+
title: import_opticore_translator2.TranslationLoader.t("SETTING_UP", this.localLanguage),
|
|
882
|
+
message: import_opticore_translator2.TranslationLoader.t("SETTING_UP_ERROR", this.localLanguage)
|
|
883
|
+
});
|
|
884
|
+
this.errorEmitter = eventProcessHandler(this.localLanguage, this.expressApp);
|
|
885
|
+
if (this.errorEmitter) {
|
|
886
|
+
this.expressApp.use((err, req, res, next) => {
|
|
887
|
+
this.serverListenEvent.expressErrorHandlingMiddleware(
|
|
888
|
+
this.errorEmitter,
|
|
889
|
+
err,
|
|
890
|
+
req,
|
|
891
|
+
res,
|
|
892
|
+
next
|
|
893
|
+
);
|
|
664
894
|
});
|
|
665
|
-
this.
|
|
666
|
-
this.
|
|
895
|
+
this.errorEmitter.on("transformError", (error) => {
|
|
896
|
+
this.serverListenEvent.listenerError(error);
|
|
667
897
|
});
|
|
668
|
-
this.
|
|
669
|
-
|
|
670
|
-
title: import_opticore_translator2.TranslationLoader.t("WATCHER_STARTED", this.localLanguage),
|
|
671
|
-
message: import_opticore_translator2.TranslationLoader.t("FILE_WATCHER_ACTIVE", this.localLanguage)
|
|
672
|
-
});
|
|
898
|
+
this.errorEmitter.on("error", (error) => {
|
|
899
|
+
this.serverListenEvent.listenerError(error);
|
|
673
900
|
});
|
|
674
|
-
this.
|
|
901
|
+
this.errorEmitter.on("hotReload", (data) => {
|
|
675
902
|
SLogger(this.localLanguage).logger.info({
|
|
676
|
-
title: import_opticore_translator2.TranslationLoader.t("
|
|
677
|
-
message:
|
|
903
|
+
title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_EVENT", this.localLanguage),
|
|
904
|
+
message: `Hot reload triggered for ${data.file}`
|
|
678
905
|
});
|
|
679
906
|
});
|
|
680
|
-
} catch (error) {
|
|
681
|
-
SLogger(this.localLanguage).logger.error({
|
|
682
|
-
title: import_opticore_translator2.TranslationLoader.t("WATCHER_EVENTS_ERROR", this.localLanguage),
|
|
683
|
-
message: `Failed to setup watcher events: ${error.message}`,
|
|
684
|
-
errorType: "WatcherEventsError",
|
|
685
|
-
httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
686
|
-
});
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
/**
|
|
690
|
-
* Handle file changes detected by watcher
|
|
691
|
-
*/
|
|
692
|
-
handleFileChange(data) {
|
|
693
|
-
const { event: event2, action, requiresReload } = data;
|
|
694
|
-
SLogger(this.localLanguage).logger.info({
|
|
695
|
-
title: import_opticore_translator2.TranslationLoader.t("FILE_CHANGE_HANDLED", this.localLanguage),
|
|
696
|
-
message: import_opticore_translator2.TranslationLoader.t(
|
|
697
|
-
"PROCESSING_FILE_CHANGE",
|
|
698
|
-
this.localLanguage
|
|
699
|
-
).replace(
|
|
700
|
-
"{file}",
|
|
701
|
-
path2.basename(event2.filePath)
|
|
702
|
-
).replace(
|
|
703
|
-
"{action}",
|
|
704
|
-
action
|
|
705
|
-
)
|
|
706
|
-
});
|
|
707
|
-
if (this.errorEmitter) {
|
|
708
|
-
this.errorEmitter.emit("fileChanged", {
|
|
709
|
-
file: event2.filePath,
|
|
710
|
-
type: event2.extension,
|
|
711
|
-
action,
|
|
712
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
713
|
-
});
|
|
714
|
-
}
|
|
715
|
-
switch (action) {
|
|
716
|
-
case "reloadEnvironment":
|
|
717
|
-
this.reloadEnvironmentConfig();
|
|
718
|
-
break;
|
|
719
|
-
case "reloadConfig":
|
|
720
|
-
this.reloadConfigurationFiles();
|
|
721
|
-
break;
|
|
722
|
-
case "reloadRoutes":
|
|
723
|
-
this.reloadApplicationRoutes(event2.filePath);
|
|
724
|
-
break;
|
|
725
|
-
case "reloadDependencies":
|
|
726
|
-
this.reloadDependencies();
|
|
727
|
-
break;
|
|
728
|
-
case "notifyOnly":
|
|
729
|
-
this.notifyFileChange(event2);
|
|
730
|
-
break;
|
|
731
907
|
}
|
|
732
|
-
}
|
|
733
|
-
/**
|
|
734
|
-
* Handle hot reload requested by watcher
|
|
735
|
-
*/
|
|
736
|
-
handleHotReload(data) {
|
|
737
|
-
const { file, type, action } = data;
|
|
738
908
|
SLogger(this.localLanguage).logger.info({
|
|
739
|
-
title: import_opticore_translator2.TranslationLoader.t("
|
|
740
|
-
message: import_opticore_translator2.TranslationLoader.t("
|
|
741
|
-
});
|
|
742
|
-
if (this.errorEmitter) {
|
|
743
|
-
this.errorEmitter.emit("hotReload", {
|
|
744
|
-
file,
|
|
745
|
-
type,
|
|
746
|
-
action,
|
|
747
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
748
|
-
});
|
|
749
|
-
}
|
|
750
|
-
switch (action) {
|
|
751
|
-
case "reloadEnvironment":
|
|
752
|
-
this.executeHotReloadEnvironment(file);
|
|
753
|
-
break;
|
|
754
|
-
case "reloadConfig":
|
|
755
|
-
this.executeHotReloadConfig(file);
|
|
756
|
-
break;
|
|
757
|
-
case "reloadRoutes":
|
|
758
|
-
this.executeHotReloadRoutes(file);
|
|
759
|
-
break;
|
|
760
|
-
case "reloadDependencies":
|
|
761
|
-
this.executeHotReloadDependencies(file);
|
|
762
|
-
break;
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
/**
|
|
766
|
-
* Handle watcher errors
|
|
767
|
-
*/
|
|
768
|
-
handleWatcherError(error) {
|
|
769
|
-
SLogger(this.localLanguage).logger.error({
|
|
770
|
-
title: import_opticore_translator2.TranslationLoader.t("WATCHER_SYSTEM_ERROR", this.localLanguage),
|
|
771
|
-
message: error.message || "Unknown watcher system error",
|
|
772
|
-
errorType: "WatcherSystemError",
|
|
773
|
-
stackTrace: error.stack,
|
|
774
|
-
httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
909
|
+
title: import_opticore_translator2.TranslationLoader.t("ERROR_HANDLING", this.localLanguage),
|
|
910
|
+
message: import_opticore_translator2.TranslationLoader.t("ERROR_HANDLING_CONFIGURED", this.localLanguage)
|
|
775
911
|
});
|
|
776
912
|
}
|
|
777
913
|
/**
|
|
778
|
-
*
|
|
914
|
+
* Registers routes with the Express application.
|
|
915
|
+
*
|
|
916
|
+
* @method registerRoutes
|
|
917
|
+
* @private
|
|
918
|
+
*
|
|
919
|
+
* @param {any[]} allFeatureRoutes - Array of feature routes to register
|
|
920
|
+
*
|
|
921
|
+
* @returns {void}
|
|
779
922
|
*/
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
923
|
+
registerRoutes(allFeatureRoutes) {
|
|
924
|
+
allFeatureRoutes.forEach((router) => {
|
|
925
|
+
if (router.routes) {
|
|
926
|
+
router.routes.forEach((route) => {
|
|
927
|
+
this.expressApp.use(route.path, route.handler);
|
|
928
|
+
});
|
|
929
|
+
}
|
|
784
930
|
});
|
|
785
931
|
}
|
|
786
932
|
/**
|
|
787
|
-
*
|
|
933
|
+
* Displays server information.
|
|
934
|
+
*
|
|
935
|
+
* @method infoWebApp
|
|
936
|
+
* @private
|
|
937
|
+
*
|
|
938
|
+
* @returns {void}
|
|
788
939
|
*/
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
});
|
|
796
|
-
this.notifyEnvironmentReload();
|
|
797
|
-
} catch (error) {
|
|
798
|
-
SLogger(this.localLanguage).logger.error({
|
|
799
|
-
title: import_opticore_translator2.TranslationLoader.t("ENV_RELOAD_FAILED", this.localLanguage),
|
|
800
|
-
message: error.message,
|
|
801
|
-
errorType: "EnvironmentReloadError",
|
|
802
|
-
httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
803
|
-
});
|
|
804
|
-
}
|
|
940
|
+
infoWebApp() {
|
|
941
|
+
loaderTranslationFile(this.localLanguage);
|
|
942
|
+
this.serverUtility.infoServer(
|
|
943
|
+
this.getEnvironment.appHost,
|
|
944
|
+
Number(this.getEnvironment.appPort)
|
|
945
|
+
);
|
|
805
946
|
}
|
|
806
947
|
/**
|
|
807
|
-
*
|
|
948
|
+
* Starts the Hot Module Replacement (HMR) file watching system.
|
|
949
|
+
*
|
|
950
|
+
* @method startHMR
|
|
951
|
+
* @private
|
|
952
|
+
*
|
|
953
|
+
* @returns {void}
|
|
954
|
+
*
|
|
955
|
+
* @remarks
|
|
956
|
+
* Configures file watcher based on environment variables:
|
|
957
|
+
* - HMR_ENABLED: Enable/disable HMR
|
|
958
|
+
* - HMR_WATCH_PATTERNS: Files to watch
|
|
959
|
+
* - HMR_IGNORE_PATTERNS: Files to ignore
|
|
960
|
+
*
|
|
961
|
+
* @throws {Error} If HMR configuration is invalid
|
|
808
962
|
*/
|
|
809
|
-
|
|
963
|
+
startHMR() {
|
|
810
964
|
try {
|
|
811
|
-
const newEnv = (0, import_opticore_env_access2.getEnvironnementValue)(this.environmentPath);
|
|
812
|
-
Object.keys(newEnv).forEach((key) => {
|
|
813
|
-
this.getEnvironment[key] = newEnv[key];
|
|
814
|
-
});
|
|
815
965
|
loaderTranslationFile(this.localLanguage);
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
966
|
+
const hmrConfig = this.getEnvironment;
|
|
967
|
+
if (!hmrConfig.hmrEnabled) {
|
|
968
|
+
SLogger(this.localLanguage).logger.info({
|
|
969
|
+
title: import_opticore_translator2.TranslationLoader.t("HMR_DISABLED", this.localLanguage),
|
|
970
|
+
message: "HMR is disabled in configuration"
|
|
971
|
+
});
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
if (!hmrConfig.hmrWatchPatterns || hmrConfig.hmrWatchPatterns.length === 0) {
|
|
975
|
+
SLogger(this.localLanguage).logger.error({
|
|
976
|
+
title: import_opticore_translator2.TranslationLoader.t("HMR_WATCH_PATTERNS_MISSING", this.localLanguage),
|
|
977
|
+
message: "No watch patterns defined for HMR",
|
|
978
|
+
errorType: "HMR Configuration Error",
|
|
979
|
+
httpCodeValue: import_opticore_http_response3.HttpStatusCode.BAD_REQUEST
|
|
980
|
+
});
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
const watchPatterns = hmrConfig.hmrWatchPatterns;
|
|
984
|
+
const ignorePatterns = hmrConfig.hmrIgnorePatterns || [
|
|
985
|
+
"node_modules/**",
|
|
986
|
+
"dist/**",
|
|
987
|
+
"build/**",
|
|
988
|
+
"*.log",
|
|
989
|
+
".git/**"
|
|
990
|
+
];
|
|
991
|
+
const allPatterns = [
|
|
992
|
+
...watchPatterns,
|
|
993
|
+
...ignorePatterns.map((pattern) => `!${pattern}`)
|
|
994
|
+
];
|
|
995
|
+
this.fileWatcher = import_chokidar.default.watch(allPatterns, {
|
|
996
|
+
ignored: /(^|[/\\])\../,
|
|
997
|
+
persistent: true,
|
|
998
|
+
ignoreInitial: true,
|
|
999
|
+
awaitWriteFinish: {
|
|
1000
|
+
stabilityThreshold: 300,
|
|
1001
|
+
pollInterval: 100
|
|
1002
|
+
},
|
|
1003
|
+
cwd: import_node_process3.default.cwd(),
|
|
1004
|
+
depth: 10
|
|
826
1005
|
});
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
* Reload configuration files
|
|
831
|
-
*/
|
|
832
|
-
reloadConfigurationFiles() {
|
|
833
|
-
try {
|
|
834
|
-
loaderTranslationFile(this.localLanguage);
|
|
1006
|
+
this.fileWatcher.on("ready", () => this.onHMRWatcherReady(watchPatterns, ignorePatterns)).on("change", (filePath) => this.handleFileChange(filePath)).on("add", (filePath) => this.handleFileChange(filePath, "added")).on("unlink", (filePath) => this.handleFileChange(filePath, "deleted")).on("error", (error) => this.onHMRWatcherError(error));
|
|
1007
|
+
this.hmrRestartCount = 0;
|
|
1008
|
+
this.lastHmrRestartTime = Date.now();
|
|
835
1009
|
SLogger(this.localLanguage).logger.info({
|
|
836
|
-
title: import_opticore_translator2.TranslationLoader.t("
|
|
837
|
-
message: import_opticore_translator2.TranslationLoader.t("
|
|
1010
|
+
title: import_opticore_translator2.TranslationLoader.t("HMR_STARTED", this.localLanguage),
|
|
1011
|
+
message: import_opticore_translator2.TranslationLoader.t("HMR_MONITORING_STARTED", this.localLanguage)
|
|
838
1012
|
});
|
|
839
1013
|
} catch (error) {
|
|
840
1014
|
SLogger(this.localLanguage).logger.error({
|
|
841
|
-
title: import_opticore_translator2.TranslationLoader.t("
|
|
1015
|
+
title: import_opticore_translator2.TranslationLoader.t("HMR_START_FAILED", this.localLanguage),
|
|
842
1016
|
message: error.message,
|
|
843
|
-
errorType: "
|
|
844
|
-
|
|
1017
|
+
errorType: "HMR Error",
|
|
1018
|
+
stackTrace: error.stack
|
|
845
1019
|
});
|
|
846
1020
|
}
|
|
847
1021
|
}
|
|
848
1022
|
/**
|
|
849
|
-
*
|
|
1023
|
+
* Handles file change events with debouncing.
|
|
1024
|
+
*
|
|
1025
|
+
* @method handleFileChange
|
|
1026
|
+
* @private
|
|
1027
|
+
*
|
|
1028
|
+
* @param {string} filePath - Path of the changed file
|
|
1029
|
+
* @param {string} [action="modified"] - Type of file change (modified/added/deleted)
|
|
1030
|
+
*
|
|
1031
|
+
* @returns {void}
|
|
1032
|
+
*
|
|
1033
|
+
* @remarks
|
|
1034
|
+
* Uses debouncing to prevent multiple rapid reloads.
|
|
1035
|
+
* Debounce time configurable via HMR_DEBOUNCE_MS environment variable.
|
|
850
1036
|
*/
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
SLogger(this.localLanguage).logger.info({
|
|
856
|
-
title: import_opticore_translator2.TranslationLoader.t("TRANSLATIONS_RELOADED", this.localLanguage),
|
|
857
|
-
message: import_opticore_translator2.TranslationLoader.t("TRANSLATIONS_HOT_RELOAD_COMPLETE", this.localLanguage).replace("{file}", path2.basename(filePath))
|
|
858
|
-
});
|
|
859
|
-
}
|
|
860
|
-
} catch (error) {
|
|
861
|
-
SLogger(this.localLanguage).logger.error({
|
|
862
|
-
title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_CONFIG_FAILED", this.localLanguage),
|
|
863
|
-
message: error.message,
|
|
864
|
-
errorType: "HotReloadConfigError",
|
|
865
|
-
httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
866
|
-
});
|
|
1037
|
+
handleFileChange(filePath, action = "modified") {
|
|
1038
|
+
const debounceMs = this.getEnvironment.hmrDebounceMs || 500;
|
|
1039
|
+
if (this.hmrDebounceTimeout) {
|
|
1040
|
+
clearTimeout(this.hmrDebounceTimeout);
|
|
867
1041
|
}
|
|
1042
|
+
this.hmrDebounceTimeout = setTimeout(async () => {
|
|
1043
|
+
await this.triggerHotReload(filePath, action);
|
|
1044
|
+
}, debounceMs);
|
|
1045
|
+
SLogger(this.localLanguage).logger.info({
|
|
1046
|
+
title: import_opticore_translator2.TranslationLoader.t("FILE_CHANGE_DETECTED", this.localLanguage),
|
|
1047
|
+
message: `File ${action}: ${filePath}`
|
|
1048
|
+
});
|
|
868
1049
|
}
|
|
869
1050
|
/**
|
|
870
|
-
*
|
|
1051
|
+
* Triggers a hot reload operation.
|
|
1052
|
+
*
|
|
1053
|
+
* @method triggerHotReload
|
|
1054
|
+
* @private
|
|
1055
|
+
*
|
|
1056
|
+
* @param {string} filePath - Path of the changed file
|
|
1057
|
+
* @param {string} action - Type of file change
|
|
1058
|
+
*
|
|
1059
|
+
* @returns {Promise<void>}
|
|
1060
|
+
*
|
|
1061
|
+
* @remarks
|
|
1062
|
+
* - Checks if reload is already in progress
|
|
1063
|
+
* - Validates restart limits
|
|
1064
|
+
* - Performs appropriate reload actions based on file type
|
|
1065
|
+
* - Emits hotReload event
|
|
871
1066
|
*/
|
|
872
|
-
|
|
1067
|
+
async triggerHotReload(filePath, action) {
|
|
1068
|
+
if (this.hmrRestartPending) {
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
if (!this.canProceedWithHMRRestart()) {
|
|
1072
|
+
return;
|
|
1073
|
+
}
|
|
1074
|
+
this.hmrRestartPending = true;
|
|
1075
|
+
this.hmrRestartCount++;
|
|
1076
|
+
this.lastHmrRestartTime = Date.now();
|
|
873
1077
|
try {
|
|
1078
|
+
loaderTranslationFile(this.localLanguage);
|
|
874
1079
|
SLogger(this.localLanguage).logger.info({
|
|
875
|
-
title: import_opticore_translator2.TranslationLoader.t("
|
|
876
|
-
message: import_opticore_translator2.TranslationLoader.t("
|
|
1080
|
+
title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_STARTING", this.localLanguage),
|
|
1081
|
+
message: import_opticore_translator2.TranslationLoader.t("RELOADING_APPLICATION", this.localLanguage, {
|
|
1082
|
+
file: filePath,
|
|
1083
|
+
action
|
|
1084
|
+
})
|
|
877
1085
|
});
|
|
878
|
-
if (filePath.includes("routes") || filePath.includes("controller")) {
|
|
879
|
-
this.reloadSpecificRoute(filePath);
|
|
880
|
-
}
|
|
881
1086
|
if (this.errorEmitter) {
|
|
882
|
-
this.errorEmitter.emit("
|
|
883
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
1087
|
+
this.errorEmitter.emit("hotReload", {
|
|
884
1088
|
file: filePath,
|
|
885
|
-
|
|
1089
|
+
action,
|
|
1090
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1091
|
+
restartCount: this.hmrRestartCount
|
|
886
1092
|
});
|
|
887
1093
|
}
|
|
888
|
-
|
|
889
|
-
SLogger(this.localLanguage).logger.
|
|
890
|
-
title: import_opticore_translator2.TranslationLoader.t("
|
|
891
|
-
message:
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
}
|
|
897
|
-
/**
|
|
898
|
-
* Execute hot reload for routes
|
|
899
|
-
*/
|
|
900
|
-
executeHotReloadRoutes(filePath) {
|
|
901
|
-
try {
|
|
902
|
-
SLogger(this.localLanguage).logger.info({
|
|
903
|
-
title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_ROUTES_START", this.localLanguage),
|
|
904
|
-
message: import_opticore_translator2.TranslationLoader.t("ROUTES_HOT_RELOADING", this.localLanguage).replace("{file}", path2.basename(filePath))
|
|
905
|
-
});
|
|
906
|
-
this.reloadRouterForFile(filePath);
|
|
907
|
-
SLogger(this.localLanguage).logger.info({
|
|
908
|
-
title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_ROUTES_SUCCESS", this.localLanguage),
|
|
909
|
-
message: import_opticore_translator2.TranslationLoader.t("ROUTES_HOT_RELOAD_COMPLETE", this.localLanguage)
|
|
1094
|
+
await this.performHotReloadActions(filePath);
|
|
1095
|
+
SLogger(this.localLanguage).logger.success({
|
|
1096
|
+
title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_COMPLETE", this.localLanguage),
|
|
1097
|
+
message: import_opticore_translator2.TranslationLoader.t("APPLICATION_RELOADED", this.localLanguage, {
|
|
1098
|
+
file: filePath,
|
|
1099
|
+
restartCount: this.hmrRestartCount,
|
|
1100
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1101
|
+
})
|
|
910
1102
|
});
|
|
911
1103
|
} catch (error) {
|
|
912
1104
|
SLogger(this.localLanguage).logger.error({
|
|
913
|
-
title: import_opticore_translator2.TranslationLoader.t("
|
|
1105
|
+
title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_FAILED", this.localLanguage),
|
|
914
1106
|
message: error.message,
|
|
915
|
-
errorType: "
|
|
1107
|
+
errorType: "HotReloadError",
|
|
1108
|
+
stackTrace: error.stack,
|
|
916
1109
|
httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
917
1110
|
});
|
|
1111
|
+
} finally {
|
|
1112
|
+
this.hmrRestartPending = false;
|
|
918
1113
|
}
|
|
919
1114
|
}
|
|
920
1115
|
/**
|
|
921
|
-
*
|
|
1116
|
+
* Performs appropriate hot reload actions based on file type.
|
|
1117
|
+
*
|
|
1118
|
+
* @method performHotReloadActions
|
|
1119
|
+
* @private
|
|
1120
|
+
*
|
|
1121
|
+
* @param {string} filePath - Path of the changed file
|
|
1122
|
+
*
|
|
1123
|
+
* @returns {Promise<void>}
|
|
1124
|
+
*
|
|
1125
|
+
* @remarks
|
|
1126
|
+
* Different actions for different file types:
|
|
1127
|
+
* - .json/.env: Reload translations
|
|
1128
|
+
* - routes/controller files: Reload routes
|
|
1129
|
+
* - config/.env files: Reload dependencies
|
|
922
1130
|
*/
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_DEPS_START", this.localLanguage),
|
|
927
|
-
message: import_opticore_translator2.TranslationLoader.t(
|
|
928
|
-
"DEPENDENCIES_HOT_RELOADING",
|
|
929
|
-
this.localLanguage
|
|
930
|
-
).replace("{file}", path2.basename(filePath))
|
|
931
|
-
});
|
|
932
|
-
this.reloadDependencies();
|
|
933
|
-
SLogger(this.localLanguage).logger.info({
|
|
934
|
-
title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_DEPS_SUCCESS", this.localLanguage),
|
|
935
|
-
message: import_opticore_translator2.TranslationLoader.t("DEPENDENCIES_HOT_RELOAD_COMPLETE", this.localLanguage)
|
|
936
|
-
});
|
|
937
|
-
} catch (error) {
|
|
938
|
-
SLogger(this.localLanguage).logger.error({
|
|
939
|
-
title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_DEPS_FAILED", this.localLanguage),
|
|
940
|
-
message: error.message,
|
|
941
|
-
errorType: "HotReloadDependenciesError",
|
|
942
|
-
httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
943
|
-
});
|
|
1131
|
+
async performHotReloadActions(filePath) {
|
|
1132
|
+
if (filePath.includes(".json") || filePath.endsWith(".env")) {
|
|
1133
|
+
loaderTranslationFile(this.localLanguage);
|
|
944
1134
|
}
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
if (this.errorEmitter) {
|
|
951
|
-
this.errorEmitter.emit("environmentReloaded", {
|
|
952
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
953
|
-
environment: this.getEnvironment
|
|
954
|
-
});
|
|
1135
|
+
if (filePath.includes("routes") || filePath.includes("controller")) {
|
|
1136
|
+
await this.reloadRoutes();
|
|
1137
|
+
}
|
|
1138
|
+
if (filePath.includes("config") || filePath.includes(".env")) {
|
|
1139
|
+
await this.reloadDependencies();
|
|
955
1140
|
}
|
|
956
1141
|
}
|
|
957
1142
|
/**
|
|
958
|
-
*
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
*
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
SLogger(this.localLanguage).logger.info({
|
|
971
|
-
title: "Router Reload",
|
|
972
|
-
message: `Reloading router for file: ${filePath}`
|
|
973
|
-
});
|
|
974
|
-
}
|
|
975
|
-
/**
|
|
976
|
-
* Reload configurations
|
|
1143
|
+
* Reloads routes dynamically.
|
|
1144
|
+
*
|
|
1145
|
+
* @method reloadRoutes
|
|
1146
|
+
* @private
|
|
1147
|
+
*
|
|
1148
|
+
* @returns {Promise<void>}
|
|
1149
|
+
*
|
|
1150
|
+
* @throws {Error} If route reloading fails
|
|
1151
|
+
*
|
|
1152
|
+
* @remarks
|
|
1153
|
+
* This method should be implemented based on your architecture.
|
|
1154
|
+
* It should reload route modules from the filesystem.
|
|
977
1155
|
*/
|
|
978
|
-
|
|
1156
|
+
async reloadRoutes() {
|
|
979
1157
|
try {
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
1158
|
+
SLogger(this.localLanguage).logger.info({
|
|
1159
|
+
title: import_opticore_translator2.TranslationLoader.t("ROUTES_RELOADED", this.localLanguage),
|
|
1160
|
+
message: "Routes dynamically reloaded"
|
|
983
1161
|
});
|
|
984
|
-
loaderTranslationFile(this.localLanguage);
|
|
985
1162
|
} catch (error) {
|
|
986
|
-
throw new Error(`
|
|
1163
|
+
throw new Error(`Route reload failed: ${error.message}`);
|
|
987
1164
|
}
|
|
988
1165
|
}
|
|
989
1166
|
/**
|
|
990
|
-
*
|
|
1167
|
+
* Reloads dependencies dynamically.
|
|
1168
|
+
*
|
|
1169
|
+
* @method reloadDependencies
|
|
1170
|
+
* @private
|
|
1171
|
+
*
|
|
1172
|
+
* @returns {Promise<void>}
|
|
1173
|
+
*
|
|
1174
|
+
* @throws {Error} If dependency reloading fails
|
|
991
1175
|
*/
|
|
992
|
-
reloadDependencies() {
|
|
1176
|
+
async reloadDependencies() {
|
|
993
1177
|
try {
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1178
|
+
if (this.currentDependencies.length > 0) {
|
|
1179
|
+
new import_opticore_dependency_inject2.SContainer(this.localLanguage, this.currentDependencies);
|
|
1180
|
+
SLogger(this.localLanguage).logger.info({
|
|
1181
|
+
title: import_opticore_translator2.TranslationLoader.t("DEPENDENCIES_RELOADED", this.localLanguage),
|
|
1182
|
+
message: "Dependencies reloaded"
|
|
1183
|
+
});
|
|
998
1184
|
}
|
|
999
1185
|
} catch (error) {
|
|
1000
1186
|
throw new Error(`Dependency reload failed: ${error.message}`);
|
|
1001
1187
|
}
|
|
1002
1188
|
}
|
|
1003
1189
|
/**
|
|
1004
|
-
*
|
|
1190
|
+
* Checks if HMR restart can proceed based on configuration limits.
|
|
1191
|
+
*
|
|
1192
|
+
* @method canProceedWithHMRRestart
|
|
1193
|
+
* @private
|
|
1194
|
+
*
|
|
1195
|
+
* @returns {boolean} True if restart can proceed, false otherwise
|
|
1196
|
+
*
|
|
1197
|
+
* @remarks
|
|
1198
|
+
* Checks:
|
|
1199
|
+
* - Auto-restart enabled/disabled
|
|
1200
|
+
* - Maximum restarts per minute limit
|
|
1005
1201
|
*/
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1202
|
+
canProceedWithHMRRestart() {
|
|
1203
|
+
const hmrConfig = this.getEnvironment;
|
|
1204
|
+
if (!hmrConfig.hmrAutoRestarts) {
|
|
1205
|
+
SLogger(this.localLanguage).logger.warn({
|
|
1206
|
+
title: import_opticore_translator2.TranslationLoader.t("HMR_AUTO_RESTART_DISABLED", this.localLanguage),
|
|
1207
|
+
message: "HMR auto-restart disabled"
|
|
1208
|
+
});
|
|
1209
|
+
return false;
|
|
1210
|
+
}
|
|
1211
|
+
const maxRestarts = hmrConfig.hmrMaxRestarts || 5;
|
|
1212
|
+
const now = Date.now();
|
|
1213
|
+
const oneMinuteAgo = now - 6e4;
|
|
1214
|
+
if (this.lastHmrRestartTime < oneMinuteAgo) {
|
|
1215
|
+
this.hmrRestartCount = 0;
|
|
1216
|
+
}
|
|
1217
|
+
if (this.hmrRestartCount >= maxRestarts) {
|
|
1218
|
+
const nextReset = Math.ceil((this.lastHmrRestartTime + 6e4 - now) / 1e3);
|
|
1219
|
+
SLogger(this.localLanguage).logger.error({
|
|
1220
|
+
title: import_opticore_translator2.TranslationLoader.t("HMR_RESTART_LIMIT_EXCEEDED", this.localLanguage),
|
|
1221
|
+
message: import_opticore_translator2.TranslationLoader.t("HMR_RESTART_LIMIT_MESSAGE", this.localLanguage, {
|
|
1222
|
+
max: maxRestarts,
|
|
1223
|
+
nextReset
|
|
1224
|
+
})
|
|
1225
|
+
});
|
|
1226
|
+
return false;
|
|
1227
|
+
}
|
|
1228
|
+
return true;
|
|
1014
1229
|
}
|
|
1015
1230
|
/**
|
|
1016
|
-
*
|
|
1231
|
+
* Called when the HMR watcher is ready.
|
|
1232
|
+
*
|
|
1233
|
+
* @method onHMRWatcherReady
|
|
1234
|
+
* @private
|
|
1235
|
+
*
|
|
1236
|
+
* @param {string[]} watchPatterns - Patterns being watched
|
|
1237
|
+
* @param {string[]} ignorePatterns - Patterns being ignored
|
|
1238
|
+
*
|
|
1239
|
+
* @returns {void}
|
|
1017
1240
|
*/
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
const column = fileMatch ? parseInt(fileMatch[3], 10) : null;
|
|
1027
|
-
const errorDetailMatch = errorMessage.match(/ERROR:\s*(.+?)(?:\n|$)/);
|
|
1028
|
-
const errorDetail = errorDetailMatch ? errorDetailMatch[1].trim() : null;
|
|
1029
|
-
return {
|
|
1030
|
-
message: errorMessage,
|
|
1031
|
-
file,
|
|
1032
|
-
line,
|
|
1033
|
-
column,
|
|
1034
|
-
errorDetail,
|
|
1035
|
-
tool
|
|
1036
|
-
};
|
|
1241
|
+
onHMRWatcherReady(watchPatterns, ignorePatterns) {
|
|
1242
|
+
SLogger(this.localLanguage).logger.info({
|
|
1243
|
+
title: import_opticore_translator2.TranslationLoader.t("HMR_WATCHER_READY", this.localLanguage),
|
|
1244
|
+
message: import_opticore_translator2.TranslationLoader.t("HMR_WATCHING_DETAILS", this.localLanguage, {
|
|
1245
|
+
watchCount: watchPatterns,
|
|
1246
|
+
ignoreCount: ignorePatterns
|
|
1247
|
+
})
|
|
1248
|
+
});
|
|
1037
1249
|
}
|
|
1038
1250
|
/**
|
|
1039
|
-
*
|
|
1251
|
+
* Handles HMR watcher errors.
|
|
1252
|
+
*
|
|
1253
|
+
* @method onHMRWatcherError
|
|
1254
|
+
* @private
|
|
1255
|
+
*
|
|
1256
|
+
* @param {Error} error - The watcher error
|
|
1257
|
+
*
|
|
1258
|
+
* @returns {void}
|
|
1040
1259
|
*/
|
|
1041
|
-
|
|
1042
|
-
this.
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1260
|
+
onHMRWatcherError(error) {
|
|
1261
|
+
SLogger(this.localLanguage).logger.error({
|
|
1262
|
+
title: import_opticore_translator2.TranslationLoader.t("HMR_WATCHER_ERROR", this.localLanguage),
|
|
1263
|
+
message: error.message,
|
|
1264
|
+
errorType: "FileWatcherError",
|
|
1265
|
+
stackTrace: error.stack
|
|
1266
|
+
});
|
|
1046
1267
|
}
|
|
1047
1268
|
/**
|
|
1048
|
-
*
|
|
1269
|
+
* Stops the HMR system.
|
|
1270
|
+
*
|
|
1271
|
+
* @method stopHMR
|
|
1272
|
+
* @private
|
|
1273
|
+
*
|
|
1274
|
+
* @returns {void}
|
|
1049
1275
|
*/
|
|
1050
|
-
|
|
1276
|
+
stopHMR() {
|
|
1051
1277
|
if (this.fileWatcher) {
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
SLogger(this.localLanguage).logger.info({
|
|
1055
|
-
title: import_opticore_translator2.TranslationLoader.t("WATCHER_STOPPED", this.localLanguage),
|
|
1056
|
-
message: import_opticore_translator2.TranslationLoader.t("FILE_WATCHER_STOPPED_GRACEFULLY", this.localLanguage)
|
|
1057
|
-
});
|
|
1058
|
-
} catch (error) {
|
|
1059
|
-
SLogger(this.localLanguage).logger.error({
|
|
1060
|
-
title: import_opticore_translator2.TranslationLoader.t("WATCHER_STOP_ERROR", this.localLanguage),
|
|
1061
|
-
message: `Error stopping watcher: ${error.message}`,
|
|
1062
|
-
errorType: "WatcherStopError",
|
|
1063
|
-
httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
1064
|
-
});
|
|
1065
|
-
} finally {
|
|
1066
|
-
this.fileWatcher = void 0;
|
|
1067
|
-
}
|
|
1278
|
+
this.fileWatcher.close();
|
|
1279
|
+
this.fileWatcher = null;
|
|
1068
1280
|
}
|
|
1281
|
+
if (this.hmrDebounceTimeout) {
|
|
1282
|
+
clearTimeout(this.hmrDebounceTimeout);
|
|
1283
|
+
this.hmrDebounceTimeout = null;
|
|
1284
|
+
}
|
|
1285
|
+
SLogger(this.localLanguage).logger.info({
|
|
1286
|
+
title: import_opticore_translator2.TranslationLoader.t("HMR_STOPPED", this.localLanguage),
|
|
1287
|
+
message: import_opticore_translator2.TranslationLoader.t("HMR_MONITORING_STOPPED", this.localLanguage)
|
|
1288
|
+
});
|
|
1069
1289
|
}
|
|
1070
1290
|
/**
|
|
1071
|
-
*
|
|
1291
|
+
* Stops the server and HMR system cleanly.
|
|
1292
|
+
*
|
|
1293
|
+
* @method onStopServer
|
|
1294
|
+
* @public
|
|
1295
|
+
*
|
|
1296
|
+
* @returns {void}
|
|
1072
1297
|
*/
|
|
1073
|
-
|
|
1074
|
-
this.
|
|
1298
|
+
onStopServer() {
|
|
1299
|
+
this.stopHMR();
|
|
1075
1300
|
if (this.server) {
|
|
1076
1301
|
this.server.close(() => {
|
|
1077
1302
|
SLogger(this.localLanguage).logger.info({
|
|
1078
|
-
title: import_opticore_translator2.TranslationLoader.t("
|
|
1079
|
-
message:
|
|
1303
|
+
title: import_opticore_translator2.TranslationLoader.t("SERVER_STOPPED", this.localLanguage),
|
|
1304
|
+
message: "Server stopped cleanly"
|
|
1080
1305
|
});
|
|
1081
|
-
import_node_process3.default.exit(0);
|
|
1082
1306
|
});
|
|
1083
|
-
|
|
1084
|
-
SLogger(this.localLanguage).logger.error({
|
|
1085
|
-
title: import_opticore_translator2.TranslationLoader.t("FORCE_SHUTDOWN", this.localLanguage),
|
|
1086
|
-
message: import_opticore_translator2.TranslationLoader.t("SERVER_FORCE_SHUTDOWN", this.localLanguage)
|
|
1087
|
-
});
|
|
1088
|
-
import_node_process3.default.exit(1);
|
|
1089
|
-
}, 5e3);
|
|
1090
|
-
} else {
|
|
1091
|
-
import_node_process3.default.exit(0);
|
|
1092
|
-
}
|
|
1093
|
-
}
|
|
1094
|
-
/**
|
|
1095
|
-
* Enable/disable watcher
|
|
1096
|
-
*/
|
|
1097
|
-
setWatcherEnabled(enabled) {
|
|
1098
|
-
this.isWatcherEnabled = enabled;
|
|
1099
|
-
if (enabled && !this.fileWatcher) {
|
|
1100
|
-
this.initializeFileWatcher();
|
|
1101
|
-
} else if (!enabled && this.fileWatcher) {
|
|
1102
|
-
this.stopFileWatcher();
|
|
1307
|
+
this.serverStatus = "STOPPED";
|
|
1103
1308
|
}
|
|
1104
|
-
SLogger(this.localLanguage).logger.info({
|
|
1105
|
-
title: "Watcher Status",
|
|
1106
|
-
message: `File watcher ${enabled ? "enabled" : "disabled"}`
|
|
1107
|
-
});
|
|
1108
|
-
}
|
|
1109
|
-
/**
|
|
1110
|
-
* Get watcher status
|
|
1111
|
-
*/
|
|
1112
|
-
getWatcherStatus() {
|
|
1113
|
-
return {
|
|
1114
|
-
enabled: this.isWatcherEnabled,
|
|
1115
|
-
active: this.fileWatcher !== void 0
|
|
1116
|
-
};
|
|
1117
1309
|
}
|
|
1118
1310
|
/**
|
|
1119
|
-
*
|
|
1311
|
+
* Gets the current server state information.
|
|
1312
|
+
*
|
|
1313
|
+
* @method getServerState
|
|
1314
|
+
* @public
|
|
1315
|
+
*
|
|
1316
|
+
* @returns {IServerStateInfo} Server state information object
|
|
1317
|
+
*
|
|
1318
|
+
* @remarks
|
|
1319
|
+
* Includes:
|
|
1320
|
+
* - Status, host, port
|
|
1321
|
+
* - Route and dependency counts
|
|
1322
|
+
* - Uptime and memory usage
|
|
1323
|
+
* - HMR configuration and statistics
|
|
1120
1324
|
*/
|
|
1121
1325
|
getServerState() {
|
|
1122
1326
|
const now = /* @__PURE__ */ new Date();
|
|
1123
1327
|
const uptime = this.serverStartTime ? now.getTime() - this.serverStartTime.getTime() : 0;
|
|
1124
|
-
const formatUptime = (ms) => {
|
|
1125
|
-
const seconds = Math.floor(ms / 1e3);
|
|
1126
|
-
const minutes = Math.floor(seconds / 60);
|
|
1127
|
-
const hours = Math.floor(minutes / 60);
|
|
1128
|
-
const days = Math.floor(hours / 24);
|
|
1129
|
-
if (days > 0) return `${days}j ${hours % 24}h ${minutes % 60}m`;
|
|
1130
|
-
if (hours > 0) return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
|
|
1131
|
-
if (minutes > 0) return `${minutes}m ${seconds % 60}s`;
|
|
1132
|
-
return `${seconds}s`;
|
|
1133
|
-
};
|
|
1134
|
-
const memory = import_node_process3.default.memoryUsage();
|
|
1135
1328
|
return {
|
|
1136
1329
|
status: this.serverStatus,
|
|
1137
|
-
isRunning: this.server !== void 0,
|
|
1330
|
+
isRunning: this.server !== void 0 && this.serverStatus === "READY",
|
|
1138
1331
|
host: this.getEnvironment.appHost,
|
|
1139
1332
|
port: Number(this.getEnvironment.appPort),
|
|
1140
1333
|
language: this.localLanguage,
|
|
1141
|
-
watcherEnabled: this.isWatcherEnabled,
|
|
1142
|
-
watcherActive: this.fileWatcher !== void 0,
|
|
1143
1334
|
routesCount: this.currentRoutes.length,
|
|
1144
1335
|
dependenciesCount: this.currentDependencies.length,
|
|
1145
1336
|
startTime: this.serverStartTime,
|
|
1146
1337
|
currentTime: now,
|
|
1147
1338
|
uptime,
|
|
1148
|
-
uptimeFormatted: formatUptime(uptime),
|
|
1149
|
-
memoryUsage:
|
|
1150
|
-
rss: memory.rss,
|
|
1151
|
-
heapTotal: memory.heapTotal,
|
|
1152
|
-
heapUsed: memory.heapUsed,
|
|
1153
|
-
external: memory.external,
|
|
1154
|
-
arrayBuffers: memory.arrayBuffers
|
|
1155
|
-
},
|
|
1339
|
+
uptimeFormatted: this.formatUptime(uptime),
|
|
1340
|
+
memoryUsage: import_node_process3.default.memoryUsage(),
|
|
1156
1341
|
pid: import_node_process3.default.pid,
|
|
1157
1342
|
platform: import_node_process3.default.platform,
|
|
1158
1343
|
nodeVersion: import_node_process3.default.version,
|
|
1159
|
-
cwd: import_node_process3.default.cwd()
|
|
1344
|
+
cwd: import_node_process3.default.cwd(),
|
|
1345
|
+
hmrEnabled: this.getEnvironment.hmrEnabled,
|
|
1346
|
+
hmrWatchingFiles: this.getEnvironment.hmrWatchPatterns?.length || 0,
|
|
1347
|
+
hmrRestartCount: this.hmrRestartCount
|
|
1160
1348
|
};
|
|
1161
1349
|
}
|
|
1162
1350
|
/**
|
|
1163
|
-
*
|
|
1351
|
+
* Gets the current server status.
|
|
1352
|
+
*
|
|
1353
|
+
* @method getServerStatus
|
|
1354
|
+
* @public
|
|
1355
|
+
*
|
|
1356
|
+
* @returns {TServerStatus} Current server status
|
|
1164
1357
|
*/
|
|
1165
1358
|
getServerStatus() {
|
|
1166
1359
|
return this.serverStatus;
|
|
1167
1360
|
}
|
|
1168
1361
|
/**
|
|
1169
|
-
*
|
|
1362
|
+
* Gets detailed server statistics.
|
|
1363
|
+
*
|
|
1364
|
+
* @method getServerStats
|
|
1365
|
+
* @public
|
|
1366
|
+
*
|
|
1367
|
+
* @returns {IServerStats} Server statistics object
|
|
1368
|
+
*
|
|
1369
|
+
* @remarks
|
|
1370
|
+
* Includes:
|
|
1371
|
+
* - Performance metrics (CPU, memory)
|
|
1372
|
+
* - Uptime information
|
|
1373
|
+
* - HMR statistics
|
|
1170
1374
|
*/
|
|
1171
1375
|
getServerStats() {
|
|
1172
1376
|
const uptime = this.serverStartTime ? Date.now() - this.serverStartTime.getTime() : 0;
|
|
@@ -1183,24 +1387,27 @@ var WebServerCore = class {
|
|
|
1183
1387
|
performance: {
|
|
1184
1388
|
cpuUsage: import_node_process3.default.cpuUsage(),
|
|
1185
1389
|
resourceUsage: import_node_process3.default.resourceUsage?.()
|
|
1390
|
+
},
|
|
1391
|
+
hmrStats: {
|
|
1392
|
+
enabled: this.getEnvironment.hmrEnabled,
|
|
1393
|
+
restartCount: this.hmrRestartCount,
|
|
1394
|
+
lastRestartTime: this.lastHmrRestartTime,
|
|
1395
|
+
watchingFiles: this.getEnvironment.hmrWatchPatterns?.length || 0
|
|
1186
1396
|
}
|
|
1187
1397
|
};
|
|
1188
1398
|
}
|
|
1189
1399
|
/**
|
|
1190
|
-
*
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
}
|
|
1202
|
-
/**
|
|
1203
|
-
* Format uptime to human readable string
|
|
1400
|
+
* Formats milliseconds into a human-readable uptime string.
|
|
1401
|
+
*
|
|
1402
|
+
* @method formatUptime
|
|
1403
|
+
* @private
|
|
1404
|
+
*
|
|
1405
|
+
* @param {number} ms - Milliseconds to format
|
|
1406
|
+
*
|
|
1407
|
+
* @returns {string} Formatted uptime string
|
|
1408
|
+
*
|
|
1409
|
+
* @example
|
|
1410
|
+
* formatUptime(3661000) // returns "1h 1m 1s"
|
|
1204
1411
|
*/
|
|
1205
1412
|
formatUptime(ms) {
|
|
1206
1413
|
const seconds = Math.floor(ms / 1e3);
|
|
@@ -1208,7 +1415,7 @@ var WebServerCore = class {
|
|
|
1208
1415
|
const hours = Math.floor(minutes / 60);
|
|
1209
1416
|
const days = Math.floor(hours / 24);
|
|
1210
1417
|
if (days > 0) {
|
|
1211
|
-
return `${days}
|
|
1418
|
+
return `${days}d ${hours % 24}h ${minutes % 60}m`;
|
|
1212
1419
|
} else if (hours > 0) {
|
|
1213
1420
|
return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
|
|
1214
1421
|
} else if (minutes > 0) {
|
|
@@ -1218,55 +1425,66 @@ var WebServerCore = class {
|
|
|
1218
1425
|
}
|
|
1219
1426
|
}
|
|
1220
1427
|
/**
|
|
1221
|
-
*
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
*
|
|
1428
|
+
* Formats bytes into a human-readable size string.
|
|
1429
|
+
*
|
|
1430
|
+
* @method formatBytes
|
|
1431
|
+
* @private
|
|
1432
|
+
*
|
|
1433
|
+
* @param {number} bytes - Bytes to format
|
|
1434
|
+
*
|
|
1435
|
+
* @returns {string} Formatted size string
|
|
1436
|
+
*
|
|
1437
|
+
* @example
|
|
1438
|
+
* formatBytes(1048576) // returns "1.00 MB"
|
|
1230
1439
|
*/
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1440
|
+
formatBytes(bytes) {
|
|
1441
|
+
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
1442
|
+
let value = bytes;
|
|
1443
|
+
let unitIndex = 0;
|
|
1444
|
+
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
1445
|
+
value /= 1024;
|
|
1446
|
+
unitIndex++;
|
|
1234
1447
|
}
|
|
1448
|
+
return `${value.toFixed(2)} ${units[unitIndex]}`;
|
|
1235
1449
|
}
|
|
1236
1450
|
/**
|
|
1237
|
-
*
|
|
1451
|
+
* Checks if HMR is currently active.
|
|
1452
|
+
*
|
|
1453
|
+
* @method isHMRActive
|
|
1454
|
+
* @public
|
|
1455
|
+
*
|
|
1456
|
+
* @returns {boolean} True if HMR is enabled and watching files, false otherwise
|
|
1238
1457
|
*/
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
this.reloadConfigurations();
|
|
1242
|
-
this.reloadDependencies();
|
|
1243
|
-
SLogger(this.localLanguage).logger.info({
|
|
1244
|
-
title: "Force Reload",
|
|
1245
|
-
message: "All configurations and dependencies have been reloaded"
|
|
1246
|
-
});
|
|
1247
|
-
} catch (error) {
|
|
1248
|
-
SLogger(this.localLanguage).logger.error({
|
|
1249
|
-
title: "Force Reload Failed",
|
|
1250
|
-
message: error.message,
|
|
1251
|
-
errorType: "ForceReloadError",
|
|
1252
|
-
httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
1253
|
-
});
|
|
1254
|
-
}
|
|
1458
|
+
isHMRActive() {
|
|
1459
|
+
return this.getEnvironment.hmrEnabled && this.fileWatcher !== null;
|
|
1255
1460
|
}
|
|
1256
1461
|
/**
|
|
1257
|
-
*
|
|
1462
|
+
* Gets detailed HMR information and status.
|
|
1463
|
+
*
|
|
1464
|
+
* @method getHMRInfo
|
|
1465
|
+
* @public
|
|
1466
|
+
*
|
|
1467
|
+
* @returns {any} HMR information object
|
|
1468
|
+
*
|
|
1469
|
+
* @remarks
|
|
1470
|
+
* Includes:
|
|
1471
|
+
* - Configuration settings from .env
|
|
1472
|
+
* - Current restart count
|
|
1473
|
+
* - Watcher status
|
|
1258
1474
|
*/
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1475
|
+
getHMRInfo() {
|
|
1476
|
+
return {
|
|
1477
|
+
enabled: this.getEnvironment.hmrEnabled,
|
|
1478
|
+
watchPatterns: this.getEnvironment.hmrWatchPatterns,
|
|
1479
|
+
ignorePatterns: this.getEnvironment.hmrIgnorePatterns,
|
|
1480
|
+
debounceMs: this.getEnvironment.hmrDebounceMs,
|
|
1481
|
+
maxRestarts: this.getEnvironment.hmrMaxRestarts,
|
|
1482
|
+
autoRestart: this.getEnvironment.hmrAutoRestarts,
|
|
1483
|
+
currentRestartCount: this.hmrRestartCount,
|
|
1484
|
+
lastRestartTime: this.lastHmrRestartTime,
|
|
1485
|
+
isWatching: this.fileWatcher !== null,
|
|
1486
|
+
isRestartPending: this.hmrRestartPending
|
|
1487
|
+
};
|
|
1270
1488
|
}
|
|
1271
1489
|
};
|
|
1272
1490
|
// Annotate the CommonJS export names for ESM import in node:
|