twin-db 1.3.0 → 2.0.0

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/README.md CHANGED
@@ -1,18 +1,63 @@
1
1
  ### Before All
2
2
  Make sure to pass just values that JSON accepts, if not, the values will be changed to `null`.
3
+
3
4
  # How to Use?
4
5
  To create a new database make the following step:
5
6
  ```js
6
7
  import { TwinDB } from 'twin-db';
7
- const database = new TwinDB('db');
8
+ const database = new TwinDB('database/twin');
9
+ ```
10
+ or
11
+ ```js
12
+ const { TwinDB } = require('twin-db');
13
+ const database = new TwinDB('database/twin');
8
14
  ```
9
15
  And your database is done.
10
16
  ### You can make various databases too:
11
17
  ```js
12
18
  import { TwinDB } from 'twin-db';
13
- const database = new TwinDB('db');
14
- const coolDatabase = new TwinDB('cool');
19
+ const database = new TwinDB('database/db');
20
+ const coolDatabase = new TwinDB('database/cool');
21
+ ```
22
+ > The first argument is a file **path** — folders in it are created automatically if they don't exist. If you don't pass one, it defaults to `database/twin`.
23
+
24
+ # Storages
25
+ By default, `TwinDB` saves your data in a local `.json` file (`JSONStorage`). If you'd rather store it in a local SQLite database, pass `SqliteStorage` in the options:
26
+ ```js
27
+ import { TwinDB, SqliteStorage } from 'twin-db';
28
+
29
+ const database = new TwinDB('database/db', { storage: SqliteStorage });
30
+ ```
31
+ `SqliteStorage` also accepts an optional `table` and `key`, in case you want more than one database sharing the same `.db` file:
32
+ ```js
33
+ const database = new TwinDB('database/db', {
34
+ storage: SqliteStorage,
35
+ table: 'users', // defaults to "twin"
36
+ key: 'main', // defaults to "data"
37
+ });
38
+ ```
39
+ Both storages implement the same interface, so switching between them doesn't change any of the methods in **Database Methods**.
40
+
41
+ # TwinMongoDB
42
+ If you'd rather store your data in MongoDB instead of locally, use `TwinMongoDB`. It shares the exact same methods as `TwinDB` (`set`, `get`, `delete`, `sum`, `sub`, `concat`, `push`, `pull`, all with the same `fetch` parameter), the only difference is how you create it and that every method is asynchronous:
43
+ ```js
44
+ import { TwinMongoDB } from 'twin-db';
45
+
46
+ const database = new TwinMongoDB('mongodb://localhost:27017/mydb', 'myCollection', 'myId');
47
+
48
+ await database.set('name', 'De');
49
+ const name = await database.get('name');
50
+ await database.push('hobbies', ['sleep'], true);
51
+ ```
52
+ - `connectionURI` (required) — your MongoDB connection string.
53
+ - `modelName` (optional) — the collection name, defaults to `"twin"`.
54
+ - `id` (optional) — the document `_id` used to store your data, defaults to `"data"`. Useful if you want multiple independent databases inside the same collection.
55
+
56
+ When you're done with it (e.g. before your process exits), make sure to close the connection so it doesn't hang:
57
+ ```js
58
+ await database.close();
15
59
  ```
60
+
16
61
  # Database Methods
17
62
  Now we going to explain you the database methods.<br>
18
63
  Imagine the following data from a random database:
@@ -42,18 +87,18 @@ Get a value from a given path.
42
87
  ```js
43
88
  database.get('surname'); // returns "Costa".
44
89
  ```
45
- ### 3. Delete Method
90
+ ### 3. Delete/Remove Method
46
91
  Deletes a value from data.
47
92
  ```js
48
93
  database.delete('cool') // now the cool value no longer exists.
49
94
  database.delete('address.country') // now the country no longer exists too.
50
95
  ```
51
- ### 4. Sum Method
96
+ ### 4. Sum/Add Method
52
97
  Sum the current value of the given path with the given value.
53
98
  ```js
54
99
  database.sum('age', 30); // now the age is 80.
55
100
  ```
56
- ### 5. Sub Method
101
+ ### 5. Sub/Subtract Method
57
102
  Subtract the current value of the given path with the given value.
58
103
  ```js
59
104
  database.sub('age', 10); // now the age is 70.
@@ -64,13 +109,14 @@ Concatenate the current value of the given path with the given value.
64
109
  database.concat('address.city', ' know'); // now the city is "I dont know".
65
110
  ```
66
111
  ### 7. Push Method
67
- Push the given values into the current value array.
112
+ Push the given values into the current value array. **The values must be passed as an array**, even if it's just one value.
68
113
  ```js
69
- database.push('hobbies', 'sleep', 'valorant'); // now the hobbies is ["cs", "pizza", "sleep", "valorant"].
114
+ database.push('hobbies', ['sleep', 'valorant']); // now the hobbies is ["cs", "pizza", "sleep", "valorant"].
70
115
  ```
71
116
  ### 8. Pull Method
117
+ Removes the given values from the current value array. **The values must be passed as an array**, even if it's just one value.
72
118
  ```js
73
- database.pull('hobbies', 'cs', 'sleep') // now the hobbies is ["pizza", "valorant"].
119
+ database.pull('hobbies', ['cs', 'sleep']) // now the hobbies is ["pizza", "valorant"].
74
120
  ```
75
121
  ### Now the data object will looks like that:
76
122
  ```json
@@ -85,13 +131,13 @@ database.pull('hobbies', 'cs', 'sleep') // now the hobbies is ["pizza", "valoran
85
131
  }
86
132
  }
87
133
  ```
88
- ## Updates
89
- `MM/DD/YYYY`<br>
90
- 04/09/2026 - 1.1.*
91
- - Now **sum**, **sub** and **push** sets the value to the value you passed in execution when the path does not exists.
92
134
 
93
- 05/03/2026 - 1.2.*
94
- - Now package doesn't uses eval anymore, providing better security.
135
+ ## The `fetch` parameter
136
+ Every method above accepts an optional `fetch` boolean as its last parameter (default `false`). When `true`, it re-reads the storage before running the operation and refreshes the cache with it — useful if another process might have written to the same storage since your last read.
137
+ ```js
138
+ database.get('name', true);
139
+ database.push('hobbies', ['sleep'], true);
140
+ ```
95
141
 
96
- 06/29/2026 - 1.3.*
97
- - Added support to require in commonjs.
142
+ ## Updates
143
+ See new updates [here](https://github.com/toddy007/twin-db/releases).
package/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,91 +17,300 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
21
31
  var index_exports = {};
22
32
  __export(index_exports, {
23
- TwinDB: () => TwinDB
33
+ JSONStorage: () => JSONStorage,
34
+ SqliteStorage: () => SqliteStorage,
35
+ TwinDB: () => TwinDB,
36
+ TwinMongoDB: () => TwinMongoDB
24
37
  });
25
38
  module.exports = __toCommonJS(index_exports);
26
39
 
27
- // src/structures/database.ts
28
- var import_fs = require("fs");
29
- var pathErrorMessage = "The path must be a string or you dont provide a path";
30
- var TwinDB = class {
31
- constructor(name = "db") {
32
- this.path = "database/" + name + ".json";
33
- this.name = name;
34
- this.data = {};
35
- if (!(0, import_fs.existsSync)("database")) (0, import_fs.mkdirSync)("database");
36
- this.load();
37
- }
38
- load() {
40
+ // src/structures/TwinDB.ts
41
+ var import_lodash = __toESM(require("lodash"), 1);
42
+
43
+ // src/storages/JSONStorage.ts
44
+ var import_node_fs = require("node:fs");
45
+ var JSONStorage = class {
46
+ constructor(path2) {
47
+ if (!path2.endsWith(".json")) path2 += ".json";
48
+ this.path = path2;
49
+ if (!(0, import_node_fs.existsSync)(path2)) (0, import_node_fs.writeFileSync)(path2, "{}", "utf8");
50
+ else {
51
+ const data = (0, import_node_fs.readFileSync)(path2, "utf8");
52
+ let parsedData;
53
+ try {
54
+ parsedData = JSON.parse(data);
55
+ } catch (_) {
56
+ }
57
+ if (!data || !parsedData || typeof parsedData !== "object" || Array.isArray(parsedData))
58
+ (0, import_node_fs.writeFileSync)(path2, "{}", "utf8");
59
+ }
60
+ }
61
+ get() {
39
62
  let data;
40
63
  try {
41
- data = (0, import_fs.readFileSync)(this.path, "utf8");
42
- } catch (e) {
43
- data = "";
64
+ data = (0, import_node_fs.readFileSync)(this.path, "utf8");
65
+ } catch (_) {
44
66
  }
45
- this.data = data ? JSON.parse(data) : {};
46
- if (!data)
47
- (0, import_fs.writeFileSync)(
48
- this.path,
49
- JSON.stringify(this.data, null, 2),
50
- "utf8"
67
+ let parsedData;
68
+ try {
69
+ if (data) parsedData = JSON.parse(data);
70
+ } catch (_) {
71
+ }
72
+ const checkedData = data && parsedData && typeof parsedData === "object" && !Array.isArray(parsedData);
73
+ if (!checkedData) (0, import_node_fs.writeFileSync)(this.path, "{}", "utf8");
74
+ return checkedData ? parsedData : {};
75
+ }
76
+ set(value) {
77
+ (0, import_node_fs.writeFileSync)(this.path, value, "utf8");
78
+ return true;
79
+ }
80
+ };
81
+
82
+ // src/storages/SqliteStorage.ts
83
+ var import_node_sqlite = require("node:sqlite");
84
+
85
+ // src/utils/vars.ts
86
+ var DEFAULT_KEY = "data";
87
+ var DEFAULT_NAME = "twin";
88
+ var pathErrorMessage = "The path must be a string or you dont provided a path";
89
+
90
+ // src/storages/SqliteStorage.ts
91
+ var SqliteStorage = class {
92
+ constructor(path2, table = DEFAULT_NAME, key = DEFAULT_KEY) {
93
+ if (!table || typeof table !== "string") table = DEFAULT_NAME;
94
+ if (!key || typeof key !== "string") key = DEFAULT_KEY;
95
+ this.table = table;
96
+ this.key = key;
97
+ if (!path2.endsWith(".db")) path2 += ".db";
98
+ this.db = new import_node_sqlite.DatabaseSync(path2);
99
+ this.db.exec(`
100
+ CREATE TABLE IF NOT EXISTS ${table} (
101
+ key TEXT PRIMARY KEY,
102
+ value TEXT
103
+ )
104
+ `);
105
+ }
106
+ set(value) {
107
+ this.db.prepare(
108
+ `INSERT OR REPLACE INTO ${this.table} (key, value) VALUES (?, ?)`
109
+ ).run(this.key, value);
110
+ return true;
111
+ }
112
+ get() {
113
+ const row = this.db.prepare(`SELECT value FROM ${this.table} WHERE key = ?`).get(this.key);
114
+ return row ? JSON.parse(row.value) : {};
115
+ }
116
+ };
117
+
118
+ // src/structures/TwinDB.ts
119
+ var import_node_path = __toESM(require("node:path"), 1);
120
+ var import_node_fs2 = require("node:fs");
121
+ var TwinDB = class {
122
+ constructor(argPath = "database/twin", options = { storage: JSONStorage }) {
123
+ this.remove = this.delete;
124
+ this.add = this.sum;
125
+ this.subtract = this.sub;
126
+ if (!argPath || typeof argPath !== "string")
127
+ throw new Error(pathErrorMessage);
128
+ const solvedPath = import_node_path.default.resolve(process.cwd(), argPath);
129
+ (0, import_node_fs2.mkdirSync)(import_node_path.default.dirname(solvedPath), { recursive: true });
130
+ if (!options || typeof options !== "object" || Array.isArray(options))
131
+ options = { storage: JSONStorage };
132
+ options.storage || (options.storage = JSONStorage);
133
+ if (![JSONStorage, SqliteStorage].includes(options.storage))
134
+ throw new Error("Invalid storage type passed in options");
135
+ this.storage = options.storage === SqliteStorage ? new options.storage(solvedPath, options.table, options.key) : new options.storage(solvedPath);
136
+ this.cache = this.storage.get();
137
+ }
138
+ update(path2, value, fetch = false) {
139
+ if (fetch) this.cache = this.storage.get();
140
+ import_lodash.default.set(this.cache, path2, value);
141
+ this.storage.set(JSON.stringify(this.cache));
142
+ return this.cache;
143
+ }
144
+ set(path2, value, fetch = false) {
145
+ if (!path2 || typeof path2 !== "string")
146
+ throw new Error(pathErrorMessage);
147
+ if (value === void 0)
148
+ throw new Error("You must provide a value to update");
149
+ return this.update(path2, value, fetch);
150
+ }
151
+ get(path2, fetch = false) {
152
+ if (!path2 || typeof path2 !== "string")
153
+ throw new Error(pathErrorMessage);
154
+ if (fetch) this.cache = this.storage.get();
155
+ return import_lodash.default.get(this.cache, path2, null);
156
+ }
157
+ delete(path2, fetch = false) {
158
+ if (!path2 || typeof path2 !== "string")
159
+ throw new Error(pathErrorMessage);
160
+ if (fetch) this.cache = this.storage.get();
161
+ const pathExists = this.get(path2);
162
+ if (pathExists === null)
163
+ throw new Error("The path does not exists or its value is null");
164
+ return this.update(path2, null);
165
+ }
166
+ sumOrSub(path2, value, type, fetch = false) {
167
+ if (!path2 || typeof path2 !== "string")
168
+ throw new Error(pathErrorMessage);
169
+ if (!type || !["sum", "sub"].includes(type))
170
+ throw new Error('The type must be "sum" or "sub"');
171
+ const isSum = type === "sum";
172
+ if (!value || typeof value !== "number")
173
+ throw new Error(
174
+ `The value to ${isSum ? "sum" : "sub"} must be a number`
51
175
  );
176
+ if (fetch) this.cache = this.storage.get();
177
+ let currentValue = this.get(path2) || 0;
178
+ if (typeof currentValue !== "number") currentValue = 0;
179
+ return this.update(
180
+ path2,
181
+ isSum ? currentValue + value : currentValue - value
182
+ );
52
183
  }
53
- update(path, value) {
54
- const keys = path.split(".");
55
- let current = this.data;
56
- for (let i = 0; i < keys.length; i++) {
57
- let key = keys[i];
58
- if (i === keys.length - 1) {
59
- current[key] = value;
60
- break;
61
- }
62
- if (typeof current[key] !== "object" || Array.isArray(current[key]) || !current[key]) {
63
- current[key] = {};
64
- }
65
- current = current[key];
184
+ sum(path2, value, fetch = false) {
185
+ return this.sumOrSub(path2, value, "sum", fetch);
186
+ }
187
+ sub(path2, value, fetch = false) {
188
+ return this.sumOrSub(path2, value, "sub", fetch);
189
+ }
190
+ concat(path2, value, fetch = false) {
191
+ if (!path2 || typeof path2 !== "string")
192
+ throw new Error(pathErrorMessage);
193
+ if (!value || typeof value !== "string")
194
+ throw new Error("You must provide a string value to update");
195
+ if (fetch) this.cache = this.storage.get();
196
+ const currentValue = this.get(path2);
197
+ if (typeof currentValue !== "string")
198
+ throw new Error(
199
+ "The value to concat is not a string or the path does not exists"
200
+ );
201
+ return this.update(path2, currentValue + value);
202
+ }
203
+ push(path2, values, fetch = false) {
204
+ if (!path2 || typeof path2 !== "string")
205
+ throw new Error(pathErrorMessage);
206
+ if (!values || values.length === 0)
207
+ throw new Error("You must provide a value to update");
208
+ if (fetch) this.cache = this.storage.get();
209
+ let currentValue = this.get(path2) || [];
210
+ if (!Array.isArray(currentValue)) currentValue = [];
211
+ currentValue.push(...values);
212
+ return this.update(path2, currentValue);
213
+ }
214
+ pull(path2, values, fetch = false) {
215
+ if (!path2 || typeof path2 !== "string")
216
+ throw new Error(pathErrorMessage);
217
+ if (!values || values.length === 0)
218
+ throw new Error("You must provide a value to update");
219
+ if (fetch) this.cache = this.storage.get();
220
+ const currentValue = this.get(path2);
221
+ if (!Array.isArray(currentValue))
222
+ throw new Error(
223
+ "The current value of this path is not an array or the path does not exists"
224
+ );
225
+ for (const value of values) {
226
+ const index = currentValue.indexOf(value);
227
+ if (index < 0) continue;
228
+ currentValue.splice(index, 1);
229
+ }
230
+ return this.update(path2, currentValue);
231
+ }
232
+ };
233
+
234
+ // src/structures/TwinMongoDB.ts
235
+ var import_lodash2 = __toESM(require("lodash"), 1);
236
+ var import_mongodb = require("mongodb");
237
+ var TwinMongoDB = class {
238
+ constructor(connectionURI, modelName = DEFAULT_NAME, id = DEFAULT_KEY) {
239
+ this.remove = this.delete;
240
+ this.add = this.sum;
241
+ this.subtract = this.sub;
242
+ if (!modelName || typeof modelName !== "string")
243
+ modelName = DEFAULT_NAME;
244
+ if (!id || typeof id !== "string") id = DEFAULT_KEY;
245
+ this.client = new import_mongodb.MongoClient(connectionURI);
246
+ this.cache = {};
247
+ this.id = id;
248
+ this.initPromise = this.init(modelName);
249
+ }
250
+ async init(modelName) {
251
+ await this.client.connect();
252
+ this.collection = this.client.db().collection(modelName);
253
+ const data = await this.collection.findOne({ _id: this.id });
254
+ if (!data) {
255
+ const created = { _id: this.id, data: {} };
256
+ await this.collection.insertOne(created);
257
+ this.cache = created.data;
258
+ return;
66
259
  }
67
- (0, import_fs.writeFileSync)(this.path, JSON.stringify(this.data, null, 2), "utf8");
68
- return this.data;
260
+ this.cache = data.data;
69
261
  }
70
- set(path, value) {
71
- if (!path || typeof path !== "string")
262
+ async close() {
263
+ await this.client.close();
264
+ }
265
+ async ready() {
266
+ await this.initPromise;
267
+ }
268
+ async update(path2, value, fetch = false) {
269
+ await this.ready();
270
+ if (fetch) {
271
+ const data = await this.collection.findOne({ _id: this.id });
272
+ this.cache = data ? data.data : {};
273
+ }
274
+ import_lodash2.default.set(this.cache, path2, value);
275
+ await this.collection.updateOne(
276
+ { _id: this.id },
277
+ { $set: { data: this.cache } },
278
+ { upsert: true }
279
+ );
280
+ return this.cache;
281
+ }
282
+ async set(path2, value, fetch = false) {
283
+ if (!path2 || typeof path2 !== "string")
72
284
  throw new Error(pathErrorMessage);
73
285
  if (value === void 0)
74
286
  throw new Error("You must provide a value to update");
75
- return this.update(path, value);
287
+ return this.update(path2, value, fetch);
76
288
  }
77
- get(path) {
78
- if (!path || typeof path !== "string")
289
+ async get(path2, fetch = false) {
290
+ if (!path2 || typeof path2 !== "string")
79
291
  throw new Error(pathErrorMessage);
80
- const keys = path.split(".");
81
- let current = this.data;
82
- let i = 0;
83
- for (const key of keys) {
84
- i++;
85
- if (i === keys.length) return current[key] ?? null;
86
- if (typeof current[key] !== "object") return null;
87
- current = current[key];
292
+ await this.ready();
293
+ if (fetch) {
294
+ const data = await this.collection.findOne({ _id: this.id });
295
+ this.cache = data ? data.data : {};
88
296
  }
297
+ return import_lodash2.default.get(this.cache, path2, null);
89
298
  }
90
- delete(path) {
91
- if (!path || typeof path !== "string")
299
+ async delete(path2, fetch = false) {
300
+ if (!path2 || typeof path2 !== "string")
92
301
  throw new Error(pathErrorMessage);
93
- const keys = path.split(".");
94
- const pathExists = this.get(path);
302
+ await this.ready();
303
+ if (fetch) {
304
+ const data = await this.collection.findOne({ _id: this.id });
305
+ this.cache = data ? data.data : {};
306
+ }
307
+ const pathExists = await this.get(path2);
95
308
  if (pathExists === null)
96
309
  throw new Error("The path does not exists or its value is null");
97
- this.update(path, null);
98
- (0, import_fs.writeFileSync)(this.path, JSON.stringify(this.data, null, 2), "utf8");
99
- return this.data;
310
+ return this.update(path2, null);
100
311
  }
101
- sumOrSub(path, value, type) {
102
- if (!path || typeof path !== "string")
312
+ async sumOrSub(path2, value, type, fetch = false) {
313
+ if (!path2 || typeof path2 !== "string")
103
314
  throw new Error(pathErrorMessage);
104
315
  if (!type || !["sum", "sub"].includes(type))
105
316
  throw new Error('The type must be "sum" or "sub"');
@@ -108,47 +319,67 @@ var TwinDB = class {
108
319
  throw new Error(
109
320
  `The value to ${isSum ? "sum" : "sub"} must be a number`
110
321
  );
111
- let currentValue = this.get(path) || 0;
322
+ await this.ready();
323
+ if (fetch) {
324
+ const data = await this.collection.findOne({ _id: this.id });
325
+ this.cache = data ? data.data : {};
326
+ }
327
+ let currentValue = await this.get(path2) || 0;
112
328
  if (typeof currentValue !== "number") currentValue = 0;
113
329
  return this.update(
114
- path,
330
+ path2,
115
331
  isSum ? currentValue + value : currentValue - value
116
332
  );
117
333
  }
118
- sum(path, value) {
119
- return this.sumOrSub(path, value, "sum");
334
+ async sum(path2, value, fetch = false) {
335
+ return this.sumOrSub(path2, value, "sum", fetch);
120
336
  }
121
- sub(path, value) {
122
- return this.sumOrSub(path, value, "sub");
337
+ async sub(path2, value, fetch = false) {
338
+ return this.sumOrSub(path2, value, "sub", fetch);
123
339
  }
124
- concat(path, value) {
125
- if (!path || typeof path !== "string")
340
+ async concat(path2, value, fetch = false) {
341
+ if (!path2 || typeof path2 !== "string")
126
342
  throw new Error(pathErrorMessage);
127
343
  if (!value || typeof value !== "string")
128
344
  throw new Error("You must provide a string value to update");
129
- const currentValue = this.get(path);
345
+ await this.ready();
346
+ if (fetch) {
347
+ const data = await this.collection.findOne({ _id: this.id });
348
+ this.cache = data ? data.data : {};
349
+ }
350
+ const currentValue = await this.get(path2);
130
351
  if (typeof currentValue !== "string")
131
352
  throw new Error(
132
353
  "The value to concat is not a string or the path does not exists"
133
354
  );
134
- return this.update(path, currentValue + value);
355
+ return this.update(path2, currentValue + value);
135
356
  }
136
- push(path, ...values) {
137
- if (!path || typeof path !== "string")
357
+ async push(path2, values, fetch = false) {
358
+ if (!path2 || typeof path2 !== "string")
138
359
  throw new Error(pathErrorMessage);
139
360
  if (!values || values.length === 0)
140
361
  throw new Error("You must provide a value to update");
141
- let currentValue = this.get(path) || [];
362
+ await this.ready();
363
+ if (fetch) {
364
+ const data = await this.collection.findOne({ _id: this.id });
365
+ this.cache = data ? data.data : {};
366
+ }
367
+ let currentValue = await this.get(path2) || [];
142
368
  if (!Array.isArray(currentValue)) currentValue = [];
143
369
  currentValue.push(...values);
144
- return this.update(path, currentValue);
370
+ return this.update(path2, currentValue);
145
371
  }
146
- pull(path, ...values) {
147
- if (!path || typeof path !== "string")
372
+ async pull(path2, values, fetch = false) {
373
+ if (!path2 || typeof path2 !== "string")
148
374
  throw new Error(pathErrorMessage);
149
375
  if (!values || values.length === 0)
150
376
  throw new Error("You must provide a value to update");
151
- const currentValue = this.get(path);
377
+ await this.ready();
378
+ if (fetch) {
379
+ const data = await this.collection.findOne({ _id: this.id });
380
+ this.cache = data ? data.data : {};
381
+ }
382
+ const currentValue = await this.get(path2);
152
383
  if (!Array.isArray(currentValue))
153
384
  throw new Error(
154
385
  "The current value of this path is not an array or the path does not exists"
@@ -158,11 +389,14 @@ var TwinDB = class {
158
389
  if (index < 0) continue;
159
390
  currentValue.splice(index, 1);
160
391
  }
161
- return this.update(path, currentValue);
392
+ return this.update(path2, currentValue);
162
393
  }
163
394
  };
164
395
  // Annotate the CommonJS export names for ESM import in node:
165
396
  0 && (module.exports = {
166
- TwinDB
397
+ JSONStorage,
398
+ SqliteStorage,
399
+ TwinDB,
400
+ TwinMongoDB
167
401
  });
168
402
  //# sourceMappingURL=index.cjs.map