ueberdb2 5.0.43 → 5.0.44

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.
Files changed (23) hide show
  1. package/dist/{lib/AbstractDatabase.js → AbstractDatabase-a4jdIEuT.js} +7 -2
  2. package/dist/{databases/cassandra_db.js → cassandra_db-C5K2zZew.js} +3 -3
  3. package/dist/{_virtual/_rolldown/runtime.js → chunk-8l464Juk.js} +6 -1
  4. package/dist/{databases/couch_db.js → couch_db-BVd81sS7.js} +5 -5
  5. package/dist/{databases/dirty_db.js → dirty_db-C9zUhXIG.js} +4 -4
  6. package/dist/{databases/dirty_git_db.js → dirty_git_db-Cj3oEEyZ.js} +4 -4
  7. package/dist/{databases/elasticsearch_db.js → elasticsearch_db-DjnZ1DHG.js} +4 -4
  8. package/dist/index.js +502 -22
  9. package/dist/{lib/logging.js → logging-DmqnZRde.js} +6 -1
  10. package/dist/{databases/memory_db.js → memory_db-SlQsh4tk.js} +2 -2
  11. package/dist/{databases/mock_db.js → mock_db-BBijMErd.js} +2 -2
  12. package/dist/{databases/mongodb_db.js → mongodb_db-ByZscnbs.js} +3 -3
  13. package/dist/{databases/mssql_db.js → mssql_db-C9-gmVgP.js} +5 -5
  14. package/dist/{databases/mysql_db.js → mysql_db-CRYtP-Mk.js} +4 -4
  15. package/dist/{databases/postgres_db.js → postgres_db-CVDQiNwN.js} +5 -5
  16. package/dist/{databases/postgrespool_db.js → postgrespool_db-CynysVC1.js} +1 -1
  17. package/dist/{databases/redis_db.js → redis_db-CDma40om.js} +3 -3
  18. package/dist/{databases/rethink_db.js → rethink_db-D7NvPe_4.js} +5 -5
  19. package/dist/{databases/rusty_db.js → rusty_db-CaVGu0z7.js} +3 -3
  20. package/dist/{databases/sqlite_db.js → sqlite_db-B-nmfVje.js} +3 -4
  21. package/dist/{databases/surrealdb_db.js → surrealdb_db-JmcyCabz.js} +3 -3
  22. package/package.json +4 -5
  23. package/dist/lib/CacheAndBufferLayer.js +0 -484
@@ -1,5 +1,5 @@
1
1
  //#region lib/AbstractDatabase.ts
2
- const nullLogger = require("./logging.js").normalizeLogger(null);
2
+ const nullLogger = require("./logging-DmqnZRde.js").normalizeLogger(null);
3
3
  const simpleGlobToRegExp = (s) => s.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
4
4
  var AbstractDatabase = class {
5
5
  logger;
@@ -33,4 +33,9 @@ var AbstractDatabase = class {
33
33
  }
34
34
  };
35
35
  //#endregion
36
- exports.default = AbstractDatabase;
36
+ Object.defineProperty(exports, "AbstractDatabase", {
37
+ enumerable: true,
38
+ get: function() {
39
+ return AbstractDatabase;
40
+ }
41
+ });
@@ -1,5 +1,5 @@
1
- require("../_virtual/_rolldown/runtime.js");
2
- const require_AbstractDatabase = require("../lib/AbstractDatabase.js");
1
+ require("./chunk-8l464Juk.js");
2
+ const require_AbstractDatabase = require("./AbstractDatabase-a4jdIEuT.js");
3
3
  let cassandra_driver = require("cassandra-driver");
4
4
  //#region databases/cassandra_db.ts
5
5
  /**
@@ -15,7 +15,7 @@ let cassandra_driver = require("cassandra-driver");
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
- var Cassandra_db = class extends require_AbstractDatabase.default {
18
+ var Cassandra_db = class extends require_AbstractDatabase.AbstractDatabase {
19
19
  client;
20
20
  pool;
21
21
  /**
@@ -20,4 +20,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
20
20
  enumerable: true
21
21
  }) : target, mod));
22
22
  //#endregion
23
- exports.__toESM = __toESM;
23
+ Object.defineProperty(exports, "__toESM", {
24
+ enumerable: true,
25
+ get: function() {
26
+ return __toESM;
27
+ }
28
+ });
@@ -1,9 +1,9 @@
1
- const require_runtime = require("../_virtual/_rolldown/runtime.js");
2
- const require_AbstractDatabase = require("../lib/AbstractDatabase.js");
1
+ const require_chunk = require("./chunk-8l464Juk.js");
2
+ const require_AbstractDatabase = require("./AbstractDatabase-a4jdIEuT.js");
3
3
  let http = require("http");
4
- http = require_runtime.__toESM(http);
4
+ http = require_chunk.__toESM(http);
5
5
  let nano = require("nano");
6
- nano = require_runtime.__toESM(nano);
6
+ nano = require_chunk.__toESM(nano);
7
7
  //#region databases/couch_db.ts
8
8
  /**
9
9
  * 2012 Max 'Azul' Wiehle
@@ -20,7 +20,7 @@ nano = require_runtime.__toESM(nano);
20
20
  * See the License for the specific language governing permissions and
21
21
  * limitations under the License.
22
22
  */
23
- var Couch_db = class extends require_AbstractDatabase.default {
23
+ var Couch_db = class extends require_AbstractDatabase.AbstractDatabase {
24
24
  agent;
25
25
  db;
26
26
  constructor(settings) {
@@ -1,7 +1,7 @@
1
- const require_runtime = require("../_virtual/_rolldown/runtime.js");
2
- const require_AbstractDatabase = require("../lib/AbstractDatabase.js");
1
+ const require_chunk = require("./chunk-8l464Juk.js");
2
+ const require_AbstractDatabase = require("./AbstractDatabase-a4jdIEuT.js");
3
3
  let dirty_ts = require("dirty-ts");
4
- dirty_ts = require_runtime.__toESM(dirty_ts);
4
+ dirty_ts = require_chunk.__toESM(dirty_ts);
5
5
  //#region databases/dirty_db.ts
6
6
  /**
7
7
  * 2011 Peter 'Pita' Martischka
@@ -18,7 +18,7 @@ dirty_ts = require_runtime.__toESM(dirty_ts);
18
18
  * See the License for the specific language governing permissions and
19
19
  * limitations under the License.
20
20
  */
21
- var dirty_db_default = class extends require_AbstractDatabase.default {
21
+ var dirty_db_default = class extends require_AbstractDatabase.AbstractDatabase {
22
22
  db;
23
23
  constructor(settings) {
24
24
  super(settings);
@@ -1,7 +1,7 @@
1
- const require_runtime = require("../_virtual/_rolldown/runtime.js");
2
- const require_AbstractDatabase = require("../lib/AbstractDatabase.js");
1
+ const require_chunk = require("./chunk-8l464Juk.js");
2
+ const require_AbstractDatabase = require("./AbstractDatabase-a4jdIEuT.js");
3
3
  let dirty_ts = require("dirty-ts");
4
- dirty_ts = require_runtime.__toESM(dirty_ts);
4
+ dirty_ts = require_chunk.__toESM(dirty_ts);
5
5
  let node_path = require("node:path");
6
6
  let simple_git = require("simple-git");
7
7
  //#region databases/dirty_git_db.ts
@@ -20,7 +20,7 @@ let simple_git = require("simple-git");
20
20
  * See the License for the specific language governing permissions and
21
21
  * limitations under the License.
22
22
  */
23
- var dirty_git_db_default = class extends require_AbstractDatabase.default {
23
+ var dirty_git_db_default = class extends require_AbstractDatabase.AbstractDatabase {
24
24
  db;
25
25
  constructor(settings) {
26
26
  super(settings);
@@ -1,7 +1,7 @@
1
- const require_runtime = require("../_virtual/_rolldown/runtime.js");
2
- const require_AbstractDatabase = require("../lib/AbstractDatabase.js");
1
+ const require_chunk = require("./chunk-8l464Juk.js");
2
+ const require_AbstractDatabase = require("./AbstractDatabase-a4jdIEuT.js");
3
3
  let assert = require("assert");
4
- assert = require_runtime.__toESM(assert);
4
+ assert = require_chunk.__toESM(assert);
5
5
  let buffer = require("buffer");
6
6
  let crypto = require("crypto");
7
7
  let _elastic_elasticsearch = require("@elastic/elasticsearch");
@@ -103,7 +103,7 @@ const migrateToSchema2 = async (client, v1BaseIndex, v2Index, logger) => {
103
103
  await Promise.all([...scrollIds.values()].map((scrollId) => client.clearScroll({ scroll_id: scrollId })));
104
104
  }
105
105
  };
106
- var elasticsearch_db_default = class extends require_AbstractDatabase.default {
106
+ var elasticsearch_db_default = class extends require_AbstractDatabase.AbstractDatabase {
107
107
  _client;
108
108
  _index;
109
109
  _indexClean;
package/dist/index.js CHANGED
@@ -3,10 +3,490 @@ Object.defineProperties(exports, {
3
3
  __esModule: { value: true },
4
4
  [Symbol.toStringTag]: { value: "Module" }
5
5
  });
6
- require("./_virtual/_rolldown/runtime.js");
7
- const require_CacheAndBufferLayer = require("./lib/CacheAndBufferLayer.js");
8
- const require_logging = require("./lib/logging.js");
6
+ const require_chunk = require("./chunk-8l464Juk.js");
7
+ const require_logging = require("./logging-DmqnZRde.js");
9
8
  let util = require("util");
9
+ util = require_chunk.__toESM(util);
10
+ //#region lib/CacheAndBufferLayer.ts
11
+ /**
12
+ * 2011 Peter 'Pita' Martischka
13
+ *
14
+ * Licensed under the Apache License, Version 2.0 (the "License");
15
+ * you may not use this file except in compliance with the License.
16
+ * You may obtain a copy of the License at
17
+ *
18
+ * http://www.apache.org/licenses/LICENSE-2.0
19
+ *
20
+ * Unless required by applicable law or agreed to in writing, software
21
+ * distributed under the License is distributed on an "AS-IS" BASIS,
22
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
+ * See the License for the specific language governing permissions and
24
+ * limitations under the License.
25
+ */
26
+ /**
27
+ * This module is made for the case, you want to use a SQL-Based Databse or a KeyValue Database that
28
+ * can only save strings(and no objects), as a JSON KeyValue Store.
29
+ *
30
+ * The idea of the dbWrapper is to provide following features:
31
+ *
32
+ * * automatic JSON serialize/deserialize to abstract that away from the database driver and the
33
+ * module user.
34
+ * * cache reads. A amount of KeyValues are hold in the memory, so that reading is faster.
35
+ * * Buffer DB Writings. Sets and deletes should be buffered to make them in a setted interval
36
+ * with a bulk. This reduces the overhead of database transactions and makes the database
37
+ * faster. But there is also a danger to loose data integrity, to keep that, we should provide a
38
+ * flush function.
39
+ *
40
+ * All Features can be disabled or configured. The Wrapper provides default settings that can be
41
+ * overwriden by the driver and by the module user.
42
+ */
43
+ /**
44
+ * Cache with Least Recently Used eviction policy.
45
+ */
46
+ var LRU = class {
47
+ /**
48
+ * @param evictable Optional predicate that dictates whether it is permissable to evict the entry
49
+ * if it is old and the cache is over capacity. The predicate is passed two arguments (key,
50
+ * value). If no predicate is provided, all entries are evictable. Warning: Non-evictable
51
+ * entries can cause the cache to go over capacity. If the number of non-evictable entries is
52
+ * greater than or equal to the capacity, all new evictable entries will be evicted
53
+ * immediately.
54
+ */
55
+ constructor(capacity, evictable = (k, v) => true) {
56
+ this._capacity = capacity;
57
+ this._evictable = evictable;
58
+ this._cache = /* @__PURE__ */ new Map();
59
+ }
60
+ /**
61
+ * The entries accessed via this iterator are not considered to have been "used" (for purposes of
62
+ * determining least recently used).
63
+ */
64
+ [Symbol.iterator]() {
65
+ return this._cache.entries();
66
+ }
67
+ /**
68
+ * @param isUse Optional boolean indicating whether this get() should be considered a "use" of the
69
+ * entry (for determining least recently used). Defaults to true.
70
+ * @returns undefined if there is no entry matching the given key.
71
+ */
72
+ get(k, isUse = true) {
73
+ if (!this._cache.has(k)) return;
74
+ const v = this._cache.get(k);
75
+ if (isUse) {
76
+ this._cache.delete(k);
77
+ this._cache.set(k, v);
78
+ }
79
+ return v;
80
+ }
81
+ /**
82
+ * Adds or updates an entry in the cache. This marks the entry as the most recently used entry.
83
+ */
84
+ set(k, v) {
85
+ this._cache.delete(k);
86
+ this._cache.set(k, v);
87
+ this.evictOld();
88
+ }
89
+ /**
90
+ * Evicts the oldest evictable entries until the number of entries is equal to or less than the
91
+ * cache's capacity. This method is automatically called by set(). Call this if you need to evict
92
+ * newly evictable entries before the next call to set().
93
+ */
94
+ evictOld() {
95
+ for (const [k, v] of this._cache.entries()) {
96
+ if (this._cache.size <= this._capacity) break;
97
+ if (!this._evictable(k, v)) continue;
98
+ this._cache.delete(k);
99
+ }
100
+ }
101
+ };
102
+ var SelfContainedPromise = class extends Promise {
103
+ constructor(executor = null) {
104
+ let done;
105
+ super((resolve, reject) => {
106
+ done = (err, val) => err != null ? reject(err) : resolve(val);
107
+ if (executor != null) executor(resolve, reject);
108
+ });
109
+ this.done = done;
110
+ }
111
+ };
112
+ const defaultSettings = {
113
+ bulkLimit: 0,
114
+ cache: 1e4,
115
+ writeInterval: 100,
116
+ json: true,
117
+ charset: "utf8mb4"
118
+ };
119
+ const Database$1 = class {
120
+ /**
121
+ * @param wrappedDB The Database that should be wrapped
122
+ * @param settings (optional) The settings that should be applied to the wrapper
123
+ */
124
+ constructor(wrappedDB, settings, logger) {
125
+ if (wrappedDB.isAsync) this.wrappedDB = wrappedDB;
126
+ else {
127
+ this.wrappedDB = {};
128
+ for (const fn of [
129
+ "close",
130
+ "doBulk",
131
+ "findKeys",
132
+ "get",
133
+ "init",
134
+ "remove",
135
+ "set"
136
+ ]) {
137
+ const f = wrappedDB[fn];
138
+ if (typeof f !== "function") continue;
139
+ this.wrappedDB[fn] = util.default.promisify(f.bind(wrappedDB));
140
+ }
141
+ }
142
+ this.logger = logger;
143
+ this.settings = Object.freeze({
144
+ ...defaultSettings,
145
+ ...wrappedDB.settings || {},
146
+ ...settings || {}
147
+ });
148
+ this.buffer = new LRU(this.settings.cache, (k, v) => !v.dirty && !v.writingInProgress);
149
+ this._flushPaused = null;
150
+ this._locks = /* @__PURE__ */ new Map();
151
+ this.metrics = {
152
+ lockAwaits: 0,
153
+ lockAcquires: 0,
154
+ lockReleases: 0,
155
+ reads: 0,
156
+ readsFailed: 0,
157
+ readsFinished: 0,
158
+ readsFromCache: 0,
159
+ readsFromDb: 0,
160
+ readsFromDbFailed: 0,
161
+ readsFromDbFinished: 0,
162
+ writes: 0,
163
+ writesFailed: 0,
164
+ writesFinished: 0,
165
+ writesObsoleted: 0,
166
+ writesToDb: 0,
167
+ writesToDbFailed: 0,
168
+ writesToDbFinished: 0,
169
+ writesToDbRetried: 0
170
+ };
171
+ this.flushInterval = this.settings.writeInterval > 0 ? setInterval(() => this.flush(), this.settings.writeInterval) : null;
172
+ }
173
+ async _lock(key) {
174
+ while (true) {
175
+ const l = this._locks.get(key);
176
+ if (l == null) break;
177
+ ++this.metrics.lockAwaits;
178
+ await l;
179
+ }
180
+ ++this.metrics.lockAcquires;
181
+ this._locks.set(key, new SelfContainedPromise());
182
+ }
183
+ async _unlock(key) {
184
+ ++this.metrics.lockReleases;
185
+ this._locks.get(key).done();
186
+ this._locks.delete(key);
187
+ }
188
+ _pauseFlush() {
189
+ if (this._flushPaused == null) {
190
+ this._flushPaused = new SelfContainedPromise();
191
+ this._flushPaused.count = 0;
192
+ }
193
+ ++this._flushPaused.count;
194
+ }
195
+ _resumeFlush() {
196
+ if (--this._flushPaused.count > 0) return;
197
+ this._flushPaused.done();
198
+ this._flushPaused = null;
199
+ }
200
+ /**
201
+ * wraps the init function of the original DB
202
+ */
203
+ async init() {
204
+ await this.wrappedDB.init();
205
+ }
206
+ /**
207
+ * wraps the close function of the original DB
208
+ */
209
+ async close() {
210
+ clearInterval(this.flushInterval);
211
+ await this.flush();
212
+ await this.wrappedDB.close();
213
+ this.wrappedDB = null;
214
+ }
215
+ /**
216
+ * Gets the value trough the wrapper.
217
+ */
218
+ async get(key) {
219
+ let v;
220
+ await this._lock(key);
221
+ try {
222
+ v = await this._getLocked(key);
223
+ } finally {
224
+ this._unlock(key);
225
+ }
226
+ return clone(v);
227
+ }
228
+ async _getLocked(key) {
229
+ ++this.metrics.reads;
230
+ try {
231
+ const entry = this.buffer.get(key);
232
+ if (entry != null) {
233
+ ++this.metrics.readsFromCache;
234
+ if (this.logger.isDebugEnabled()) this.logger.debug(`GET - ${key} - ${JSON.stringify(entry.value)} - from ${entry.dirty ? "dirty buffer" : "cache"}`);
235
+ return entry.value;
236
+ }
237
+ let value;
238
+ ++this.metrics.readsFromDb;
239
+ try {
240
+ value = await this.wrappedDB.get(key);
241
+ } catch (err) {
242
+ ++this.metrics.readsFromDbFailed;
243
+ throw err;
244
+ } finally {
245
+ ++this.metrics.readsFromDbFinished;
246
+ }
247
+ if (this.settings.json) try {
248
+ value = JSON.parse(value);
249
+ } catch (err) {
250
+ this.logger.error(`JSON-PROBLEM:${value}`);
251
+ throw err;
252
+ }
253
+ if (this.settings.cache > 0) this.buffer.set(key, {
254
+ value,
255
+ dirty: null,
256
+ writingInProgress: false
257
+ });
258
+ if (this.logger.isDebugEnabled()) this.logger.debug(`GET - ${key} - ${JSON.stringify(value)} - from database `);
259
+ return value;
260
+ } catch (err) {
261
+ ++this.metrics.readsFailed;
262
+ throw err;
263
+ } finally {
264
+ ++this.metrics.readsFinished;
265
+ }
266
+ }
267
+ /**
268
+ * Find keys function searches the db sets for matching entries and
269
+ * returns the key entries via callback.
270
+ */
271
+ async findKeys(key, notKey) {
272
+ await this.flush();
273
+ const keyValues = await this.wrappedDB.findKeys(key, notKey);
274
+ if (this.logger.isDebugEnabled()) this.logger.debug(`GET - ${key}-${notKey} - ${JSON.stringify(keyValues)} - from database `);
275
+ return clone(keyValues);
276
+ }
277
+ /**
278
+ * Remove a record from the database
279
+ */
280
+ async remove(key) {
281
+ if (this.logger.isDebugEnabled()) this.logger.debug(`DELETE - ${key} - from database `);
282
+ await this.set(key, null);
283
+ }
284
+ /**
285
+ * Sets the value trough the wrapper
286
+ */
287
+ async set(key, value) {
288
+ value = clone(value);
289
+ let p;
290
+ this._pauseFlush();
291
+ try {
292
+ await this._lock(key);
293
+ try {
294
+ p = this._setLocked(key, value);
295
+ } finally {
296
+ this._unlock(key);
297
+ }
298
+ } finally {
299
+ this._resumeFlush();
300
+ }
301
+ await p;
302
+ }
303
+ async _setLocked(key, value) {
304
+ ++this.metrics.writes;
305
+ try {
306
+ let entry = this.buffer.get(key);
307
+ if (!entry || entry.writingInProgress) entry = {};
308
+ else if (entry.dirty) ++this.metrics.writesObsoleted;
309
+ entry.value = value;
310
+ if (!entry.dirty) entry.dirty = new SelfContainedPromise();
311
+ this.buffer.set(key, entry);
312
+ const buffered = this.settings.writeInterval > 0;
313
+ if (this.logger.isDebugEnabled()) this.logger.debug(`SET - ${key} - ${JSON.stringify(value)} - to ${buffered ? "buffer" : "database"}`);
314
+ if (!buffered) this._write([[key, entry]]);
315
+ await entry.dirty;
316
+ } catch (err) {
317
+ ++this.metrics.writesFailed;
318
+ throw err;
319
+ } finally {
320
+ ++this.metrics.writesFinished;
321
+ }
322
+ }
323
+ /**
324
+ * Sets a subvalue
325
+ */
326
+ async setSub(key, sub, value) {
327
+ value = clone(value);
328
+ if (this.logger.isDebugEnabled()) this.logger.debug(`SETSUB - ${key}${JSON.stringify(sub)} - ${JSON.stringify(value)}`);
329
+ let p;
330
+ this._pauseFlush();
331
+ try {
332
+ await this._lock(key);
333
+ try {
334
+ let base;
335
+ try {
336
+ const fullValue = await this._getLocked(key);
337
+ base = { fullValue };
338
+ const ptr = {
339
+ obj: base,
340
+ prop: "fullValue"
341
+ };
342
+ for (let i = 0; i < sub.length; i++) {
343
+ if (sub[i] === "__proto__") throw new Error("Modifying object prototype is not supported for security reasons");
344
+ let o = ptr.obj[ptr.prop];
345
+ if (o == null) ptr.obj[ptr.prop] = o = {};
346
+ if (typeof o !== "object") throw new TypeError(`Cannot set property ${JSON.stringify(sub[i])} on non-object ${JSON.stringify(o)} (key: ${JSON.stringify(key)} value in db: ${JSON.stringify(fullValue)} sub: ${JSON.stringify(sub.slice(0, i + 1))})`);
347
+ ptr.obj = ptr.obj[ptr.prop];
348
+ ptr.prop = sub[i];
349
+ }
350
+ if (value == null) delete ptr.obj[ptr.prop];
351
+ else ptr.obj[ptr.prop] = value;
352
+ } catch (err) {
353
+ ++this.metrics.writes;
354
+ ++this.metrics.writesFailed;
355
+ ++this.metrics.writesFinished;
356
+ throw err;
357
+ }
358
+ p = this._setLocked(key, base.fullValue);
359
+ } finally {
360
+ await this._unlock(key);
361
+ }
362
+ } finally {
363
+ this._resumeFlush();
364
+ }
365
+ await p;
366
+ }
367
+ /**
368
+ * Returns a sub value of the object
369
+ * @param sub is a array, for example if you want to access object.test.bla, the array is ["test",
370
+ * "bla"]
371
+ */
372
+ async getSub(key, sub) {
373
+ await this._lock(key);
374
+ try {
375
+ let v = await this._getLocked(key);
376
+ for (const k of sub) {
377
+ if (typeof v !== "object" || v != null && !Object.prototype.hasOwnProperty.call(v, k) || k === "__proto__") v = null;
378
+ if (v == null) break;
379
+ v = v[k];
380
+ }
381
+ if (this.logger.isDebugEnabled()) this.logger.debug(`GETSUB - ${key}${JSON.stringify(sub)} - ${JSON.stringify(v)}`);
382
+ return clone(v);
383
+ } finally {
384
+ this._unlock(key);
385
+ }
386
+ }
387
+ /**
388
+ * Writes all dirty values to the database
389
+ */
390
+ async flush() {
391
+ if (this._flushDone == null) this._flushDone = (async () => {
392
+ while (true) {
393
+ while (this._flushPaused != null) await this._flushPaused;
394
+ const dirtyEntries = [];
395
+ for (const entry of this.buffer) if (entry[1].dirty && !entry[1].writingInProgress) {
396
+ dirtyEntries.push(entry);
397
+ if (this.settings.bulkLimit && dirtyEntries.length >= this.settings.bulkLimit) break;
398
+ }
399
+ if (dirtyEntries.length === 0) return;
400
+ await this._write(dirtyEntries);
401
+ }
402
+ })();
403
+ await this._flushDone;
404
+ this._flushDone = null;
405
+ }
406
+ async _write(dirtyEntries) {
407
+ const markDone = (entry, err) => {
408
+ if (entry.writingInProgress) {
409
+ entry.writingInProgress = false;
410
+ if (err != null) ++this.metrics.writesToDbFailed;
411
+ ++this.metrics.writesToDbFinished;
412
+ }
413
+ entry.dirty.done(err);
414
+ entry.dirty = null;
415
+ };
416
+ const ops = [];
417
+ const entries = [];
418
+ for (const [key, entry] of dirtyEntries) {
419
+ let value = entry.value;
420
+ try {
421
+ value = this.settings.json && value != null ? JSON.stringify(value) : clone(value);
422
+ } catch (err) {
423
+ markDone(entry, err);
424
+ continue;
425
+ }
426
+ entry.writingInProgress = true;
427
+ ops.push({
428
+ type: value == null ? "remove" : "set",
429
+ key,
430
+ value
431
+ });
432
+ entries.push(entry);
433
+ }
434
+ if (ops.length === 0) return;
435
+ this.metrics.writesToDb += ops.length;
436
+ const writeOneOp = async (op, entry) => {
437
+ let writeErr = null;
438
+ try {
439
+ switch (op.type) {
440
+ case "remove":
441
+ await this.wrappedDB.remove(op.key);
442
+ break;
443
+ case "set":
444
+ await this.wrappedDB.set(op.key, op.value);
445
+ break;
446
+ default: throw new Error(`unsupported operation type: ${op.type}`);
447
+ }
448
+ } catch (err) {
449
+ writeErr = err || new Error(err);
450
+ }
451
+ markDone(entry, writeErr);
452
+ };
453
+ if (ops.length === 1) await writeOneOp(ops[0], entries[0]);
454
+ else {
455
+ let success = false;
456
+ try {
457
+ await this.wrappedDB.doBulk(ops);
458
+ success = true;
459
+ } catch (err) {
460
+ this.logger.error(`Bulk write of ${ops.length} ops failed, retrying individually: ${err.stack || err}`);
461
+ this.metrics.writesToDbRetried += ops.length;
462
+ await Promise.all(ops.map(async (op, i) => await writeOneOp(op, entries[i])));
463
+ }
464
+ if (success) entries.forEach((entry) => markDone(entry, null));
465
+ }
466
+ this.buffer.evictOld();
467
+ }
468
+ };
469
+ const clone = (obj, key = "") => {
470
+ if (null == obj || "object" !== typeof obj) return obj;
471
+ if (typeof obj.toJSON === "function") return clone(obj.toJSON(key));
472
+ if (obj instanceof Date) {
473
+ const copy = /* @__PURE__ */ new Date();
474
+ copy.setTime(obj.getTime());
475
+ return copy;
476
+ }
477
+ if (obj instanceof Array) {
478
+ const copy = [];
479
+ for (let i = 0, len = obj.length; i < len; ++i) copy[i] = clone(obj[i], String(i));
480
+ return copy;
481
+ }
482
+ if (obj instanceof Object) {
483
+ const copy = {};
484
+ for (const attr in obj) if (Object.prototype.hasOwnProperty.call(obj, attr)) copy[attr] = clone(obj[attr], attr);
485
+ return copy;
486
+ }
487
+ throw new Error("Unable to copy obj! Its type isn't supported.");
488
+ };
489
+ //#endregion
10
490
  //#region index.ts
11
491
  /**
12
492
  * 2011 Peter 'Pita' Martischka
@@ -45,7 +525,7 @@ for (const fn of [
45
525
  "remove",
46
526
  "set",
47
527
  "setSub"
48
- ]) if (fn in cbDb) cbDb[fn] = (0, util.callbackify)(require_CacheAndBufferLayer.Database.prototype[fn]);
528
+ ]) if (fn in cbDb) cbDb[fn] = (0, util.callbackify)(Database$1.prototype[fn]);
49
529
  const makeDoneCallback = (callback, deprecated) => (err) => {
50
530
  if (callback) callback(err);
51
531
  if (deprecated) deprecated(err);
@@ -84,7 +564,7 @@ var Database = class {
84
564
  init(callback = null) {
85
565
  const p = this.initDB().then((db) => {
86
566
  db.logger = this.logger;
87
- this.db = new require_CacheAndBufferLayer.Database(db, this.wrapperSettings, this.logger);
567
+ this.db = new Database$1(db, this.wrapperSettings, this.logger);
88
568
  this.metrics = this.db.metrics;
89
569
  return this.db.init();
90
570
  });
@@ -93,23 +573,23 @@ var Database = class {
93
573
  }
94
574
  async initDB() {
95
575
  switch (this.type) {
96
- case "mysql": return new (await (Promise.resolve().then(() => require("./databases/mysql_db.js")))).default(this.dbSettings);
97
- case "postgres": return new (await (Promise.resolve().then(() => require("./databases/postgres_db.js")))).default(this.dbSettings);
98
- case "sqlite": return new (await (Promise.resolve().then(() => require("./databases/sqlite_db.js")))).default(this.dbSettings);
99
- case "rustydb": return new (await (Promise.resolve().then(() => require("./databases/rusty_db.js")))).default(this.dbSettings);
100
- case "mongodb": return new (await (Promise.resolve().then(() => require("./databases/mongodb_db.js")))).default(this.dbSettings);
101
- case "redis": return new (await (Promise.resolve().then(() => require("./databases/redis_db.js")))).default(this.dbSettings);
102
- case "cassandra": return new (await (Promise.resolve().then(() => require("./databases/cassandra_db.js")))).default(this.dbSettings);
103
- case "dirty": return new (await (Promise.resolve().then(() => require("./databases/dirty_db.js")))).default(this.dbSettings);
104
- case "dirtygit": return new (await (Promise.resolve().then(() => require("./databases/dirty_git_db.js")))).default(this.dbSettings);
105
- case "elasticsearch": return new (await (Promise.resolve().then(() => require("./databases/elasticsearch_db.js")))).default(this.dbSettings);
106
- case "memory": return new (await (Promise.resolve().then(() => require("./databases/memory_db.js")))).default(this.dbSettings);
107
- case "mock": return new (await (Promise.resolve().then(() => require("./databases/mock_db.js")))).default(this.dbSettings);
108
- case "mssql": return new (await (Promise.resolve().then(() => require("./databases/mssql_db.js")))).default(this.dbSettings);
109
- case "postgrespool": return new (await (Promise.resolve().then(() => require("./databases/postgrespool_db.js")))).default(this.dbSettings);
110
- case "rethink": return new (await (Promise.resolve().then(() => require("./databases/rethink_db.js")))).default(this.dbSettings);
111
- case "couch": return new (await (Promise.resolve().then(() => require("./databases/couch_db.js")))).default(this.dbSettings);
112
- case "surrealdb": return new (await (Promise.resolve().then(() => require("./databases/surrealdb_db.js")))).default(this.dbSettings);
576
+ case "mysql": return new (await (Promise.resolve().then(() => require("./mysql_db-CRYtP-Mk.js")))).default(this.dbSettings);
577
+ case "postgres": return new (await (Promise.resolve().then(() => require("./postgres_db-CVDQiNwN.js")))).default(this.dbSettings);
578
+ case "sqlite": return new (await (Promise.resolve().then(() => require("./sqlite_db-B-nmfVje.js")))).default(this.dbSettings);
579
+ case "rustydb": return new (await (Promise.resolve().then(() => require("./rusty_db-CaVGu0z7.js")))).default(this.dbSettings);
580
+ case "mongodb": return new (await (Promise.resolve().then(() => require("./mongodb_db-ByZscnbs.js")))).default(this.dbSettings);
581
+ case "redis": return new (await (Promise.resolve().then(() => require("./redis_db-CDma40om.js")))).default(this.dbSettings);
582
+ case "cassandra": return new (await (Promise.resolve().then(() => require("./cassandra_db-C5K2zZew.js")))).default(this.dbSettings);
583
+ case "dirty": return new (await (Promise.resolve().then(() => require("./dirty_db-C9zUhXIG.js")))).default(this.dbSettings);
584
+ case "dirtygit": return new (await (Promise.resolve().then(() => require("./dirty_git_db-Cj3oEEyZ.js")))).default(this.dbSettings);
585
+ case "elasticsearch": return new (await (Promise.resolve().then(() => require("./elasticsearch_db-DjnZ1DHG.js")))).default(this.dbSettings);
586
+ case "memory": return new (await (Promise.resolve().then(() => require("./memory_db-SlQsh4tk.js")))).default(this.dbSettings);
587
+ case "mock": return new (await (Promise.resolve().then(() => require("./mock_db-BBijMErd.js")))).default(this.dbSettings);
588
+ case "mssql": return new (await (Promise.resolve().then(() => require("./mssql_db-C9-gmVgP.js")))).default(this.dbSettings);
589
+ case "postgrespool": return new (await (Promise.resolve().then(() => require("./postgrespool_db-CynysVC1.js")))).default(this.dbSettings);
590
+ case "rethink": return new (await (Promise.resolve().then(() => require("./rethink_db-D7NvPe_4.js")))).default(this.dbSettings);
591
+ case "couch": return new (await (Promise.resolve().then(() => require("./couch_db-BVd81sS7.js")))).default(this.dbSettings);
592
+ case "surrealdb": return new (await (Promise.resolve().then(() => require("./surrealdb_db-JmcyCabz.js")))).default(this.dbSettings);
113
593
  default: throw new Error("Invalid database type");
114
594
  }
115
595
  }