@dbcube/core 5.2.1 → 5.2.3
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/bin.cjs +29 -17
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +31 -19
- package/dist/bin.js.map +1 -1
- package/dist/index.cjs +521 -224
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +17 -6
- package/dist/index.d.ts +17 -6
- package/dist/index.js +542 -238
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
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 path4 from "path";
|
|
3
10
|
|
|
@@ -132,7 +139,7 @@ import * as unzipper from "unzipper";
|
|
|
132
139
|
import ora from "ora";
|
|
133
140
|
import chalk from "chalk";
|
|
134
141
|
import { fileURLToPath } from "url";
|
|
135
|
-
import { dirname } from "path";
|
|
142
|
+
import { dirname as dirname2 } from "path";
|
|
136
143
|
var { https } = followRedirects;
|
|
137
144
|
var Downloader = class {
|
|
138
145
|
static mainSpinner = null;
|
|
@@ -147,7 +154,7 @@ var Downloader = class {
|
|
|
147
154
|
*/
|
|
148
155
|
static async fetchLatestVersion(prefix) {
|
|
149
156
|
const url = this.VERSION_URLS[prefix];
|
|
150
|
-
return new Promise((
|
|
157
|
+
return new Promise((resolve6, reject) => {
|
|
151
158
|
https.get(url, (response) => {
|
|
152
159
|
let data = "";
|
|
153
160
|
response.on("data", (chunk) => {
|
|
@@ -157,7 +164,7 @@ var Downloader = class {
|
|
|
157
164
|
try {
|
|
158
165
|
const versions = JSON.parse(data);
|
|
159
166
|
if (versions && versions.length > 0) {
|
|
160
|
-
|
|
167
|
+
resolve6(versions[0].version);
|
|
161
168
|
} else {
|
|
162
169
|
reject(new Error("No versions found"));
|
|
163
170
|
}
|
|
@@ -366,7 +373,7 @@ var Downloader = class {
|
|
|
366
373
|
if (attempt < maxRetries && (errorMessage.includes("ECONNRESET") || errorMessage.includes("timeout") || errorMessage.includes("ETIMEDOUT") || errorMessage.includes("ENOTFOUND"))) {
|
|
367
374
|
attempt++;
|
|
368
375
|
console.log(`\u{1F504} Retrying ${binary.prefix}-engine (${attempt}/${maxRetries})...`);
|
|
369
|
-
await new Promise((
|
|
376
|
+
await new Promise((resolve6) => setTimeout(resolve6, 1e3 + Math.random() * 1e3));
|
|
370
377
|
} else {
|
|
371
378
|
throw new Error(`Error downloading ${binary.prefix}: ${errorMessage}`);
|
|
372
379
|
}
|
|
@@ -414,12 +421,12 @@ var Downloader = class {
|
|
|
414
421
|
return `[${filledBar}${emptyBar}] ${percentage}`;
|
|
415
422
|
}
|
|
416
423
|
static downloadFileWithProgress(url, outputPath, prefix) {
|
|
417
|
-
return new Promise((
|
|
424
|
+
return new Promise((resolve6, reject) => {
|
|
418
425
|
const request = https.get(url, { timeout: 0 }, (response) => {
|
|
419
426
|
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
420
427
|
const redirectUrl = response.headers.location;
|
|
421
428
|
if (redirectUrl) {
|
|
422
|
-
return this.downloadFileWithProgress(redirectUrl, outputPath, prefix).then(
|
|
429
|
+
return this.downloadFileWithProgress(redirectUrl, outputPath, prefix).then(resolve6).catch(reject);
|
|
423
430
|
}
|
|
424
431
|
}
|
|
425
432
|
if (response.statusCode !== 200) {
|
|
@@ -442,7 +449,7 @@ var Downloader = class {
|
|
|
442
449
|
}
|
|
443
450
|
});
|
|
444
451
|
response.on("end", () => {
|
|
445
|
-
file.end(() =>
|
|
452
|
+
file.end(() => resolve6());
|
|
446
453
|
});
|
|
447
454
|
response.on("error", (err) => {
|
|
448
455
|
file.close();
|
|
@@ -474,35 +481,47 @@ var Downloader = class {
|
|
|
474
481
|
this.mainSpinner.text = `\u{1F4E5} ${chalk.bold(binary)} - ${progressText}`;
|
|
475
482
|
}
|
|
476
483
|
static extractBinary(zipPath, outputPath, prefix) {
|
|
477
|
-
return new Promise((
|
|
478
|
-
|
|
484
|
+
return new Promise((resolve6, reject) => {
|
|
485
|
+
const outDir = path.dirname(outputPath);
|
|
486
|
+
let extracted = 0;
|
|
487
|
+
const pending = [];
|
|
479
488
|
fs.createReadStream(zipPath).pipe(unzipper.Parse()).on("entry", (entry) => {
|
|
480
|
-
if (entry.type
|
|
481
|
-
|
|
482
|
-
|
|
489
|
+
if (entry.type !== "File") {
|
|
490
|
+
entry.autodrain();
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
const isMain = extracted === 0;
|
|
494
|
+
extracted++;
|
|
495
|
+
const target = isMain ? outputPath : path.join(outDir, path.basename(entry.path));
|
|
496
|
+
pending.push(new Promise((res, rej) => {
|
|
497
|
+
const writeStream = fs.createWriteStream(target);
|
|
483
498
|
entry.pipe(writeStream);
|
|
484
499
|
writeStream.on("finish", () => {
|
|
485
500
|
if (process.platform !== "win32") {
|
|
486
|
-
|
|
501
|
+
try {
|
|
502
|
+
fs.chmodSync(target, 493);
|
|
503
|
+
} catch {
|
|
504
|
+
}
|
|
487
505
|
}
|
|
488
|
-
|
|
489
|
-
resolve5();
|
|
490
|
-
});
|
|
491
|
-
writeStream.on("error", (err) => {
|
|
492
|
-
this.cleanupFile(zipPath);
|
|
493
|
-
reject(err);
|
|
506
|
+
res();
|
|
494
507
|
});
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
}
|
|
508
|
+
writeStream.on("error", rej);
|
|
509
|
+
}));
|
|
498
510
|
}).on("error", (err) => {
|
|
499
511
|
this.cleanupFile(zipPath);
|
|
500
512
|
reject(err);
|
|
501
513
|
}).on("close", () => {
|
|
502
|
-
|
|
514
|
+
Promise.all(pending).then(() => {
|
|
503
515
|
this.cleanupFile(zipPath);
|
|
504
|
-
|
|
505
|
-
|
|
516
|
+
if (extracted === 0) {
|
|
517
|
+
reject(new Error(`No se encontr\xF3 archivo v\xE1lido en el ZIP para ${prefix}`));
|
|
518
|
+
} else {
|
|
519
|
+
resolve6();
|
|
520
|
+
}
|
|
521
|
+
}).catch((err) => {
|
|
522
|
+
this.cleanupFile(zipPath);
|
|
523
|
+
reject(err);
|
|
524
|
+
});
|
|
506
525
|
});
|
|
507
526
|
});
|
|
508
527
|
}
|
|
@@ -516,7 +535,7 @@ var Downloader = class {
|
|
|
516
535
|
}
|
|
517
536
|
static getDefaultBinDir() {
|
|
518
537
|
const __filename2 = typeof import.meta !== "undefined" && import.meta.url ? fileURLToPath(import.meta.url) : "";
|
|
519
|
-
const __dirname = __filename2 ?
|
|
538
|
+
const __dirname = __filename2 ? dirname2(__filename2) : process.cwd();
|
|
520
539
|
const possibleDirs = [
|
|
521
540
|
path.resolve(process.cwd(), ".dbcube", "bin"),
|
|
522
541
|
path.resolve(process.cwd(), "node_modules", ".dbcube", "bin"),
|
|
@@ -546,7 +565,7 @@ import * as fs2 from "fs";
|
|
|
546
565
|
import * as path2 from "path";
|
|
547
566
|
import * as os3 from "os";
|
|
548
567
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
549
|
-
import { dirname as
|
|
568
|
+
import { dirname as dirname3 } from "path";
|
|
550
569
|
var Binary = class {
|
|
551
570
|
static isDownloading = false;
|
|
552
571
|
static downloadPromise = null;
|
|
@@ -579,7 +598,7 @@ var Binary = class {
|
|
|
579
598
|
}
|
|
580
599
|
static getBinDir() {
|
|
581
600
|
const __filename2 = typeof import.meta !== "undefined" && import.meta.url ? fileURLToPath2(import.meta.url) : "";
|
|
582
|
-
const __dirname = __filename2 ?
|
|
601
|
+
const __dirname = __filename2 ? dirname3(__filename2) : process.cwd();
|
|
583
602
|
const possibleDirs = [
|
|
584
603
|
path2.resolve(process.cwd(), ".dbcube", "bin"),
|
|
585
604
|
path2.resolve(process.cwd(), "node_modules", ".dbcube", "bin"),
|
|
@@ -816,22 +835,22 @@ var DaemonClient = class _DaemonClient {
|
|
|
816
835
|
child.unref();
|
|
817
836
|
}
|
|
818
837
|
tryConnect(port) {
|
|
819
|
-
return new Promise((
|
|
838
|
+
return new Promise((resolve6) => {
|
|
820
839
|
const socket = net.createConnection({ host: "127.0.0.1", port }, async () => {
|
|
821
840
|
socket.setNoDelay(true);
|
|
822
841
|
this.attach(socket);
|
|
823
842
|
try {
|
|
824
843
|
const pong = await this.send({ action: "ping" }, 2e3);
|
|
825
|
-
|
|
844
|
+
resolve6(pong.status === 200);
|
|
826
845
|
} catch {
|
|
827
846
|
this.detach();
|
|
828
|
-
|
|
847
|
+
resolve6(false);
|
|
829
848
|
}
|
|
830
849
|
});
|
|
831
|
-
socket.once("error", () =>
|
|
850
|
+
socket.once("error", () => resolve6(false));
|
|
832
851
|
socket.setTimeout(3e3, () => {
|
|
833
852
|
socket.destroy();
|
|
834
|
-
|
|
853
|
+
resolve6(false);
|
|
835
854
|
});
|
|
836
855
|
});
|
|
837
856
|
}
|
|
@@ -879,7 +898,7 @@ var DaemonClient = class _DaemonClient {
|
|
|
879
898
|
* single socket, so pending requests resolve in send order.
|
|
880
899
|
*/
|
|
881
900
|
send(payload, timeoutMs) {
|
|
882
|
-
return new Promise((
|
|
901
|
+
return new Promise((resolve6, reject) => {
|
|
883
902
|
if (!this.socket || this.socket.destroyed) {
|
|
884
903
|
reject(new Error("Daemon not connected"));
|
|
885
904
|
return;
|
|
@@ -890,12 +909,12 @@ var DaemonClient = class _DaemonClient {
|
|
|
890
909
|
reject(new Error("Daemon request timeout"));
|
|
891
910
|
this.detach();
|
|
892
911
|
}, timeoutMs ?? this.requestTimeout);
|
|
893
|
-
this.pending.push({ resolve:
|
|
912
|
+
this.pending.push({ resolve: resolve6, reject, timer });
|
|
894
913
|
this.socket.write(JSON.stringify(payload) + "\n");
|
|
895
914
|
});
|
|
896
915
|
}
|
|
897
916
|
async execute(dml, txId) {
|
|
898
|
-
const payload = { action: "execute", dml
|
|
917
|
+
const payload = { action: "execute", dml };
|
|
899
918
|
if (txId) payload.tx_id = txId;
|
|
900
919
|
return this.send(payload);
|
|
901
920
|
}
|
|
@@ -962,8 +981,8 @@ var Engine = class {
|
|
|
962
981
|
const binaryPath = this.binary["query_engine"];
|
|
963
982
|
if (!binaryPath) return null;
|
|
964
983
|
const client = DaemonClient.get(this.name, binaryPath, this.arguments);
|
|
965
|
-
const
|
|
966
|
-
if (!
|
|
984
|
+
const ok2 = await client.ensure();
|
|
985
|
+
if (!ok2) {
|
|
967
986
|
this.daemonFailed = true;
|
|
968
987
|
return null;
|
|
969
988
|
}
|
|
@@ -1094,7 +1113,7 @@ var Engine = class {
|
|
|
1094
1113
|
if (!this.binary) {
|
|
1095
1114
|
throw new Error("Binary not initialized");
|
|
1096
1115
|
}
|
|
1097
|
-
return new Promise((
|
|
1116
|
+
return new Promise((resolve6, reject) => {
|
|
1098
1117
|
const child = spawn2(this.binary[binary], [...this.arguments, ...args]);
|
|
1099
1118
|
let stdoutBuffer = "";
|
|
1100
1119
|
let stderrBuffer = "";
|
|
@@ -1110,18 +1129,18 @@ var Engine = class {
|
|
|
1110
1129
|
if (!isResolved) {
|
|
1111
1130
|
isResolved = true;
|
|
1112
1131
|
clearTimeout(timeoutId);
|
|
1113
|
-
|
|
1132
|
+
resolve6(response);
|
|
1114
1133
|
}
|
|
1115
1134
|
};
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1135
|
+
const tryParseLines = (buffer) => {
|
|
1136
|
+
let idx;
|
|
1137
|
+
while ((idx = buffer.indexOf("\n")) !== -1) {
|
|
1138
|
+
const line = buffer.slice(0, idx);
|
|
1139
|
+
buffer = buffer.slice(idx + 1);
|
|
1140
|
+
const marker = line.indexOf("PROCESS_RESPONSE:");
|
|
1141
|
+
if (marker === -1) continue;
|
|
1123
1142
|
try {
|
|
1124
|
-
const response = JSON.parse(
|
|
1143
|
+
const response = JSON.parse(line.slice(marker + "PROCESS_RESPONSE:".length));
|
|
1125
1144
|
resolveOnce({
|
|
1126
1145
|
status: response.status,
|
|
1127
1146
|
message: response.message,
|
|
@@ -1135,29 +1154,19 @@ var Engine = class {
|
|
|
1135
1154
|
});
|
|
1136
1155
|
}
|
|
1137
1156
|
}
|
|
1157
|
+
return buffer;
|
|
1158
|
+
};
|
|
1159
|
+
child.stdout.on("data", (data) => {
|
|
1160
|
+
const text = data.toString();
|
|
1161
|
+
const visible = text.split("\n").filter((l) => l.trim() && !l.includes("PROCESS_RESPONSE:")).join("\n");
|
|
1162
|
+
if (visible) console.log(visible);
|
|
1163
|
+
stdoutBuffer = tryParseLines(stdoutBuffer + text);
|
|
1138
1164
|
});
|
|
1139
1165
|
child.stderr.on("data", (data) => {
|
|
1140
1166
|
const text = data.toString();
|
|
1141
|
-
stderrBuffer += text;
|
|
1142
1167
|
const visible = text.split("\n").filter((l) => l.trim() && !l.includes("PROCESS_RESPONSE:")).join("\n");
|
|
1143
1168
|
if (visible) console.log(visible);
|
|
1144
|
-
|
|
1145
|
-
if (match) {
|
|
1146
|
-
try {
|
|
1147
|
-
const response = JSON.parse(match[1]);
|
|
1148
|
-
resolveOnce({
|
|
1149
|
-
status: response.status,
|
|
1150
|
-
message: response.message,
|
|
1151
|
-
data: response.data
|
|
1152
|
-
});
|
|
1153
|
-
} catch (error) {
|
|
1154
|
-
resolveOnce({
|
|
1155
|
-
status: 500,
|
|
1156
|
-
message: "Failed to parse response JSON",
|
|
1157
|
-
data: null
|
|
1158
|
-
});
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1169
|
+
stderrBuffer = tryParseLines(stderrBuffer + text);
|
|
1161
1170
|
});
|
|
1162
1171
|
child.on("close", (code) => {
|
|
1163
1172
|
clearTimeout(timeoutId);
|
|
@@ -1185,14 +1194,265 @@ var Engine = class {
|
|
|
1185
1194
|
};
|
|
1186
1195
|
|
|
1187
1196
|
// src/lib/QueryEngine.ts
|
|
1188
|
-
import
|
|
1197
|
+
import path6 from "path";
|
|
1198
|
+
|
|
1199
|
+
// src/lib/EmbeddedEngine.ts
|
|
1200
|
+
import * as fs4 from "fs";
|
|
1201
|
+
import * as path5 from "path";
|
|
1202
|
+
if (!process.env.UV_THREADPOOL_SIZE) {
|
|
1203
|
+
process.env.UV_THREADPOOL_SIZE = "16";
|
|
1204
|
+
}
|
|
1205
|
+
var backend = null;
|
|
1206
|
+
var loadFailed = false;
|
|
1207
|
+
var handles = /* @__PURE__ */ new Map();
|
|
1208
|
+
var connecting = /* @__PURE__ */ new Map();
|
|
1209
|
+
function platTag() {
|
|
1210
|
+
const arch2 = process.arch === "arm64" ? "arm64" : "x64";
|
|
1211
|
+
if (process.platform === "win32") return { plat: "windows", ext: "dll", arch: arch2 };
|
|
1212
|
+
if (process.platform === "darwin") return { plat: "macos", ext: "dylib", arch: arch2 };
|
|
1213
|
+
return { plat: "linux", ext: "so", arch: arch2 };
|
|
1214
|
+
}
|
|
1215
|
+
function findFile(name) {
|
|
1216
|
+
const candidates = [
|
|
1217
|
+
path5.resolve(process.cwd(), ".dbcube", "bin", name),
|
|
1218
|
+
path5.resolve(process.cwd(), "node_modules", ".dbcube", "bin", name)
|
|
1219
|
+
];
|
|
1220
|
+
for (const c of candidates) {
|
|
1221
|
+
if (fs4.existsSync(c)) return c;
|
|
1222
|
+
}
|
|
1223
|
+
return null;
|
|
1224
|
+
}
|
|
1225
|
+
function ok(data) {
|
|
1226
|
+
return { status: 200, message: "OK", data };
|
|
1227
|
+
}
|
|
1228
|
+
function errResp(e) {
|
|
1229
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
1230
|
+
return { status: 500, message: msg, data: null };
|
|
1231
|
+
}
|
|
1232
|
+
function loadNapiBackend() {
|
|
1233
|
+
const { plat, arch: arch2 } = platTag();
|
|
1234
|
+
const addonPath = findFile(`query-engine-node-${plat}-${arch2}.node`);
|
|
1235
|
+
if (!addonPath) return null;
|
|
1236
|
+
try {
|
|
1237
|
+
const addon = __require(addonPath);
|
|
1238
|
+
if (typeof addon.connect !== "function") return null;
|
|
1239
|
+
return {
|
|
1240
|
+
async connect(cfgJson) {
|
|
1241
|
+
return Number(await addon.connect(cfgJson));
|
|
1242
|
+
},
|
|
1243
|
+
async execute(handle, dml, txId) {
|
|
1244
|
+
try {
|
|
1245
|
+
const rows = await addon.execute(handle, dml, txId ?? void 0);
|
|
1246
|
+
return ok(rows);
|
|
1247
|
+
} catch (e) {
|
|
1248
|
+
return errResp(e);
|
|
1249
|
+
}
|
|
1250
|
+
},
|
|
1251
|
+
async executeBatch(handle, ops) {
|
|
1252
|
+
try {
|
|
1253
|
+
const results = await addon.executeBatch(handle, ops);
|
|
1254
|
+
return ok(results);
|
|
1255
|
+
} catch (e) {
|
|
1256
|
+
return errResp(e);
|
|
1257
|
+
}
|
|
1258
|
+
},
|
|
1259
|
+
async raw(handle, query, params, txId) {
|
|
1260
|
+
try {
|
|
1261
|
+
const rows = await addon.raw(handle, query, params, txId ?? void 0);
|
|
1262
|
+
return ok(rows);
|
|
1263
|
+
} catch (e) {
|
|
1264
|
+
return errResp(e);
|
|
1265
|
+
}
|
|
1266
|
+
},
|
|
1267
|
+
async begin(handle) {
|
|
1268
|
+
try {
|
|
1269
|
+
const txId = await addon.begin(handle);
|
|
1270
|
+
return ok({ tx_id: txId });
|
|
1271
|
+
} catch (e) {
|
|
1272
|
+
return errResp(e);
|
|
1273
|
+
}
|
|
1274
|
+
},
|
|
1275
|
+
async commit(_handle, txId) {
|
|
1276
|
+
try {
|
|
1277
|
+
await addon.commit(txId);
|
|
1278
|
+
return ok(null);
|
|
1279
|
+
} catch (e) {
|
|
1280
|
+
return errResp(e);
|
|
1281
|
+
}
|
|
1282
|
+
},
|
|
1283
|
+
async rollback(_handle, txId) {
|
|
1284
|
+
try {
|
|
1285
|
+
await addon.rollback(txId);
|
|
1286
|
+
return ok(null);
|
|
1287
|
+
} catch (e) {
|
|
1288
|
+
return errResp(e);
|
|
1289
|
+
}
|
|
1290
|
+
},
|
|
1291
|
+
async disconnect(handle) {
|
|
1292
|
+
try {
|
|
1293
|
+
addon.disconnect(handle);
|
|
1294
|
+
} catch {
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
};
|
|
1298
|
+
} catch {
|
|
1299
|
+
return null;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
function loadKoffiBackend() {
|
|
1303
|
+
const { plat, ext, arch: arch2 } = platTag();
|
|
1304
|
+
const libPath = findFile(`query-engine-embedded-${plat}-${arch2}.${ext}`);
|
|
1305
|
+
if (!libPath) return null;
|
|
1306
|
+
try {
|
|
1307
|
+
const koffi = __require("koffi");
|
|
1308
|
+
const lib = koffi.load(libPath);
|
|
1309
|
+
const cConnect = lib.func("dbc_connect", "void *", ["str"]);
|
|
1310
|
+
const cExecute = lib.func("dbc_execute", "void *", ["uint64", "str", "str"]);
|
|
1311
|
+
const cExecuteBatch = lib.func("dbc_execute_batch", "void *", ["uint64", "str"]);
|
|
1312
|
+
const cRaw = lib.func("dbc_raw", "void *", ["uint64", "str", "str", "str"]);
|
|
1313
|
+
const cBegin = lib.func("dbc_begin", "void *", ["uint64"]);
|
|
1314
|
+
const cCommit = lib.func("dbc_commit", "void *", ["uint64", "str"]);
|
|
1315
|
+
const cRollback = lib.func("dbc_rollback", "void *", ["uint64", "str"]);
|
|
1316
|
+
const cDisconnect = lib.func("dbc_disconnect", "void *", ["uint64"]);
|
|
1317
|
+
const cFree = lib.func("dbc_free", "void", ["void *"]);
|
|
1318
|
+
const take = (ptr) => {
|
|
1319
|
+
if (!ptr) return { status: 500, message: "embedded engine returned null", data: null };
|
|
1320
|
+
const s = koffi.decode(ptr, "char", -1);
|
|
1321
|
+
cFree(ptr);
|
|
1322
|
+
try {
|
|
1323
|
+
const r = JSON.parse(s);
|
|
1324
|
+
return { status: r.status ?? 500, message: r.message ?? "", data: r.data ?? null };
|
|
1325
|
+
} catch (e) {
|
|
1326
|
+
return { status: 500, message: `Invalid embedded response: ${e.message}`, data: null };
|
|
1327
|
+
}
|
|
1328
|
+
};
|
|
1329
|
+
const call = (fn, ...args) => new Promise((resolve6, reject) => {
|
|
1330
|
+
fn.async(...args, (err, ptr) => {
|
|
1331
|
+
if (err) return reject(err);
|
|
1332
|
+
resolve6(take(ptr));
|
|
1333
|
+
});
|
|
1334
|
+
});
|
|
1335
|
+
return {
|
|
1336
|
+
async connect(cfgJson) {
|
|
1337
|
+
const res = await call(cConnect, cfgJson);
|
|
1338
|
+
if (res.status !== 200 || !res.data?.handle) {
|
|
1339
|
+
throw new Error(String(res.message || "embedded connect failed"));
|
|
1340
|
+
}
|
|
1341
|
+
return Number(res.data.handle);
|
|
1342
|
+
},
|
|
1343
|
+
execute: (handle, dml, txId) => call(cExecute, handle, JSON.stringify(dml), txId),
|
|
1344
|
+
executeBatch: (handle, ops) => call(cExecuteBatch, handle, JSON.stringify(ops)),
|
|
1345
|
+
raw: (handle, query, params, txId) => call(cRaw, handle, query, JSON.stringify(params ?? []), txId),
|
|
1346
|
+
begin: (handle) => call(cBegin, handle),
|
|
1347
|
+
commit: (handle, txId) => call(cCommit, handle, txId),
|
|
1348
|
+
rollback: (handle, txId) => call(cRollback, handle, txId),
|
|
1349
|
+
async disconnect(handle) {
|
|
1350
|
+
try {
|
|
1351
|
+
await call(cDisconnect, handle);
|
|
1352
|
+
} catch {
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1356
|
+
} catch {
|
|
1357
|
+
return null;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
function loadBackend() {
|
|
1361
|
+
if (backend) return backend;
|
|
1362
|
+
if (loadFailed) return null;
|
|
1363
|
+
if (process.env.DBCUBE_EMBEDDED === "0" || process.env.DBCUBE_EMBEDDED === "false") {
|
|
1364
|
+
loadFailed = true;
|
|
1365
|
+
return null;
|
|
1366
|
+
}
|
|
1367
|
+
backend = loadNapiBackend() ?? loadKoffiBackend();
|
|
1368
|
+
if (!backend) loadFailed = true;
|
|
1369
|
+
return backend;
|
|
1370
|
+
}
|
|
1371
|
+
var EmbeddedEngine = class {
|
|
1372
|
+
/** true si algún backend nativo está disponible en esta instalación. */
|
|
1373
|
+
static available() {
|
|
1374
|
+
return loadBackend() !== null;
|
|
1375
|
+
}
|
|
1376
|
+
static async handleFor(connectionId, config) {
|
|
1377
|
+
const existing = handles.get(connectionId);
|
|
1378
|
+
if (existing) return existing;
|
|
1379
|
+
const inFlight = connecting.get(connectionId);
|
|
1380
|
+
if (inFlight) return inFlight;
|
|
1381
|
+
const promise = (async () => {
|
|
1382
|
+
const be = loadBackend();
|
|
1383
|
+
if (!be) throw new Error("embedded engine not available");
|
|
1384
|
+
const motor = config.type === "postgres" ? "postgresql" : config.type;
|
|
1385
|
+
const cfg = {
|
|
1386
|
+
databaseRef: connectionId,
|
|
1387
|
+
motor,
|
|
1388
|
+
database: config.type === "sqlite" ? `${config.config.DATABASE}.db` : config.config.DATABASE,
|
|
1389
|
+
host: config.config.HOST,
|
|
1390
|
+
port: config.config.PORT != null ? Number(config.config.PORT) : void 0,
|
|
1391
|
+
user: config.config.USER,
|
|
1392
|
+
password: config.config.PASSWORD,
|
|
1393
|
+
maxConnections: config.pool?.maxConnections,
|
|
1394
|
+
minConnections: config.pool?.minConnections,
|
|
1395
|
+
acquireTimeoutMs: config.pool?.acquireTimeoutMs,
|
|
1396
|
+
idleTimeoutMs: config.pool?.idleTimeoutMs
|
|
1397
|
+
};
|
|
1398
|
+
const handle = await be.connect(JSON.stringify(cfg));
|
|
1399
|
+
handles.set(connectionId, handle);
|
|
1400
|
+
return handle;
|
|
1401
|
+
})();
|
|
1402
|
+
connecting.set(connectionId, promise);
|
|
1403
|
+
try {
|
|
1404
|
+
return await promise;
|
|
1405
|
+
} finally {
|
|
1406
|
+
connecting.delete(connectionId);
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
static async executeDml(connectionId, config, dml, txId) {
|
|
1410
|
+
const be = loadBackend();
|
|
1411
|
+
const handle = await this.handleFor(connectionId, config);
|
|
1412
|
+
return be.execute(handle, dml, txId ?? null);
|
|
1413
|
+
}
|
|
1414
|
+
static async executeBatch(connectionId, config, ops) {
|
|
1415
|
+
const be = loadBackend();
|
|
1416
|
+
const handle = await this.handleFor(connectionId, config);
|
|
1417
|
+
return be.executeBatch(handle, ops);
|
|
1418
|
+
}
|
|
1419
|
+
static async rawQuery(connectionId, config, query, params, txId) {
|
|
1420
|
+
const be = loadBackend();
|
|
1421
|
+
const handle = await this.handleFor(connectionId, config);
|
|
1422
|
+
return be.raw(handle, query, params ?? [], txId ?? null);
|
|
1423
|
+
}
|
|
1424
|
+
static async begin(connectionId, config) {
|
|
1425
|
+
const be = loadBackend();
|
|
1426
|
+
const handle = await this.handleFor(connectionId, config);
|
|
1427
|
+
return be.begin(handle);
|
|
1428
|
+
}
|
|
1429
|
+
static async commit(connectionId, config, txId) {
|
|
1430
|
+
const be = loadBackend();
|
|
1431
|
+
const handle = await this.handleFor(connectionId, config);
|
|
1432
|
+
return be.commit(handle, txId);
|
|
1433
|
+
}
|
|
1434
|
+
static async rollback(connectionId, config, txId) {
|
|
1435
|
+
const be = loadBackend();
|
|
1436
|
+
const handle = await this.handleFor(connectionId, config);
|
|
1437
|
+
return be.rollback(handle, txId);
|
|
1438
|
+
}
|
|
1439
|
+
static async disconnect(connectionId) {
|
|
1440
|
+
const be = loadBackend();
|
|
1441
|
+
const handle = handles.get(connectionId);
|
|
1442
|
+
if (be && handle) {
|
|
1443
|
+
handles.delete(connectionId);
|
|
1444
|
+
await be.disconnect(handle);
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
};
|
|
1448
|
+
|
|
1449
|
+
// src/lib/QueryEngine.ts
|
|
1189
1450
|
import { createRequire as createRequire2 } from "module";
|
|
1190
1451
|
import * as net2 from "net";
|
|
1191
1452
|
import { spawn as spawn3 } from "child_process";
|
|
1192
1453
|
var globalTcpServers = /* @__PURE__ */ new Map();
|
|
1193
|
-
var
|
|
1194
|
-
var
|
|
1195
|
-
var connectionProcessing = /* @__PURE__ */ new Map();
|
|
1454
|
+
var socketPools = /* @__PURE__ */ new Map();
|
|
1455
|
+
var CLIENT_POOL_SIZE = 10;
|
|
1196
1456
|
var queryCache = /* @__PURE__ */ new Map();
|
|
1197
1457
|
var MAX_CACHE_SIZE = 500;
|
|
1198
1458
|
var QueryEngine = class {
|
|
@@ -1223,12 +1483,12 @@ var QueryEngine = class {
|
|
|
1223
1483
|
throw new Error("No available ports found in range 9900-9944");
|
|
1224
1484
|
}
|
|
1225
1485
|
isPortAvailable(port) {
|
|
1226
|
-
return new Promise((
|
|
1486
|
+
return new Promise((resolve6) => {
|
|
1227
1487
|
const tester = net2.createServer();
|
|
1228
|
-
tester.once("error", () =>
|
|
1488
|
+
tester.once("error", () => resolve6(false));
|
|
1229
1489
|
tester.once("listening", () => {
|
|
1230
1490
|
tester.close();
|
|
1231
|
-
|
|
1491
|
+
resolve6(true);
|
|
1232
1492
|
});
|
|
1233
1493
|
tester.listen(port, "127.0.0.1");
|
|
1234
1494
|
});
|
|
@@ -1289,7 +1549,7 @@ var QueryEngine = class {
|
|
|
1289
1549
|
setConfig(name) {
|
|
1290
1550
|
const configInstance = new Config();
|
|
1291
1551
|
try {
|
|
1292
|
-
const configFilePath =
|
|
1552
|
+
const configFilePath = path6.resolve(process.cwd(), "dbcube.config.js");
|
|
1293
1553
|
const requireUrl = typeof __filename !== "undefined" ? __filename : process.cwd();
|
|
1294
1554
|
const require2 = createRequire2(requireUrl);
|
|
1295
1555
|
if (require2.cache && require2.resolve) {
|
|
@@ -1335,38 +1595,79 @@ var QueryEngine = class {
|
|
|
1335
1595
|
}
|
|
1336
1596
|
return command;
|
|
1337
1597
|
}
|
|
1598
|
+
/** El motor embebido (FFI) es el camino por defecto cuando la librería
|
|
1599
|
+
* nativa está disponible; el daemon TCP queda como fallback y como modo
|
|
1600
|
+
* multi-proceso explícito. */
|
|
1601
|
+
useEmbedded() {
|
|
1602
|
+
return EmbeddedEngine.available();
|
|
1603
|
+
}
|
|
1338
1604
|
/**
|
|
1339
|
-
* Executes a DML plan
|
|
1605
|
+
* Executes a DML plan. Embedded engine when available (in-process FFI,
|
|
1606
|
+
* no network hop); persistent TCP daemon otherwise.
|
|
1340
1607
|
* Pass txId to run it inside an active transaction.
|
|
1341
1608
|
*/
|
|
1342
1609
|
async executeDml(dml, txId) {
|
|
1343
|
-
|
|
1610
|
+
if (this.useEmbedded()) {
|
|
1611
|
+
return EmbeddedEngine.executeDml(this.connectionId, this.config, dml, txId);
|
|
1612
|
+
}
|
|
1613
|
+
const command = { action: "execute", dml };
|
|
1344
1614
|
if (txId) command.tx_id = txId;
|
|
1345
1615
|
return this.executeWithTcpServer(command);
|
|
1346
1616
|
}
|
|
1347
1617
|
/**
|
|
1348
|
-
*
|
|
1349
|
-
* over the
|
|
1618
|
+
* Atomic batch: N write plans inside one transaction with a single
|
|
1619
|
+
* engine round-trip. Falls back to begin/ops/commit over the daemon
|
|
1620
|
+
* when the embedded engine is not available.
|
|
1621
|
+
*/
|
|
1622
|
+
async executeBatch(ops) {
|
|
1623
|
+
if (this.useEmbedded()) {
|
|
1624
|
+
return EmbeddedEngine.executeBatch(this.connectionId, this.config, ops);
|
|
1625
|
+
}
|
|
1626
|
+
const txId = await this.beginTransaction();
|
|
1627
|
+
try {
|
|
1628
|
+
const results = [];
|
|
1629
|
+
for (const op of ops) {
|
|
1630
|
+
const res = await this.executeDml(op, txId);
|
|
1631
|
+
if (res.status !== 200) {
|
|
1632
|
+
throw new Error(String(res.message));
|
|
1633
|
+
}
|
|
1634
|
+
results.push(res.data);
|
|
1635
|
+
}
|
|
1636
|
+
await this.commitTransaction(txId);
|
|
1637
|
+
return { status: 200, message: "Batch committed", data: results };
|
|
1638
|
+
} catch (error) {
|
|
1639
|
+
try {
|
|
1640
|
+
await this.rollbackTransaction(txId);
|
|
1641
|
+
} catch {
|
|
1642
|
+
}
|
|
1643
|
+
return { status: 500, message: error?.message ?? String(error), data: null };
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
/**
|
|
1647
|
+
* Executes raw SQL (or a MongoDB command document) with bound parameters.
|
|
1350
1648
|
*/
|
|
1351
1649
|
async rawQuery(query, params = [], txId) {
|
|
1650
|
+
if (this.useEmbedded()) {
|
|
1651
|
+
return EmbeddedEngine.rawQuery(this.connectionId, this.config, query, params, txId);
|
|
1652
|
+
}
|
|
1352
1653
|
const command = { action: "raw", query, params };
|
|
1353
1654
|
if (txId) command.tx_id = txId;
|
|
1354
1655
|
return this.executeWithTcpServer(command);
|
|
1355
1656
|
}
|
|
1356
|
-
/** Starts a
|
|
1657
|
+
/** Starts a transaction and returns its id. */
|
|
1357
1658
|
async beginTransaction() {
|
|
1358
|
-
const res = await this.executeWithTcpServer({ action: "begin" });
|
|
1659
|
+
const res = this.useEmbedded() ? await EmbeddedEngine.begin(this.connectionId, this.config) : await this.executeWithTcpServer({ action: "begin" });
|
|
1359
1660
|
if (res.status !== 200 || !res.data?.tx_id) {
|
|
1360
1661
|
throw new Error(String(res.message || "Failed to begin transaction (update the query-engine binary: npx dbcube update)"));
|
|
1361
1662
|
}
|
|
1362
1663
|
return res.data.tx_id;
|
|
1363
1664
|
}
|
|
1364
1665
|
async commitTransaction(txId) {
|
|
1365
|
-
const res = await this.executeWithTcpServer({ action: "commit", tx_id: txId });
|
|
1666
|
+
const res = this.useEmbedded() ? await EmbeddedEngine.commit(this.connectionId, this.config, txId) : await this.executeWithTcpServer({ action: "commit", tx_id: txId });
|
|
1366
1667
|
if (res.status !== 200) throw new Error(String(res.message || "Failed to commit transaction"));
|
|
1367
1668
|
}
|
|
1368
1669
|
async rollbackTransaction(txId) {
|
|
1369
|
-
const res = await this.executeWithTcpServer({ action: "rollback", tx_id: txId });
|
|
1670
|
+
const res = this.useEmbedded() ? await EmbeddedEngine.rollback(this.connectionId, this.config, txId) : await this.executeWithTcpServer({ action: "rollback", tx_id: txId });
|
|
1370
1671
|
if (res.status !== 200) throw new Error(String(res.message || "Failed to rollback transaction"));
|
|
1371
1672
|
}
|
|
1372
1673
|
async executeWithTcpServer(command) {
|
|
@@ -1385,7 +1686,63 @@ var QueryEngine = class {
|
|
|
1385
1686
|
await this.startTcpServer();
|
|
1386
1687
|
await this.waitForServerReady();
|
|
1387
1688
|
}
|
|
1388
|
-
|
|
1689
|
+
const port = globalTcpServers.get(this.connectionId).port;
|
|
1690
|
+
const socket = await this.acquireSocket(port);
|
|
1691
|
+
try {
|
|
1692
|
+
const result = await this.executeOnConnection(socket, command);
|
|
1693
|
+
this.releaseSocket(socket, false);
|
|
1694
|
+
return result;
|
|
1695
|
+
} catch (error) {
|
|
1696
|
+
this.releaseSocket(socket, true);
|
|
1697
|
+
throw error;
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
poolFor() {
|
|
1701
|
+
let pool = socketPools.get(this.connectionId);
|
|
1702
|
+
if (!pool) {
|
|
1703
|
+
pool = { free: [], total: 0, waiters: [] };
|
|
1704
|
+
socketPools.set(this.connectionId, pool);
|
|
1705
|
+
}
|
|
1706
|
+
return pool;
|
|
1707
|
+
}
|
|
1708
|
+
async acquireSocket(port) {
|
|
1709
|
+
const pool = this.poolFor();
|
|
1710
|
+
while (pool.free.length > 0) {
|
|
1711
|
+
const s = pool.free.pop();
|
|
1712
|
+
if (!s.destroyed) return s;
|
|
1713
|
+
pool.total--;
|
|
1714
|
+
}
|
|
1715
|
+
if (pool.total < CLIENT_POOL_SIZE) {
|
|
1716
|
+
pool.total++;
|
|
1717
|
+
try {
|
|
1718
|
+
return await this.createNewConnection(port);
|
|
1719
|
+
} catch (e) {
|
|
1720
|
+
pool.total--;
|
|
1721
|
+
throw e;
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
return new Promise((resolve6) => pool.waiters.push(resolve6));
|
|
1725
|
+
}
|
|
1726
|
+
releaseSocket(socket, broken) {
|
|
1727
|
+
const pool = socketPools.get(this.connectionId);
|
|
1728
|
+
if (!pool) {
|
|
1729
|
+
socket.destroy();
|
|
1730
|
+
return;
|
|
1731
|
+
}
|
|
1732
|
+
if (broken || socket.destroyed) {
|
|
1733
|
+
pool.total--;
|
|
1734
|
+
try {
|
|
1735
|
+
socket.destroy();
|
|
1736
|
+
} catch {
|
|
1737
|
+
}
|
|
1738
|
+
return;
|
|
1739
|
+
}
|
|
1740
|
+
const waiter = pool.waiters.shift();
|
|
1741
|
+
if (waiter) {
|
|
1742
|
+
waiter(socket);
|
|
1743
|
+
} else {
|
|
1744
|
+
pool.free.push(socket);
|
|
1745
|
+
}
|
|
1389
1746
|
}
|
|
1390
1747
|
async waitForServerReady() {
|
|
1391
1748
|
const maxRetries = 10;
|
|
@@ -1403,25 +1760,25 @@ var QueryEngine = class {
|
|
|
1403
1760
|
throw new Error("TCP server failed to become ready within timeout");
|
|
1404
1761
|
}
|
|
1405
1762
|
async isServerResponding(port) {
|
|
1406
|
-
return new Promise((
|
|
1763
|
+
return new Promise((resolve6) => {
|
|
1407
1764
|
const client = new net2.Socket();
|
|
1408
1765
|
const timeout = setTimeout(() => {
|
|
1409
1766
|
client.destroy();
|
|
1410
|
-
|
|
1767
|
+
resolve6(false);
|
|
1411
1768
|
}, 1e3);
|
|
1412
1769
|
client.connect(port, "127.0.0.1", () => {
|
|
1413
1770
|
clearTimeout(timeout);
|
|
1414
1771
|
client.destroy();
|
|
1415
|
-
|
|
1772
|
+
resolve6(true);
|
|
1416
1773
|
});
|
|
1417
1774
|
client.on("error", () => {
|
|
1418
1775
|
clearTimeout(timeout);
|
|
1419
|
-
|
|
1776
|
+
resolve6(false);
|
|
1420
1777
|
});
|
|
1421
1778
|
});
|
|
1422
1779
|
}
|
|
1423
1780
|
sleep(ms) {
|
|
1424
|
-
return new Promise((
|
|
1781
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
1425
1782
|
}
|
|
1426
1783
|
getCachedDML(dmlJson) {
|
|
1427
1784
|
if (queryCache.has(dmlJson)) {
|
|
@@ -1441,7 +1798,7 @@ var QueryEngine = class {
|
|
|
1441
1798
|
throw new Error("Binary not initialized");
|
|
1442
1799
|
}
|
|
1443
1800
|
this.tcpPort = await this.findAvailablePort(this.tcpPort);
|
|
1444
|
-
return new Promise((
|
|
1801
|
+
return new Promise((resolve6, reject) => {
|
|
1445
1802
|
const serverArgs = [...this.arguments, "--action", "server", "--tcp-port", this.tcpPort.toString()];
|
|
1446
1803
|
const serverProcess = spawn3(this.binary["query_engine"], serverArgs);
|
|
1447
1804
|
let started = false;
|
|
@@ -1461,7 +1818,7 @@ var QueryEngine = class {
|
|
|
1461
1818
|
port: this.tcpPort,
|
|
1462
1819
|
process: serverProcess
|
|
1463
1820
|
});
|
|
1464
|
-
|
|
1821
|
+
resolve6();
|
|
1465
1822
|
}
|
|
1466
1823
|
}
|
|
1467
1824
|
});
|
|
@@ -1479,60 +1836,8 @@ var QueryEngine = class {
|
|
|
1479
1836
|
});
|
|
1480
1837
|
});
|
|
1481
1838
|
}
|
|
1482
|
-
async sendTcpRequestFast(command) {
|
|
1483
|
-
return new Promise((resolve5, reject) => {
|
|
1484
|
-
let queue = connectionQueues.get(this.connectionId);
|
|
1485
|
-
if (!queue) {
|
|
1486
|
-
queue = [];
|
|
1487
|
-
connectionQueues.set(this.connectionId, queue);
|
|
1488
|
-
}
|
|
1489
|
-
queue.push({ command, resolve: resolve5, reject });
|
|
1490
|
-
this.processQueue();
|
|
1491
|
-
});
|
|
1492
|
-
}
|
|
1493
|
-
async processQueue() {
|
|
1494
|
-
if (connectionProcessing.get(this.connectionId)) {
|
|
1495
|
-
return;
|
|
1496
|
-
}
|
|
1497
|
-
const queue = connectionQueues.get(this.connectionId);
|
|
1498
|
-
if (!queue || queue.length === 0) {
|
|
1499
|
-
return;
|
|
1500
|
-
}
|
|
1501
|
-
connectionProcessing.set(this.connectionId, true);
|
|
1502
|
-
try {
|
|
1503
|
-
const serverInfo = globalTcpServers.get(this.connectionId);
|
|
1504
|
-
if (!serverInfo) {
|
|
1505
|
-
throw new Error("Server not initialized");
|
|
1506
|
-
}
|
|
1507
|
-
while (queue.length > 0) {
|
|
1508
|
-
const request = queue.shift();
|
|
1509
|
-
if (!request) break;
|
|
1510
|
-
try {
|
|
1511
|
-
let connection = globalTcpConnections.get(this.connectionId);
|
|
1512
|
-
if (!connection || connection.destroyed || connection.readyState !== "open") {
|
|
1513
|
-
connection = await this.createNewConnection(serverInfo.port);
|
|
1514
|
-
globalTcpConnections.set(this.connectionId, connection);
|
|
1515
|
-
}
|
|
1516
|
-
const result = await this.executeOnConnection(connection, request.command);
|
|
1517
|
-
request.resolve(result);
|
|
1518
|
-
} catch (error) {
|
|
1519
|
-
const staleConnection = globalTcpConnections.get(this.connectionId);
|
|
1520
|
-
if (staleConnection) {
|
|
1521
|
-
try {
|
|
1522
|
-
staleConnection.destroy();
|
|
1523
|
-
} catch {
|
|
1524
|
-
}
|
|
1525
|
-
}
|
|
1526
|
-
globalTcpConnections.delete(this.connectionId);
|
|
1527
|
-
request.reject(error);
|
|
1528
|
-
}
|
|
1529
|
-
}
|
|
1530
|
-
} finally {
|
|
1531
|
-
connectionProcessing.set(this.connectionId, false);
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
1839
|
async createNewConnection(port) {
|
|
1535
|
-
return new Promise((
|
|
1840
|
+
return new Promise((resolve6, reject) => {
|
|
1536
1841
|
const client = new net2.Socket();
|
|
1537
1842
|
client.setNoDelay(true);
|
|
1538
1843
|
client.setKeepAlive(true, 6e4);
|
|
@@ -1542,7 +1847,7 @@ var QueryEngine = class {
|
|
|
1542
1847
|
}, 5e3);
|
|
1543
1848
|
client.connect(port, "127.0.0.1", () => {
|
|
1544
1849
|
clearTimeout(timeout);
|
|
1545
|
-
|
|
1850
|
+
resolve6(client);
|
|
1546
1851
|
});
|
|
1547
1852
|
client.on("error", (error) => {
|
|
1548
1853
|
clearTimeout(timeout);
|
|
@@ -1551,7 +1856,7 @@ var QueryEngine = class {
|
|
|
1551
1856
|
});
|
|
1552
1857
|
}
|
|
1553
1858
|
async executeOnConnection(connection, command) {
|
|
1554
|
-
return new Promise((
|
|
1859
|
+
return new Promise((resolve6, reject) => {
|
|
1555
1860
|
let responseBuffer = "";
|
|
1556
1861
|
let isResolved = false;
|
|
1557
1862
|
const timeout = setTimeout(() => {
|
|
@@ -1564,15 +1869,19 @@ var QueryEngine = class {
|
|
|
1564
1869
|
}, this.timeout);
|
|
1565
1870
|
const onData = (data) => {
|
|
1566
1871
|
responseBuffer += data.toString();
|
|
1567
|
-
|
|
1568
|
-
|
|
1872
|
+
let idx;
|
|
1873
|
+
while ((idx = responseBuffer.indexOf("\n")) !== -1 && !isResolved) {
|
|
1874
|
+
const line = responseBuffer.slice(0, idx);
|
|
1875
|
+
responseBuffer = responseBuffer.slice(idx + 1);
|
|
1876
|
+
const marker = line.indexOf("PROCESS_RESPONSE:");
|
|
1877
|
+
if (marker === -1) continue;
|
|
1569
1878
|
isResolved = true;
|
|
1570
1879
|
clearTimeout(timeout);
|
|
1571
1880
|
connection.removeListener("data", onData);
|
|
1572
1881
|
connection.removeListener("error", onError);
|
|
1573
1882
|
try {
|
|
1574
|
-
const response = JSON.parse(
|
|
1575
|
-
|
|
1883
|
+
const response = JSON.parse(line.slice(marker + "PROCESS_RESPONSE:".length));
|
|
1884
|
+
resolve6({
|
|
1576
1885
|
status: response.status,
|
|
1577
1886
|
message: response.message,
|
|
1578
1887
|
data: response.data
|
|
@@ -1601,7 +1910,7 @@ var QueryEngine = class {
|
|
|
1601
1910
|
if (!this.binary) {
|
|
1602
1911
|
throw new Error("Binary not initialized");
|
|
1603
1912
|
}
|
|
1604
|
-
return new Promise((
|
|
1913
|
+
return new Promise((resolve6, reject) => {
|
|
1605
1914
|
const child = spawn3(this.binary[binary], [...this.arguments, ...args]);
|
|
1606
1915
|
let stdoutBuffer = "";
|
|
1607
1916
|
let stderrBuffer = "";
|
|
@@ -1617,15 +1926,18 @@ var QueryEngine = class {
|
|
|
1617
1926
|
if (!isResolved) {
|
|
1618
1927
|
isResolved = true;
|
|
1619
1928
|
clearTimeout(timeoutId);
|
|
1620
|
-
|
|
1929
|
+
resolve6(response);
|
|
1621
1930
|
}
|
|
1622
1931
|
};
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1932
|
+
const tryParseLines = (buffer) => {
|
|
1933
|
+
let idx;
|
|
1934
|
+
while ((idx = buffer.indexOf("\n")) !== -1) {
|
|
1935
|
+
const line = buffer.slice(0, idx);
|
|
1936
|
+
buffer = buffer.slice(idx + 1);
|
|
1937
|
+
const marker = line.indexOf("PROCESS_RESPONSE:");
|
|
1938
|
+
if (marker === -1) continue;
|
|
1627
1939
|
try {
|
|
1628
|
-
const response = JSON.parse(
|
|
1940
|
+
const response = JSON.parse(line.slice(marker + "PROCESS_RESPONSE:".length));
|
|
1629
1941
|
resolveOnce({
|
|
1630
1942
|
status: response.status,
|
|
1631
1943
|
message: response.message,
|
|
@@ -1639,26 +1951,13 @@ var QueryEngine = class {
|
|
|
1639
1951
|
});
|
|
1640
1952
|
}
|
|
1641
1953
|
}
|
|
1954
|
+
return buffer;
|
|
1955
|
+
};
|
|
1956
|
+
child.stdout.on("data", (data) => {
|
|
1957
|
+
stdoutBuffer = tryParseLines(stdoutBuffer + data.toString());
|
|
1642
1958
|
});
|
|
1643
1959
|
child.stderr.on("data", (data) => {
|
|
1644
|
-
stderrBuffer
|
|
1645
|
-
const match = stderrBuffer.match(/PROCESS_RESPONSE:(\{.*\})/);
|
|
1646
|
-
if (match) {
|
|
1647
|
-
try {
|
|
1648
|
-
const response = JSON.parse(match[1]);
|
|
1649
|
-
resolveOnce({
|
|
1650
|
-
status: response.status,
|
|
1651
|
-
message: response.message,
|
|
1652
|
-
data: response.data
|
|
1653
|
-
});
|
|
1654
|
-
} catch (error) {
|
|
1655
|
-
resolveOnce({
|
|
1656
|
-
status: 500,
|
|
1657
|
-
message: "Failed to parse response JSON",
|
|
1658
|
-
data: null
|
|
1659
|
-
});
|
|
1660
|
-
}
|
|
1661
|
-
}
|
|
1960
|
+
stderrBuffer = tryParseLines(stderrBuffer + data.toString());
|
|
1662
1961
|
});
|
|
1663
1962
|
child.on("close", (code) => {
|
|
1664
1963
|
clearTimeout(timeoutId);
|
|
@@ -1684,11 +1983,16 @@ var QueryEngine = class {
|
|
|
1684
1983
|
});
|
|
1685
1984
|
}
|
|
1686
1985
|
async disconnect() {
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1986
|
+
await EmbeddedEngine.disconnect(this.connectionId);
|
|
1987
|
+
const pool = socketPools.get(this.connectionId);
|
|
1988
|
+
if (pool) {
|
|
1989
|
+
for (const s of pool.free) {
|
|
1990
|
+
try {
|
|
1991
|
+
s.destroy();
|
|
1992
|
+
} catch {
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
socketPools.delete(this.connectionId);
|
|
1692
1996
|
}
|
|
1693
1997
|
const serverInfo = globalTcpServers.get(this.connectionId);
|
|
1694
1998
|
if (serverInfo && serverInfo.process && !serverInfo.process.killed) {
|
|
@@ -1710,12 +2014,12 @@ var QueryEngine = class {
|
|
|
1710
2014
|
|
|
1711
2015
|
// src/lib/SqliteExecutor.ts
|
|
1712
2016
|
import { exec } from "child_process";
|
|
1713
|
-
import * as
|
|
1714
|
-
import * as
|
|
2017
|
+
import * as path7 from "path";
|
|
2018
|
+
import * as fs5 from "fs";
|
|
1715
2019
|
import { promisify } from "util";
|
|
1716
2020
|
import { createRequire as createRequire3 } from "module";
|
|
1717
2021
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
1718
|
-
import { dirname as
|
|
2022
|
+
import { dirname as dirname4 } from "path";
|
|
1719
2023
|
var execAsync = promisify(exec);
|
|
1720
2024
|
var SqliteExecutor = class {
|
|
1721
2025
|
binaryPath;
|
|
@@ -1726,13 +2030,13 @@ var SqliteExecutor = class {
|
|
|
1726
2030
|
}
|
|
1727
2031
|
findVersionedBinary(binDir, platform2) {
|
|
1728
2032
|
try {
|
|
1729
|
-
const files =
|
|
2033
|
+
const files = fs5.readdirSync(binDir);
|
|
1730
2034
|
const extension = platform2 === "win32" ? ".exe" : "";
|
|
1731
2035
|
const platformName = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "macos" : "linux";
|
|
1732
2036
|
const pattern = new RegExp(`^sqlite-engine-v\\d+\\.\\d+\\.\\d+-${platformName}-x64${extension.replace(".", "\\.")}$`);
|
|
1733
2037
|
const matchingFile = files.find((f) => pattern.test(f));
|
|
1734
2038
|
if (matchingFile) {
|
|
1735
|
-
return
|
|
2039
|
+
return path7.join(binDir, matchingFile);
|
|
1736
2040
|
}
|
|
1737
2041
|
} catch (error) {
|
|
1738
2042
|
}
|
|
@@ -1740,36 +2044,36 @@ var SqliteExecutor = class {
|
|
|
1740
2044
|
}
|
|
1741
2045
|
getBinaryPath() {
|
|
1742
2046
|
const __filename2 = typeof import.meta !== "undefined" && import.meta.url ? fileURLToPath3(import.meta.url) : "";
|
|
1743
|
-
const __dirname = __filename2 ?
|
|
2047
|
+
const __dirname = __filename2 ? dirname4(__filename2) : process.cwd();
|
|
1744
2048
|
const possibleDirs = [
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
2049
|
+
path7.resolve(process.cwd(), ".dbcube", "bin"),
|
|
2050
|
+
path7.resolve(process.cwd(), "node_modules", ".dbcube", "bin"),
|
|
2051
|
+
path7.resolve(__dirname, "..", "bin")
|
|
1748
2052
|
];
|
|
1749
2053
|
const platform2 = process.platform;
|
|
1750
2054
|
const extension = platform2 === "win32" ? ".exe" : "";
|
|
1751
2055
|
const platformName = platform2 === "win32" ? "windows" : platform2 === "darwin" ? "macos" : "linux";
|
|
1752
2056
|
for (const dir of possibleDirs) {
|
|
1753
2057
|
const versionedPath = this.findVersionedBinary(dir, platform2);
|
|
1754
|
-
if (versionedPath &&
|
|
2058
|
+
if (versionedPath && fs5.existsSync(versionedPath)) {
|
|
1755
2059
|
return versionedPath;
|
|
1756
2060
|
}
|
|
1757
2061
|
}
|
|
1758
2062
|
const binaryName = `sqlite-engine-${platformName}-x64${extension}`;
|
|
1759
2063
|
for (const dir of possibleDirs) {
|
|
1760
|
-
const fullPath =
|
|
1761
|
-
if (
|
|
2064
|
+
const fullPath = path7.join(dir, binaryName);
|
|
2065
|
+
if (fs5.existsSync(fullPath)) {
|
|
1762
2066
|
return fullPath;
|
|
1763
2067
|
}
|
|
1764
2068
|
}
|
|
1765
2069
|
const fallbackName = `sqlite-engine${extension}`;
|
|
1766
2070
|
for (const dir of possibleDirs) {
|
|
1767
|
-
const fullPath =
|
|
1768
|
-
if (
|
|
2071
|
+
const fullPath = path7.join(dir, fallbackName);
|
|
2072
|
+
if (fs5.existsSync(fullPath)) {
|
|
1769
2073
|
return fullPath;
|
|
1770
2074
|
}
|
|
1771
2075
|
}
|
|
1772
|
-
return
|
|
2076
|
+
return path7.join(possibleDirs[0], binaryName);
|
|
1773
2077
|
}
|
|
1774
2078
|
async executeBinary(args) {
|
|
1775
2079
|
const escapedArgs = args.map((arg) => {
|
|
@@ -1920,9 +2224,9 @@ var SqliteExecutor = class {
|
|
|
1920
2224
|
};
|
|
1921
2225
|
|
|
1922
2226
|
// src/lib/DbConfig.ts
|
|
1923
|
-
import * as
|
|
1924
|
-
import
|
|
1925
|
-
var rootPath =
|
|
2227
|
+
import * as path8 from "path";
|
|
2228
|
+
import fs6 from "fs";
|
|
2229
|
+
var rootPath = path8.resolve(process.cwd(), ".dbcube");
|
|
1926
2230
|
var SQLite = class {
|
|
1927
2231
|
executor = null;
|
|
1928
2232
|
database;
|
|
@@ -1932,11 +2236,11 @@ var SQLite = class {
|
|
|
1932
2236
|
async ifExist() {
|
|
1933
2237
|
if (this.database) {
|
|
1934
2238
|
const dbPath = this.database || ":memory:";
|
|
1935
|
-
const configPath =
|
|
1936
|
-
if (!
|
|
1937
|
-
|
|
2239
|
+
const configPath = path8.join(rootPath, dbPath + ".db");
|
|
2240
|
+
if (!fs6.existsSync(rootPath)) {
|
|
2241
|
+
fs6.mkdirSync(rootPath, { recursive: true });
|
|
1938
2242
|
}
|
|
1939
|
-
if (
|
|
2243
|
+
if (fs6.existsSync(configPath)) {
|
|
1940
2244
|
return true;
|
|
1941
2245
|
}
|
|
1942
2246
|
if (!this.executor) {
|
|
@@ -1947,13 +2251,13 @@ var SQLite = class {
|
|
|
1947
2251
|
return false;
|
|
1948
2252
|
}
|
|
1949
2253
|
async connect() {
|
|
1950
|
-
return new Promise(async (
|
|
2254
|
+
return new Promise(async (resolve6, reject) => {
|
|
1951
2255
|
try {
|
|
1952
2256
|
if (!this.executor) {
|
|
1953
2257
|
const dbPath = this.database || ":memory:";
|
|
1954
|
-
const configPath =
|
|
1955
|
-
if (!
|
|
1956
|
-
|
|
2258
|
+
const configPath = path8.join(rootPath, dbPath + ".db");
|
|
2259
|
+
if (!fs6.existsSync(rootPath)) {
|
|
2260
|
+
fs6.mkdirSync(rootPath, { recursive: true });
|
|
1957
2261
|
}
|
|
1958
2262
|
this.executor = new SqliteExecutor(configPath);
|
|
1959
2263
|
const connected = await this.executor.connect();
|
|
@@ -1961,22 +2265,22 @@ var SQLite = class {
|
|
|
1961
2265
|
throw new Error("Failed to connect to SQLite database");
|
|
1962
2266
|
}
|
|
1963
2267
|
}
|
|
1964
|
-
|
|
2268
|
+
resolve6(this.executor);
|
|
1965
2269
|
} catch (error) {
|
|
1966
2270
|
reject(error);
|
|
1967
2271
|
}
|
|
1968
2272
|
});
|
|
1969
2273
|
}
|
|
1970
2274
|
async disconnect() {
|
|
1971
|
-
return new Promise((
|
|
2275
|
+
return new Promise((resolve6) => {
|
|
1972
2276
|
if (this.executor) {
|
|
1973
2277
|
this.executor = null;
|
|
1974
2278
|
}
|
|
1975
|
-
|
|
2279
|
+
resolve6();
|
|
1976
2280
|
});
|
|
1977
2281
|
}
|
|
1978
2282
|
async query(sqlQuery) {
|
|
1979
|
-
return new Promise(async (
|
|
2283
|
+
return new Promise(async (resolve6) => {
|
|
1980
2284
|
try {
|
|
1981
2285
|
if (typeof sqlQuery !== "string") {
|
|
1982
2286
|
throw new Error("The SQL query must be a string.");
|
|
@@ -1989,20 +2293,20 @@ var SQLite = class {
|
|
|
1989
2293
|
}
|
|
1990
2294
|
const result = await this.executor.queryMultiple(sqlQuery);
|
|
1991
2295
|
if (result.status === "error") {
|
|
1992
|
-
|
|
2296
|
+
resolve6({
|
|
1993
2297
|
status: "error",
|
|
1994
2298
|
message: result.message,
|
|
1995
2299
|
data: null
|
|
1996
2300
|
});
|
|
1997
2301
|
} else {
|
|
1998
|
-
|
|
2302
|
+
resolve6({
|
|
1999
2303
|
status: "success",
|
|
2000
2304
|
message: "Query executed successfully",
|
|
2001
2305
|
data: result.data
|
|
2002
2306
|
});
|
|
2003
2307
|
}
|
|
2004
2308
|
} catch (error) {
|
|
2005
|
-
|
|
2309
|
+
resolve6({
|
|
2006
2310
|
status: "error",
|
|
2007
2311
|
message: error.message || "An error occurred while executing the query.",
|
|
2008
2312
|
data: null
|
|
@@ -2011,7 +2315,7 @@ var SQLite = class {
|
|
|
2011
2315
|
});
|
|
2012
2316
|
}
|
|
2013
2317
|
async queryWithParameters(sqlQuery, params = []) {
|
|
2014
|
-
return new Promise(async (
|
|
2318
|
+
return new Promise(async (resolve6) => {
|
|
2015
2319
|
try {
|
|
2016
2320
|
if (typeof sqlQuery !== "string") {
|
|
2017
2321
|
throw new Error("The SQL query must be a string.");
|
|
@@ -2027,13 +2331,13 @@ var SQLite = class {
|
|
|
2027
2331
|
}
|
|
2028
2332
|
const result = await this.executor.query(sqlQuery, params);
|
|
2029
2333
|
if (result.status === "error") {
|
|
2030
|
-
|
|
2334
|
+
resolve6({
|
|
2031
2335
|
status: "error",
|
|
2032
2336
|
message: result.message,
|
|
2033
2337
|
data: null
|
|
2034
2338
|
});
|
|
2035
2339
|
} else {
|
|
2036
|
-
|
|
2340
|
+
resolve6({
|
|
2037
2341
|
status: "success",
|
|
2038
2342
|
message: "Query executed successfully",
|
|
2039
2343
|
data: result.data
|
|
@@ -2041,7 +2345,7 @@ var SQLite = class {
|
|
|
2041
2345
|
}
|
|
2042
2346
|
} catch (error) {
|
|
2043
2347
|
console.log(error);
|
|
2044
|
-
|
|
2348
|
+
resolve6({
|
|
2045
2349
|
status: "error",
|
|
2046
2350
|
message: error.message || "An error occurred while executing the query.",
|
|
2047
2351
|
data: null
|
|
@@ -2135,8 +2439,8 @@ var DbConfig = new SQLite({ DATABASE: "config" });
|
|
|
2135
2439
|
var DbConfig_default = DbConfig;
|
|
2136
2440
|
|
|
2137
2441
|
// src/lib/FileLogger.ts
|
|
2138
|
-
import * as
|
|
2139
|
-
import * as
|
|
2442
|
+
import * as fs7 from "fs";
|
|
2443
|
+
import * as path9 from "path";
|
|
2140
2444
|
import { EventEmitter } from "events";
|
|
2141
2445
|
var FileLogger = class _FileLogger extends EventEmitter {
|
|
2142
2446
|
static watchers = /* @__PURE__ */ new Map();
|
|
@@ -2151,9 +2455,9 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2151
2455
|
*/
|
|
2152
2456
|
static async write(filePath, message, level = "INFO", append = true) {
|
|
2153
2457
|
try {
|
|
2154
|
-
const dir =
|
|
2155
|
-
if (!
|
|
2156
|
-
|
|
2458
|
+
const dir = path9.dirname(filePath);
|
|
2459
|
+
if (!fs7.existsSync(dir)) {
|
|
2460
|
+
fs7.mkdirSync(dir, { recursive: true });
|
|
2157
2461
|
}
|
|
2158
2462
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2159
2463
|
const formattedMessage = `[${timestamp}] [${level}] ${message}
|
|
@@ -2163,9 +2467,9 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2163
2467
|
return true;
|
|
2164
2468
|
}
|
|
2165
2469
|
if (append) {
|
|
2166
|
-
await
|
|
2470
|
+
await fs7.promises.appendFile(filePath, formattedMessage, "utf8");
|
|
2167
2471
|
} else {
|
|
2168
|
-
await
|
|
2472
|
+
await fs7.promises.writeFile(filePath, formattedMessage, "utf8");
|
|
2169
2473
|
}
|
|
2170
2474
|
return true;
|
|
2171
2475
|
} catch (error) {
|
|
@@ -2190,12 +2494,12 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2190
2494
|
const buffer = _FileLogger.buffers.get(filePath);
|
|
2191
2495
|
if (buffer && buffer.length > 0) {
|
|
2192
2496
|
try {
|
|
2193
|
-
const dir =
|
|
2194
|
-
if (!
|
|
2195
|
-
|
|
2497
|
+
const dir = path9.dirname(filePath);
|
|
2498
|
+
if (!fs7.existsSync(dir)) {
|
|
2499
|
+
fs7.mkdirSync(dir, { recursive: true });
|
|
2196
2500
|
}
|
|
2197
2501
|
const content = buffer.join("");
|
|
2198
|
-
await
|
|
2502
|
+
await fs7.promises.appendFile(filePath, content, "utf8");
|
|
2199
2503
|
_FileLogger.buffers.delete(filePath);
|
|
2200
2504
|
return true;
|
|
2201
2505
|
} catch (error) {
|
|
@@ -2331,10 +2635,10 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2331
2635
|
// Si debe retornar como array de líneas
|
|
2332
2636
|
} = options;
|
|
2333
2637
|
try {
|
|
2334
|
-
if (!
|
|
2638
|
+
if (!fs7.existsSync(filePath)) {
|
|
2335
2639
|
return asArray ? [] : "";
|
|
2336
2640
|
}
|
|
2337
|
-
let content = await
|
|
2641
|
+
let content = await fs7.promises.readFile(filePath, "utf8");
|
|
2338
2642
|
if (asArray) {
|
|
2339
2643
|
let linesArray = content.split("\n").filter((line) => line.trim() !== "");
|
|
2340
2644
|
if (lines !== null) {
|
|
@@ -2377,15 +2681,15 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2377
2681
|
} = options;
|
|
2378
2682
|
let lastSize = 0;
|
|
2379
2683
|
let lastPosition = 0;
|
|
2380
|
-
if (
|
|
2381
|
-
const stats =
|
|
2684
|
+
if (fs7.existsSync(filePath)) {
|
|
2685
|
+
const stats = fs7.statSync(filePath);
|
|
2382
2686
|
lastSize = stats.size;
|
|
2383
2687
|
lastPosition = fromEnd ? stats.size : 0;
|
|
2384
2688
|
}
|
|
2385
2689
|
const listener = async (curr, prev) => {
|
|
2386
2690
|
try {
|
|
2387
2691
|
if (curr.size > lastSize) {
|
|
2388
|
-
const stream =
|
|
2692
|
+
const stream = fs7.createReadStream(filePath, {
|
|
2389
2693
|
start: lastPosition,
|
|
2390
2694
|
end: curr.size - 1,
|
|
2391
2695
|
encoding: "utf8"
|
|
@@ -2413,7 +2717,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2413
2717
|
console.error("Error en watcher:", error);
|
|
2414
2718
|
}
|
|
2415
2719
|
};
|
|
2416
|
-
|
|
2720
|
+
fs7.watchFile(filePath, { persistent, interval }, listener);
|
|
2417
2721
|
const watcherId = `${filePath}_${Date.now()}`;
|
|
2418
2722
|
_FileLogger.watchers.set(watcherId, listener);
|
|
2419
2723
|
return {
|
|
@@ -2421,7 +2725,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2421
2725
|
stop: () => {
|
|
2422
2726
|
const storedListener = _FileLogger.watchers.get(watcherId);
|
|
2423
2727
|
if (storedListener) {
|
|
2424
|
-
|
|
2728
|
+
fs7.unwatchFile(filePath, storedListener);
|
|
2425
2729
|
_FileLogger.watchers.delete(watcherId);
|
|
2426
2730
|
}
|
|
2427
2731
|
},
|
|
@@ -2434,7 +2738,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2434
2738
|
static stopAllWatchers() {
|
|
2435
2739
|
for (const [watcherId] of _FileLogger.watchers) {
|
|
2436
2740
|
const filePath = watcherId.split("_")[0];
|
|
2437
|
-
|
|
2741
|
+
fs7.unwatchFile(filePath);
|
|
2438
2742
|
}
|
|
2439
2743
|
_FileLogger.watchers.clear();
|
|
2440
2744
|
}
|
|
@@ -2464,7 +2768,7 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2464
2768
|
if (lines.length > maxLines) {
|
|
2465
2769
|
const keepLines = lines.slice(-maxLines);
|
|
2466
2770
|
const content = keepLines.join("\n") + "\n";
|
|
2467
|
-
await
|
|
2771
|
+
await fs7.promises.writeFile(filePath, content, "utf8");
|
|
2468
2772
|
return lines.length - maxLines;
|
|
2469
2773
|
}
|
|
2470
2774
|
return 0;
|
|
@@ -2479,8 +2783,8 @@ var FileLogger = class _FileLogger extends EventEmitter {
|
|
|
2479
2783
|
*/
|
|
2480
2784
|
static async deleteLogFile(filePath) {
|
|
2481
2785
|
try {
|
|
2482
|
-
if (
|
|
2483
|
-
await
|
|
2786
|
+
if (fs7.existsSync(filePath)) {
|
|
2787
|
+
await fs7.promises.unlink(filePath);
|
|
2484
2788
|
return true;
|
|
2485
2789
|
}
|
|
2486
2790
|
return false;
|