@dbcube/core 3.0.6 → 3.0.8
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 +221 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +228 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -32,6 +32,8 @@ declare class QueryEngine {
|
|
|
32
32
|
private tcpPort;
|
|
33
33
|
constructor(name: string, timeout?: number);
|
|
34
34
|
private generatePort;
|
|
35
|
+
private findAvailablePort;
|
|
36
|
+
private isPortAvailable;
|
|
35
37
|
initializeBinary(): Promise<void>;
|
|
36
38
|
setArguments(): any[];
|
|
37
39
|
setConfig(name: string): {
|
|
@@ -40,8 +42,14 @@ declare class QueryEngine {
|
|
|
40
42
|
getConfig(): any;
|
|
41
43
|
run(binary: string, args: string[]): Promise<ResponseEngine>;
|
|
42
44
|
private executeWithTcpServer;
|
|
45
|
+
private waitForServerReady;
|
|
46
|
+
private isServerResponding;
|
|
47
|
+
private sleep;
|
|
43
48
|
private startTcpServer;
|
|
44
49
|
private sendTcpRequest;
|
|
50
|
+
private sendTcpRequestFast;
|
|
51
|
+
private sendOnExistingConnection;
|
|
52
|
+
private createPersistentConnection;
|
|
45
53
|
private createProcess;
|
|
46
54
|
disconnect(): Promise<ResponseEngine>;
|
|
47
55
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -32,6 +32,8 @@ declare class QueryEngine {
|
|
|
32
32
|
private tcpPort;
|
|
33
33
|
constructor(name: string, timeout?: number);
|
|
34
34
|
private generatePort;
|
|
35
|
+
private findAvailablePort;
|
|
36
|
+
private isPortAvailable;
|
|
35
37
|
initializeBinary(): Promise<void>;
|
|
36
38
|
setArguments(): any[];
|
|
37
39
|
setConfig(name: string): {
|
|
@@ -40,8 +42,14 @@ declare class QueryEngine {
|
|
|
40
42
|
getConfig(): any;
|
|
41
43
|
run(binary: string, args: string[]): Promise<ResponseEngine>;
|
|
42
44
|
private executeWithTcpServer;
|
|
45
|
+
private waitForServerReady;
|
|
46
|
+
private isServerResponding;
|
|
47
|
+
private sleep;
|
|
43
48
|
private startTcpServer;
|
|
44
49
|
private sendTcpRequest;
|
|
50
|
+
private sendTcpRequestFast;
|
|
51
|
+
private sendOnExistingConnection;
|
|
52
|
+
private createPersistentConnection;
|
|
45
53
|
private createProcess;
|
|
46
54
|
disconnect(): Promise<ResponseEngine>;
|
|
47
55
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
1
8
|
// src/lib/Engine.ts
|
|
2
9
|
import path3 from "path";
|
|
3
10
|
|
|
@@ -722,6 +729,7 @@ import { createRequire as createRequire2 } from "module";
|
|
|
722
729
|
import * as net from "net";
|
|
723
730
|
import { spawn as spawn2 } from "child_process";
|
|
724
731
|
var globalTcpServers = /* @__PURE__ */ new Map();
|
|
732
|
+
var globalTcpConnections = /* @__PURE__ */ new Map();
|
|
725
733
|
var QueryEngine = class {
|
|
726
734
|
name;
|
|
727
735
|
config;
|
|
@@ -739,13 +747,27 @@ var QueryEngine = class {
|
|
|
739
747
|
this.tcpPort = this.generatePort();
|
|
740
748
|
}
|
|
741
749
|
generatePort() {
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
750
|
+
return 9944;
|
|
751
|
+
}
|
|
752
|
+
async findAvailablePort(startPort) {
|
|
753
|
+
for (let port = startPort; port >= 9900; port--) {
|
|
754
|
+
if (await this.isPortAvailable(port)) {
|
|
755
|
+
return port;
|
|
756
|
+
}
|
|
747
757
|
}
|
|
748
|
-
|
|
758
|
+
throw new Error("No available ports found in range 9900-9944");
|
|
759
|
+
}
|
|
760
|
+
isPortAvailable(port) {
|
|
761
|
+
return new Promise((resolve5) => {
|
|
762
|
+
const net2 = __require("net");
|
|
763
|
+
const tester = net2.createServer();
|
|
764
|
+
tester.once("error", () => resolve5(false));
|
|
765
|
+
tester.once("listening", () => {
|
|
766
|
+
tester.close();
|
|
767
|
+
resolve5(true);
|
|
768
|
+
});
|
|
769
|
+
tester.listen(port, "127.0.0.1");
|
|
770
|
+
});
|
|
749
771
|
}
|
|
750
772
|
async initializeBinary() {
|
|
751
773
|
if (!this.binary) {
|
|
@@ -826,15 +848,51 @@ var QueryEngine = class {
|
|
|
826
848
|
if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {
|
|
827
849
|
console.log("\u{1F680} Starting TCP server for ultra-fast queries...");
|
|
828
850
|
await this.startTcpServer();
|
|
851
|
+
await this.waitForServerReady();
|
|
829
852
|
}
|
|
830
853
|
console.log("\u26A1 Using TCP server (ultra-fast)");
|
|
831
|
-
return this.
|
|
854
|
+
return this.sendTcpRequestFast(args);
|
|
855
|
+
}
|
|
856
|
+
async waitForServerReady() {
|
|
857
|
+
const maxRetries = 10;
|
|
858
|
+
const retryDelay = 500;
|
|
859
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
860
|
+
if (await this.isServerResponding()) {
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
console.log(`\u23F3 Waiting for TCP server to be ready... (${i + 1}/${maxRetries})`);
|
|
864
|
+
await this.sleep(retryDelay);
|
|
865
|
+
}
|
|
866
|
+
throw new Error("TCP server failed to become ready within timeout");
|
|
867
|
+
}
|
|
868
|
+
async isServerResponding() {
|
|
869
|
+
return new Promise((resolve5) => {
|
|
870
|
+
const client = new net.Socket();
|
|
871
|
+
const timeout = setTimeout(() => {
|
|
872
|
+
client.destroy();
|
|
873
|
+
resolve5(false);
|
|
874
|
+
}, 1e3);
|
|
875
|
+
client.connect(this.tcpPort, "127.0.0.1", () => {
|
|
876
|
+
clearTimeout(timeout);
|
|
877
|
+
client.destroy();
|
|
878
|
+
resolve5(true);
|
|
879
|
+
});
|
|
880
|
+
client.on("error", () => {
|
|
881
|
+
clearTimeout(timeout);
|
|
882
|
+
resolve5(false);
|
|
883
|
+
});
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
sleep(ms) {
|
|
887
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
832
888
|
}
|
|
833
889
|
async startTcpServer() {
|
|
834
890
|
await this.initializeBinary();
|
|
835
891
|
if (!this.binary) {
|
|
836
892
|
throw new Error("Binary not initialized");
|
|
837
893
|
}
|
|
894
|
+
this.tcpPort = await this.findAvailablePort(this.tcpPort);
|
|
895
|
+
console.log(`\u{1F310} Using port ${this.tcpPort} for TCP server`);
|
|
838
896
|
return new Promise((resolve5, reject) => {
|
|
839
897
|
const serverArgs = [...this.arguments, "--action", "server", "--port", this.tcpPort.toString()];
|
|
840
898
|
const serverProcess = spawn2(this.binary["query_engine"], serverArgs);
|
|
@@ -844,7 +902,7 @@ var QueryEngine = class {
|
|
|
844
902
|
serverProcess.kill();
|
|
845
903
|
reject(new Error("TCP server startup timeout"));
|
|
846
904
|
}
|
|
847
|
-
},
|
|
905
|
+
}, 15e3);
|
|
848
906
|
serverProcess.stdout.on("data", (data) => {
|
|
849
907
|
const output = data.toString();
|
|
850
908
|
console.log(`[TCP Server] ${output.trim()}`);
|
|
@@ -879,16 +937,24 @@ var QueryEngine = class {
|
|
|
879
937
|
return new Promise((resolve5, reject) => {
|
|
880
938
|
const client = new net.Socket();
|
|
881
939
|
let responseBuffer = "";
|
|
940
|
+
let isResolved = false;
|
|
882
941
|
const timeout = setTimeout(() => {
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
942
|
+
if (!isResolved) {
|
|
943
|
+
isResolved = true;
|
|
944
|
+
client.destroy();
|
|
945
|
+
reject(new Error("TCP request timeout"));
|
|
946
|
+
}
|
|
947
|
+
}, this.timeout * 2);
|
|
886
948
|
client.connect(this.tcpPort, "127.0.0.1", () => {
|
|
887
949
|
const dmlIndex = args.findIndex((arg) => arg === "--dml");
|
|
888
950
|
const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
|
|
889
951
|
if (!dmlJson) {
|
|
890
|
-
|
|
891
|
-
|
|
952
|
+
if (!isResolved) {
|
|
953
|
+
isResolved = true;
|
|
954
|
+
clearTimeout(timeout);
|
|
955
|
+
client.destroy();
|
|
956
|
+
reject(new Error("No DML found in arguments"));
|
|
957
|
+
}
|
|
892
958
|
return;
|
|
893
959
|
}
|
|
894
960
|
const command = {
|
|
@@ -900,7 +966,8 @@ var QueryEngine = class {
|
|
|
900
966
|
client.on("data", (data) => {
|
|
901
967
|
responseBuffer += data.toString();
|
|
902
968
|
const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
903
|
-
if (match) {
|
|
969
|
+
if (match && !isResolved) {
|
|
970
|
+
isResolved = true;
|
|
904
971
|
clearTimeout(timeout);
|
|
905
972
|
client.destroy();
|
|
906
973
|
try {
|
|
@@ -916,13 +983,149 @@ var QueryEngine = class {
|
|
|
916
983
|
}
|
|
917
984
|
});
|
|
918
985
|
client.on("error", (error) => {
|
|
919
|
-
|
|
920
|
-
|
|
986
|
+
if (!isResolved) {
|
|
987
|
+
isResolved = true;
|
|
988
|
+
clearTimeout(timeout);
|
|
989
|
+
reject(error);
|
|
990
|
+
}
|
|
921
991
|
});
|
|
922
992
|
client.on("close", () => {
|
|
993
|
+
if (!isResolved) {
|
|
994
|
+
clearTimeout(timeout);
|
|
995
|
+
if (!responseBuffer.includes("PROCESS_RESPONSE:")) {
|
|
996
|
+
reject(new Error("Connection closed without valid response"));
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
});
|
|
1000
|
+
});
|
|
1001
|
+
}
|
|
1002
|
+
async sendTcpRequestFast(args) {
|
|
1003
|
+
const existingConnection = globalTcpConnections.get(this.connectionId);
|
|
1004
|
+
if (existingConnection && existingConnection.readyState === "open") {
|
|
1005
|
+
try {
|
|
1006
|
+
return await this.sendOnExistingConnection(existingConnection, args);
|
|
1007
|
+
} catch (error) {
|
|
1008
|
+
globalTcpConnections.delete(this.connectionId);
|
|
1009
|
+
existingConnection.destroy();
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
return await this.createPersistentConnection(args);
|
|
1013
|
+
}
|
|
1014
|
+
async sendOnExistingConnection(connection, args) {
|
|
1015
|
+
return new Promise((resolve5, reject) => {
|
|
1016
|
+
const dmlIndex = args.findIndex((arg) => arg === "--dml");
|
|
1017
|
+
const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
|
|
1018
|
+
if (!dmlJson) {
|
|
1019
|
+
reject(new Error("No DML found in arguments"));
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
let responseBuffer = "";
|
|
1023
|
+
let isResolved = false;
|
|
1024
|
+
const timeout = setTimeout(() => {
|
|
1025
|
+
if (!isResolved) {
|
|
1026
|
+
isResolved = true;
|
|
1027
|
+
reject(new Error("TCP request timeout"));
|
|
1028
|
+
}
|
|
1029
|
+
}, 5e3);
|
|
1030
|
+
const onData = (data) => {
|
|
1031
|
+
responseBuffer += data.toString();
|
|
1032
|
+
const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1033
|
+
if (match && !isResolved) {
|
|
1034
|
+
isResolved = true;
|
|
1035
|
+
clearTimeout(timeout);
|
|
1036
|
+
connection.off("data", onData);
|
|
1037
|
+
connection.off("error", onError);
|
|
1038
|
+
try {
|
|
1039
|
+
const response = JSON.parse(match[1]);
|
|
1040
|
+
resolve5({
|
|
1041
|
+
status: response.status,
|
|
1042
|
+
message: response.message,
|
|
1043
|
+
data: response.data
|
|
1044
|
+
});
|
|
1045
|
+
} catch (error) {
|
|
1046
|
+
reject(new Error("Failed to parse TCP response"));
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
1050
|
+
const onError = (error) => {
|
|
1051
|
+
if (!isResolved) {
|
|
1052
|
+
isResolved = true;
|
|
1053
|
+
clearTimeout(timeout);
|
|
1054
|
+
connection.off("data", onData);
|
|
1055
|
+
connection.off("error", onError);
|
|
1056
|
+
reject(error);
|
|
1057
|
+
}
|
|
1058
|
+
};
|
|
1059
|
+
connection.on("data", onData);
|
|
1060
|
+
connection.on("error", onError);
|
|
1061
|
+
const command = {
|
|
1062
|
+
action: "execute",
|
|
1063
|
+
dml: dmlJson
|
|
1064
|
+
};
|
|
1065
|
+
connection.write(JSON.stringify(command));
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
async createPersistentConnection(args) {
|
|
1069
|
+
return new Promise((resolve5, reject) => {
|
|
1070
|
+
const client = new net.Socket();
|
|
1071
|
+
let responseBuffer = "";
|
|
1072
|
+
let isResolved = false;
|
|
1073
|
+
client.setNoDelay(true);
|
|
1074
|
+
client.setKeepAlive(true, 6e4);
|
|
1075
|
+
const timeout = setTimeout(() => {
|
|
1076
|
+
if (!isResolved) {
|
|
1077
|
+
isResolved = true;
|
|
1078
|
+
client.destroy();
|
|
1079
|
+
reject(new Error("TCP connection timeout"));
|
|
1080
|
+
}
|
|
1081
|
+
}, 5e3);
|
|
1082
|
+
client.connect(this.tcpPort, "127.0.0.1", () => {
|
|
923
1083
|
clearTimeout(timeout);
|
|
924
|
-
|
|
925
|
-
|
|
1084
|
+
const dmlIndex = args.findIndex((arg) => arg === "--dml");
|
|
1085
|
+
const dmlJson = dmlIndex !== -1 ? args[dmlIndex + 1] : null;
|
|
1086
|
+
if (!dmlJson) {
|
|
1087
|
+
if (!isResolved) {
|
|
1088
|
+
isResolved = true;
|
|
1089
|
+
client.destroy();
|
|
1090
|
+
reject(new Error("No DML found in arguments"));
|
|
1091
|
+
}
|
|
1092
|
+
return;
|
|
1093
|
+
}
|
|
1094
|
+
globalTcpConnections.set(this.connectionId, client);
|
|
1095
|
+
const command = {
|
|
1096
|
+
action: "execute",
|
|
1097
|
+
dml: dmlJson
|
|
1098
|
+
};
|
|
1099
|
+
client.write(JSON.stringify(command));
|
|
1100
|
+
});
|
|
1101
|
+
client.on("data", (data) => {
|
|
1102
|
+
responseBuffer += data.toString();
|
|
1103
|
+
const match = responseBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1104
|
+
if (match && !isResolved) {
|
|
1105
|
+
isResolved = true;
|
|
1106
|
+
try {
|
|
1107
|
+
const response = JSON.parse(match[1]);
|
|
1108
|
+
resolve5({
|
|
1109
|
+
status: response.status,
|
|
1110
|
+
message: response.message,
|
|
1111
|
+
data: response.data
|
|
1112
|
+
});
|
|
1113
|
+
} catch (error) {
|
|
1114
|
+
reject(new Error("Failed to parse TCP response"));
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
});
|
|
1118
|
+
client.on("error", (error) => {
|
|
1119
|
+
if (!isResolved) {
|
|
1120
|
+
isResolved = true;
|
|
1121
|
+
globalTcpConnections.delete(this.connectionId);
|
|
1122
|
+
reject(error);
|
|
1123
|
+
}
|
|
1124
|
+
});
|
|
1125
|
+
client.on("close", () => {
|
|
1126
|
+
globalTcpConnections.delete(this.connectionId);
|
|
1127
|
+
if (!isResolved && !responseBuffer.includes("PROCESS_RESPONSE:")) {
|
|
1128
|
+
reject(new Error("Connection closed without valid response"));
|
|
926
1129
|
}
|
|
927
1130
|
});
|
|
928
1131
|
});
|
|
@@ -1015,6 +1218,12 @@ var QueryEngine = class {
|
|
|
1015
1218
|
});
|
|
1016
1219
|
}
|
|
1017
1220
|
async disconnect() {
|
|
1221
|
+
const connection = globalTcpConnections.get(this.connectionId);
|
|
1222
|
+
if (connection && connection.readyState === "open") {
|
|
1223
|
+
connection.write(JSON.stringify({ action: "disconnect" }));
|
|
1224
|
+
connection.destroy();
|
|
1225
|
+
globalTcpConnections.delete(this.connectionId);
|
|
1226
|
+
}
|
|
1018
1227
|
const serverInfo = globalTcpServers.get(this.connectionId);
|
|
1019
1228
|
if (serverInfo && serverInfo.process && !serverInfo.process.killed) {
|
|
1020
1229
|
console.log("\u{1F50C} Stopping TCP server...");
|
|
@@ -1022,7 +1231,7 @@ var QueryEngine = class {
|
|
|
1022
1231
|
globalTcpServers.delete(this.connectionId);
|
|
1023
1232
|
return {
|
|
1024
1233
|
status: 200,
|
|
1025
|
-
message: "TCP server stopped",
|
|
1234
|
+
message: "TCP server and connections stopped",
|
|
1026
1235
|
data: null
|
|
1027
1236
|
};
|
|
1028
1237
|
}
|