@liorandb/core 1.0.9 → 1.0.10

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.
@@ -0,0 +1,703 @@
1
+ // src/core/database.ts
2
+ import path2 from "path";
3
+ import fs2 from "fs";
4
+
5
+ // src/core/collection.ts
6
+ import fs from "fs";
7
+ import path from "path";
8
+ import { ClassicLevel } from "classic-level";
9
+
10
+ // src/core/query.ts
11
+ function getByPath(obj, path6) {
12
+ return path6.split(".").reduce((o, p) => o ? o[p] : void 0, obj);
13
+ }
14
+ function matchDocument(doc, query) {
15
+ for (const key of Object.keys(query)) {
16
+ const cond = query[key];
17
+ const val = getByPath(doc, key);
18
+ if (cond && typeof cond === "object" && !Array.isArray(cond)) {
19
+ for (const op of Object.keys(cond)) {
20
+ const v = cond[op];
21
+ if (op === "$gt" && !(val > v)) return false;
22
+ if (op === "$gte" && !(val >= v)) return false;
23
+ if (op === "$lt" && !(val < v)) return false;
24
+ if (op === "$lte" && !(val <= v)) return false;
25
+ if (op === "$ne" && val === v) return false;
26
+ if (op === "$eq" && val !== v) return false;
27
+ if (op === "$in" && (!Array.isArray(v) || !v.includes(val)))
28
+ return false;
29
+ }
30
+ } else {
31
+ if (val !== cond) return false;
32
+ }
33
+ }
34
+ return true;
35
+ }
36
+ function applyUpdate(oldDoc, update) {
37
+ const doc = structuredClone(oldDoc);
38
+ if (update.$set) {
39
+ for (const k in update.$set) {
40
+ const parts = k.split(".");
41
+ let cur = doc;
42
+ for (let i = 0; i < parts.length - 1; i++) {
43
+ cur[parts[i]] ??= {};
44
+ cur = cur[parts[i]];
45
+ }
46
+ cur[parts.at(-1)] = update.$set[k];
47
+ }
48
+ }
49
+ if (update.$inc) {
50
+ for (const k in update.$inc) {
51
+ const val = getByPath(doc, k) ?? 0;
52
+ const parts = k.split(".");
53
+ let cur = doc;
54
+ for (let i = 0; i < parts.length - 1; i++) {
55
+ cur[parts[i]] ??= {};
56
+ cur = cur[parts[i]];
57
+ }
58
+ cur[parts.at(-1)] = val + update.$inc[k];
59
+ }
60
+ }
61
+ const hasOp = Object.keys(update).some((k) => k.startsWith("$"));
62
+ if (!hasOp) {
63
+ return { ...doc, ...update };
64
+ }
65
+ return doc;
66
+ }
67
+
68
+ // src/core/collection.ts
69
+ import { v4 as uuid } from "uuid";
70
+
71
+ // src/utils/encryption.ts
72
+ import crypto2 from "crypto";
73
+
74
+ // src/utils/secureKey.ts
75
+ import crypto from "crypto";
76
+ import os from "os";
77
+ function getMasterKey() {
78
+ const fingerprint = [
79
+ os.hostname(),
80
+ os.platform(),
81
+ os.arch(),
82
+ os.cpus()?.[0]?.model ?? "unknown",
83
+ os.cpus()?.length ?? 0,
84
+ os.totalmem()
85
+ ].join("|");
86
+ return crypto.createHash("sha256").update(fingerprint).digest();
87
+ }
88
+
89
+ // src/utils/encryption.ts
90
+ var algorithm = "aes-256-gcm";
91
+ var ACTIVE_KEY = getMasterKey();
92
+ function setEncryptionKey(key) {
93
+ if (!key) return;
94
+ if (typeof key === "string") {
95
+ ACTIVE_KEY = crypto2.createHash("sha256").update(key).digest();
96
+ return;
97
+ }
98
+ if (Buffer.isBuffer(key)) {
99
+ if (key.length !== 32) {
100
+ throw new Error("Encryption key must be 32 bytes");
101
+ }
102
+ ACTIVE_KEY = key;
103
+ return;
104
+ }
105
+ throw new Error("Invalid encryption key format");
106
+ }
107
+ function encryptData(obj) {
108
+ const iv = crypto2.randomBytes(16);
109
+ const data = Buffer.from(JSON.stringify(obj), "utf8");
110
+ const cipher = crypto2.createCipheriv(algorithm, ACTIVE_KEY, iv);
111
+ const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
112
+ const tag = cipher.getAuthTag();
113
+ return Buffer.concat([iv, tag, encrypted]).toString("base64");
114
+ }
115
+ function decryptData(enc) {
116
+ const buf = Buffer.from(enc, "base64");
117
+ const iv = buf.subarray(0, 16);
118
+ const tag = buf.subarray(16, 32);
119
+ const encrypted = buf.subarray(32);
120
+ const decipher = crypto2.createDecipheriv(algorithm, ACTIVE_KEY, iv);
121
+ decipher.setAuthTag(tag);
122
+ const decrypted = Buffer.concat([
123
+ decipher.update(encrypted),
124
+ decipher.final()
125
+ ]);
126
+ return JSON.parse(decrypted.toString("utf8"));
127
+ }
128
+
129
+ // src/utils/schema.ts
130
+ function validateSchema(schema, data) {
131
+ const result = schema.safeParse(data);
132
+ if (!result.success) {
133
+ throw new Error(
134
+ "Schema validation failed:\n" + JSON.stringify(result.error.format(), null, 2)
135
+ );
136
+ }
137
+ return result.data;
138
+ }
139
+
140
+ // src/core/collection.ts
141
+ var Collection = class {
142
+ dir;
143
+ db;
144
+ queue;
145
+ walPath;
146
+ schema;
147
+ constructor(dir, schema) {
148
+ this.dir = dir;
149
+ this.db = new ClassicLevel(dir);
150
+ this.queue = Promise.resolve();
151
+ this.walPath = path.join(dir, "__wal.log");
152
+ this.schema = schema;
153
+ this.recoverFromWAL().catch(console.error);
154
+ }
155
+ setSchema(schema) {
156
+ this.schema = schema;
157
+ }
158
+ validate(doc) {
159
+ return this.schema ? validateSchema(this.schema, doc) : doc;
160
+ }
161
+ /* ---------------- WAL ---------------- */
162
+ async writeWAL(entry) {
163
+ await fs.promises.appendFile(
164
+ this.walPath,
165
+ JSON.stringify(entry) + "\n"
166
+ );
167
+ }
168
+ async clearWAL() {
169
+ if (fs.existsSync(this.walPath)) {
170
+ await fs.promises.unlink(this.walPath);
171
+ }
172
+ }
173
+ async recoverFromWAL() {
174
+ if (!fs.existsSync(this.walPath)) return;
175
+ const lines = (await fs.promises.readFile(this.walPath, "utf8")).split("\n").filter(Boolean);
176
+ for (const line of lines) {
177
+ try {
178
+ const { op, args } = JSON.parse(line);
179
+ await this._exec(op, args, false);
180
+ } catch (err) {
181
+ console.error("WAL recovery failed:", err);
182
+ }
183
+ }
184
+ await this.clearWAL();
185
+ }
186
+ /* ---------------- Queue ---------------- */
187
+ _enqueue(task) {
188
+ this.queue = this.queue.then(task).catch(console.error);
189
+ return this.queue;
190
+ }
191
+ /* ---------------- Core Executor ---------------- */
192
+ async _exec(op, args, log = true) {
193
+ if (log) await this.writeWAL({ op, args });
194
+ let result;
195
+ switch (op) {
196
+ case "insertOne":
197
+ result = await this._insertOne(args[0]);
198
+ break;
199
+ case "insertMany":
200
+ result = await this._insertMany(args[0]);
201
+ break;
202
+ case "find":
203
+ result = await this._find(args[0]);
204
+ break;
205
+ case "findOne":
206
+ result = await this._findOne(args[0]);
207
+ break;
208
+ case "updateOne":
209
+ result = await this._updateOne(args[0], args[1], args[2]);
210
+ break;
211
+ case "updateMany":
212
+ result = await this._updateMany(args[0], args[1]);
213
+ break;
214
+ case "deleteOne":
215
+ result = await this._deleteOne(args[0]);
216
+ break;
217
+ case "deleteMany":
218
+ result = await this._deleteMany(args[0]);
219
+ break;
220
+ case "countDocuments":
221
+ result = await this._countDocuments(args[0]);
222
+ break;
223
+ default:
224
+ throw new Error(`Unknown operation: ${op}`);
225
+ }
226
+ if (log) await this.clearWAL();
227
+ return result;
228
+ }
229
+ /* ---------------- Public API ---------------- */
230
+ async close() {
231
+ try {
232
+ await this.db.close();
233
+ } catch {
234
+ }
235
+ }
236
+ insertOne(doc) {
237
+ return this._enqueue(() => this._exec("insertOne", [doc]));
238
+ }
239
+ insertMany(docs = []) {
240
+ return this._enqueue(() => this._exec("insertMany", [docs]));
241
+ }
242
+ find(query = {}) {
243
+ return this._enqueue(() => this._exec("find", [query]));
244
+ }
245
+ findOne(query = {}) {
246
+ return this._enqueue(() => this._exec("findOne", [query]));
247
+ }
248
+ updateOne(filter = {}, update = {}, options = { upsert: false }) {
249
+ return this._enqueue(
250
+ () => this._exec("updateOne", [filter, update, options])
251
+ );
252
+ }
253
+ updateMany(filter = {}, update = {}) {
254
+ return this._enqueue(
255
+ () => this._exec("updateMany", [filter, update])
256
+ );
257
+ }
258
+ deleteOne(filter = {}) {
259
+ return this._enqueue(() => this._exec("deleteOne", [filter]));
260
+ }
261
+ deleteMany(filter = {}) {
262
+ return this._enqueue(() => this._exec("deleteMany", [filter]));
263
+ }
264
+ countDocuments(filter = {}) {
265
+ return this._enqueue(
266
+ () => this._exec("countDocuments", [filter])
267
+ );
268
+ }
269
+ /* ---------------- Internal Ops ---------------- */
270
+ async _insertOne(doc) {
271
+ const _id = doc._id ?? uuid();
272
+ const final = this.validate({ _id, ...doc });
273
+ await this.db.put(String(_id), encryptData(final));
274
+ return final;
275
+ }
276
+ async _insertMany(docs) {
277
+ const ops = [];
278
+ const out = [];
279
+ for (const d of docs) {
280
+ const _id = d._id ?? uuid();
281
+ const final = this.validate({ _id, ...d });
282
+ ops.push({
283
+ type: "put",
284
+ key: String(_id),
285
+ value: encryptData(final)
286
+ });
287
+ out.push(final);
288
+ }
289
+ await this.db.batch(ops);
290
+ return out;
291
+ }
292
+ async _updateOne(filter, update, options) {
293
+ for await (const [key, enc] of this.db.iterator()) {
294
+ const value = decryptData(enc);
295
+ if (matchDocument(value, filter)) {
296
+ const updated = applyUpdate(value, update);
297
+ updated._id = value._id;
298
+ const validated = this.validate(updated);
299
+ await this.db.put(key, encryptData(validated));
300
+ return validated;
301
+ }
302
+ }
303
+ if (options?.upsert) {
304
+ const doc = applyUpdate(filter, update);
305
+ doc._id ??= uuid();
306
+ const validated = this.validate(doc);
307
+ await this.db.put(String(doc._id), encryptData(validated));
308
+ return validated;
309
+ }
310
+ return null;
311
+ }
312
+ async _updateMany(filter, update) {
313
+ const updated = [];
314
+ for await (const [key, enc] of this.db.iterator()) {
315
+ const value = decryptData(enc);
316
+ if (matchDocument(value, filter)) {
317
+ const doc = applyUpdate(value, update);
318
+ doc._id = value._id;
319
+ const validated = this.validate(doc);
320
+ await this.db.put(key, encryptData(validated));
321
+ updated.push(validated);
322
+ }
323
+ }
324
+ return updated;
325
+ }
326
+ async _find(query) {
327
+ const out = [];
328
+ for await (const [, enc] of this.db.iterator()) {
329
+ const value = decryptData(enc);
330
+ if (matchDocument(value, query)) out.push(value);
331
+ }
332
+ return out;
333
+ }
334
+ async _findOne(query) {
335
+ for await (const [, enc] of this.db.iterator()) {
336
+ const value = decryptData(enc);
337
+ if (matchDocument(value, query)) return value;
338
+ }
339
+ return null;
340
+ }
341
+ async _deleteOne(filter) {
342
+ for await (const [key, enc] of this.db.iterator()) {
343
+ const value = decryptData(enc);
344
+ if (matchDocument(value, filter)) {
345
+ await this.db.del(key);
346
+ return true;
347
+ }
348
+ }
349
+ return false;
350
+ }
351
+ async _deleteMany(filter) {
352
+ let count = 0;
353
+ for await (const [key, enc] of this.db.iterator()) {
354
+ const value = decryptData(enc);
355
+ if (matchDocument(value, filter)) {
356
+ await this.db.del(key);
357
+ count++;
358
+ }
359
+ }
360
+ return count;
361
+ }
362
+ async _countDocuments(filter) {
363
+ let c = 0;
364
+ for await (const [, enc] of this.db.iterator()) {
365
+ const value = decryptData(enc);
366
+ if (matchDocument(value, filter)) c++;
367
+ }
368
+ return c;
369
+ }
370
+ };
371
+
372
+ // src/core/database.ts
373
+ var LioranDB = class {
374
+ basePath;
375
+ dbName;
376
+ manager;
377
+ collections;
378
+ constructor(basePath, dbName, manager) {
379
+ this.basePath = basePath;
380
+ this.dbName = dbName;
381
+ this.manager = manager;
382
+ this.collections = /* @__PURE__ */ new Map();
383
+ if (!fs2.existsSync(basePath)) {
384
+ fs2.mkdirSync(basePath, { recursive: true });
385
+ }
386
+ }
387
+ /* -------------------------------- COLLECTION -------------------------------- */
388
+ collection(name, schema) {
389
+ if (this.collections.has(name)) {
390
+ const col2 = this.collections.get(name);
391
+ if (schema) col2.setSchema(schema);
392
+ return col2;
393
+ }
394
+ const colPath = path2.join(this.basePath, name);
395
+ if (!fs2.existsSync(colPath)) {
396
+ fs2.mkdirSync(colPath, { recursive: true });
397
+ }
398
+ const col = new Collection(colPath, schema);
399
+ this.collections.set(name, col);
400
+ return col;
401
+ }
402
+ async createCollection(name, schema) {
403
+ const colPath = path2.join(this.basePath, name);
404
+ if (fs2.existsSync(colPath)) {
405
+ throw new Error("Collection already exists");
406
+ }
407
+ await fs2.promises.mkdir(colPath, { recursive: true });
408
+ const col = new Collection(colPath, schema);
409
+ this.collections.set(name, col);
410
+ return col;
411
+ }
412
+ async deleteCollection(name) {
413
+ const colPath = path2.join(this.basePath, name);
414
+ if (!fs2.existsSync(colPath)) {
415
+ throw new Error("Collection does not exist");
416
+ }
417
+ if (this.collections.has(name)) {
418
+ await this.collections.get(name).close();
419
+ this.collections.delete(name);
420
+ }
421
+ await fs2.promises.rm(colPath, { recursive: true, force: true });
422
+ return true;
423
+ }
424
+ async renameCollection(oldName, newName) {
425
+ const oldPath = path2.join(this.basePath, oldName);
426
+ const newPath = path2.join(this.basePath, newName);
427
+ if (!fs2.existsSync(oldPath)) {
428
+ throw new Error("Collection does not exist");
429
+ }
430
+ if (fs2.existsSync(newPath)) {
431
+ throw new Error("New collection name already exists");
432
+ }
433
+ if (this.collections.has(oldName)) {
434
+ await this.collections.get(oldName).close();
435
+ this.collections.delete(oldName);
436
+ }
437
+ await fs2.promises.rename(oldPath, newPath);
438
+ const col = new Collection(newPath);
439
+ this.collections.set(newName, col);
440
+ return true;
441
+ }
442
+ async dropCollection(name) {
443
+ return this.deleteCollection(name);
444
+ }
445
+ async listCollections() {
446
+ const dirs = await fs2.promises.readdir(this.basePath, {
447
+ withFileTypes: true
448
+ });
449
+ return dirs.filter((d) => d.isDirectory()).map((d) => d.name);
450
+ }
451
+ /* -------------------------------- LIFECYCLE -------------------------------- */
452
+ async close() {
453
+ for (const col of this.collections.values()) {
454
+ try {
455
+ await col.close();
456
+ } catch {
457
+ }
458
+ }
459
+ this.collections.clear();
460
+ }
461
+ /* -------------------------------- DEBUG -------------------------------- */
462
+ getStats() {
463
+ return {
464
+ dbName: this.dbName,
465
+ basePath: this.basePath,
466
+ collections: [...this.collections.keys()]
467
+ };
468
+ }
469
+ };
470
+
471
+ // src/utils/rootpath.ts
472
+ import os2 from "os";
473
+ import path3 from "path";
474
+ import fs3 from "fs";
475
+ function getDefaultRootPath() {
476
+ let dbPath = process.env.LIORANDB_PATH;
477
+ if (!dbPath) {
478
+ const homeDir = os2.homedir();
479
+ dbPath = path3.join(homeDir, "LioranDB", "db");
480
+ if (!fs3.existsSync(dbPath)) {
481
+ fs3.mkdirSync(dbPath, { recursive: true });
482
+ }
483
+ process.env.LIORANDB_PATH = dbPath;
484
+ }
485
+ return dbPath;
486
+ }
487
+ function getBaseDBFolder() {
488
+ return getDefaultRootPath();
489
+ }
490
+
491
+ // src/LioranManager.ts
492
+ import path5 from "path";
493
+ import fs4 from "fs";
494
+
495
+ // src/ipc/queue.ts
496
+ import { fork } from "child_process";
497
+ import path4 from "path";
498
+ import { fileURLToPath } from "url";
499
+ var __filename = fileURLToPath(import.meta.url);
500
+ var __dirname = path4.dirname(__filename);
501
+ function resolveWorkerPath() {
502
+ return path4.resolve(__dirname, "../worker/dbWorker.js");
503
+ }
504
+ var DBQueue = class {
505
+ worker;
506
+ seq = 0;
507
+ pending = /* @__PURE__ */ new Map();
508
+ constructor() {
509
+ const workerPath = resolveWorkerPath();
510
+ this.worker = fork(workerPath);
511
+ this.worker.on("message", (msg) => {
512
+ const cb = this.pending.get(msg.id);
513
+ if (cb) {
514
+ this.pending.delete(msg.id);
515
+ cb(msg);
516
+ }
517
+ });
518
+ }
519
+ exec(action, args) {
520
+ return new Promise((resolve, reject) => {
521
+ const id = ++this.seq;
522
+ this.pending.set(id, (msg) => {
523
+ if (msg.ok) resolve(msg.result);
524
+ else reject(new Error(msg.error));
525
+ });
526
+ this.worker.send({ id, action, args });
527
+ });
528
+ }
529
+ };
530
+ var dbQueue = new DBQueue();
531
+
532
+ // src/LioranManager.ts
533
+ var LioranManager = class {
534
+ rootPath;
535
+ openDBs;
536
+ closed = false;
537
+ ipc;
538
+ constructor(options = {}) {
539
+ const { rootPath, encryptionKey, ipc } = options;
540
+ this.rootPath = rootPath || getDefaultRootPath();
541
+ this.ipc = ipc ?? process.env.LIORANDB_IPC === "1";
542
+ if (!fs4.existsSync(this.rootPath)) {
543
+ fs4.mkdirSync(this.rootPath, { recursive: true });
544
+ }
545
+ if (encryptionKey) {
546
+ setEncryptionKey(encryptionKey);
547
+ }
548
+ this.openDBs = /* @__PURE__ */ new Map();
549
+ if (!this.ipc) {
550
+ this._registerShutdownHooks();
551
+ }
552
+ }
553
+ /* -------------------------------- CORE -------------------------------- */
554
+ async db(name) {
555
+ if (this.ipc) {
556
+ await dbQueue.exec("db", { db: name });
557
+ return new IPCDatabase(name);
558
+ }
559
+ return this.openDatabase(name);
560
+ }
561
+ async createDatabase(name) {
562
+ this._assertOpen();
563
+ const dbPath = path5.join(this.rootPath, name);
564
+ if (fs4.existsSync(dbPath)) {
565
+ throw new Error(`Database "${name}" already exists`);
566
+ }
567
+ await fs4.promises.mkdir(dbPath, { recursive: true });
568
+ return this.db(name);
569
+ }
570
+ async openDatabase(name) {
571
+ this._assertOpen();
572
+ if (this.openDBs.has(name)) {
573
+ return this.openDBs.get(name);
574
+ }
575
+ const dbPath = path5.join(this.rootPath, name);
576
+ if (!fs4.existsSync(dbPath)) {
577
+ await fs4.promises.mkdir(dbPath, { recursive: true });
578
+ }
579
+ const db = new LioranDB(dbPath, name, this);
580
+ this.openDBs.set(name, db);
581
+ return db;
582
+ }
583
+ /* -------------------------------- LIFECYCLE -------------------------------- */
584
+ async closeDatabase(name) {
585
+ if (this.ipc) return;
586
+ if (!this.openDBs.has(name)) return;
587
+ const db = this.openDBs.get(name);
588
+ await db.close();
589
+ this.openDBs.delete(name);
590
+ }
591
+ async closeAll() {
592
+ if (this.ipc || this.closed) return;
593
+ this.closed = true;
594
+ for (const db of this.openDBs.values()) {
595
+ try {
596
+ await db.close();
597
+ } catch {
598
+ }
599
+ }
600
+ this.openDBs.clear();
601
+ }
602
+ _registerShutdownHooks() {
603
+ const shutdown = async () => {
604
+ await this.closeAll();
605
+ process.exit(0);
606
+ };
607
+ process.on("SIGINT", shutdown);
608
+ process.on("SIGTERM", shutdown);
609
+ process.on("exit", () => {
610
+ this.closeAll().catch(() => {
611
+ });
612
+ });
613
+ }
614
+ _assertOpen() {
615
+ if (this.closed) {
616
+ throw new Error("LioranManager is closed");
617
+ }
618
+ }
619
+ /* -------------------------------- MANAGEMENT -------------------------------- */
620
+ async renameDatabase(oldName, newName) {
621
+ if (this.ipc) {
622
+ return await dbQueue.exec("renameDatabase", { oldName, newName });
623
+ }
624
+ const oldPath = path5.join(this.rootPath, oldName);
625
+ const newPath = path5.join(this.rootPath, newName);
626
+ if (!fs4.existsSync(oldPath)) {
627
+ throw new Error(`Database "${oldName}" not found`);
628
+ }
629
+ if (fs4.existsSync(newPath)) {
630
+ throw new Error(`Database "${newName}" already exists`);
631
+ }
632
+ await this.closeDatabase(oldName);
633
+ await fs4.promises.rename(oldPath, newPath);
634
+ return true;
635
+ }
636
+ async deleteDatabase(name) {
637
+ return this.dropDatabase(name);
638
+ }
639
+ async dropDatabase(name) {
640
+ if (this.ipc) {
641
+ return await dbQueue.exec("dropDatabase", { name });
642
+ }
643
+ const dbPath = path5.join(this.rootPath, name);
644
+ if (!fs4.existsSync(dbPath)) return false;
645
+ await this.closeDatabase(name);
646
+ await fs4.promises.rm(dbPath, { recursive: true, force: true });
647
+ return true;
648
+ }
649
+ async listDatabases() {
650
+ if (this.ipc) {
651
+ return await dbQueue.exec("listDatabases", {});
652
+ }
653
+ const items = await fs4.promises.readdir(this.rootPath, {
654
+ withFileTypes: true
655
+ });
656
+ return items.filter((i) => i.isDirectory()).map((i) => i.name);
657
+ }
658
+ /* -------------------------------- DEBUG -------------------------------- */
659
+ getStats() {
660
+ return {
661
+ rootPath: this.rootPath,
662
+ openDatabases: this.ipc ? ["<ipc>"] : [...this.openDBs.keys()],
663
+ ipc: this.ipc
664
+ };
665
+ }
666
+ };
667
+ var IPCDatabase = class {
668
+ constructor(name) {
669
+ this.name = name;
670
+ }
671
+ collection(name) {
672
+ return new IPCCollection(this.name, name);
673
+ }
674
+ };
675
+ var IPCCollection = class {
676
+ constructor(db, col) {
677
+ this.db = db;
678
+ this.col = col;
679
+ }
680
+ call(method, params) {
681
+ return dbQueue.exec("op", {
682
+ db: this.db,
683
+ col: this.col,
684
+ method,
685
+ params
686
+ });
687
+ }
688
+ insertOne = (doc) => this.call("insertOne", [doc]);
689
+ insertMany = (docs) => this.call("insertMany", [docs]);
690
+ find = (query) => this.call("find", [query]);
691
+ findOne = (query) => this.call("findOne", [query]);
692
+ updateOne = (filter, update, options) => this.call("updateOne", [filter, update, options]);
693
+ updateMany = (filter, update) => this.call("updateMany", [filter, update]);
694
+ deleteOne = (filter) => this.call("deleteOne", [filter]);
695
+ deleteMany = (filter) => this.call("deleteMany", [filter]);
696
+ countDocuments = (filter) => this.call("countDocuments", [filter]);
697
+ };
698
+
699
+ export {
700
+ LioranDB,
701
+ getBaseDBFolder,
702
+ LioranManager
703
+ };