@dbcube/core 5.1.12 → 5.1.15
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 +337 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +70 -0
- package/dist/index.d.ts +70 -0
- package/dist/index.js +332 -58
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/lib/Engine.ts
|
|
2
|
-
import
|
|
2
|
+
import path4 from "path";
|
|
3
3
|
|
|
4
4
|
// src/lib/Arquitecture.ts
|
|
5
5
|
import * as os from "os";
|
|
@@ -687,14 +687,216 @@ var Config = class {
|
|
|
687
687
|
};
|
|
688
688
|
|
|
689
689
|
// src/lib/Engine.ts
|
|
690
|
-
import { spawn } from "child_process";
|
|
690
|
+
import { spawn as spawn2 } from "child_process";
|
|
691
691
|
import { createRequire } from "module";
|
|
692
|
+
|
|
693
|
+
// src/lib/DaemonClient.ts
|
|
694
|
+
import net from "net";
|
|
695
|
+
import fs3 from "fs";
|
|
696
|
+
import path3 from "path";
|
|
697
|
+
import { spawn } from "child_process";
|
|
698
|
+
var DaemonClient = class _DaemonClient {
|
|
699
|
+
static registry = /* @__PURE__ */ new Map();
|
|
700
|
+
name;
|
|
701
|
+
binaryPath;
|
|
702
|
+
engineArgs;
|
|
703
|
+
socket = null;
|
|
704
|
+
buffer = "";
|
|
705
|
+
pending = [];
|
|
706
|
+
starting = null;
|
|
707
|
+
requestTimeout;
|
|
708
|
+
constructor(name, binaryPath, engineArgs, requestTimeout = 3e4) {
|
|
709
|
+
this.name = name;
|
|
710
|
+
this.binaryPath = binaryPath;
|
|
711
|
+
this.engineArgs = engineArgs;
|
|
712
|
+
this.requestTimeout = requestTimeout;
|
|
713
|
+
}
|
|
714
|
+
static get(name, binaryPath, engineArgs) {
|
|
715
|
+
let client = this.registry.get(name);
|
|
716
|
+
if (!client) {
|
|
717
|
+
client = new _DaemonClient(name, binaryPath, engineArgs);
|
|
718
|
+
this.registry.set(name, client);
|
|
719
|
+
}
|
|
720
|
+
return client;
|
|
721
|
+
}
|
|
722
|
+
static isEnabled() {
|
|
723
|
+
const flag = process.env.DBCUBE_DAEMON;
|
|
724
|
+
if (flag === "0" || flag === "false") return false;
|
|
725
|
+
return true;
|
|
726
|
+
}
|
|
727
|
+
portfilePath() {
|
|
728
|
+
return path3.join(process.cwd(), ".dbcube", "daemon", `${this.name}.json`);
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Ensures a usable daemon connection. Returns false when the daemon
|
|
732
|
+
* can't be used (old binary, startup failure) so callers fall back
|
|
733
|
+
* to one-shot spawn mode.
|
|
734
|
+
*/
|
|
735
|
+
async ensure() {
|
|
736
|
+
if (this.socket && !this.socket.destroyed) return true;
|
|
737
|
+
if (this.starting) return this.starting;
|
|
738
|
+
this.starting = this.connectOrStart().catch(() => false);
|
|
739
|
+
const result = await this.starting;
|
|
740
|
+
this.starting = null;
|
|
741
|
+
return result;
|
|
742
|
+
}
|
|
743
|
+
async connectOrStart() {
|
|
744
|
+
const port = this.readPortfile();
|
|
745
|
+
if (port && await this.tryConnect(port)) return true;
|
|
746
|
+
try {
|
|
747
|
+
fs3.unlinkSync(this.portfilePath());
|
|
748
|
+
} catch {
|
|
749
|
+
}
|
|
750
|
+
this.spawnDaemon();
|
|
751
|
+
const deadline = Date.now() + 1e4;
|
|
752
|
+
while (Date.now() < deadline) {
|
|
753
|
+
await new Promise((r) => setTimeout(r, 150));
|
|
754
|
+
const newPort = this.readPortfile();
|
|
755
|
+
if (newPort && await this.tryConnect(newPort)) return true;
|
|
756
|
+
}
|
|
757
|
+
return false;
|
|
758
|
+
}
|
|
759
|
+
readPortfile() {
|
|
760
|
+
try {
|
|
761
|
+
const raw = fs3.readFileSync(this.portfilePath(), "utf8");
|
|
762
|
+
const info = JSON.parse(raw);
|
|
763
|
+
return typeof info.port === "number" ? info.port : null;
|
|
764
|
+
} catch {
|
|
765
|
+
return null;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
spawnDaemon() {
|
|
769
|
+
const child = spawn(this.binaryPath, [...this.engineArgs, "--action", "server", "--tcp-port", "9944"], {
|
|
770
|
+
detached: true,
|
|
771
|
+
stdio: "ignore",
|
|
772
|
+
cwd: process.cwd()
|
|
773
|
+
});
|
|
774
|
+
child.unref();
|
|
775
|
+
}
|
|
776
|
+
tryConnect(port) {
|
|
777
|
+
return new Promise((resolve5) => {
|
|
778
|
+
const socket = net.createConnection({ host: "127.0.0.1", port }, async () => {
|
|
779
|
+
socket.setNoDelay(true);
|
|
780
|
+
this.attach(socket);
|
|
781
|
+
try {
|
|
782
|
+
const pong = await this.send({ action: "ping" });
|
|
783
|
+
resolve5(pong.status === 200);
|
|
784
|
+
} catch {
|
|
785
|
+
this.detach();
|
|
786
|
+
resolve5(false);
|
|
787
|
+
}
|
|
788
|
+
});
|
|
789
|
+
socket.once("error", () => resolve5(false));
|
|
790
|
+
socket.setTimeout(3e3, () => {
|
|
791
|
+
socket.destroy();
|
|
792
|
+
resolve5(false);
|
|
793
|
+
});
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
attach(socket) {
|
|
797
|
+
this.socket = socket;
|
|
798
|
+
this.buffer = "";
|
|
799
|
+
socket.setTimeout(0);
|
|
800
|
+
socket.on("data", (chunk) => this.onData(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
|
|
801
|
+
socket.on("close", () => this.detach());
|
|
802
|
+
socket.on("error", () => this.detach());
|
|
803
|
+
}
|
|
804
|
+
detach() {
|
|
805
|
+
if (this.socket) {
|
|
806
|
+
this.socket.removeAllListeners();
|
|
807
|
+
this.socket.destroy();
|
|
808
|
+
this.socket = null;
|
|
809
|
+
}
|
|
810
|
+
for (const req of this.pending.splice(0)) {
|
|
811
|
+
clearTimeout(req.timer);
|
|
812
|
+
req.reject(new Error("Daemon connection lost"));
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
onData(chunk) {
|
|
816
|
+
this.buffer += chunk.toString("utf8");
|
|
817
|
+
let idx;
|
|
818
|
+
while ((idx = this.buffer.indexOf("\n")) !== -1) {
|
|
819
|
+
const line = this.buffer.slice(0, idx).trim();
|
|
820
|
+
this.buffer = this.buffer.slice(idx + 1);
|
|
821
|
+
if (!line) continue;
|
|
822
|
+
const marker = line.indexOf("PROCESS_RESPONSE:");
|
|
823
|
+
if (marker === -1) continue;
|
|
824
|
+
const jsonPart = line.slice(marker + "PROCESS_RESPONSE:".length);
|
|
825
|
+
const req = this.pending.shift();
|
|
826
|
+
if (!req) continue;
|
|
827
|
+
clearTimeout(req.timer);
|
|
828
|
+
try {
|
|
829
|
+
req.resolve(JSON.parse(jsonPart));
|
|
830
|
+
} catch (e) {
|
|
831
|
+
req.reject(new Error(`Invalid daemon response: ${e.message}`));
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* Sends a request to the daemon. Responses arrive in FIFO order on the
|
|
837
|
+
* single socket, so pending requests resolve in send order.
|
|
838
|
+
*/
|
|
839
|
+
send(payload) {
|
|
840
|
+
return new Promise((resolve5, reject) => {
|
|
841
|
+
if (!this.socket || this.socket.destroyed) {
|
|
842
|
+
reject(new Error("Daemon not connected"));
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
const timer = setTimeout(() => {
|
|
846
|
+
const i = this.pending.findIndex((p) => p.timer === timer);
|
|
847
|
+
if (i !== -1) this.pending.splice(i, 1);
|
|
848
|
+
reject(new Error("Daemon request timeout"));
|
|
849
|
+
}, this.requestTimeout);
|
|
850
|
+
this.pending.push({ resolve: resolve5, reject, timer });
|
|
851
|
+
this.socket.write(JSON.stringify(payload) + "\n");
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
async execute(dml, txId) {
|
|
855
|
+
const payload = { action: "execute", dml: JSON.stringify(dml) };
|
|
856
|
+
if (txId) payload.tx_id = txId;
|
|
857
|
+
return this.send(payload);
|
|
858
|
+
}
|
|
859
|
+
async raw(query, params = [], txId) {
|
|
860
|
+
const payload = { action: "raw", query, params };
|
|
861
|
+
if (txId) payload.tx_id = txId;
|
|
862
|
+
return this.send(payload);
|
|
863
|
+
}
|
|
864
|
+
async begin() {
|
|
865
|
+
const res = await this.send({ action: "begin" });
|
|
866
|
+
if (res.status !== 200 || !res.data?.tx_id) {
|
|
867
|
+
throw new Error(res.message || "Failed to begin transaction");
|
|
868
|
+
}
|
|
869
|
+
return res.data.tx_id;
|
|
870
|
+
}
|
|
871
|
+
async commit(txId) {
|
|
872
|
+
const res = await this.send({ action: "commit", tx_id: txId });
|
|
873
|
+
if (res.status !== 200) throw new Error(res.message || "Failed to commit transaction");
|
|
874
|
+
}
|
|
875
|
+
async rollback(txId) {
|
|
876
|
+
const res = await this.send({ action: "rollback", tx_id: txId });
|
|
877
|
+
if (res.status !== 200) throw new Error(res.message || "Failed to rollback transaction");
|
|
878
|
+
}
|
|
879
|
+
async shutdown() {
|
|
880
|
+
try {
|
|
881
|
+
await this.send({ action: "shutdown" });
|
|
882
|
+
} catch {
|
|
883
|
+
}
|
|
884
|
+
this.detach();
|
|
885
|
+
try {
|
|
886
|
+
fs3.unlinkSync(this.portfilePath());
|
|
887
|
+
} catch {
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
// src/lib/Engine.ts
|
|
692
893
|
var Engine = class {
|
|
693
894
|
name;
|
|
694
895
|
config;
|
|
695
896
|
arguments;
|
|
696
897
|
binary = null;
|
|
697
898
|
timeout;
|
|
899
|
+
daemonFailed = false;
|
|
698
900
|
constructor(name, timeout = 3e4) {
|
|
699
901
|
this.name = name;
|
|
700
902
|
this.config = this.setConfig(name);
|
|
@@ -706,6 +908,77 @@ var Engine = class {
|
|
|
706
908
|
this.binary = await Binary.get();
|
|
707
909
|
}
|
|
708
910
|
}
|
|
911
|
+
/**
|
|
912
|
+
* Returns a connected DaemonClient for this database, or null when
|
|
913
|
+
* daemon mode is disabled/unavailable (then callers use spawn mode).
|
|
914
|
+
*/
|
|
915
|
+
async getDaemon() {
|
|
916
|
+
if (this.daemonFailed || !DaemonClient.isEnabled()) return null;
|
|
917
|
+
await this.initializeBinary();
|
|
918
|
+
if (!this.binary) return null;
|
|
919
|
+
const binaryPath = this.binary["query_engine"];
|
|
920
|
+
if (!binaryPath) return null;
|
|
921
|
+
const client = DaemonClient.get(this.name, binaryPath, this.arguments);
|
|
922
|
+
const ok = await client.ensure();
|
|
923
|
+
if (!ok) {
|
|
924
|
+
this.daemonFailed = true;
|
|
925
|
+
return null;
|
|
926
|
+
}
|
|
927
|
+
return client;
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* Executes a DML plan. Uses the persistent daemon (sub-millisecond
|
|
931
|
+
* overhead) when available; falls back to one-shot spawn otherwise.
|
|
932
|
+
*/
|
|
933
|
+
async executeDml(dml, txId) {
|
|
934
|
+
const daemon = await this.getDaemon();
|
|
935
|
+
if (daemon) {
|
|
936
|
+
try {
|
|
937
|
+
return await daemon.execute(dml, txId);
|
|
938
|
+
} catch (error) {
|
|
939
|
+
if (txId) throw error;
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
if (txId) {
|
|
943
|
+
throw new Error("Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).");
|
|
944
|
+
}
|
|
945
|
+
return this.run("query_engine", ["--action", "execute", "--dml", JSON.stringify(dml)]);
|
|
946
|
+
}
|
|
947
|
+
/**
|
|
948
|
+
* Executes raw SQL (or a MongoDB command document) with bound parameters.
|
|
949
|
+
*/
|
|
950
|
+
async rawQuery(query, params = [], txId) {
|
|
951
|
+
const daemon = await this.getDaemon();
|
|
952
|
+
if (daemon) {
|
|
953
|
+
try {
|
|
954
|
+
return await daemon.raw(query, params, txId);
|
|
955
|
+
} catch (error) {
|
|
956
|
+
if (txId) throw error;
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
if (txId) {
|
|
960
|
+
throw new Error("Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).");
|
|
961
|
+
}
|
|
962
|
+
return this.run("query_engine", ["--action", "raw", "--query", query, "--params", JSON.stringify(params)]);
|
|
963
|
+
}
|
|
964
|
+
/** Starts a transaction (daemon mode only). Returns the transaction id. */
|
|
965
|
+
async beginTransaction() {
|
|
966
|
+
const daemon = await this.getDaemon();
|
|
967
|
+
if (!daemon) {
|
|
968
|
+
throw new Error("Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).");
|
|
969
|
+
}
|
|
970
|
+
return daemon.begin();
|
|
971
|
+
}
|
|
972
|
+
async commitTransaction(txId) {
|
|
973
|
+
const daemon = await this.getDaemon();
|
|
974
|
+
if (!daemon) throw new Error("Daemon connection lost during transaction");
|
|
975
|
+
return daemon.commit(txId);
|
|
976
|
+
}
|
|
977
|
+
async rollbackTransaction(txId) {
|
|
978
|
+
const daemon = await this.getDaemon();
|
|
979
|
+
if (!daemon) throw new Error("Daemon connection lost during transaction");
|
|
980
|
+
return daemon.rollback(txId);
|
|
981
|
+
}
|
|
709
982
|
setArguments() {
|
|
710
983
|
let args = [];
|
|
711
984
|
if (this.config.type == "sqlite") {
|
|
@@ -744,7 +1017,7 @@ var Engine = class {
|
|
|
744
1017
|
setConfig(name) {
|
|
745
1018
|
const configInstance = new Config();
|
|
746
1019
|
try {
|
|
747
|
-
const configFilePath =
|
|
1020
|
+
const configFilePath = path4.resolve(process.cwd(), "dbcube.config.js");
|
|
748
1021
|
const requireUrl = typeof __filename !== "undefined" ? __filename : process.cwd();
|
|
749
1022
|
const require2 = createRequire(requireUrl);
|
|
750
1023
|
if (require2.cache && require2.resolve) {
|
|
@@ -777,7 +1050,7 @@ var Engine = class {
|
|
|
777
1050
|
throw new Error("Binary not initialized");
|
|
778
1051
|
}
|
|
779
1052
|
return new Promise((resolve5, reject) => {
|
|
780
|
-
const child =
|
|
1053
|
+
const child = spawn2(this.binary[binary], [...this.arguments, ...args]);
|
|
781
1054
|
let stdoutBuffer = "";
|
|
782
1055
|
let stderrBuffer = "";
|
|
783
1056
|
let isResolved = false;
|
|
@@ -863,10 +1136,10 @@ var Engine = class {
|
|
|
863
1136
|
};
|
|
864
1137
|
|
|
865
1138
|
// src/lib/QueryEngine.ts
|
|
866
|
-
import
|
|
1139
|
+
import path5 from "path";
|
|
867
1140
|
import { createRequire as createRequire2 } from "module";
|
|
868
|
-
import * as
|
|
869
|
-
import { spawn as
|
|
1141
|
+
import * as net2 from "net";
|
|
1142
|
+
import { spawn as spawn3 } from "child_process";
|
|
870
1143
|
var globalTcpServers = /* @__PURE__ */ new Map();
|
|
871
1144
|
var globalTcpConnections = /* @__PURE__ */ new Map();
|
|
872
1145
|
var connectionQueues = /* @__PURE__ */ new Map();
|
|
@@ -903,7 +1176,7 @@ var QueryEngine = class {
|
|
|
903
1176
|
}
|
|
904
1177
|
isPortAvailable(port) {
|
|
905
1178
|
return new Promise((resolve5) => {
|
|
906
|
-
const tester =
|
|
1179
|
+
const tester = net2.createServer();
|
|
907
1180
|
tester.once("error", () => resolve5(false));
|
|
908
1181
|
tester.once("listening", () => {
|
|
909
1182
|
tester.close();
|
|
@@ -955,7 +1228,7 @@ var QueryEngine = class {
|
|
|
955
1228
|
setConfig(name) {
|
|
956
1229
|
const configInstance = new Config();
|
|
957
1230
|
try {
|
|
958
|
-
const configFilePath =
|
|
1231
|
+
const configFilePath = path5.resolve(process.cwd(), "dbcube.config.js");
|
|
959
1232
|
const requireUrl = typeof __filename !== "undefined" ? __filename : process.cwd();
|
|
960
1233
|
const require2 = createRequire2(requireUrl);
|
|
961
1234
|
if (require2.cache && require2.resolve) {
|
|
@@ -1017,7 +1290,7 @@ var QueryEngine = class {
|
|
|
1017
1290
|
}
|
|
1018
1291
|
async isServerResponding(port) {
|
|
1019
1292
|
return new Promise((resolve5) => {
|
|
1020
|
-
const client = new
|
|
1293
|
+
const client = new net2.Socket();
|
|
1021
1294
|
const timeout = setTimeout(() => {
|
|
1022
1295
|
client.destroy();
|
|
1023
1296
|
resolve5(false);
|
|
@@ -1055,7 +1328,7 @@ var QueryEngine = class {
|
|
|
1055
1328
|
this.tcpPort = await this.findAvailablePort(this.tcpPort);
|
|
1056
1329
|
return new Promise((resolve5, reject) => {
|
|
1057
1330
|
const serverArgs = [...this.arguments, "--action", "server", "--tcp-port", this.tcpPort.toString()];
|
|
1058
|
-
const serverProcess =
|
|
1331
|
+
const serverProcess = spawn3(this.binary["query_engine"], serverArgs);
|
|
1059
1332
|
let started = false;
|
|
1060
1333
|
const timeout = setTimeout(() => {
|
|
1061
1334
|
if (!started) {
|
|
@@ -1138,7 +1411,7 @@ var QueryEngine = class {
|
|
|
1138
1411
|
}
|
|
1139
1412
|
async createNewConnection(port) {
|
|
1140
1413
|
return new Promise((resolve5, reject) => {
|
|
1141
|
-
const client = new
|
|
1414
|
+
const client = new net2.Socket();
|
|
1142
1415
|
client.setNoDelay(true);
|
|
1143
1416
|
client.setKeepAlive(true, 6e4);
|
|
1144
1417
|
const timeout = setTimeout(() => {
|
|
@@ -1215,7 +1488,7 @@ var QueryEngine = class {
|
|
|
1215
1488
|
throw new Error("Binary not initialized");
|
|
1216
1489
|
}
|
|
1217
1490
|
return new Promise((resolve5, reject) => {
|
|
1218
|
-
const child =
|
|
1491
|
+
const child = spawn3(this.binary[binary], [...this.arguments, ...args]);
|
|
1219
1492
|
let stdoutBuffer = "";
|
|
1220
1493
|
let stderrBuffer = "";
|
|
1221
1494
|
let isResolved = false;
|
|
@@ -1323,8 +1596,8 @@ var QueryEngine = class {
|
|
|
1323
1596
|
|
|
1324
1597
|
// src/lib/SqliteExecutor.ts
|
|
1325
1598
|
import { exec } from "child_process";
|
|
1326
|
-
import * as
|
|
1327
|
-
import * as
|
|
1599
|
+
import * as path6 from "path";
|
|
1600
|
+
import * as fs4 from "fs";
|
|
1328
1601
|
import { promisify } from "util";
|
|
1329
1602
|
import { createRequire as createRequire3 } from "module";
|
|
1330
1603
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -1339,13 +1612,13 @@ var SqliteExecutor = class {
|
|
|
1339
1612
|
}
|
|
1340
1613
|
findVersionedBinary(binDir, platform2) {
|
|
1341
1614
|
try {
|
|
1342
|
-
const files =
|
|
1615
|
+
const files = fs4.readdirSync(binDir);
|
|
1343
1616
|
const extension = platform2 === "win32" ? ".exe" : "";
|
|
1344
1617
|
const platformName = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "macos" : "linux";
|
|
1345
1618
|
const pattern = new RegExp(`^sqlite-engine-v\\d+\\.\\d+\\.\\d+-${platformName}-x64${extension.replace(".", "\\.")}$`);
|
|
1346
1619
|
const matchingFile = files.find((f) => pattern.test(f));
|
|
1347
1620
|
if (matchingFile) {
|
|
1348
|
-
return
|
|
1621
|
+
return path6.join(binDir, matchingFile);
|
|
1349
1622
|
}
|
|
1350
1623
|
} catch (error) {
|
|
1351
1624
|
}
|
|
@@ -1355,34 +1628,34 @@ var SqliteExecutor = class {
|
|
|
1355
1628
|
const __filename2 = typeof import.meta !== "undefined" && import.meta.url ? fileURLToPath3(import.meta.url) : "";
|
|
1356
1629
|
const __dirname = __filename2 ? dirname3(__filename2) : process.cwd();
|
|
1357
1630
|
const possibleDirs = [
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1631
|
+
path6.resolve(process.cwd(), ".dbcube", "bin"),
|
|
1632
|
+
path6.resolve(process.cwd(), "node_modules", ".dbcube", "bin"),
|
|
1633
|
+
path6.resolve(__dirname, "..", "bin")
|
|
1361
1634
|
];
|
|
1362
1635
|
const platform2 = process.platform;
|
|
1363
1636
|
const extension = platform2 === "win32" ? ".exe" : "";
|
|
1364
1637
|
const platformName = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "macos" : "linux";
|
|
1365
1638
|
for (const dir of possibleDirs) {
|
|
1366
1639
|
const versionedPath = this.findVersionedBinary(dir, platform2);
|
|
1367
|
-
if (versionedPath &&
|
|
1640
|
+
if (versionedPath && fs4.existsSync(versionedPath)) {
|
|
1368
1641
|
return versionedPath;
|
|
1369
1642
|
}
|
|
1370
1643
|
}
|
|
1371
1644
|
const binaryName = `sqlite-engine-${platformName}-x64${extension}`;
|
|
1372
1645
|
for (const dir of possibleDirs) {
|
|
1373
|
-
const fullPath =
|
|
1374
|
-
if (
|
|
1646
|
+
const fullPath = path6.join(dir, binaryName);
|
|
1647
|
+
if (fs4.existsSync(fullPath)) {
|
|
1375
1648
|
return fullPath;
|
|
1376
1649
|
}
|
|
1377
1650
|
}
|
|
1378
1651
|
const fallbackName = `sqlite-engine${extension}`;
|
|
1379
1652
|
for (const dir of possibleDirs) {
|
|
1380
|
-
const fullPath =
|
|
1381
|
-
if (
|
|
1653
|
+
const fullPath = path6.join(dir, fallbackName);
|
|
1654
|
+
if (fs4.existsSync(fullPath)) {
|
|
1382
1655
|
return fullPath;
|
|
1383
1656
|
}
|
|
1384
1657
|
}
|
|
1385
|
-
return
|
|
1658
|
+
return path6.join(possibleDirs[0], binaryName);
|
|
1386
1659
|
}
|
|
1387
1660
|
async executeBinary(args) {
|
|
1388
1661
|
const escapedArgs = args.map((arg) => {
|
|
@@ -1533,9 +1806,9 @@ var SqliteExecutor = class {
|
|
|
1533
1806
|
};
|
|
1534
1807
|
|
|
1535
1808
|
// src/lib/DbConfig.ts
|
|
1536
|
-
import * as
|
|
1537
|
-
import
|
|
1538
|
-
var rootPath =
|
|
1809
|
+
import * as path7 from "path";
|
|
1810
|
+
import fs5 from "fs";
|
|
1811
|
+
var rootPath = path7.resolve(process.cwd(), ".dbcube");
|
|
1539
1812
|
var SQLite = class {
|
|
1540
1813
|
executor = null;
|
|
1541
1814
|
database;
|
|
@@ -1545,11 +1818,11 @@ var SQLite = class {
|
|
|
1545
1818
|
async ifExist() {
|
|
1546
1819
|
if (this.database) {
|
|
1547
1820
|
const dbPath = this.database || ":memory:";
|
|
1548
|
-
const configPath =
|
|
1549
|
-
if (!
|
|
1550
|
-
|
|
1821
|
+
const configPath = path7.join(rootPath, dbPath + ".db");
|
|
1822
|
+
if (!fs5.existsSync(rootPath)) {
|
|
1823
|
+
fs5.mkdirSync(rootPath, { recursive: true });
|
|
1551
1824
|
}
|
|
1552
|
-
if (
|
|
1825
|
+
if (fs5.existsSync(configPath)) {
|
|
1553
1826
|
return true;
|
|
1554
1827
|
}
|
|
1555
1828
|
if (!this.executor) {
|
|
@@ -1564,9 +1837,9 @@ var SQLite = class {
|
|
|
1564
1837
|
try {
|
|
1565
1838
|
if (!this.executor) {
|
|
1566
1839
|
const dbPath = this.database || ":memory:";
|
|
1567
|
-
const configPath =
|
|
1568
|
-
if (!
|
|
1569
|
-
|
|
1840
|
+
const configPath = path7.join(rootPath, dbPath + ".db");
|
|
1841
|
+
if (!fs5.existsSync(rootPath)) {
|
|
1842
|
+
fs5.mkdirSync(rootPath, { recursive: true });
|
|
1570
1843
|
}
|
|
1571
1844
|
this.executor = new SqliteExecutor(configPath);
|
|
1572
1845
|
const connected = await this.executor.connect();
|
|
@@ -1748,8 +2021,8 @@ var DbConfig = new SQLite({ DATABASE: "config" });
|
|
|
1748
2021
|
var DbConfig_default = DbConfig;
|
|
1749
2022
|
|
|
1750
2023
|
// src/lib/FileLogger.ts
|
|
1751
|
-
import * as
|
|
1752
|
-
import * as
|
|
2024
|
+
import * as fs6 from "fs";
|
|
2025
|
+
import * as path8 from "path";
|
|
1753
2026
|
import { EventEmitter } from "events";
|
|
1754
2027
|
var FileLogger = class _FileLogger extends EventEmitter {
|
|
1755
2028
|
static watchers = /* @__PURE__ */ new Map();
|
|
@@ -1764,9 +2037,9 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
1764
2037
|
*/
|
|
1765
2038
|
static async write(filePath, message, level = "INFO", append = true) {
|
|
1766
2039
|
try {
|
|
1767
|
-
const dir =
|
|
1768
|
-
if (!
|
|
1769
|
-
|
|
2040
|
+
const dir = path8.dirname(filePath);
|
|
2041
|
+
if (!fs6.existsSync(dir)) {
|
|
2042
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
1770
2043
|
}
|
|
1771
2044
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1772
2045
|
const formattedMessage = `[${timestamp}] [${level}] ${message}
|
|
@@ -1776,9 +2049,9 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
1776
2049
|
return true;
|
|
1777
2050
|
}
|
|
1778
2051
|
if (append) {
|
|
1779
|
-
await
|
|
2052
|
+
await fs6.promises.appendFile(filePath, formattedMessage, "utf8");
|
|
1780
2053
|
} else {
|
|
1781
|
-
await
|
|
2054
|
+
await fs6.promises.writeFile(filePath, formattedMessage, "utf8");
|
|
1782
2055
|
}
|
|
1783
2056
|
return true;
|
|
1784
2057
|
} catch (error) {
|
|
@@ -1803,12 +2076,12 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
1803
2076
|
const buffer = _FileLogger.buffers.get(filePath);
|
|
1804
2077
|
if (buffer && buffer.length > 0) {
|
|
1805
2078
|
try {
|
|
1806
|
-
const dir =
|
|
1807
|
-
if (!
|
|
1808
|
-
|
|
2079
|
+
const dir = path8.dirname(filePath);
|
|
2080
|
+
if (!fs6.existsSync(dir)) {
|
|
2081
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
1809
2082
|
}
|
|
1810
2083
|
const content = buffer.join("");
|
|
1811
|
-
await
|
|
2084
|
+
await fs6.promises.appendFile(filePath, content, "utf8");
|
|
1812
2085
|
_FileLogger.buffers.delete(filePath);
|
|
1813
2086
|
return true;
|
|
1814
2087
|
} catch (error) {
|
|
@@ -1944,10 +2217,10 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
1944
2217
|
// Si debe retornar como array de líneas
|
|
1945
2218
|
} = options;
|
|
1946
2219
|
try {
|
|
1947
|
-
if (!
|
|
2220
|
+
if (!fs6.existsSync(filePath)) {
|
|
1948
2221
|
return asArray ? [] : "";
|
|
1949
2222
|
}
|
|
1950
|
-
let content = await
|
|
2223
|
+
let content = await fs6.promises.readFile(filePath, "utf8");
|
|
1951
2224
|
if (asArray) {
|
|
1952
2225
|
let linesArray = content.split("\n").filter((line) => line.trim() !== "");
|
|
1953
2226
|
if (lines !== null) {
|
|
@@ -1990,15 +2263,15 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
1990
2263
|
} = options;
|
|
1991
2264
|
let lastSize = 0;
|
|
1992
2265
|
let lastPosition = 0;
|
|
1993
|
-
if (
|
|
1994
|
-
const stats =
|
|
2266
|
+
if (fs6.existsSync(filePath)) {
|
|
2267
|
+
const stats = fs6.statSync(filePath);
|
|
1995
2268
|
lastSize = stats.size;
|
|
1996
2269
|
lastPosition = fromEnd ? stats.size : 0;
|
|
1997
2270
|
}
|
|
1998
2271
|
const listener = async (curr, prev) => {
|
|
1999
2272
|
try {
|
|
2000
2273
|
if (curr.size > lastSize) {
|
|
2001
|
-
const stream =
|
|
2274
|
+
const stream = fs6.createReadStream(filePath, {
|
|
2002
2275
|
start: lastPosition,
|
|
2003
2276
|
end: curr.size - 1,
|
|
2004
2277
|
encoding: "utf8"
|
|
@@ -2026,7 +2299,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2026
2299
|
console.error("Error en watcher:", error);
|
|
2027
2300
|
}
|
|
2028
2301
|
};
|
|
2029
|
-
|
|
2302
|
+
fs6.watchFile(filePath, { persistent, interval }, listener);
|
|
2030
2303
|
const watcherId = `${filePath}_${Date.now()}`;
|
|
2031
2304
|
_FileLogger.watchers.set(watcherId, listener);
|
|
2032
2305
|
return {
|
|
@@ -2034,7 +2307,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2034
2307
|
stop: () => {
|
|
2035
2308
|
const storedListener = _FileLogger.watchers.get(watcherId);
|
|
2036
2309
|
if (storedListener) {
|
|
2037
|
-
|
|
2310
|
+
fs6.unwatchFile(filePath, storedListener);
|
|
2038
2311
|
_FileLogger.watchers.delete(watcherId);
|
|
2039
2312
|
}
|
|
2040
2313
|
},
|
|
@@ -2047,7 +2320,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2047
2320
|
static stopAllWatchers() {
|
|
2048
2321
|
for (const [watcherId] of _FileLogger.watchers) {
|
|
2049
2322
|
const filePath = watcherId.split("_")[0];
|
|
2050
|
-
|
|
2323
|
+
fs6.unwatchFile(filePath);
|
|
2051
2324
|
}
|
|
2052
2325
|
_FileLogger.watchers.clear();
|
|
2053
2326
|
}
|
|
@@ -2077,7 +2350,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2077
2350
|
if (lines.length > maxLines) {
|
|
2078
2351
|
const keepLines = lines.slice(-maxLines);
|
|
2079
2352
|
const content = keepLines.join("\n") + "\n";
|
|
2080
|
-
await
|
|
2353
|
+
await fs6.promises.writeFile(filePath, content, "utf8");
|
|
2081
2354
|
return lines.length - maxLines;
|
|
2082
2355
|
}
|
|
2083
2356
|
return 0;
|
|
@@ -2092,8 +2365,8 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2092
2365
|
*/
|
|
2093
2366
|
static async deleteLogFile(filePath) {
|
|
2094
2367
|
try {
|
|
2095
|
-
if (
|
|
2096
|
-
await
|
|
2368
|
+
if (fs6.existsSync(filePath)) {
|
|
2369
|
+
await fs6.promises.unlink(filePath);
|
|
2097
2370
|
return true;
|
|
2098
2371
|
}
|
|
2099
2372
|
return false;
|
|
@@ -2523,6 +2796,7 @@ export {
|
|
|
2523
2796
|
Binary,
|
|
2524
2797
|
ComputedFieldProcessor,
|
|
2525
2798
|
Config,
|
|
2799
|
+
DaemonClient,
|
|
2526
2800
|
DbConfig,
|
|
2527
2801
|
Engine,
|
|
2528
2802
|
FileLogger,
|