@dbcube/core 3.0.3 → 3.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -600,17 +600,15 @@ var Engine = class {
600
600
  arguments;
601
601
  binary = null;
602
602
  timeout;
603
- connectionId;
604
- isConnected = false;
603
+ childProcess = null;
604
+ pendingRequests = /* @__PURE__ */ new Map();
605
+ requestCounter = 0;
606
+ isProcessStarting = false;
605
607
  constructor(name, timeout = 3e4) {
606
608
  this.name = name;
607
609
  this.config = this.setConfig(name);
608
610
  this.arguments = this.setArguments();
609
611
  this.timeout = timeout;
610
- this.connectionId = this.generateConnectionId();
611
- }
612
- generateConnectionId() {
613
- return `${this.name}_${this.config.type}_${this.config.config.DATABASE}_${this.config.config.HOST || "localhost"}`;
614
612
  }
615
613
  async initializeBinary() {
616
614
  if (!this.binary) {
@@ -628,7 +626,9 @@ var Engine = class {
628
626
  "--database",
629
627
  this.config.config.DATABASE + ".db",
630
628
  "--motor",
631
- this.config.type
629
+ this.config.type,
630
+ "--persistent"
631
+ // Agregar flag para modo persistente si el binario lo soporta
632
632
  ];
633
633
  } else {
634
634
  args = [
@@ -647,7 +647,9 @@ var Engine = class {
647
647
  "--password",
648
648
  this.config.config.PASSWORD,
649
649
  "--motor",
650
- this.config.type
650
+ this.config.type,
651
+ "--persistent"
652
+ // Agregar flag para modo persistente si el binario lo soporta
651
653
  ];
652
654
  }
653
655
  return args;
@@ -677,139 +679,151 @@ var Engine = class {
677
679
  getConfig() {
678
680
  return this.config;
679
681
  }
680
- async ensurePersistentConnection() {
681
- if (!this.isConnected) {
682
- console.log("\u{1F50C} Creating persistent connection...");
683
- const response = await this.createProcess("query_engine", [
684
- "--action",
685
- "connect"
686
- ]);
687
- if (response.status === 200) {
688
- this.isConnected = true;
689
- console.log("\u2705 Persistent connection established");
690
- } else {
691
- throw new Error(`Failed to create persistent connection: ${response.message}`);
682
+ async ensureProcess(binary) {
683
+ if (this.childProcess && !this.childProcess.killed) {
684
+ return;
685
+ }
686
+ if (this.isProcessStarting) {
687
+ return new Promise((resolve5) => {
688
+ const checkProcess = () => {
689
+ if (!this.isProcessStarting) {
690
+ resolve5();
691
+ } else {
692
+ setTimeout(checkProcess, 10);
693
+ }
694
+ };
695
+ checkProcess();
696
+ });
697
+ }
698
+ this.isProcessStarting = true;
699
+ try {
700
+ await this.initializeBinary();
701
+ if (!this.binary) {
702
+ throw new Error("Binary not initialized");
692
703
  }
704
+ this.childProcess = (0, import_child_process.spawn)(this.binary[binary], this.arguments, {
705
+ stdio: ["pipe", "pipe", "pipe"]
706
+ });
707
+ this.setupProcessHandlers();
708
+ } finally {
709
+ this.isProcessStarting = false;
693
710
  }
694
711
  }
695
- async run(binary, args) {
696
- const actionIndex = args.indexOf("--action");
697
- const isExecuteAction = actionIndex !== -1 && args[actionIndex + 1] === "execute";
698
- if (isExecuteAction) {
699
- await this.ensurePersistentConnection();
700
- return this.executeWithPersistentConnection(args);
701
- } else {
702
- return this.createProcess(binary, args);
712
+ setupProcessHandlers() {
713
+ if (!this.childProcess) return;
714
+ let stdoutBuffer = "";
715
+ let stderrBuffer = "";
716
+ this.childProcess.stdout?.on("data", (data) => {
717
+ stdoutBuffer += data.toString();
718
+ this.processBuffer(stdoutBuffer, "stdout");
719
+ });
720
+ this.childProcess.stderr?.on("data", (data) => {
721
+ stderrBuffer += data.toString();
722
+ this.processBuffer(stderrBuffer, "stderr");
723
+ });
724
+ this.childProcess.on("close", (code) => {
725
+ this.handleProcessClose(code);
726
+ });
727
+ this.childProcess.on("error", (error) => {
728
+ this.handleProcessError(error);
729
+ });
730
+ this.childProcess.unref();
731
+ }
732
+ processBuffer(buffer, source) {
733
+ const responsePattern = /PROCESS_RESPONSE:(\{[^}]*\})/g;
734
+ let match;
735
+ while ((match = responsePattern.exec(buffer)) !== null) {
736
+ try {
737
+ const response = JSON.parse(match[1]);
738
+ const requestId = response.requestId || "unknown";
739
+ const pendingRequest = this.pendingRequests.get(requestId);
740
+ if (pendingRequest) {
741
+ clearTimeout(pendingRequest.timeoutId);
742
+ this.pendingRequests.delete(requestId);
743
+ pendingRequest.resolve({
744
+ status: response.status,
745
+ message: response.message,
746
+ data: response.data
747
+ });
748
+ }
749
+ } catch (error) {
750
+ console.error("Failed to parse response JSON:", error);
751
+ }
703
752
  }
704
753
  }
705
- async executeWithPersistentConnection(args) {
706
- return this.createProcess("query_engine", args);
754
+ handleProcessClose(code) {
755
+ this.childProcess = null;
756
+ for (const [requestId, request] of this.pendingRequests) {
757
+ clearTimeout(request.timeoutId);
758
+ request.reject(new Error(`Process closed with code ${code}`));
759
+ }
760
+ this.pendingRequests.clear();
707
761
  }
708
- async createProcess(binary, args) {
709
- await this.initializeBinary();
710
- if (!this.binary) {
711
- throw new Error("Binary not initialized");
762
+ handleProcessError(error) {
763
+ this.childProcess = null;
764
+ for (const [requestId, request] of this.pendingRequests) {
765
+ clearTimeout(request.timeoutId);
766
+ request.reject(error);
767
+ }
768
+ this.pendingRequests.clear();
769
+ }
770
+ async run(binary, args) {
771
+ await this.ensureProcess(binary);
772
+ if (!this.childProcess) {
773
+ throw new Error("Failed to start process");
712
774
  }
713
775
  return new Promise((resolve5, reject) => {
714
- const child = (0, import_child_process.spawn)(this.binary[binary], [...this.arguments, ...args]);
715
- let stdoutBuffer = "";
716
- let stderrBuffer = "";
717
- let isResolved = false;
776
+ const requestId = `req_${++this.requestCounter}_${Date.now()}`;
718
777
  const timeoutId = setTimeout(() => {
719
- if (!isResolved) {
720
- isResolved = true;
721
- child.kill();
722
- reject(new Error("Process timeout"));
778
+ const request = this.pendingRequests.get(requestId);
779
+ if (request) {
780
+ this.pendingRequests.delete(requestId);
781
+ reject(new Error("Request timeout"));
723
782
  }
724
783
  }, this.timeout);
725
- const resolveOnce = (response) => {
726
- if (!isResolved) {
727
- isResolved = true;
728
- clearTimeout(timeoutId);
729
- resolve5(response);
730
- }
731
- };
732
- child.stdout.on("data", (data) => {
733
- stdoutBuffer += data.toString();
734
- const match = stdoutBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
735
- if (match) {
736
- try {
737
- const response = JSON.parse(match[1]);
738
- resolveOnce({
739
- status: response.status,
740
- message: response.message,
741
- data: response.data
742
- });
743
- } catch (error) {
744
- resolveOnce({
745
- status: 500,
746
- message: "Failed to parse response JSON",
747
- data: null
748
- });
749
- }
750
- }
784
+ this.pendingRequests.set(requestId, {
785
+ resolve: resolve5,
786
+ reject,
787
+ timeoutId,
788
+ requestId
751
789
  });
752
- child.stderr.on("data", (data) => {
753
- stderrBuffer += data.toString();
754
- const match = stderrBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
755
- if (match) {
756
- try {
757
- const response = JSON.parse(match[1]);
758
- resolveOnce({
759
- status: response.status,
760
- message: response.message,
761
- data: response.data
762
- });
763
- } catch (error) {
764
- resolveOnce({
765
- status: 500,
766
- message: "Failed to parse response JSON",
767
- data: null
768
- });
769
- }
770
- }
771
- });
772
- child.on("close", (code) => {
773
- clearTimeout(timeoutId);
774
- if (!isResolved) {
775
- resolveOnce({
776
- status: code === 0 ? 200 : 500,
777
- message: code === 0 ? "Process completed" : `Process exited with code ${code}`,
778
- data: null
779
- });
780
- }
781
- });
782
- child.on("error", (error) => {
790
+ const command = {
791
+ requestId,
792
+ args
793
+ };
794
+ try {
795
+ this.childProcess.stdin?.write(JSON.stringify(command) + "\n");
796
+ } catch (error) {
783
797
  clearTimeout(timeoutId);
784
- if (!isResolved) {
785
- resolveOnce({
786
- status: 500,
787
- message: `Process error: ${error.message}`,
788
- data: null
789
- });
790
- }
791
- });
792
- child.unref();
798
+ this.pendingRequests.delete(requestId);
799
+ reject(error);
800
+ }
793
801
  });
794
802
  }
795
- async disconnect() {
796
- if (this.isConnected) {
797
- console.log("\u{1F50C} Disconnecting persistent connection...");
798
- const response = await this.createProcess("query_engine", [
799
- "--action",
800
- "disconnect"
801
- ]);
802
- if (response.status === 200) {
803
- this.isConnected = false;
804
- console.log("\u2705 Persistent connection closed");
805
- }
806
- return response;
803
+ // Método para cerrar el proceso manualmente
804
+ async close() {
805
+ if (this.childProcess && !this.childProcess.killed) {
806
+ return new Promise((resolve5) => {
807
+ this.childProcess.once("close", () => {
808
+ resolve5();
809
+ });
810
+ this.childProcess.stdin?.end();
811
+ setTimeout(() => {
812
+ if (this.childProcess && !this.childProcess.killed) {
813
+ this.childProcess.kill("SIGTERM");
814
+ setTimeout(() => {
815
+ if (this.childProcess && !this.childProcess.killed) {
816
+ this.childProcess.kill("SIGKILL");
817
+ }
818
+ }, 2e3);
819
+ }
820
+ }, 5e3);
821
+ });
807
822
  }
808
- return {
809
- status: 200,
810
- message: "No persistent connection to disconnect",
811
- data: null
812
- };
823
+ }
824
+ // Verificar si el proceso está activo
825
+ isProcessAlive() {
826
+ return this.childProcess !== null && !this.childProcess.killed;
813
827
  }
814
828
  };
815
829