opticore-webapp 1.0.67 → 1.0.68

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 CHANGED
@@ -42,6 +42,10 @@ var import_cors = __toESM(require("cors"), 1);
42
42
  var import_opticore_catch_exception_error3 = require("opticore-catch-exception-error");
43
43
  var import_opticore_express = require("opticore-express");
44
44
  var import_opticore_env_access2 = require("opticore-env-access");
45
+ var import_opticore_request_call_event = require("opticore-request-call-event");
46
+ var import_opticore_dependency_inject2 = require("opticore-dependency-inject");
47
+ var import_opticore_http_response3 = require("opticore-http-response");
48
+ var import_opticore_translator2 = require("opticore-translator");
45
49
 
46
50
  // src/core/handlers/eventProcess.handler.ts
47
51
  var import_node_process = __toESM(require("process"), 1);
@@ -472,13 +476,11 @@ var SServerStartError = (err, environmentPath) => {
472
476
  };
473
477
 
474
478
  // src/core/webServer.core.ts
475
- var import_opticore_request_call_event = require("opticore-request-call-event");
476
- var import_opticore_dependency_inject2 = require("opticore-dependency-inject");
477
- var import_opticore_http_response3 = require("opticore-http-response");
478
- var import_opticore_translator2 = require("opticore-translator");
479
+ var import_opticore_watcher = require("opticore-watcher");
479
480
  var WebServerCore = class {
480
481
  serverUtility;
481
482
  expressApp = (0, import_opticore_express.express)();
483
+ fileWatcher;
482
484
  localLanguage;
483
485
  loggerConfig;
484
486
  routerExpressApp;
@@ -489,13 +491,9 @@ var WebServerCore = class {
489
491
  currentDependencies = [];
490
492
  server = void 0;
491
493
  errorEmitter;
492
- // ✅✅✅ ÉTAT DU SERVEUR
493
- serverState = "READY";
494
- lastError = null;
495
- // Statistiques
496
- hotReloadAttempts = 0;
497
- hotReloadSuccesses = 0;
498
- hotReloadFailures = 0;
494
+ isWatcherEnabled = true;
495
+ serverStatus = "STARTING";
496
+ serverStartTime = /* @__PURE__ */ new Date();
499
497
  constructor(paramsConstructor) {
500
498
  this.getEnvironment = (0, import_opticore_env_access2.getEnvironnementValue)(paramsConstructor.environmentPath);
501
499
  this.routerExpressApp = paramsConstructor.app;
@@ -509,8 +507,6 @@ var WebServerCore = class {
509
507
  this.expressApp.use((0, import_cors.default)(paramsConstructor.corsOriginOptions));
510
508
  this.serverListenEvent = new import_opticore_catch_exception_error3.ServerListenEventError(paramsConstructor.localLanguage);
511
509
  this.serverUtility = new CoreService(paramsConstructor.localLanguage, paramsConstructor.environmentPath);
512
- this.setupSignalHandlers();
513
- this.setupIPCHandlers();
514
510
  }
515
511
  onStartServer(routers, databaseCallback, dependenciesProvider) {
516
512
  loaderTranslationFile(this.localLanguage);
@@ -543,11 +539,7 @@ var WebServerCore = class {
543
539
  this.getEnvironment.appHost,
544
540
  () => {
545
541
  try {
546
- SLogger(this.localLanguage).logger.info({
547
- message: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_READY", this.localLanguage),
548
- title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD", this.localLanguage)
549
- });
550
- if (databaseCallback) {
542
+ if (databaseCallback && typeof databaseCallback === "function") {
551
543
  databaseCallback(this.getEnvironment);
552
544
  }
553
545
  new import_opticore_dependency_inject2.SContainer(this.localLanguage, this.currentDependencies);
@@ -555,9 +547,10 @@ var WebServerCore = class {
555
547
  this.registerRoutes(this.currentRoutes);
556
548
  this.setupErrorHandling();
557
549
  this.setupServerEvents();
558
- this.serverState = "READY";
550
+ if (this.isWatcherEnabled) {
551
+ this.initializeFileWatcher();
552
+ }
559
553
  this.infoWebApp();
560
- this.notifyServerReady();
561
554
  } catch (err) {
562
555
  SLogger(this.localLanguage).logger.error({
563
556
  title: import_opticore_translator2.TranslationLoader.t("STARTUP_ERROR", this.localLanguage),
@@ -573,7 +566,7 @@ var WebServerCore = class {
573
566
  return this.server;
574
567
  }
575
568
  /**
576
- * ✅✅✅ Configuration de la gestion d'erreurs
569
+ * Error handling configuration
577
570
  */
578
571
  setupErrorHandling() {
579
572
  SLogger(this.localLanguage).logger.info({
@@ -583,18 +576,24 @@ var WebServerCore = class {
583
576
  this.errorEmitter = eventProcessHandler(this.localLanguage, this.expressApp);
584
577
  if (this.errorEmitter) {
585
578
  this.errorEmitter.on("transformError", (error) => {
586
- SLogger(this.localLanguage).logger.info({
587
- title: import_opticore_translator2.TranslationLoader.t("", this.localLanguage),
588
- message: import_opticore_translator2.TranslationLoader.t("", this.localLanguage)
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
589
585
  });
590
- this.lastError = error;
591
- this.serverState = "BLOCKED";
592
- this.notifyWatcherBlockedByError(error);
593
586
  });
594
587
  this.errorEmitter.on("error", (error) => {
595
588
  SLogger(this.localLanguage).logger.info({
596
589
  title: import_opticore_translator2.TranslationLoader.t("ERROR_EMITTED", this.localLanguage),
597
- message: `Error emitted: ${error.message}`
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}`
598
597
  });
599
598
  });
600
599
  }
@@ -603,6 +602,9 @@ var WebServerCore = class {
603
602
  message: import_opticore_translator2.TranslationLoader.t("ERROR_HANDLING_CONFIGURED", this.localLanguage)
604
603
  });
605
604
  }
605
+ /**
606
+ * Setup server events
607
+ */
606
608
  setupServerEvents() {
607
609
  if (!this.server) return;
608
610
  this.server.on(import_opticore_catch_exception_error3.CEventNameError.error, (err) => {
@@ -626,145 +628,353 @@ var WebServerCore = class {
626
628
  );
627
629
  });
628
630
  }
629
- notifyServerReady() {
630
- setTimeout(() => {
631
- if (import_node_process3.default.send) {
632
- import_node_process3.default.send({
633
- type: "SERVER_READY",
634
- timestamp: Date.now(),
635
- port: Number(this.getEnvironment.appPort),
636
- host: this.getEnvironment.appHost,
637
- message: "Server ready for hot reload"
638
- });
639
- }
640
- }, 100);
631
+ /**
632
+ * Initialize file watcher
633
+ */
634
+ initializeFileWatcher() {
635
+ try {
636
+ this.fileWatcher = new import_opticore_watcher.WebServerWatcherService(this.localLanguage);
637
+ this.setupWatcherEvents();
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
+ }
641
652
  }
642
- setupSignalHandlers() {
643
- import_node_process3.default.on("SIGHUP", async () => {
644
- if (this.serverState === "READY") {
653
+ /**
654
+ * Setup watcher events
655
+ */
656
+ setupWatcherEvents() {
657
+ if (!this.fileWatcher) return;
658
+ try {
659
+ this.fileWatcher.on("fileChangeDetected", (data) => {
660
+ this.handleFileChange(data);
661
+ });
662
+ this.fileWatcher.on("hotReloadRequired", (data) => {
663
+ this.handleHotReload(data);
664
+ });
665
+ this.fileWatcher.on("watcherError", (error) => {
666
+ this.handleWatcherError(error);
667
+ });
668
+ this.fileWatcher.on("started", () => {
645
669
  SLogger(this.localLanguage).logger.info({
646
- title: import_opticore_translator2.TranslationLoader.t("SIGHUP", this.localLanguage),
647
- message: import_opticore_translator2.TranslationLoader.t("RECEIVED_SIGHUP", this.localLanguage)
670
+ title: import_opticore_translator2.TranslationLoader.t("WATCHER_STARTED", this.localLanguage),
671
+ message: import_opticore_translator2.TranslationLoader.t("FILE_WATCHER_ACTIVE", this.localLanguage)
648
672
  });
649
- await this.performTrueHotReload();
650
- }
651
- });
652
- import_node_process3.default.on("SIGTERM", () => {
653
- SLogger(this.localLanguage).logger.info({
654
- title: import_opticore_translator2.TranslationLoader.t("SIGHUP", this.localLanguage),
655
- message: import_opticore_translator2.TranslationLoader.t("RECEIVED_SIGHUP", this.localLanguage)
656
673
  });
657
- this.shutdown();
658
- });
659
- import_node_process3.default.on("SIGINT", () => {
660
- SLogger(this.localLanguage).logger.info({
661
- title: import_opticore_translator2.TranslationLoader.t("SIGINT", this.localLanguage),
662
- message: import_opticore_translator2.TranslationLoader.t("RECEIVED_SIGINT", this.localLanguage)
674
+ this.fileWatcher.on("stopped", () => {
675
+ SLogger(this.localLanguage).logger.info({
676
+ title: import_opticore_translator2.TranslationLoader.t("WATCHER_STOPPED", this.localLanguage),
677
+ message: import_opticore_translator2.TranslationLoader.t("FILE_WATCHER_INACTIVE", this.localLanguage)
678
+ });
663
679
  });
664
- this.shutdown();
665
- });
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
+ }
666
688
  }
667
- setupIPCHandlers() {
668
- if (!import_node_process3.default.send) {
669
- SLogger(this.localLanguage).logger.info({
670
- title: import_opticore_translator2.TranslationLoader.t("IPC", this.localLanguage),
671
- message: import_opticore_translator2.TranslationLoader.t("IPC_NOT_AVAILABLE", this.localLanguage)
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()
672
713
  });
673
- return;
674
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
+ }
732
+ }
733
+ /**
734
+ * Handle hot reload requested by watcher
735
+ */
736
+ handleHotReload(data) {
737
+ const { file, type, action } = data;
675
738
  SLogger(this.localLanguage).logger.info({
676
- title: import_opticore_translator2.TranslationLoader.t("IPC_READY", this.localLanguage),
677
- message: import_opticore_translator2.TranslationLoader.t("IPC_READY_HOT_RELOAD", this.localLanguage)
739
+ title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_STARTING", this.localLanguage),
740
+ message: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_FOR_FILE", this.localLanguage).replace("{file}", path2.basename(file)).replace("{type}", type)
678
741
  });
679
- import_node_process3.default.on("message", async (message) => {
680
- if (message.type === "HOT_RELOAD_REQUEST") {
681
- if (this.serverState === "BLOCKED") {
682
- SLogger(this.localLanguage).logger.info({
683
- title: import_opticore_translator2.TranslationLoader.t("BLOCKED", this.localLanguage),
684
- message: import_opticore_translator2.TranslationLoader.t("BLOCKED_STATE", this.localLanguage)
685
- });
686
- return;
687
- }
688
- if (this.serverState === "READY") {
689
- await this.performTrueHotReload();
690
- }
691
- }
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
692
775
  });
693
776
  }
694
777
  /**
695
- * ✅✅✅ HOT RELOAD avec gestion d'état stricte
778
+ * Notify file change without action
696
779
  */
697
- async performTrueHotReload() {
698
- this.serverState = "RELOADING";
699
- this.hotReloadAttempts++;
700
- const startTime = Date.now();
780
+ notifyFileChange(event2) {
701
781
  SLogger(this.localLanguage).logger.info({
702
- title: import_opticore_translator2.TranslationLoader.t("RELOAD_STARTING", this.localLanguage),
703
- message: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_ATTEMPTED", this.localLanguage, { hotReloadAttempts: this.hotReloadAttempts })
782
+ title: import_opticore_translator2.TranslationLoader.t("FILE_CHANGE_NOTIFIED", this.localLanguage),
783
+ message: import_opticore_translator2.TranslationLoader.t("FILE_CHANGE_NO_ACTION", this.localLanguage).replace("{file}", path2.basename(event2.filePath))
704
784
  });
785
+ }
786
+ /**
787
+ * Reload environment configuration
788
+ */
789
+ reloadEnvironmentConfig() {
705
790
  try {
706
- const clearedModules = this.clearApplicationModulesCache();
707
- SLogger(this.localLanguage).logger.info({
708
- title: import_opticore_translator2.TranslationLoader.t("APP_MODULES_CLEARED", this.localLanguage),
709
- message: import_opticore_translator2.TranslationLoader.t("CLEARED_MODULES", this.localLanguage, { clearedModules })
710
- });
711
791
  this.reloadConfigurations();
712
792
  SLogger(this.localLanguage).logger.info({
713
- title: import_opticore_translator2.TranslationLoader.t("APP_MODULES_CLEARED", this.localLanguage),
714
- message: import_opticore_translator2.TranslationLoader.t("CLEARED_MODULES", this.localLanguage, { hotReloadAttempts: this.hotReloadAttempts })
793
+ title: import_opticore_translator2.TranslationLoader.t("ENV_RELOADED", this.localLanguage),
794
+ message: import_opticore_translator2.TranslationLoader.t("ENVIRONMENT_RELOADED_SUCCESS", this.localLanguage)
715
795
  });
716
- this.reloadDependencies();
717
- SLogger(this.localLanguage).logger.info({
718
- title: import_opticore_translator2.TranslationLoader.t("DEPENDENCIES", this.localLanguage),
719
- message: import_opticore_translator2.TranslationLoader.t("RELOAD_DEPENDENCIES", this.localLanguage)
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
720
803
  });
721
- const duration = Date.now() - startTime;
722
- this.hotReloadSuccesses++;
723
- this.serverState = "READY";
724
- this.lastError = null;
804
+ }
805
+ }
806
+ /**
807
+ * Execute hot reload for environment files
808
+ */
809
+ executeHotReloadEnvironment(filePath) {
810
+ 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
+ loaderTranslationFile(this.localLanguage);
725
816
  SLogger(this.localLanguage).logger.info({
726
- title: import_opticore_translator2.TranslationLoader.t("RELOAD_SUCCESS", this.localLanguage),
727
- message: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_SUCCESS", this.localLanguage, { duration })
817
+ title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_ENV_SUCCESS", this.localLanguage),
818
+ message: import_opticore_translator2.TranslationLoader.t("ENV_HOT_RELOAD_COMPLETE", this.localLanguage).replace("{file}", path2.basename(filePath))
728
819
  });
729
- this.notifyWatcherReloadSuccess(duration);
730
820
  } catch (error) {
731
- this.hotReloadFailures++;
732
- const duration = Date.now() - startTime;
821
+ SLogger(this.localLanguage).logger.error({
822
+ title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_ENV_FAILED", this.localLanguage),
823
+ message: error.message,
824
+ errorType: "HotReloadEnvironmentError",
825
+ httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
826
+ });
827
+ }
828
+ }
829
+ /**
830
+ * Reload configuration files
831
+ */
832
+ reloadConfigurationFiles() {
833
+ try {
834
+ loaderTranslationFile(this.localLanguage);
733
835
  SLogger(this.localLanguage).logger.info({
734
- title: import_opticore_translator2.TranslationLoader.t("RELOAD_FAILED", this.localLanguage),
735
- message: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_FAILED", this.localLanguage, { duration, errorMessage: error.message })
736
- });
737
- const isTransformError = error?.name === "TransformError" || error?.message?.includes("Transform failed") || error?.message?.includes("esbuild");
738
- if (isTransformError) {
739
- this.lastError = error;
740
- this.serverState = "BLOCKED";
741
- this.notifyWatcherBlockedByError(error);
742
- } else {
743
- this.serverState = "BLOCKED";
744
- this.notifyWatcherReloadError(error);
836
+ title: import_opticore_translator2.TranslationLoader.t("CONFIG_RELOADED", this.localLanguage),
837
+ message: import_opticore_translator2.TranslationLoader.t("CONFIGURATION_RELOADED_SUCCESS", this.localLanguage)
838
+ });
839
+ } catch (error) {
840
+ SLogger(this.localLanguage).logger.error({
841
+ title: import_opticore_translator2.TranslationLoader.t("CONFIG_RELOAD_FAILED", this.localLanguage),
842
+ message: error.message,
843
+ errorType: "ConfigurationReloadError",
844
+ httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
845
+ });
846
+ }
847
+ }
848
+ /**
849
+ * Execute hot reload for config files
850
+ */
851
+ executeHotReloadConfig(filePath) {
852
+ try {
853
+ if (filePath.includes("locales") || filePath.includes("translations")) {
854
+ loaderTranslationFile(this.localLanguage);
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
+ });
745
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
+ });
746
867
  }
747
868
  }
748
869
  /**
749
- * Nettoie le cache des modules applicatifs
870
+ * Reload application routes
750
871
  */
751
- clearApplicationModulesCache() {
752
- const baseDirs = [
753
- path2.join(import_node_process3.default.cwd(), "src"),
754
- path2.join(import_node_process3.default.cwd(), "dist")
755
- ];
756
- let clearedCount = 0;
757
- for (const key in require.cache) {
758
- const isApplicationModule = baseDirs.some((dir) => key.startsWith(dir));
759
- const isNodeModule = key.includes("node_modules");
760
- const isJsonFile = key.endsWith(".json");
761
- if (isApplicationModule && !isNodeModule && !isJsonFile) {
762
- delete require.cache[key];
763
- clearedCount++;
872
+ reloadApplicationRoutes(filePath) {
873
+ try {
874
+ SLogger(this.localLanguage).logger.info({
875
+ title: import_opticore_translator2.TranslationLoader.t("ROUTES_RELOADING", this.localLanguage),
876
+ message: import_opticore_translator2.TranslationLoader.t("APPLICATION_ROUTES_RELOADING", this.localLanguage).replace("{file}", path2.basename(filePath))
877
+ });
878
+ if (filePath.includes("routes") || filePath.includes("controller")) {
879
+ this.reloadSpecificRoute(filePath);
764
880
  }
881
+ if (this.errorEmitter) {
882
+ this.errorEmitter.emit("routesReloaded", {
883
+ timestamp: /* @__PURE__ */ new Date(),
884
+ file: filePath,
885
+ routesCount: this.currentRoutes.length
886
+ });
887
+ }
888
+ } catch (error) {
889
+ SLogger(this.localLanguage).logger.error({
890
+ title: import_opticore_translator2.TranslationLoader.t("ROUTES_RELOAD_FAILED", this.localLanguage),
891
+ message: error.message,
892
+ errorType: "RoutesReloadError",
893
+ httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
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)
910
+ });
911
+ } catch (error) {
912
+ SLogger(this.localLanguage).logger.error({
913
+ title: import_opticore_translator2.TranslationLoader.t("HOT_RELOAD_ROUTES_FAILED", this.localLanguage),
914
+ message: error.message,
915
+ errorType: "HotReloadRoutesError",
916
+ httpCodeValue: import_opticore_http_response3.HttpStatusCode.INTERNAL_SERVER_ERROR
917
+ });
765
918
  }
766
- return clearedCount;
767
919
  }
920
+ /**
921
+ * Execute hot reload for dependencies
922
+ */
923
+ executeHotReloadDependencies(filePath) {
924
+ try {
925
+ SLogger(this.localLanguage).logger.info({
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
+ });
944
+ }
945
+ }
946
+ /**
947
+ * Notify environment reload
948
+ */
949
+ notifyEnvironmentReload() {
950
+ if (this.errorEmitter) {
951
+ this.errorEmitter.emit("environmentReloaded", {
952
+ timestamp: /* @__PURE__ */ new Date(),
953
+ environment: this.getEnvironment
954
+ });
955
+ }
956
+ }
957
+ /**
958
+ * Reload specific route
959
+ */
960
+ reloadSpecificRoute(filePath) {
961
+ SLogger(this.localLanguage).logger.info({
962
+ title: "Route Reload",
963
+ message: `Reloading route from: ${filePath}`
964
+ });
965
+ }
966
+ /**
967
+ * Reload router for specific file
968
+ */
969
+ reloadRouterForFile(filePath) {
970
+ SLogger(this.localLanguage).logger.info({
971
+ title: "Router Reload",
972
+ message: `Reloading router for file: ${filePath}`
973
+ });
974
+ }
975
+ /**
976
+ * Reload configurations
977
+ */
768
978
  reloadConfigurations() {
769
979
  try {
770
980
  const newEnv = (0, import_opticore_env_access2.getEnvironnementValue)(this.environmentPath);
@@ -776,6 +986,9 @@ var WebServerCore = class {
776
986
  throw new Error(`Configuration reload failed: ${error.message}`);
777
987
  }
778
988
  }
989
+ /**
990
+ * Reload dependencies
991
+ */
779
992
  reloadDependencies() {
780
993
  try {
781
994
  new import_opticore_dependency_inject2.SContainer(this.localLanguage, this.currentDependencies);
@@ -788,57 +1001,19 @@ var WebServerCore = class {
788
1001
  }
789
1002
  }
790
1003
  /**
791
- * ✅✅✅ Notifier le watcher : SUCCÈS
792
- */
793
- notifyWatcherReloadSuccess(duration) {
794
- if (import_node_process3.default.send && import_node_process3.default.env.WATCHER_MODE === "true") {
795
- import_node_process3.default.send({
796
- type: "HOT_RELOAD_SUCCESS",
797
- timestamp: Date.now(),
798
- duration,
799
- serverState: this.serverState,
800
- message: "Code reloaded successfully"
801
- });
802
- }
803
- }
804
- /**
805
- * ✅✅✅ Notifier le watcher : BLOQUÉ PAR ERREUR TRANSFORM
806
- */
807
- notifyWatcherBlockedByError(error) {
808
- if (import_node_process3.default.send && import_node_process3.default.env.WATCHER_MODE === "true") {
809
- const errorDetails = this.parseTransformError(error);
810
- import_node_process3.default.send({
811
- type: "HOT_RELOAD_BLOCKED_BY_ERROR",
812
- timestamp: Date.now(),
813
- serverState: this.serverState,
814
- error: {
815
- message: error.message,
816
- errorType: error.name || "TransformError",
817
- file: errorDetails.file,
818
- line: errorDetails.line,
819
- column: errorDetails.column,
820
- detail: errorDetails.errorDetail,
821
- tool: errorDetails.tool
822
- }
823
- });
824
- }
825
- }
826
- /**
827
- * ✅✅✅ Notifier le watcher : ERREUR GÉNÉRIQUE
1004
+ * Register routes
828
1005
  */
829
- notifyWatcherReloadError(error) {
830
- if (import_node_process3.default.send && import_node_process3.default.env.WATCHER_MODE === "true") {
831
- import_node_process3.default.send({
832
- type: "HOT_RELOAD_ERROR",
833
- timestamp: Date.now(),
834
- serverState: this.serverState,
835
- error: error.message,
836
- errorType: error.name || "UNKNOWN_ERROR"
837
- });
838
- }
1006
+ registerRoutes(allFeatureRoutes) {
1007
+ allFeatureRoutes.forEach((router) => {
1008
+ if (router.routes) {
1009
+ router.routes.forEach((route) => {
1010
+ this.expressApp.use(route.path, route.handler);
1011
+ });
1012
+ }
1013
+ });
839
1014
  }
840
1015
  /**
841
- * ✅✅✅ Parser les détails d'une TransformError
1016
+ * Parse transform error
842
1017
  */
843
1018
  parseTransformError(error) {
844
1019
  const errorMessage = error.message || String(error);
@@ -860,22 +1035,43 @@ var WebServerCore = class {
860
1035
  tool
861
1036
  };
862
1037
  }
863
- registerRoutes(allFeatureRoutes) {
864
- allFeatureRoutes.forEach((router) => {
865
- if (router.routes) {
866
- router.routes.forEach((route) => {
867
- this.expressApp.use(route.path, route.handler);
868
- });
869
- }
870
- });
871
- }
1038
+ /**
1039
+ * Display server info
1040
+ */
872
1041
  infoWebApp() {
873
1042
  this.serverUtility.infoServer(
874
1043
  this.getEnvironment.appHost,
875
1044
  Number(this.getEnvironment.appPort)
876
1045
  );
877
1046
  }
1047
+ /**
1048
+ * Stop file watcher
1049
+ */
1050
+ stopFileWatcher() {
1051
+ if (this.fileWatcher) {
1052
+ try {
1053
+ this.fileWatcher.stopWatching();
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
+ }
1068
+ }
1069
+ }
1070
+ /**
1071
+ * Shutdown server
1072
+ */
878
1073
  shutdown() {
1074
+ this.stopFileWatcher();
879
1075
  if (this.server) {
880
1076
  this.server.close(() => {
881
1077
  SLogger(this.localLanguage).logger.info({
@@ -885,12 +1081,193 @@ var WebServerCore = class {
885
1081
  import_node_process3.default.exit(0);
886
1082
  });
887
1083
  setTimeout(() => {
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
+ });
888
1088
  import_node_process3.default.exit(1);
889
1089
  }, 5e3);
890
1090
  } else {
891
1091
  import_node_process3.default.exit(0);
892
1092
  }
893
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();
1103
+ }
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
+ }
1118
+ /**
1119
+ * Get server state information
1120
+ */
1121
+ getServerState() {
1122
+ const now = /* @__PURE__ */ new Date();
1123
+ 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
+ return {
1136
+ status: this.serverStatus,
1137
+ isRunning: this.server !== void 0,
1138
+ host: this.getEnvironment.appHost,
1139
+ port: Number(this.getEnvironment.appPort),
1140
+ language: this.localLanguage,
1141
+ watcherEnabled: this.isWatcherEnabled,
1142
+ watcherActive: this.fileWatcher !== void 0,
1143
+ routesCount: this.currentRoutes.length,
1144
+ dependenciesCount: this.currentDependencies.length,
1145
+ startTime: this.serverStartTime,
1146
+ currentTime: now,
1147
+ 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
+ },
1156
+ pid: import_node_process3.default.pid,
1157
+ platform: import_node_process3.default.platform,
1158
+ nodeVersion: import_node_process3.default.version,
1159
+ cwd: import_node_process3.default.cwd()
1160
+ };
1161
+ }
1162
+ /**
1163
+ * Simple method to get just the status
1164
+ */
1165
+ getServerStatus() {
1166
+ return this.serverStatus;
1167
+ }
1168
+ /**
1169
+ * Get server statistics for monitoring
1170
+ */
1171
+ getServerStats() {
1172
+ const uptime = this.serverStartTime ? Date.now() - this.serverStartTime.getTime() : 0;
1173
+ const memory = import_node_process3.default.memoryUsage();
1174
+ return {
1175
+ status: this.serverStatus,
1176
+ uptime: this.formatUptime(uptime),
1177
+ memory: {
1178
+ rss: this.formatBytes(memory.rss),
1179
+ heapTotal: this.formatBytes(memory.heapTotal),
1180
+ heapUsed: this.formatBytes(memory.heapUsed),
1181
+ external: this.formatBytes(memory.external)
1182
+ },
1183
+ performance: {
1184
+ cpuUsage: import_node_process3.default.cpuUsage(),
1185
+ resourceUsage: import_node_process3.default.resourceUsage?.()
1186
+ }
1187
+ };
1188
+ }
1189
+ /**
1190
+ * Format bytes to human readable string
1191
+ */
1192
+ formatBytes(bytes) {
1193
+ const units = ["B", "KB", "MB", "GB", "TB"];
1194
+ let value = bytes;
1195
+ let unitIndex = 0;
1196
+ while (value >= 1024 && unitIndex < units.length - 1) {
1197
+ value /= 1024;
1198
+ unitIndex++;
1199
+ }
1200
+ return `${value.toFixed(2)} ${units[unitIndex]}`;
1201
+ }
1202
+ /**
1203
+ * Format uptime to human readable string
1204
+ */
1205
+ formatUptime(ms) {
1206
+ const seconds = Math.floor(ms / 1e3);
1207
+ const minutes = Math.floor(seconds / 60);
1208
+ const hours = Math.floor(minutes / 60);
1209
+ const days = Math.floor(hours / 24);
1210
+ if (days > 0) {
1211
+ return `${days}j ${hours % 24}h ${minutes % 60}m`;
1212
+ } else if (hours > 0) {
1213
+ return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
1214
+ } else if (minutes > 0) {
1215
+ return `${minutes}m ${seconds % 60}s`;
1216
+ } else {
1217
+ return `${seconds}s`;
1218
+ }
1219
+ }
1220
+ /**
1221
+ * Add watch directories
1222
+ */
1223
+ addWatchDirectories(directories) {
1224
+ if (this.fileWatcher) {
1225
+ this.fileWatcher.addWatchDirectories(directories);
1226
+ }
1227
+ }
1228
+ /**
1229
+ * Clear file cache
1230
+ */
1231
+ clearFileCache() {
1232
+ if (this.fileWatcher) {
1233
+ this.fileWatcher.clearFileCache();
1234
+ }
1235
+ }
1236
+ /**
1237
+ * Force reload configurations
1238
+ */
1239
+ forceReloadConfig() {
1240
+ try {
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
+ }
1255
+ }
1256
+ /**
1257
+ * Restart watcher
1258
+ */
1259
+ restartWatcher() {
1260
+ this.stopFileWatcher();
1261
+ if (this.isWatcherEnabled) {
1262
+ setTimeout(() => {
1263
+ this.initializeFileWatcher();
1264
+ SLogger(this.localLanguage).logger.info({
1265
+ title: "Watcher Restarted",
1266
+ message: "File watcher has been restarted successfully"
1267
+ });
1268
+ }, 1e3);
1269
+ }
1270
+ }
894
1271
  };
895
1272
  // Annotate the CommonJS export names for ESM import in node:
896
1273
  0 && (module.exports = {