@liorandb/core 1.0.9 → 1.0.11
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/chunk-DD5XS45L.js +703 -0
- package/dist/chunk-HZWANELV.js +841 -0
- package/dist/chunk-J7OD7MXK.js +741 -0
- package/dist/chunk-JETRGCOS.js +703 -0
- package/dist/chunk-JIGKUFXC.js +741 -0
- package/dist/chunk-RIHXIHVF.js +837 -0
- package/dist/chunk-SLVZTQTW.js +817 -0
- package/dist/chunk-VFFCPJGN.js +817 -0
- package/dist/client.d.ts +14 -0
- package/dist/client.js +55 -0
- package/dist/collection.d.ts +16 -0
- package/dist/collection.js +36 -0
- package/dist/db.d.ts +13 -0
- package/dist/db.js +30 -0
- package/dist/index.d.ts +51 -3
- package/dist/index.js +5 -435
- package/dist/types.d.ts +18 -0
- package/dist/types.js +2 -0
- package/dist/utils/parseUri.d.ts +7 -0
- package/dist/utils/parseUri.js +20 -0
- package/dist/worker/dbWorker.d.ts +2 -0
- package/dist/worker/dbWorker.js +40 -0
- package/package.json +5 -4
- package/src/LioranManager.ts +140 -9
- package/src/core/collection.ts +327 -105
- package/src/core/database.ts +50 -9
- package/src/ipc/index.ts +56 -0
- package/src/ipc/queue.ts +138 -0
- package/src/types/index.ts +2 -1
- package/src/utils/encryption.ts +6 -1
- package/src/utils/schema.ts +14 -0
- package/src/worker/dbWorker.ts +45 -0
package/dist/index.js
CHANGED
|
@@ -1,438 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import path from "path";
|
|
7
|
-
import fs from "fs";
|
|
8
|
-
|
|
9
|
-
// src/core/collection.ts
|
|
10
|
-
import { ClassicLevel } from "classic-level";
|
|
11
|
-
|
|
12
|
-
// src/core/query.ts
|
|
13
|
-
function getByPath(obj, path4) {
|
|
14
|
-
return path4.split(".").reduce((o, p) => o ? o[p] : void 0, obj);
|
|
15
|
-
}
|
|
16
|
-
function matchDocument(doc, query) {
|
|
17
|
-
for (const key of Object.keys(query)) {
|
|
18
|
-
const cond = query[key];
|
|
19
|
-
const val = getByPath(doc, key);
|
|
20
|
-
if (cond && typeof cond === "object" && !Array.isArray(cond)) {
|
|
21
|
-
for (const op of Object.keys(cond)) {
|
|
22
|
-
const v = cond[op];
|
|
23
|
-
if (op === "$gt" && !(val > v)) return false;
|
|
24
|
-
if (op === "$gte" && !(val >= v)) return false;
|
|
25
|
-
if (op === "$lt" && !(val < v)) return false;
|
|
26
|
-
if (op === "$lte" && !(val <= v)) return false;
|
|
27
|
-
if (op === "$ne" && val === v) return false;
|
|
28
|
-
if (op === "$eq" && val !== v) return false;
|
|
29
|
-
if (op === "$in" && (!Array.isArray(v) || !v.includes(val)))
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
} else {
|
|
33
|
-
if (val !== cond) return false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
function applyUpdate(oldDoc, update) {
|
|
39
|
-
const doc = structuredClone(oldDoc);
|
|
40
|
-
if (update.$set) {
|
|
41
|
-
for (const k in update.$set) {
|
|
42
|
-
const parts = k.split(".");
|
|
43
|
-
let cur = doc;
|
|
44
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
45
|
-
cur[parts[i]] ??= {};
|
|
46
|
-
cur = cur[parts[i]];
|
|
47
|
-
}
|
|
48
|
-
cur[parts.at(-1)] = update.$set[k];
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
if (update.$inc) {
|
|
52
|
-
for (const k in update.$inc) {
|
|
53
|
-
const val = getByPath(doc, k) ?? 0;
|
|
54
|
-
const parts = k.split(".");
|
|
55
|
-
let cur = doc;
|
|
56
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
57
|
-
cur[parts[i]] ??= {};
|
|
58
|
-
cur = cur[parts[i]];
|
|
59
|
-
}
|
|
60
|
-
cur[parts.at(-1)] = val + update.$inc[k];
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
const hasOp = Object.keys(update).some((k) => k.startsWith("$"));
|
|
64
|
-
if (!hasOp) {
|
|
65
|
-
return { ...doc, ...update };
|
|
66
|
-
}
|
|
67
|
-
return doc;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// src/core/collection.ts
|
|
71
|
-
import { v4 as uuid } from "uuid";
|
|
72
|
-
|
|
73
|
-
// src/utils/encryption.ts
|
|
74
|
-
import crypto2 from "crypto";
|
|
75
|
-
|
|
76
|
-
// src/utils/secureKey.ts
|
|
77
|
-
import crypto from "crypto";
|
|
78
|
-
import os from "os";
|
|
79
|
-
function getMasterKey() {
|
|
80
|
-
const fingerprint = [
|
|
81
|
-
os.hostname(),
|
|
82
|
-
os.platform(),
|
|
83
|
-
os.arch(),
|
|
84
|
-
os.cpus()?.[0]?.model ?? "unknown",
|
|
85
|
-
os.cpus()?.length ?? 0,
|
|
86
|
-
os.totalmem()
|
|
87
|
-
].join("|");
|
|
88
|
-
return crypto.createHash("sha256").update(fingerprint).digest();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// src/utils/encryption.ts
|
|
92
|
-
var algorithm = "aes-256-gcm";
|
|
93
|
-
var ACTIVE_KEY = getMasterKey();
|
|
94
|
-
function setEncryptionKey(key) {
|
|
95
|
-
if (!key) return;
|
|
96
|
-
if (typeof key === "string") {
|
|
97
|
-
ACTIVE_KEY = crypto2.createHash("sha256").update(key).digest();
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
if (Buffer.isBuffer(key)) {
|
|
101
|
-
if (key.length !== 32) {
|
|
102
|
-
throw new Error("Encryption key must be 32 bytes");
|
|
103
|
-
}
|
|
104
|
-
ACTIVE_KEY = key;
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
throw new Error("Invalid encryption key format");
|
|
108
|
-
}
|
|
109
|
-
function encryptData(obj) {
|
|
110
|
-
const iv = crypto2.randomBytes(16);
|
|
111
|
-
const data = Buffer.from(JSON.stringify(obj), "utf8");
|
|
112
|
-
const cipher = crypto2.createCipheriv(algorithm, ACTIVE_KEY, iv);
|
|
113
|
-
const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
|
|
114
|
-
const tag = cipher.getAuthTag();
|
|
115
|
-
return Buffer.concat([iv, tag, encrypted]).toString("base64");
|
|
116
|
-
}
|
|
117
|
-
function decryptData(enc) {
|
|
118
|
-
const buf = Buffer.from(enc, "base64");
|
|
119
|
-
const iv = buf.subarray(0, 16);
|
|
120
|
-
const tag = buf.subarray(16, 32);
|
|
121
|
-
const encrypted = buf.subarray(32);
|
|
122
|
-
const decipher = crypto2.createDecipheriv(algorithm, ACTIVE_KEY, iv);
|
|
123
|
-
decipher.setAuthTag(tag);
|
|
124
|
-
const decrypted = Buffer.concat([
|
|
125
|
-
decipher.update(encrypted),
|
|
126
|
-
decipher.final()
|
|
127
|
-
]);
|
|
128
|
-
return JSON.parse(decrypted.toString("utf8"));
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// src/core/collection.ts
|
|
132
|
-
var Collection = class {
|
|
133
|
-
dir;
|
|
134
|
-
db;
|
|
135
|
-
queue;
|
|
136
|
-
constructor(dir) {
|
|
137
|
-
this.dir = dir;
|
|
138
|
-
this.db = new ClassicLevel(dir);
|
|
139
|
-
this.queue = Promise.resolve();
|
|
140
|
-
}
|
|
141
|
-
_enqueue(task) {
|
|
142
|
-
this.queue = this.queue.then(task).catch(console.error);
|
|
143
|
-
return this.queue;
|
|
144
|
-
}
|
|
145
|
-
async close() {
|
|
146
|
-
try {
|
|
147
|
-
await this.db.close();
|
|
148
|
-
} catch {
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
async insertOne(doc) {
|
|
152
|
-
return this._enqueue(async () => {
|
|
153
|
-
const _id = doc._id ?? uuid();
|
|
154
|
-
const final = { _id, ...doc };
|
|
155
|
-
await this.db.put(String(_id), encryptData(final));
|
|
156
|
-
return final;
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
async insertMany(docs = []) {
|
|
160
|
-
return this._enqueue(async () => {
|
|
161
|
-
const ops = [];
|
|
162
|
-
const out = [];
|
|
163
|
-
for (const d of docs) {
|
|
164
|
-
const _id = d._id ?? uuid();
|
|
165
|
-
const final = { _id, ...d };
|
|
166
|
-
ops.push({
|
|
167
|
-
type: "put",
|
|
168
|
-
key: String(_id),
|
|
169
|
-
value: encryptData(final)
|
|
170
|
-
});
|
|
171
|
-
out.push(final);
|
|
172
|
-
}
|
|
173
|
-
await this.db.batch(ops);
|
|
174
|
-
return out;
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
async find(query = {}) {
|
|
178
|
-
return this._enqueue(async () => {
|
|
179
|
-
const out = [];
|
|
180
|
-
for await (const [, enc] of this.db.iterator()) {
|
|
181
|
-
const value = decryptData(enc);
|
|
182
|
-
if (matchDocument(value, query)) out.push(value);
|
|
183
|
-
}
|
|
184
|
-
return out;
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
async findOne(query = {}) {
|
|
188
|
-
return this._enqueue(async () => {
|
|
189
|
-
for await (const [, enc] of this.db.iterator()) {
|
|
190
|
-
const value = decryptData(enc);
|
|
191
|
-
if (matchDocument(value, query)) return value;
|
|
192
|
-
}
|
|
193
|
-
return null;
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
async updateOne(filter = {}, update = {}, options = { upsert: false }) {
|
|
197
|
-
return this._enqueue(async () => {
|
|
198
|
-
for await (const [key, enc] of this.db.iterator()) {
|
|
199
|
-
const value = decryptData(enc);
|
|
200
|
-
if (matchDocument(value, filter)) {
|
|
201
|
-
const updated = applyUpdate(value, update);
|
|
202
|
-
updated._id = value._id;
|
|
203
|
-
await this.db.put(key, encryptData(updated));
|
|
204
|
-
return updated;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
if (options.upsert) {
|
|
208
|
-
const doc = applyUpdate(filter, update);
|
|
209
|
-
doc._id ??= uuid();
|
|
210
|
-
await this.db.put(String(doc._id), encryptData(doc));
|
|
211
|
-
return doc;
|
|
212
|
-
}
|
|
213
|
-
return null;
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
async updateMany(filter = {}, update = {}) {
|
|
217
|
-
return this._enqueue(async () => {
|
|
218
|
-
const updated = [];
|
|
219
|
-
for await (const [key, enc] of this.db.iterator()) {
|
|
220
|
-
const value = decryptData(enc);
|
|
221
|
-
if (matchDocument(value, filter)) {
|
|
222
|
-
const doc = applyUpdate(value, update);
|
|
223
|
-
doc._id = value._id;
|
|
224
|
-
await this.db.put(key, encryptData(doc));
|
|
225
|
-
updated.push(doc);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
return updated;
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
async deleteOne(filter = {}) {
|
|
232
|
-
return this._enqueue(async () => {
|
|
233
|
-
for await (const [key, enc] of this.db.iterator()) {
|
|
234
|
-
const value = decryptData(enc);
|
|
235
|
-
if (matchDocument(value, filter)) {
|
|
236
|
-
await this.db.del(key);
|
|
237
|
-
return true;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return false;
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
async deleteMany(filter = {}) {
|
|
244
|
-
return this._enqueue(async () => {
|
|
245
|
-
let count = 0;
|
|
246
|
-
for await (const [key, enc] of this.db.iterator()) {
|
|
247
|
-
const value = decryptData(enc);
|
|
248
|
-
if (matchDocument(value, filter)) {
|
|
249
|
-
await this.db.del(key);
|
|
250
|
-
count++;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
return count;
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
async countDocuments(filter = {}) {
|
|
257
|
-
return this._enqueue(async () => {
|
|
258
|
-
let c = 0;
|
|
259
|
-
for await (const [, enc] of this.db.iterator()) {
|
|
260
|
-
const value = decryptData(enc);
|
|
261
|
-
if (matchDocument(value, filter)) c++;
|
|
262
|
-
}
|
|
263
|
-
return c;
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
// src/core/database.ts
|
|
269
|
-
var LioranDB = class {
|
|
270
|
-
basePath;
|
|
271
|
-
dbName;
|
|
272
|
-
manager;
|
|
273
|
-
collections;
|
|
274
|
-
constructor(basePath, dbName, manager) {
|
|
275
|
-
this.basePath = basePath;
|
|
276
|
-
this.dbName = dbName;
|
|
277
|
-
this.manager = manager;
|
|
278
|
-
this.collections = /* @__PURE__ */ new Map();
|
|
279
|
-
if (!fs.existsSync(basePath)) {
|
|
280
|
-
fs.mkdirSync(basePath, { recursive: true });
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
collection(name) {
|
|
284
|
-
if (this.collections.has(name)) {
|
|
285
|
-
return this.collections.get(name);
|
|
286
|
-
}
|
|
287
|
-
const colPath = path.join(this.basePath, name);
|
|
288
|
-
if (!fs.existsSync(colPath)) {
|
|
289
|
-
fs.mkdirSync(colPath, { recursive: true });
|
|
290
|
-
}
|
|
291
|
-
const col = new Collection(colPath);
|
|
292
|
-
this.collections.set(name, col);
|
|
293
|
-
return col;
|
|
294
|
-
}
|
|
295
|
-
async createCollection(name) {
|
|
296
|
-
const colPath = path.join(this.basePath, name);
|
|
297
|
-
if (fs.existsSync(colPath)) {
|
|
298
|
-
throw new Error("Collection already exists");
|
|
299
|
-
}
|
|
300
|
-
await fs.promises.mkdir(colPath, { recursive: true });
|
|
301
|
-
this.collections.set(name, new Collection(colPath));
|
|
302
|
-
return true;
|
|
303
|
-
}
|
|
304
|
-
async deleteCollection(name) {
|
|
305
|
-
const colPath = path.join(this.basePath, name);
|
|
306
|
-
if (!fs.existsSync(colPath)) {
|
|
307
|
-
throw new Error("Collection does not exist");
|
|
308
|
-
}
|
|
309
|
-
if (this.collections.has(name)) {
|
|
310
|
-
await this.collections.get(name).close();
|
|
311
|
-
this.collections.delete(name);
|
|
312
|
-
}
|
|
313
|
-
await fs.promises.rm(colPath, { recursive: true, force: true });
|
|
314
|
-
return true;
|
|
315
|
-
}
|
|
316
|
-
async renameCollection(oldName, newName) {
|
|
317
|
-
const oldPath = path.join(this.basePath, oldName);
|
|
318
|
-
const newPath = path.join(this.basePath, newName);
|
|
319
|
-
if (!fs.existsSync(oldPath)) throw new Error("Collection does not exist");
|
|
320
|
-
if (fs.existsSync(newPath)) throw new Error("New collection name exists");
|
|
321
|
-
if (this.collections.has(oldName)) {
|
|
322
|
-
await this.collections.get(oldName).close();
|
|
323
|
-
this.collections.delete(oldName);
|
|
324
|
-
}
|
|
325
|
-
await fs.promises.rename(oldPath, newPath);
|
|
326
|
-
this.collections.set(newName, new Collection(newPath));
|
|
327
|
-
return true;
|
|
328
|
-
}
|
|
329
|
-
async dropCollection(name) {
|
|
330
|
-
return this.deleteCollection(name);
|
|
331
|
-
}
|
|
332
|
-
async listCollections() {
|
|
333
|
-
const dirs = await fs.promises.readdir(this.basePath, {
|
|
334
|
-
withFileTypes: true
|
|
335
|
-
});
|
|
336
|
-
return dirs.filter((d) => d.isDirectory()).map((d) => d.name);
|
|
337
|
-
}
|
|
338
|
-
};
|
|
339
|
-
|
|
340
|
-
// src/utils/rootpath.ts
|
|
341
|
-
import os2 from "os";
|
|
342
|
-
import path2 from "path";
|
|
343
|
-
import fs2 from "fs";
|
|
344
|
-
function getDefaultRootPath() {
|
|
345
|
-
let dbPath = process.env.LIORANDB_PATH;
|
|
346
|
-
if (!dbPath) {
|
|
347
|
-
const homeDir = os2.homedir();
|
|
348
|
-
dbPath = path2.join(homeDir, "LioranDB", "db");
|
|
349
|
-
if (!fs2.existsSync(dbPath)) {
|
|
350
|
-
fs2.mkdirSync(dbPath, { recursive: true });
|
|
351
|
-
}
|
|
352
|
-
process.env.LIORANDB_PATH = dbPath;
|
|
353
|
-
}
|
|
354
|
-
return dbPath;
|
|
355
|
-
}
|
|
356
|
-
function getBaseDBFolder() {
|
|
357
|
-
return getDefaultRootPath();
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// src/LioranManager.ts
|
|
361
|
-
var LioranManager = class {
|
|
362
|
-
rootPath;
|
|
363
|
-
openDBs;
|
|
364
|
-
constructor(options = {}) {
|
|
365
|
-
const { rootPath, encryptionKey } = options;
|
|
366
|
-
this.rootPath = rootPath || getDefaultRootPath();
|
|
367
|
-
if (!fs3.existsSync(this.rootPath)) {
|
|
368
|
-
fs3.mkdirSync(this.rootPath, { recursive: true });
|
|
369
|
-
}
|
|
370
|
-
if (encryptionKey) {
|
|
371
|
-
setEncryptionKey(encryptionKey);
|
|
372
|
-
}
|
|
373
|
-
this.openDBs = /* @__PURE__ */ new Map();
|
|
374
|
-
}
|
|
375
|
-
async db(name) {
|
|
376
|
-
return this.openDatabase(name);
|
|
377
|
-
}
|
|
378
|
-
async createDatabase(name) {
|
|
379
|
-
const dbPath = path3.join(this.rootPath, name);
|
|
380
|
-
if (fs3.existsSync(dbPath)) {
|
|
381
|
-
throw new Error(`Database "${name}" already exists`);
|
|
382
|
-
}
|
|
383
|
-
await fs3.promises.mkdir(dbPath, { recursive: true });
|
|
384
|
-
return this.openDatabase(name);
|
|
385
|
-
}
|
|
386
|
-
async openDatabase(name) {
|
|
387
|
-
const dbPath = path3.join(this.rootPath, name);
|
|
388
|
-
if (!fs3.existsSync(dbPath)) {
|
|
389
|
-
await fs3.promises.mkdir(dbPath, { recursive: true });
|
|
390
|
-
}
|
|
391
|
-
if (this.openDBs.has(name)) {
|
|
392
|
-
return this.openDBs.get(name);
|
|
393
|
-
}
|
|
394
|
-
const db = new LioranDB(dbPath, name, this);
|
|
395
|
-
this.openDBs.set(name, db);
|
|
396
|
-
return db;
|
|
397
|
-
}
|
|
398
|
-
async closeDatabase(name) {
|
|
399
|
-
if (!this.openDBs.has(name)) return;
|
|
400
|
-
const db = this.openDBs.get(name);
|
|
401
|
-
for (const [, col] of db.collections.entries()) {
|
|
402
|
-
await col.close();
|
|
403
|
-
}
|
|
404
|
-
this.openDBs.delete(name);
|
|
405
|
-
}
|
|
406
|
-
async renameDatabase(oldName, newName) {
|
|
407
|
-
const oldPath = path3.join(this.rootPath, oldName);
|
|
408
|
-
const newPath = path3.join(this.rootPath, newName);
|
|
409
|
-
if (!fs3.existsSync(oldPath)) {
|
|
410
|
-
throw new Error(`Database "${oldName}" not found`);
|
|
411
|
-
}
|
|
412
|
-
if (fs3.existsSync(newPath)) {
|
|
413
|
-
throw new Error(`Database "${newName}" already exists`);
|
|
414
|
-
}
|
|
415
|
-
await this.closeDatabase(oldName);
|
|
416
|
-
await fs3.promises.rename(oldPath, newPath);
|
|
417
|
-
return true;
|
|
418
|
-
}
|
|
419
|
-
async deleteDatabase(name) {
|
|
420
|
-
return this.dropDatabase(name);
|
|
421
|
-
}
|
|
422
|
-
async dropDatabase(name) {
|
|
423
|
-
const dbPath = path3.join(this.rootPath, name);
|
|
424
|
-
if (!fs3.existsSync(dbPath)) return false;
|
|
425
|
-
await this.closeDatabase(name);
|
|
426
|
-
await fs3.promises.rm(dbPath, { recursive: true, force: true });
|
|
427
|
-
return true;
|
|
428
|
-
}
|
|
429
|
-
async listDatabases() {
|
|
430
|
-
const items = await fs3.promises.readdir(this.rootPath, {
|
|
431
|
-
withFileTypes: true
|
|
432
|
-
});
|
|
433
|
-
return items.filter((i) => i.isDirectory()).map((i) => i.name);
|
|
434
|
-
}
|
|
435
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
LioranDB,
|
|
3
|
+
LioranManager,
|
|
4
|
+
getBaseDBFolder
|
|
5
|
+
} from "./chunk-RIHXIHVF.js";
|
|
436
6
|
export {
|
|
437
7
|
LioranDB,
|
|
438
8
|
LioranManager,
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface LioranUser {
|
|
2
|
+
id: string;
|
|
3
|
+
username: string;
|
|
4
|
+
}
|
|
5
|
+
export interface LioranLoginResponse {
|
|
6
|
+
user: LioranUser;
|
|
7
|
+
token: string;
|
|
8
|
+
}
|
|
9
|
+
export interface DocumentData {
|
|
10
|
+
_id?: string;
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
}
|
|
13
|
+
export type Filter = Record<string, any>;
|
|
14
|
+
export type UpdateQuery = {
|
|
15
|
+
$set?: Record<string, any>;
|
|
16
|
+
$inc?: Record<string, number>;
|
|
17
|
+
$unset?: Record<string, boolean>;
|
|
18
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseUri = parseUri;
|
|
4
|
+
function parseUri(uri) {
|
|
5
|
+
if (!uri.startsWith("lioran://")) {
|
|
6
|
+
throw new Error("Invalid URI. Must start with lioran://");
|
|
7
|
+
}
|
|
8
|
+
const stripped = uri.replace("lioran://", "");
|
|
9
|
+
const [creds, server] = stripped.split("@");
|
|
10
|
+
if (!creds || !server) {
|
|
11
|
+
throw new Error("Invalid LioranDB URI");
|
|
12
|
+
}
|
|
13
|
+
const [username, password] = creds.split(":");
|
|
14
|
+
const [host, portStr] = server.split(":");
|
|
15
|
+
const port = Number(portStr);
|
|
16
|
+
if (!username || !password || !host || !port) {
|
|
17
|
+
throw new Error("Invalid LioranDB URI");
|
|
18
|
+
}
|
|
19
|
+
return { username, password, host, port };
|
|
20
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LioranManager
|
|
3
|
+
} from "../chunk-RIHXIHVF.js";
|
|
4
|
+
|
|
5
|
+
// src/worker/dbWorker.ts
|
|
6
|
+
var manager = new LioranManager();
|
|
7
|
+
process.on("message", async (msg) => {
|
|
8
|
+
const { id, action, args } = msg;
|
|
9
|
+
try {
|
|
10
|
+
let result;
|
|
11
|
+
switch (action) {
|
|
12
|
+
case "shutdown": {
|
|
13
|
+
await manager.closeAll();
|
|
14
|
+
result = true;
|
|
15
|
+
break;
|
|
16
|
+
}
|
|
17
|
+
case "db": {
|
|
18
|
+
const db = await manager.db(args.db);
|
|
19
|
+
result = true;
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
case "collection": {
|
|
23
|
+
const db = await manager.db(args.db);
|
|
24
|
+
result = db.collection(args.collection);
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
case "op": {
|
|
28
|
+
const { db, col, method, params } = args;
|
|
29
|
+
const collection = (await manager.db(db)).collection(col);
|
|
30
|
+
result = await collection[method](...params);
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
default:
|
|
34
|
+
throw new Error("Unknown action");
|
|
35
|
+
}
|
|
36
|
+
process.send?.({ id, ok: true, result });
|
|
37
|
+
} catch (err) {
|
|
38
|
+
process.send?.({ id, ok: false, error: err.message });
|
|
39
|
+
}
|
|
40
|
+
});
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liorandb/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"description": "**LioranDB Core Module** – Lightweight, local-first, peer-to-peer database management for Node.js.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"build": "tsup src/index.ts --dts --format esm",
|
|
8
|
+
"build": "tsup src/index.ts src/worker/dbWorker.ts --dts --format esm",
|
|
9
9
|
"prepublishOnly": "npm run build"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
@@ -29,11 +29,12 @@
|
|
|
29
29
|
"homepage": "https://github.com/LioranGroupOfficial/Liorandb#readme",
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"classic-level": "^3.0.0",
|
|
32
|
-
"uuid": "^13.0.0"
|
|
32
|
+
"uuid": "^13.0.0",
|
|
33
|
+
"zod": "^4.3.6"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
36
|
"@types/node": "^25.2.0",
|
|
36
37
|
"tsup": "^8.5.1",
|
|
37
38
|
"typescript": "^5.9.3"
|
|
38
39
|
}
|
|
39
|
-
}
|
|
40
|
+
}
|