@liorandb/core 1.0.18 → 1.0.19

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.js CHANGED
@@ -1,20 +1,18 @@
1
1
  // src/LioranManager.ts
2
- import path7 from "path";
3
- import fs7 from "fs";
2
+ import path9 from "path";
3
+ import fs9 from "fs";
4
4
  import process2 from "process";
5
5
 
6
6
  // src/core/database.ts
7
- import path4 from "path";
8
- import fs4 from "fs";
9
- import { execFile } from "child_process";
10
- import { promisify } from "util";
7
+ import path6 from "path";
8
+ import fs6 from "fs";
11
9
 
12
10
  // src/core/collection.ts
13
11
  import { ClassicLevel as ClassicLevel3 } from "classic-level";
14
12
 
15
13
  // src/core/query.ts
16
- function getByPath(obj, path8) {
17
- return path8.split(".").reduce((o, p) => o ? o[p] : void 0, obj);
14
+ function getByPath(obj, path10) {
15
+ return path10.split(".").reduce((o, p) => o ? o[p] : void 0, obj);
18
16
  }
19
17
  function matchDocument(doc, query) {
20
18
  for (const key of Object.keys(query)) {
@@ -295,12 +293,13 @@ var Index = class {
295
293
 
296
294
  // src/core/compaction.ts
297
295
  var TMP_SUFFIX = "__compact_tmp";
298
- var OLD_SUFFIX = "__old";
296
+ var OLD_SUFFIX = "__compact_old";
297
+ var INDEX_DIR = "__indexes";
299
298
  async function compactCollectionEngine(col) {
300
- await crashRecovery(col.dir);
301
299
  const baseDir = col.dir;
302
300
  const tmpDir = baseDir + TMP_SUFFIX;
303
301
  const oldDir = baseDir + OLD_SUFFIX;
302
+ await crashRecovery(baseDir);
304
303
  safeRemove(tmpDir);
305
304
  safeRemove(oldDir);
306
305
  await snapshotRebuild(col, tmpDir);
@@ -309,9 +308,13 @@ async function compactCollectionEngine(col) {
309
308
  }
310
309
  async function snapshotRebuild(col, tmpDir) {
311
310
  fs2.mkdirSync(tmpDir, { recursive: true });
312
- const tmpDB = new ClassicLevel2(tmpDir, { valueEncoding: "utf8" });
311
+ const tmpDB = new ClassicLevel2(tmpDir, {
312
+ valueEncoding: "utf8"
313
+ });
313
314
  for await (const [key, val] of col.db.iterator()) {
314
- await tmpDB.put(key, val);
315
+ if (val !== void 0) {
316
+ await tmpDB.put(key, val);
317
+ }
315
318
  }
316
319
  await tmpDB.close();
317
320
  await col.db.close();
@@ -323,38 +326,44 @@ function atomicSwap(base, tmp, old) {
323
326
  async function crashRecovery(baseDir) {
324
327
  const tmp = baseDir + TMP_SUFFIX;
325
328
  const old = baseDir + OLD_SUFFIX;
326
- if (fs2.existsSync(tmp) && fs2.existsSync(old)) {
329
+ const baseExists = fs2.existsSync(baseDir);
330
+ const tmpExists = fs2.existsSync(tmp);
331
+ const oldExists = fs2.existsSync(old);
332
+ if (tmpExists && oldExists) {
327
333
  safeRemove(baseDir);
328
334
  fs2.renameSync(tmp, baseDir);
329
335
  safeRemove(old);
336
+ return;
330
337
  }
331
- if (fs2.existsSync(old) && !fs2.existsSync(baseDir)) {
338
+ if (!baseExists && oldExists) {
332
339
  fs2.renameSync(old, baseDir);
340
+ return;
333
341
  }
334
- if (fs2.existsSync(tmp) && !fs2.existsSync(old)) {
342
+ if (tmpExists && !oldExists) {
335
343
  safeRemove(tmp);
336
344
  }
337
345
  }
338
346
  async function rebuildIndexes(col) {
339
- const indexRoot = path2.join(col.dir, "__indexes");
340
- safeRemove(indexRoot);
341
- fs2.mkdirSync(indexRoot, { recursive: true });
347
+ const indexRoot = path2.join(col.dir, INDEX_DIR);
342
348
  for (const idx of col["indexes"].values()) {
343
349
  try {
344
350
  await idx.close();
345
351
  } catch {
346
352
  }
347
353
  }
354
+ safeRemove(indexRoot);
355
+ fs2.mkdirSync(indexRoot, { recursive: true });
348
356
  const newIndexes = /* @__PURE__ */ new Map();
349
357
  for (const idx of col["indexes"].values()) {
350
- const fresh = new Index(col.dir, idx.field, {
358
+ const rebuilt = new Index(col.dir, idx.field, {
351
359
  unique: idx.unique
352
360
  });
353
361
  for await (const [, enc] of col.db.iterator()) {
362
+ if (!enc) continue;
354
363
  const doc = decryptData(enc);
355
- await fresh.insert(doc);
364
+ await rebuilt.insert(doc);
356
365
  }
357
- newIndexes.set(idx.field, fresh);
366
+ newIndexes.set(idx.field, rebuilt);
358
367
  }
359
368
  col["indexes"] = newIndexes;
360
369
  }
@@ -820,10 +829,230 @@ var MigrationEngine = class {
820
829
  }
821
830
  };
822
831
 
832
+ // src/core/wal.ts
833
+ import fs4 from "fs";
834
+ import path4 from "path";
835
+ var MAX_WAL_SIZE = 16 * 1024 * 1024;
836
+ var WAL_DIR = "__wal";
837
+ var CRC32_TABLE = (() => {
838
+ const table = new Uint32Array(256);
839
+ for (let i = 0; i < 256; i++) {
840
+ let c = i;
841
+ for (let k = 0; k < 8; k++) {
842
+ c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
843
+ }
844
+ table[i] = c >>> 0;
845
+ }
846
+ return table;
847
+ })();
848
+ function crc32(input) {
849
+ let crc = 4294967295;
850
+ for (let i = 0; i < input.length; i++) {
851
+ const byte = input.charCodeAt(i);
852
+ crc = CRC32_TABLE[(crc ^ byte) & 255] ^ crc >>> 8;
853
+ }
854
+ return (crc ^ 4294967295) >>> 0;
855
+ }
856
+ var WALManager = class {
857
+ walDir;
858
+ currentGen = 1;
859
+ lsn = 0;
860
+ fd = null;
861
+ constructor(baseDir) {
862
+ this.walDir = path4.join(baseDir, WAL_DIR);
863
+ fs4.mkdirSync(this.walDir, { recursive: true });
864
+ this.currentGen = this.detectLastGeneration();
865
+ }
866
+ /* -------------------------
867
+ INTERNAL HELPERS
868
+ ------------------------- */
869
+ walPath(gen = this.currentGen) {
870
+ return path4.join(
871
+ this.walDir,
872
+ `wal-${String(gen).padStart(6, "0")}.log`
873
+ );
874
+ }
875
+ detectLastGeneration() {
876
+ if (!fs4.existsSync(this.walDir)) return 1;
877
+ const files = fs4.readdirSync(this.walDir);
878
+ let max = 0;
879
+ for (const f of files) {
880
+ const m = f.match(/^wal-(\d+)\.log$/);
881
+ if (m) max = Math.max(max, Number(m[1]));
882
+ }
883
+ return max || 1;
884
+ }
885
+ async open() {
886
+ if (!this.fd) {
887
+ this.fd = await fs4.promises.open(this.walPath(), "a");
888
+ }
889
+ }
890
+ async rotate() {
891
+ if (this.fd) {
892
+ await this.fd.close();
893
+ this.fd = null;
894
+ }
895
+ this.currentGen++;
896
+ }
897
+ /* -------------------------
898
+ APPEND
899
+ ------------------------- */
900
+ async append(record) {
901
+ await this.open();
902
+ const full = {
903
+ ...record,
904
+ lsn: ++this.lsn
905
+ };
906
+ const body = JSON.stringify(full);
907
+ const stored = {
908
+ ...full,
909
+ crc: crc32(body)
910
+ };
911
+ await this.fd.write(JSON.stringify(stored) + "\n");
912
+ await this.fd.sync();
913
+ const stat = await this.fd.stat();
914
+ if (stat.size >= MAX_WAL_SIZE) {
915
+ await this.rotate();
916
+ }
917
+ return full.lsn;
918
+ }
919
+ /* -------------------------
920
+ REPLAY
921
+ ------------------------- */
922
+ async replay(fromLSN, apply) {
923
+ if (!fs4.existsSync(this.walDir)) return;
924
+ const files = fs4.readdirSync(this.walDir).filter((f) => f.startsWith("wal-")).sort();
925
+ for (const file of files) {
926
+ const filePath = path4.join(this.walDir, file);
927
+ const data = fs4.readFileSync(filePath, "utf8");
928
+ const lines = data.split("\n");
929
+ for (let i = 0; i < lines.length; i++) {
930
+ const line = lines[i];
931
+ if (!line.trim()) continue;
932
+ let parsed;
933
+ try {
934
+ parsed = JSON.parse(line);
935
+ } catch {
936
+ console.error("WAL parse error, stopping replay");
937
+ return;
938
+ }
939
+ const { crc, ...record } = parsed;
940
+ const expected = crc32(JSON.stringify(record));
941
+ if (expected !== crc) {
942
+ console.error(
943
+ "WAL checksum mismatch, stopping replay",
944
+ { file, line: i + 1 }
945
+ );
946
+ return;
947
+ }
948
+ if (record.lsn <= fromLSN) continue;
949
+ this.lsn = Math.max(this.lsn, record.lsn);
950
+ await apply(record);
951
+ }
952
+ }
953
+ }
954
+ /* -------------------------
955
+ CLEANUP
956
+ ------------------------- */
957
+ async cleanup(beforeGen) {
958
+ if (!fs4.existsSync(this.walDir)) return;
959
+ const files = fs4.readdirSync(this.walDir);
960
+ for (const f of files) {
961
+ const m = f.match(/^wal-(\d+)\.log$/);
962
+ if (!m) continue;
963
+ const gen = Number(m[1]);
964
+ if (gen < beforeGen) {
965
+ fs4.unlinkSync(path4.join(this.walDir, f));
966
+ }
967
+ }
968
+ }
969
+ /* -------------------------
970
+ GETTERS
971
+ ------------------------- */
972
+ getCurrentLSN() {
973
+ return this.lsn;
974
+ }
975
+ getCurrentGen() {
976
+ return this.currentGen;
977
+ }
978
+ };
979
+
980
+ // src/core/checkpoint.ts
981
+ import fs5 from "fs";
982
+ import path5 from "path";
983
+ var CHECKPOINT_FILE = "__checkpoint.json";
984
+ var TMP_SUFFIX2 = ".tmp";
985
+ var FORMAT_VERSION = 1;
986
+ var CheckpointManager = class {
987
+ filePath;
988
+ data;
989
+ constructor(baseDir) {
990
+ this.filePath = path5.join(baseDir, CHECKPOINT_FILE);
991
+ this.data = {
992
+ lsn: 0,
993
+ walGen: 1,
994
+ time: 0,
995
+ version: FORMAT_VERSION
996
+ };
997
+ this.load();
998
+ }
999
+ /* -------------------------
1000
+ LOAD (Crash-safe)
1001
+ ------------------------- */
1002
+ load() {
1003
+ if (!fs5.existsSync(this.filePath)) {
1004
+ return;
1005
+ }
1006
+ try {
1007
+ const raw = fs5.readFileSync(this.filePath, "utf8");
1008
+ const parsed = JSON.parse(raw);
1009
+ if (typeof parsed.lsn === "number" && typeof parsed.walGen === "number") {
1010
+ this.data = parsed;
1011
+ }
1012
+ } catch {
1013
+ console.error("Checkpoint corrupted, starting from zero");
1014
+ this.data = {
1015
+ lsn: 0,
1016
+ walGen: 1,
1017
+ time: 0,
1018
+ version: FORMAT_VERSION
1019
+ };
1020
+ }
1021
+ }
1022
+ /* -------------------------
1023
+ SAVE (Atomic Write)
1024
+ ------------------------- */
1025
+ save(lsn, walGen) {
1026
+ const newData = {
1027
+ lsn,
1028
+ walGen,
1029
+ time: Date.now(),
1030
+ version: FORMAT_VERSION
1031
+ };
1032
+ const tmpPath = this.filePath + TMP_SUFFIX2;
1033
+ try {
1034
+ fs5.writeFileSync(
1035
+ tmpPath,
1036
+ JSON.stringify(newData, null, 2),
1037
+ { encoding: "utf8" }
1038
+ );
1039
+ fs5.renameSync(tmpPath, this.filePath);
1040
+ this.data = newData;
1041
+ } catch (err) {
1042
+ console.error("Failed to write checkpoint:", err);
1043
+ }
1044
+ }
1045
+ /* -------------------------
1046
+ GET CURRENT
1047
+ ------------------------- */
1048
+ get() {
1049
+ return this.data;
1050
+ }
1051
+ };
1052
+
823
1053
  // src/core/database.ts
824
- var exec = promisify(execFile);
825
1054
  var META_FILE = "__db_meta.json";
826
- var META_VERSION = 1;
1055
+ var META_VERSION = 2;
827
1056
  var DEFAULT_SCHEMA_VERSION = "v1";
828
1057
  var DBTransactionContext = class {
829
1058
  constructor(db, txId) {
@@ -846,11 +1075,26 @@ var DBTransactionContext = class {
846
1075
  });
847
1076
  }
848
1077
  async commit() {
849
- await this.db.writeWAL(this.ops);
850
- await this.db.writeWAL([{ tx: this.txId, commit: true }]);
1078
+ for (const op of this.ops) {
1079
+ const recordOp = {
1080
+ tx: this.txId,
1081
+ type: "op",
1082
+ payload: op
1083
+ };
1084
+ await this.db.wal.append(recordOp);
1085
+ }
1086
+ const commitRecord = {
1087
+ tx: this.txId,
1088
+ type: "commit"
1089
+ };
1090
+ await this.db.wal.append(commitRecord);
851
1091
  await this.db.applyTransaction(this.ops);
852
- await this.db.writeWAL([{ tx: this.txId, applied: true }]);
853
- await this.db.clearWAL();
1092
+ const appliedRecord = {
1093
+ tx: this.txId,
1094
+ type: "applied"
1095
+ };
1096
+ await this.db.wal.append(appliedRecord);
1097
+ await this.db.postCommitMaintenance();
854
1098
  }
855
1099
  };
856
1100
  var LioranDB = class _LioranDB {
@@ -858,26 +1102,56 @@ var LioranDB = class _LioranDB {
858
1102
  dbName;
859
1103
  manager;
860
1104
  collections;
861
- walPath;
862
1105
  metaPath;
863
1106
  meta;
864
1107
  migrator;
865
1108
  static TX_SEQ = 0;
1109
+ wal;
1110
+ checkpoint;
866
1111
  constructor(basePath, dbName, manager) {
867
1112
  this.basePath = basePath;
868
1113
  this.dbName = dbName;
869
1114
  this.manager = manager;
870
1115
  this.collections = /* @__PURE__ */ new Map();
871
- this.walPath = path4.join(basePath, "__tx_wal.log");
872
- this.metaPath = path4.join(basePath, META_FILE);
873
- fs4.mkdirSync(basePath, { recursive: true });
1116
+ this.metaPath = path6.join(basePath, META_FILE);
1117
+ fs6.mkdirSync(basePath, { recursive: true });
874
1118
  this.loadMeta();
1119
+ this.wal = new WALManager(basePath);
1120
+ this.checkpoint = new CheckpointManager(basePath);
875
1121
  this.migrator = new MigrationEngine(this);
876
- this.recoverFromWAL().catch(console.error);
1122
+ this.initialize().catch(console.error);
1123
+ }
1124
+ /* ------------------------- INIT & RECOVERY ------------------------- */
1125
+ async initialize() {
1126
+ await this.recoverFromWAL();
1127
+ }
1128
+ async recoverFromWAL() {
1129
+ const checkpointData = this.checkpoint.get();
1130
+ const fromLSN = checkpointData.lsn;
1131
+ const committed = /* @__PURE__ */ new Set();
1132
+ const applied = /* @__PURE__ */ new Set();
1133
+ const ops = /* @__PURE__ */ new Map();
1134
+ await this.wal.replay(fromLSN, async (record) => {
1135
+ if (record.type === "commit") {
1136
+ committed.add(record.tx);
1137
+ } else if (record.type === "applied") {
1138
+ applied.add(record.tx);
1139
+ } else if (record.type === "op") {
1140
+ if (!ops.has(record.tx)) ops.set(record.tx, []);
1141
+ ops.get(record.tx).push(record.payload);
1142
+ }
1143
+ });
1144
+ for (const tx of committed) {
1145
+ if (applied.has(tx)) continue;
1146
+ const txOps = ops.get(tx);
1147
+ if (txOps) {
1148
+ await this.applyTransaction(txOps);
1149
+ }
1150
+ }
877
1151
  }
878
1152
  /* ------------------------- META ------------------------- */
879
1153
  loadMeta() {
880
- if (!fs4.existsSync(this.metaPath)) {
1154
+ if (!fs6.existsSync(this.metaPath)) {
881
1155
  this.meta = {
882
1156
  version: META_VERSION,
883
1157
  indexes: {},
@@ -886,14 +1160,14 @@ var LioranDB = class _LioranDB {
886
1160
  this.saveMeta();
887
1161
  return;
888
1162
  }
889
- this.meta = JSON.parse(fs4.readFileSync(this.metaPath, "utf8"));
1163
+ this.meta = JSON.parse(fs6.readFileSync(this.metaPath, "utf8"));
890
1164
  if (!this.meta.schemaVersion) {
891
1165
  this.meta.schemaVersion = DEFAULT_SCHEMA_VERSION;
892
1166
  this.saveMeta();
893
1167
  }
894
1168
  }
895
1169
  saveMeta() {
896
- fs4.writeFileSync(this.metaPath, JSON.stringify(this.meta, null, 2));
1170
+ fs6.writeFileSync(this.metaPath, JSON.stringify(this.meta, null, 2));
897
1171
  }
898
1172
  getSchemaVersion() {
899
1173
  return this.meta.schemaVersion;
@@ -912,44 +1186,7 @@ var LioranDB = class _LioranDB {
912
1186
  async applyMigrations(targetVersion) {
913
1187
  await this.migrator.upgradeToLatest();
914
1188
  }
915
- /* ------------------------- WAL ------------------------- */
916
- async writeWAL(entries) {
917
- const fd = await fs4.promises.open(this.walPath, "a");
918
- for (const e of entries) {
919
- await fd.write(JSON.stringify(e) + "\n");
920
- }
921
- await fd.sync();
922
- await fd.close();
923
- }
924
- async clearWAL() {
925
- try {
926
- await fs4.promises.unlink(this.walPath);
927
- } catch {
928
- }
929
- }
930
- async recoverFromWAL() {
931
- if (!fs4.existsSync(this.walPath)) return;
932
- const raw = await fs4.promises.readFile(this.walPath, "utf8");
933
- const committed = /* @__PURE__ */ new Set();
934
- const applied = /* @__PURE__ */ new Set();
935
- const ops = /* @__PURE__ */ new Map();
936
- for (const line of raw.split("\n")) {
937
- if (!line.trim()) continue;
938
- const entry = JSON.parse(line);
939
- if ("commit" in entry) committed.add(entry.tx);
940
- else if ("applied" in entry) applied.add(entry.tx);
941
- else {
942
- if (!ops.has(entry.tx)) ops.set(entry.tx, []);
943
- ops.get(entry.tx).push(entry);
944
- }
945
- }
946
- for (const tx of committed) {
947
- if (applied.has(tx)) continue;
948
- const txOps = ops.get(tx);
949
- if (txOps) await this.applyTransaction(txOps);
950
- }
951
- await this.clearWAL();
952
- }
1189
+ /* ------------------------- TX APPLY ------------------------- */
953
1190
  async applyTransaction(ops) {
954
1191
  for (const { col, op, args } of ops) {
955
1192
  const collection = this.collection(col);
@@ -965,8 +1202,8 @@ var LioranDB = class _LioranDB {
965
1202
  }
966
1203
  return col2;
967
1204
  }
968
- const colPath = path4.join(this.basePath, name);
969
- fs4.mkdirSync(colPath, { recursive: true });
1205
+ const colPath = path6.join(this.basePath, name);
1206
+ fs6.mkdirSync(colPath, { recursive: true });
970
1207
  const col = new Collection(
971
1208
  colPath,
972
1209
  schema,
@@ -1004,12 +1241,10 @@ var LioranDB = class _LioranDB {
1004
1241
  }
1005
1242
  /* ------------------------- COMPACTION ------------------------- */
1006
1243
  async compactCollection(name) {
1007
- await this.clearWAL();
1008
1244
  const col = this.collection(name);
1009
1245
  await col.compact();
1010
1246
  }
1011
1247
  async compactAll() {
1012
- await this.clearWAL();
1013
1248
  for (const name of this.collections.keys()) {
1014
1249
  await this.compactCollection(name);
1015
1250
  }
@@ -1022,6 +1257,9 @@ var LioranDB = class _LioranDB {
1022
1257
  await tx.commit();
1023
1258
  return result;
1024
1259
  }
1260
+ /* ------------------------- POST COMMIT ------------------------- */
1261
+ async postCommitMaintenance() {
1262
+ }
1025
1263
  /* ------------------------- SHUTDOWN ------------------------- */
1026
1264
  async close() {
1027
1265
  for (const col of this.collections.values()) {
@@ -1036,15 +1274,15 @@ var LioranDB = class _LioranDB {
1036
1274
 
1037
1275
  // src/utils/rootpath.ts
1038
1276
  import os2 from "os";
1039
- import path5 from "path";
1040
- import fs5 from "fs";
1277
+ import path7 from "path";
1278
+ import fs7 from "fs";
1041
1279
  function getDefaultRootPath() {
1042
1280
  let dbPath = process.env.LIORANDB_PATH;
1043
1281
  if (!dbPath) {
1044
1282
  const homeDir = os2.homedir();
1045
- dbPath = path5.join(homeDir, "LioranDB", "db");
1046
- if (!fs5.existsSync(dbPath)) {
1047
- fs5.mkdirSync(dbPath, { recursive: true });
1283
+ dbPath = path7.join(homeDir, "LioranDB", "db");
1284
+ if (!fs7.existsSync(dbPath)) {
1285
+ fs7.mkdirSync(dbPath, { recursive: true });
1048
1286
  }
1049
1287
  process.env.LIORANDB_PATH = dbPath;
1050
1288
  }
@@ -1059,24 +1297,24 @@ import net from "net";
1059
1297
 
1060
1298
  // src/ipc/socketPath.ts
1061
1299
  import os3 from "os";
1062
- import path6 from "path";
1300
+ import path8 from "path";
1063
1301
  function getIPCSocketPath(rootPath) {
1064
1302
  if (os3.platform() === "win32") {
1065
1303
  return `\\\\.\\pipe\\liorandb_${rootPath.replace(/[:\\\/]/g, "_")}`;
1066
1304
  }
1067
- return path6.join(rootPath, ".lioran.sock");
1305
+ return path8.join(rootPath, ".lioran.sock");
1068
1306
  }
1069
1307
 
1070
1308
  // src/ipc/client.ts
1071
1309
  function delay(ms) {
1072
1310
  return new Promise((r) => setTimeout(r, ms));
1073
1311
  }
1074
- async function connectWithRetry(path8) {
1312
+ async function connectWithRetry(path10) {
1075
1313
  let attempt = 0;
1076
1314
  while (true) {
1077
1315
  try {
1078
1316
  return await new Promise((resolve, reject) => {
1079
- const socket = net.connect(path8, () => resolve(socket));
1317
+ const socket = net.connect(path10, () => resolve(socket));
1080
1318
  socket.once("error", reject);
1081
1319
  });
1082
1320
  } catch (err) {
@@ -1159,11 +1397,11 @@ var DBQueue = class {
1159
1397
  return this.exec("compact:all", {});
1160
1398
  }
1161
1399
  /* ----------------------------- SNAPSHOT API ----------------------------- */
1162
- snapshot(path8) {
1163
- return this.exec("snapshot", { path: path8 });
1400
+ snapshot(path10) {
1401
+ return this.exec("snapshot", { path: path10 });
1164
1402
  }
1165
- restore(path8) {
1166
- return this.exec("restore", { path: path8 });
1403
+ restore(path10) {
1404
+ return this.exec("restore", { path: path10 });
1167
1405
  }
1168
1406
  /* ------------------------------ SHUTDOWN ------------------------------ */
1169
1407
  async shutdown() {
@@ -1178,7 +1416,7 @@ var dbQueue = new DBQueue();
1178
1416
 
1179
1417
  // src/ipc/server.ts
1180
1418
  import net2 from "net";
1181
- import fs6 from "fs";
1419
+ import fs8 from "fs";
1182
1420
  var IPCServer = class {
1183
1421
  server;
1184
1422
  manager;
@@ -1189,7 +1427,7 @@ var IPCServer = class {
1189
1427
  }
1190
1428
  start() {
1191
1429
  if (!this.socketPath.startsWith("\\\\.\\")) {
1192
- if (fs6.existsSync(this.socketPath)) fs6.unlinkSync(this.socketPath);
1430
+ if (fs8.existsSync(this.socketPath)) fs8.unlinkSync(this.socketPath);
1193
1431
  }
1194
1432
  this.server = net2.createServer((socket) => {
1195
1433
  let buffer = "";
@@ -1291,7 +1529,7 @@ var IPCServer = class {
1291
1529
  if (this.server) this.server.close();
1292
1530
  if (!this.socketPath.startsWith("\\\\.\\")) {
1293
1531
  try {
1294
- fs6.unlinkSync(this.socketPath);
1532
+ fs8.unlinkSync(this.socketPath);
1295
1533
  } catch {
1296
1534
  }
1297
1535
  }
@@ -1309,8 +1547,8 @@ var LioranManager = class {
1309
1547
  constructor(options = {}) {
1310
1548
  const { rootPath, encryptionKey } = options;
1311
1549
  this.rootPath = rootPath || getDefaultRootPath();
1312
- if (!fs7.existsSync(this.rootPath)) {
1313
- fs7.mkdirSync(this.rootPath, { recursive: true });
1550
+ if (!fs9.existsSync(this.rootPath)) {
1551
+ fs9.mkdirSync(this.rootPath, { recursive: true });
1314
1552
  }
1315
1553
  if (encryptionKey) {
1316
1554
  setEncryptionKey(encryptionKey);
@@ -1333,18 +1571,18 @@ var LioranManager = class {
1333
1571
  }
1334
1572
  }
1335
1573
  tryAcquireLock() {
1336
- const lockPath = path7.join(this.rootPath, ".lioran.lock");
1574
+ const lockPath = path9.join(this.rootPath, ".lioran.lock");
1337
1575
  try {
1338
- this.lockFd = fs7.openSync(lockPath, "wx");
1339
- fs7.writeSync(this.lockFd, String(process2.pid));
1576
+ this.lockFd = fs9.openSync(lockPath, "wx");
1577
+ fs9.writeSync(this.lockFd, String(process2.pid));
1340
1578
  return true;
1341
1579
  } catch {
1342
1580
  try {
1343
- const pid = Number(fs7.readFileSync(lockPath, "utf8"));
1581
+ const pid = Number(fs9.readFileSync(lockPath, "utf8"));
1344
1582
  if (!this.isProcessAlive(pid)) {
1345
- fs7.unlinkSync(lockPath);
1346
- this.lockFd = fs7.openSync(lockPath, "wx");
1347
- fs7.writeSync(this.lockFd, String(process2.pid));
1583
+ fs9.unlinkSync(lockPath);
1584
+ this.lockFd = fs9.openSync(lockPath, "wx");
1585
+ fs9.writeSync(this.lockFd, String(process2.pid));
1348
1586
  return true;
1349
1587
  }
1350
1588
  } catch {
@@ -1365,8 +1603,8 @@ var LioranManager = class {
1365
1603
  if (this.openDBs.has(name)) {
1366
1604
  return this.openDBs.get(name);
1367
1605
  }
1368
- const dbPath = path7.join(this.rootPath, name);
1369
- await fs7.promises.mkdir(dbPath, { recursive: true });
1606
+ const dbPath = path9.join(this.rootPath, name);
1607
+ await fs9.promises.mkdir(dbPath, { recursive: true });
1370
1608
  const db = new LioranDB(dbPath, name, this);
1371
1609
  this.openDBs.set(name, db);
1372
1610
  return db;
@@ -1387,7 +1625,7 @@ var LioranManager = class {
1387
1625
  }
1388
1626
  }
1389
1627
  }
1390
- fs7.mkdirSync(path7.dirname(snapshotPath), { recursive: true });
1628
+ fs9.mkdirSync(path9.dirname(snapshotPath), { recursive: true });
1391
1629
  const tar = await import("tar");
1392
1630
  await tar.c({
1393
1631
  gzip: true,
@@ -1405,8 +1643,8 @@ var LioranManager = class {
1405
1643
  return dbQueue.exec("restore", { path: snapshotPath });
1406
1644
  }
1407
1645
  await this.closeAll();
1408
- fs7.rmSync(this.rootPath, { recursive: true, force: true });
1409
- fs7.mkdirSync(this.rootPath, { recursive: true });
1646
+ fs9.rmSync(this.rootPath, { recursive: true, force: true });
1647
+ fs9.mkdirSync(this.rootPath, { recursive: true });
1410
1648
  const tar = await import("tar");
1411
1649
  await tar.x({
1412
1650
  file: snapshotPath,
@@ -1431,8 +1669,8 @@ var LioranManager = class {
1431
1669
  }
1432
1670
  this.openDBs.clear();
1433
1671
  try {
1434
- if (this.lockFd) fs7.closeSync(this.lockFd);
1435
- fs7.unlinkSync(path7.join(this.rootPath, ".lioran.lock"));
1672
+ if (this.lockFd) fs9.closeSync(this.lockFd);
1673
+ fs9.unlinkSync(path9.join(this.rootPath, ".lioran.lock"));
1436
1674
  } catch {
1437
1675
  }
1438
1676
  await this.ipcServer?.close();