jexidb 1.0.5 → 1.0.6

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
@@ -62,7 +62,7 @@ await db.insert({ id: 2, name: 'Jane Doe', anyArbitraryField: '1' });
62
62
  The `query` method allows you to retrieve data based on specific criteria. You can specify criteria for multiple fields.
63
63
 
64
64
  ```javascript
65
- const results = await db.query({ name: 'John Doe' });
65
+ const results = await db.query({ name: 'John Doe' }, { caseInsensitive: true });
66
66
  console.log(results); // [{ id: 1, name: 'John Doe' }]
67
67
  ```
68
68
 
package/dist/Database.cjs CHANGED
@@ -10,12 +10,11 @@ var _IndexManager = _interopRequireDefault(require("./IndexManager.mjs"));
10
10
  var _Serializer = _interopRequireDefault(require("./Serializer.mjs"));
11
11
  var _fs = _interopRequireDefault(require("fs"));
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
13
- function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
14
13
  function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
15
14
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
16
15
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
17
16
  function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
18
- function _readOnlyError(r) { throw new TypeError('"' + r + '" is read-only'); }
17
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
19
18
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
20
19
  function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
21
20
  function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
@@ -43,6 +42,8 @@ function _wrapAsyncGenerator(e) { return function () { return new AsyncGenerator
43
42
  function AsyncGenerator(e) { var r, t; function resume(r, t) { try { var n = e[r](t), o = n.value, u = o instanceof _OverloadYield; Promise.resolve(u ? o.v : o).then(function (t) { if (u) { var i = "return" === r ? "return" : "next"; if (!o.k || t.done) return resume(i, t); t = e[i](t).value; } settle(n.done ? "return" : "normal", t); }, function (e) { resume("throw", e); }); } catch (e) { settle("throw", e); } } function settle(e, n) { switch (e) { case "return": r.resolve({ value: n, done: !0 }); break; case "throw": r.reject(n); break; default: r.resolve({ value: n, done: !1 }); } (r = r.next) ? resume(r.key, r.arg) : t = null; } this._invoke = function (e, n) { return new Promise(function (o, u) { var i = { key: e, arg: n, resolve: o, reject: u, next: null }; t ? t = t.next = i : (r = t = i, resume(e, n)); }); }, "function" != typeof e["return"] && (this["return"] = void 0); }
44
43
  AsyncGenerator.prototype["function" == typeof Symbol && Symbol.asyncIterator || "@@asyncIterator"] = function () { return this; }, AsyncGenerator.prototype.next = function (e) { return this._invoke("next", e); }, AsyncGenerator.prototype["throw"] = function (e) { return this._invoke("throw", e); }, AsyncGenerator.prototype["return"] = function (e) { return this._invoke("return", e); };
45
44
  function _OverloadYield(e, d) { this.v = e, this.k = d; }
45
+ function _asyncIterator(r) { var n, t, o, e = 2; for ("undefined" != typeof Symbol && (t = Symbol.asyncIterator, o = Symbol.iterator); e--;) { if (t && null != (n = r[t])) return n.call(r); if (o && null != (n = r[o])) return new AsyncFromSyncIterator(n.call(r)); t = "@@asyncIterator", o = "@@iterator"; } throw new TypeError("Object is not async iterable"); }
46
+ function AsyncFromSyncIterator(r) { function AsyncFromSyncIteratorContinuation(r) { if (Object(r) !== r) return Promise.reject(new TypeError(r + " is not an object.")); var n = r.done; return Promise.resolve(r.value).then(function (r) { return { value: r, done: n }; }); } return AsyncFromSyncIterator = function AsyncFromSyncIterator(r) { this.s = r, this.n = r.next; }, AsyncFromSyncIterator.prototype = { s: null, n: null, next: function next() { return AsyncFromSyncIteratorContinuation(this.n.apply(this.s, arguments)); }, "return": function _return(r) { var n = this.s["return"]; return void 0 === n ? Promise.resolve({ value: r, done: !0 }) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments)); }, "throw": function _throw(r) { var n = this.s["return"]; return void 0 === n ? Promise.reject(r) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments)); } }, new AsyncFromSyncIterator(r); }
46
47
  var Database = exports.Database = /*#__PURE__*/function (_EventEmitter) {
47
48
  function Database(file) {
48
49
  var _this2;
@@ -549,36 +550,36 @@ var Database = exports.Database = /*#__PURE__*/function (_EventEmitter) {
549
550
  var _this = this;
550
551
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
551
552
  return _wrapAsyncGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee7() {
552
- var ranges, partitionedRanges, currentPartition, line, m, _i, _partitionedRanges, _ranges, lines, _loop, _line;
553
- return _regeneratorRuntime().wrap(function _callee7$(_context8) {
554
- while (1) switch (_context8.prev = _context8.next) {
553
+ var ranges, readSize, groupedRanges, fd, _iterator2, _step2, groupedRange, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, row, entry;
554
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
555
+ while (1) switch (_context7.prev = _context7.next) {
555
556
  case 0:
556
557
  if (!_this.destroyed) {
557
- _context8.next = 2;
558
+ _context7.next = 2;
558
559
  break;
559
560
  }
560
561
  throw new Error('Database is destroyed');
561
562
  case 2:
562
563
  if (_this.initialized) {
563
- _context8.next = 5;
564
+ _context7.next = 5;
564
565
  break;
565
566
  }
566
- _context8.next = 5;
567
+ _context7.next = 5;
567
568
  return _awaitAsyncGenerator(_this.init());
568
569
  case 5:
569
- _context8.t0 = _this.shouldSave;
570
- if (!_context8.t0) {
571
- _context8.next = 9;
570
+ _context7.t0 = _this.shouldSave;
571
+ if (!_context7.t0) {
572
+ _context7.next = 9;
572
573
  break;
573
574
  }
574
- _context8.next = 9;
575
+ _context7.next = 9;
575
576
  return _awaitAsyncGenerator(_this.save()["catch"](console.error));
576
577
  case 9:
577
578
  if (!(_this.indexOffset === 0)) {
578
- _context8.next = 11;
579
+ _context7.next = 11;
579
580
  break;
580
581
  }
581
- return _context8.abrupt("return");
582
+ return _context7.abrupt("return");
582
583
  case 11:
583
584
  if (!Array.isArray(map)) {
584
585
  if (map instanceof Set) {
@@ -590,83 +591,112 @@ var Database = exports.Database = /*#__PURE__*/function (_EventEmitter) {
590
591
  }
591
592
  }
592
593
  ranges = _this.getRanges(map);
593
- partitionedRanges = [], currentPartition = 0;
594
- for (line in ranges) {
595
- if (partitionedRanges[currentPartition] === undefined) {
596
- partitionedRanges[currentPartition] = [];
597
- }
598
- partitionedRanges[currentPartition].push(ranges[line]);
599
- if (partitionedRanges[currentPartition].length >= _this.opts.maxMemoryUsage) {
600
- +currentPartition, _readOnlyError("currentPartition");
601
- }
594
+ readSize = 512 * 1024; // 512KB
595
+ _context7.next = 16;
596
+ return _awaitAsyncGenerator(_this.fileHandler.groupedRanges(ranges));
597
+ case 16:
598
+ groupedRanges = _context7.sent;
599
+ _context7.next = 19;
600
+ return _awaitAsyncGenerator(_fs["default"].promises.open(_this.fileHandler.file, 'r'));
601
+ case 19:
602
+ fd = _context7.sent;
603
+ _iterator2 = _createForOfIteratorHelper(groupedRanges);
604
+ _context7.prev = 21;
605
+ _iterator2.s();
606
+ case 23:
607
+ if ((_step2 = _iterator2.n()).done) {
608
+ _context7.next = 64;
609
+ break;
602
610
  }
603
- m = 0;
604
- _i = 0, _partitionedRanges = partitionedRanges;
605
- case 17:
606
- if (!(_i < _partitionedRanges.length)) {
607
- _context8.next = 34;
611
+ groupedRange = _step2.value;
612
+ _iteratorAbruptCompletion = false;
613
+ _didIteratorError = false;
614
+ _context7.prev = 27;
615
+ _iterator = _asyncIterator(_this.fileHandler.readGroupedRange(groupedRange, fd));
616
+ case 29:
617
+ _context7.next = 31;
618
+ return _awaitAsyncGenerator(_iterator.next());
619
+ case 31:
620
+ if (!(_iteratorAbruptCompletion = !(_step = _context7.sent).done)) {
621
+ _context7.next = 46;
608
622
  break;
609
623
  }
610
- _ranges = _partitionedRanges[_i];
611
- _context8.next = 21;
612
- return _awaitAsyncGenerator(_this.fileHandler.readRanges(_ranges));
613
- case 21:
614
- lines = _context8.sent;
615
- _loop = /*#__PURE__*/_regeneratorRuntime().mark(function _loop() {
616
- var err, entry;
617
- return _regeneratorRuntime().wrap(function _loop$(_context7) {
618
- while (1) switch (_context7.prev = _context7.next) {
619
- case 0:
620
- _context7.next = 2;
621
- return _awaitAsyncGenerator(_this.serializer.deserialize(lines[_line])["catch"](function (e) {
622
- return console.error(err = e);
623
- }));
624
- case 2:
625
- entry = _context7.sent;
626
- if (!err) {
627
- _context7.next = 5;
628
- break;
629
- }
630
- return _context7.abrupt("return", 1);
631
- case 5:
632
- if (entry._ === undefined) {
633
- while (_this.offsets[m] != _line && m < map.length) m++; // weak comparison as 'start' is a string
634
- entry._ = m++;
635
- }
636
- _context7.next = 8;
637
- return entry;
638
- case 8:
639
- case "end":
640
- return _context7.stop();
641
- }
642
- }, _loop);
643
- });
644
- _context8.t1 = _regeneratorRuntime().keys(lines);
645
- case 24:
646
- if ((_context8.t2 = _context8.t1()).done) {
647
- _context8.next = 31;
624
+ row = _step.value;
625
+ _context7.next = 35;
626
+ return _awaitAsyncGenerator(_this.serializer.deserialize(row.line, {
627
+ compress: _this.opts.compress
628
+ }));
629
+ case 35:
630
+ entry = _context7.sent;
631
+ if (!options.includeOffsets) {
632
+ _context7.next = 41;
648
633
  break;
649
634
  }
650
- _line = _context8.t2.value;
651
- return _context8.delegateYield(_loop(), "t3", 27);
652
- case 27:
653
- if (!_context8.t3) {
654
- _context8.next = 29;
635
+ _context7.next = 39;
636
+ return {
637
+ entry: entry,
638
+ start: row.start
639
+ };
640
+ case 39:
641
+ _context7.next = 43;
642
+ break;
643
+ case 41:
644
+ _context7.next = 43;
645
+ return entry;
646
+ case 43:
647
+ _iteratorAbruptCompletion = false;
648
+ _context7.next = 29;
649
+ break;
650
+ case 46:
651
+ _context7.next = 52;
652
+ break;
653
+ case 48:
654
+ _context7.prev = 48;
655
+ _context7.t1 = _context7["catch"](27);
656
+ _didIteratorError = true;
657
+ _iteratorError = _context7.t1;
658
+ case 52:
659
+ _context7.prev = 52;
660
+ _context7.prev = 53;
661
+ if (!(_iteratorAbruptCompletion && _iterator["return"] != null)) {
662
+ _context7.next = 57;
655
663
  break;
656
664
  }
657
- return _context8.abrupt("continue", 24);
658
- case 29:
659
- _context8.next = 24;
665
+ _context7.next = 57;
666
+ return _awaitAsyncGenerator(_iterator["return"]());
667
+ case 57:
668
+ _context7.prev = 57;
669
+ if (!_didIteratorError) {
670
+ _context7.next = 60;
671
+ break;
672
+ }
673
+ throw _iteratorError;
674
+ case 60:
675
+ return _context7.finish(57);
676
+ case 61:
677
+ return _context7.finish(52);
678
+ case 62:
679
+ _context7.next = 23;
660
680
  break;
661
- case 31:
662
- _i++;
663
- _context8.next = 17;
681
+ case 64:
682
+ _context7.next = 69;
664
683
  break;
665
- case 34:
684
+ case 66:
685
+ _context7.prev = 66;
686
+ _context7.t2 = _context7["catch"](21);
687
+ _iterator2.e(_context7.t2);
688
+ case 69:
689
+ _context7.prev = 69;
690
+ _iterator2.f();
691
+ return _context7.finish(69);
692
+ case 72:
693
+ _context7.next = 74;
694
+ return _awaitAsyncGenerator(fd.close());
695
+ case 74:
666
696
  case "end":
667
- return _context8.stop();
697
+ return _context7.stop();
668
698
  }
669
- }, _callee7);
699
+ }, _callee7, null, [[21, 66, 69, 72], [27, 48, 52, 62], [53,, 57, 61]]);
670
700
  }))();
671
701
  }
672
702
  }, {
@@ -681,40 +711,40 @@ var Database = exports.Database = /*#__PURE__*/function (_EventEmitter) {
681
711
  _options$orderBy$spli3,
682
712
  direction,
683
713
  matchingLines,
684
- _args9 = arguments;
685
- return _regeneratorRuntime().wrap(function _callee8$(_context9) {
686
- while (1) switch (_context9.prev = _context9.next) {
714
+ _args8 = arguments;
715
+ return _regeneratorRuntime().wrap(function _callee8$(_context8) {
716
+ while (1) switch (_context8.prev = _context8.next) {
687
717
  case 0:
688
- options = _args9.length > 1 && _args9[1] !== undefined ? _args9[1] : {};
718
+ options = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {};
689
719
  if (!this.destroyed) {
690
- _context9.next = 3;
720
+ _context8.next = 3;
691
721
  break;
692
722
  }
693
723
  throw new Error('Database is destroyed');
694
724
  case 3:
695
725
  if (this.initialized) {
696
- _context9.next = 6;
726
+ _context8.next = 6;
697
727
  break;
698
728
  }
699
- _context9.next = 6;
729
+ _context8.next = 6;
700
730
  return this.init();
701
731
  case 6:
702
- _context9.t0 = this.shouldSave;
703
- if (!_context9.t0) {
704
- _context9.next = 10;
732
+ _context8.t0 = this.shouldSave;
733
+ if (!_context8.t0) {
734
+ _context8.next = 10;
705
735
  break;
706
736
  }
707
- _context9.next = 10;
737
+ _context8.next = 10;
708
738
  return this.save()["catch"](console.error);
709
739
  case 10:
710
740
  if (!Array.isArray(criteria)) {
711
- _context9.next = 19;
741
+ _context8.next = 19;
712
742
  break;
713
743
  }
714
- _context9.next = 13;
744
+ _context8.next = 13;
715
745
  return this.readLines(criteria);
716
746
  case 13:
717
- results = _context9.sent;
747
+ results = _context8.sent;
718
748
  if (options.orderBy) {
719
749
  _options$orderBy$spli = options.orderBy.split(' '), _options$orderBy$spli2 = _slicedToArray(_options$orderBy$spli, 2), field = _options$orderBy$spli2[0], _options$orderBy$spli3 = _options$orderBy$spli2[1], direction = _options$orderBy$spli3 === void 0 ? 'asc' : _options$orderBy$spli3;
720
750
  results.sort(function (a, b) {
@@ -726,25 +756,25 @@ var Database = exports.Database = /*#__PURE__*/function (_EventEmitter) {
726
756
  if (options.limit) {
727
757
  results = results.slice(0, options.limit);
728
758
  }
729
- return _context9.abrupt("return", results);
759
+ return _context8.abrupt("return", results);
730
760
  case 19:
731
- _context9.next = 21;
761
+ _context8.next = 21;
732
762
  return this.indexManager.query(criteria, options);
733
763
  case 21:
734
- matchingLines = _context9.sent;
764
+ matchingLines = _context8.sent;
735
765
  if (!(!matchingLines || !matchingLines.size)) {
736
- _context9.next = 24;
766
+ _context8.next = 24;
737
767
  break;
738
768
  }
739
- return _context9.abrupt("return", []);
769
+ return _context8.abrupt("return", []);
740
770
  case 24:
741
- _context9.next = 26;
771
+ _context8.next = 26;
742
772
  return this.query(_toConsumableArray(matchingLines), options);
743
773
  case 26:
744
- return _context9.abrupt("return", _context9.sent);
774
+ return _context8.abrupt("return", _context8.sent);
745
775
  case 27:
746
776
  case "end":
747
- return _context9.stop();
777
+ return _context8.stop();
748
778
  }
749
779
  }, _callee8, this);
750
780
  }));
@@ -764,110 +794,110 @@ var Database = exports.Database = /*#__PURE__*/function (_EventEmitter) {
764
794
  validMatchingLines,
765
795
  entries,
766
796
  lines,
767
- _iterator,
768
- _step,
769
- _loop2,
797
+ _iterator3,
798
+ _step3,
799
+ _loop,
770
800
  offsets,
771
801
  byteOffset,
772
802
  k,
773
- _args11 = arguments;
774
- return _regeneratorRuntime().wrap(function _callee9$(_context11) {
775
- while (1) switch (_context11.prev = _context11.next) {
803
+ _args10 = arguments;
804
+ return _regeneratorRuntime().wrap(function _callee9$(_context10) {
805
+ while (1) switch (_context10.prev = _context10.next) {
776
806
  case 0:
777
- options = _args11.length > 2 && _args11[2] !== undefined ? _args11[2] : {};
807
+ options = _args10.length > 2 && _args10[2] !== undefined ? _args10[2] : {};
778
808
  if (this.shouldTruncate) {
779
809
  this.writeBuffer.push(this.indexOffset);
780
810
  this.shouldTruncate = false;
781
811
  }
782
812
  if (!this.destroyed) {
783
- _context11.next = 4;
813
+ _context10.next = 4;
784
814
  break;
785
815
  }
786
816
  throw new Error('Database is destroyed');
787
817
  case 4:
788
818
  if (this.initialized) {
789
- _context11.next = 7;
819
+ _context10.next = 7;
790
820
  break;
791
821
  }
792
- _context11.next = 7;
822
+ _context10.next = 7;
793
823
  return this.init();
794
824
  case 7:
795
- _context11.t0 = this.shouldSave;
796
- if (!_context11.t0) {
797
- _context11.next = 11;
825
+ _context10.t0 = this.shouldSave;
826
+ if (!_context10.t0) {
827
+ _context10.next = 11;
798
828
  break;
799
829
  }
800
- _context11.next = 11;
830
+ _context10.next = 11;
801
831
  return this.save()["catch"](console.error);
802
832
  case 11:
803
- _context11.next = 13;
833
+ _context10.next = 13;
804
834
  return this.indexManager.query(criteria, options);
805
835
  case 13:
806
- matchingLines = _context11.sent;
836
+ matchingLines = _context10.sent;
807
837
  if (!(!matchingLines || !matchingLines.size)) {
808
- _context11.next = 16;
838
+ _context10.next = 16;
809
839
  break;
810
840
  }
811
- return _context11.abrupt("return", []);
841
+ return _context10.abrupt("return", []);
812
842
  case 16:
813
843
  ranges = this.getRanges(_toConsumableArray(matchingLines));
814
844
  validMatchingLines = new Set(ranges.map(function (r) {
815
845
  return r.index;
816
846
  }));
817
847
  if (validMatchingLines.size) {
818
- _context11.next = 20;
848
+ _context10.next = 20;
819
849
  break;
820
850
  }
821
- return _context11.abrupt("return", []);
851
+ return _context10.abrupt("return", []);
822
852
  case 20:
823
- _context11.next = 22;
853
+ _context10.next = 22;
824
854
  return this.readLines(_toConsumableArray(validMatchingLines), ranges);
825
855
  case 22:
826
- entries = _context11.sent;
856
+ entries = _context10.sent;
827
857
  lines = [];
828
- _iterator = _createForOfIteratorHelper(entries);
829
- _context11.prev = 25;
830
- _loop2 = /*#__PURE__*/_regeneratorRuntime().mark(function _loop2() {
858
+ _iterator3 = _createForOfIteratorHelper(entries);
859
+ _context10.prev = 25;
860
+ _loop = /*#__PURE__*/_regeneratorRuntime().mark(function _loop() {
831
861
  var entry, err, updated, ret;
832
- return _regeneratorRuntime().wrap(function _loop2$(_context10) {
833
- while (1) switch (_context10.prev = _context10.next) {
862
+ return _regeneratorRuntime().wrap(function _loop$(_context9) {
863
+ while (1) switch (_context9.prev = _context9.next) {
834
864
  case 0:
835
- entry = _step.value;
865
+ entry = _step3.value;
836
866
  updated = Object.assign(entry, data);
837
- _context10.next = 4;
867
+ _context9.next = 4;
838
868
  return _this8.serializer.serialize(updated)["catch"](function (e) {
839
869
  return err = e;
840
870
  });
841
871
  case 4:
842
- ret = _context10.sent;
872
+ ret = _context9.sent;
843
873
  err || lines.push(ret);
844
874
  case 6:
845
875
  case "end":
846
- return _context10.stop();
876
+ return _context9.stop();
847
877
  }
848
- }, _loop2);
878
+ }, _loop);
849
879
  });
850
- _iterator.s();
880
+ _iterator3.s();
851
881
  case 28:
852
- if ((_step = _iterator.n()).done) {
853
- _context11.next = 32;
882
+ if ((_step3 = _iterator3.n()).done) {
883
+ _context10.next = 32;
854
884
  break;
855
885
  }
856
- return _context11.delegateYield(_loop2(), "t1", 30);
886
+ return _context10.delegateYield(_loop(), "t1", 30);
857
887
  case 30:
858
- _context11.next = 28;
888
+ _context10.next = 28;
859
889
  break;
860
890
  case 32:
861
- _context11.next = 37;
891
+ _context10.next = 37;
862
892
  break;
863
893
  case 34:
864
- _context11.prev = 34;
865
- _context11.t2 = _context11["catch"](25);
866
- _iterator.e(_context11.t2);
894
+ _context10.prev = 34;
895
+ _context10.t2 = _context10["catch"](25);
896
+ _iterator3.e(_context10.t2);
867
897
  case 37:
868
- _context11.prev = 37;
869
- _iterator.f();
870
- return _context11.finish(37);
898
+ _context10.prev = 37;
899
+ _iterator3.f();
900
+ return _context10.finish(37);
871
901
  case 40:
872
902
  offsets = [];
873
903
  byteOffset = 0, k = 0;
@@ -882,7 +912,7 @@ var Database = exports.Database = /*#__PURE__*/function (_EventEmitter) {
882
912
  });
883
913
  this.offsets = offsets;
884
914
  this.indexOffset += byteOffset;
885
- _context11.next = 47;
915
+ _context10.next = 47;
886
916
  return this.fileHandler.replaceLines(ranges, lines);
887
917
  case 47:
888
918
  _toConsumableArray(validMatchingLines).forEach(function (lineNumber, i) {
@@ -890,10 +920,10 @@ var Database = exports.Database = /*#__PURE__*/function (_EventEmitter) {
890
920
  _this8.indexManager.add(entries[i], lineNumber);
891
921
  });
892
922
  this.shouldSave = true;
893
- return _context11.abrupt("return", entries);
923
+ return _context10.abrupt("return", entries);
894
924
  case 50:
895
925
  case "end":
896
- return _context11.stop();
926
+ return _context10.stop();
897
927
  }
898
928
  }, _callee9, this, [[25, 34, 37, 40]]);
899
929
  }));
@@ -913,51 +943,51 @@ var Database = exports.Database = /*#__PURE__*/function (_EventEmitter) {
913
943
  offsets,
914
944
  byteOffset,
915
945
  k,
916
- _args12 = arguments;
917
- return _regeneratorRuntime().wrap(function _callee10$(_context12) {
918
- while (1) switch (_context12.prev = _context12.next) {
946
+ _args11 = arguments;
947
+ return _regeneratorRuntime().wrap(function _callee10$(_context11) {
948
+ while (1) switch (_context11.prev = _context11.next) {
919
949
  case 0:
920
- options = _args12.length > 1 && _args12[1] !== undefined ? _args12[1] : {};
950
+ options = _args11.length > 1 && _args11[1] !== undefined ? _args11[1] : {};
921
951
  if (this.shouldTruncate) {
922
952
  this.writeBuffer.push(this.indexOffset);
923
953
  this.shouldTruncate = false;
924
954
  }
925
955
  if (!this.destroyed) {
926
- _context12.next = 4;
956
+ _context11.next = 4;
927
957
  break;
928
958
  }
929
959
  throw new Error('Database is destroyed');
930
960
  case 4:
931
961
  if (this.initialized) {
932
- _context12.next = 7;
962
+ _context11.next = 7;
933
963
  break;
934
964
  }
935
- _context12.next = 7;
965
+ _context11.next = 7;
936
966
  return this.init();
937
967
  case 7:
938
- _context12.t0 = this.shouldSave;
939
- if (!_context12.t0) {
940
- _context12.next = 11;
968
+ _context11.t0 = this.shouldSave;
969
+ if (!_context11.t0) {
970
+ _context11.next = 11;
941
971
  break;
942
972
  }
943
- _context12.next = 11;
973
+ _context11.next = 11;
944
974
  return this.save()["catch"](console.error);
945
975
  case 11:
946
- _context12.next = 13;
976
+ _context11.next = 13;
947
977
  return this.indexManager.query(criteria, options);
948
978
  case 13:
949
- matchingLines = _context12.sent;
979
+ matchingLines = _context11.sent;
950
980
  if (!(!matchingLines || !matchingLines.size)) {
951
- _context12.next = 16;
981
+ _context11.next = 16;
952
982
  break;
953
983
  }
954
- return _context12.abrupt("return", 0);
984
+ return _context11.abrupt("return", 0);
955
985
  case 16:
956
986
  ranges = this.getRanges(_toConsumableArray(matchingLines));
957
987
  validMatchingLines = new Set(ranges.map(function (r) {
958
988
  return r.index;
959
989
  }));
960
- _context12.next = 20;
990
+ _context11.next = 20;
961
991
  return this.fileHandler.replaceLines(ranges, []);
962
992
  case 20:
963
993
  offsets = [];
@@ -975,10 +1005,10 @@ var Database = exports.Database = /*#__PURE__*/function (_EventEmitter) {
975
1005
  this.indexOffset += byteOffset;
976
1006
  this.indexManager.remove(_toConsumableArray(validMatchingLines));
977
1007
  this.shouldSave = true;
978
- return _context12.abrupt("return", ranges.length);
1008
+ return _context11.abrupt("return", ranges.length);
979
1009
  case 28:
980
1010
  case "end":
981
- return _context12.stop();
1011
+ return _context11.stop();
982
1012
  }
983
1013
  }, _callee10, this);
984
1014
  }));
@@ -991,15 +1021,15 @@ var Database = exports.Database = /*#__PURE__*/function (_EventEmitter) {
991
1021
  key: "destroy",
992
1022
  value: function () {
993
1023
  var _destroy = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee11() {
994
- return _regeneratorRuntime().wrap(function _callee11$(_context13) {
995
- while (1) switch (_context13.prev = _context13.next) {
1024
+ return _regeneratorRuntime().wrap(function _callee11$(_context12) {
1025
+ while (1) switch (_context12.prev = _context12.next) {
996
1026
  case 0:
997
- _context13.t0 = this.shouldSave;
998
- if (!_context13.t0) {
999
- _context13.next = 4;
1027
+ _context12.t0 = this.shouldSave;
1028
+ if (!_context12.t0) {
1029
+ _context12.next = 4;
1000
1030
  break;
1001
1031
  }
1002
- _context13.next = 4;
1032
+ _context12.next = 4;
1003
1033
  return this.save()["catch"](console.error);
1004
1034
  case 4:
1005
1035
  this.destroyed = true;
@@ -1010,7 +1040,7 @@ var Database = exports.Database = /*#__PURE__*/function (_EventEmitter) {
1010
1040
  this.fileHandler.destroy();
1011
1041
  case 10:
1012
1042
  case "end":
1013
- return _context13.stop();
1043
+ return _context12.stop();
1014
1044
  }
1015
1045
  }, _callee11, this);
1016
1046
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jexidb",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "JexiDB is a pure JS NPM library for managing data on disk using JSONL efficiently, without the need for a server.",
5
5
  "main": "./dist/Database.cjs",
6
6
  "module": "./src/Database.mjs",
package/src/Database.mjs CHANGED
@@ -223,30 +223,20 @@ export class Database extends EventEmitter {
223
223
  }
224
224
  }
225
225
  const ranges = this.getRanges(map)
226
- const partitionedRanges = [], currentPartition = 0
227
- for (const line in ranges) {
228
- if (partitionedRanges[currentPartition] === undefined) {
229
- partitionedRanges[currentPartition] = []
230
- }
231
- partitionedRanges[currentPartition].push(ranges[line])
232
- if (partitionedRanges[currentPartition].length >= this.opts.maxMemoryUsage) {
233
- currentPartition++
234
- }
235
- }
236
- let m = 0
237
- for (const ranges of partitionedRanges) {
238
- const lines = await this.fileHandler.readRanges(ranges)
239
- for (const line in lines) {
240
- let err
241
- const entry = await this.serializer.deserialize(lines[line]).catch(e => console.error(err = e))
242
- if (err) continue
243
- if (entry._ === undefined) {
244
- while(this.offsets[m] != line && m < map.length) m++ // weak comparison as 'start' is a string
245
- entry._ = m++
226
+ const readSize = 512 * 1024 // 512KB
227
+ const groupedRanges = await this.fileHandler.groupedRanges(ranges)
228
+ const fd = await fs.promises.open(this.fileHandler.file, 'r')
229
+ for(const groupedRange of groupedRanges) {
230
+ for await (const row of this.fileHandler.readGroupedRange(groupedRange, fd)) {
231
+ const entry = await this.serializer.deserialize(row.line, {compress: this.opts.compress})
232
+ if(options.includeOffsets) {
233
+ yield {entry, start: row.start}
234
+ } else {
235
+ yield entry
246
236
  }
247
- yield entry
248
237
  }
249
238
  }
239
+ await fd.close()
250
240
  }
251
241
 
252
242
  async query(criteria, options={}) {
@@ -28,18 +28,13 @@ export default class FileHandler {
28
28
  async readRanges(ranges, mapper) {
29
29
  const lines = {}, limit = pLimit(4)
30
30
  const fd = await fs.promises.open(this.file, 'r')
31
+ const groupedRanges = await this.groupedRanges(ranges)
31
32
  try {
32
- const tasks = ranges.map(r => {
33
- return async () => {
34
- let err
35
- const length = r.end - r.start
36
- let buffer = Buffer.alloc(length)
37
- const { bytesRead } = await fd.read(buffer, 0, length, r.start).catch(e => err = e)
38
- if (buffer.length > bytesRead) buffer = buffer.subarray(0, bytesRead)
39
- lines[r.start] = mapper ? (await mapper(buffer, r)) : buffer
33
+ for(const groupedRange of groupedRanges) {
34
+ for await (const row of this.readGroupedRange(groupedRange, fd)) {
35
+ lines[row.start] = mapper ? (await mapper(row.line, groupedRange)) : row.line
40
36
  }
41
- })
42
- await Promise.allSettled(tasks.map(limit))
37
+ }
43
38
  } catch (e) {
44
39
  console.error('Error reading ranges:', e)
45
40
  } finally {
@@ -48,6 +43,61 @@ export default class FileHandler {
48
43
  return lines
49
44
  }
50
45
 
46
+ async groupedRanges(ranges) {
47
+ const readSize = 512 * 1024 // 512KB
48
+ const groupedRanges = []
49
+ let currentGroup = []
50
+ let currentSize = 0
51
+
52
+ // each range is a {start: number, end: number} object
53
+ for(const range of ranges) {
54
+ const rangeSize = range.end - range.start
55
+
56
+ if(currentGroup.length > 0) {
57
+ const lastRange = currentGroup[currentGroup.length - 1]
58
+ if(lastRange.end !== range.start || currentSize + rangeSize > readSize) {
59
+ groupedRanges.push(currentGroup)
60
+ currentGroup = []
61
+ currentSize = 0
62
+ }
63
+ }
64
+
65
+ currentGroup.push(range)
66
+ currentSize += rangeSize
67
+ }
68
+
69
+ if(currentGroup.length > 0) {
70
+ groupedRanges.push(currentGroup)
71
+ }
72
+
73
+ return groupedRanges
74
+ }
75
+
76
+ async *readGroupedRange(groupedRange, fd) {
77
+ const options = {start: groupedRange[0].start, end: groupedRange[groupedRange.length - 1].end}
78
+
79
+ let i = 0, buffer = Buffer.alloc(options.end - options.start)
80
+ const results = {}, { bytesRead } = await fd.read(buffer, 0, options.end - options.start, options.start)
81
+ if(buffer.length > bytesRead) buffer = buffer.subarray(0, bytesRead)
82
+ for(const range of groupedRange) {
83
+ const line = buffer.subarray(range.start, range.end)
84
+ yield {line, start: range.start}
85
+ }
86
+
87
+ return results
88
+ }
89
+
90
+ async *walk(ranges, options={}) {
91
+ const fd = await fs.promises.open(this.file, 'r')
92
+ const groupedRanges = await this.groupedRanges(ranges)
93
+ for(const groupedRange of groupedRanges) {
94
+ for await (const row of this.readGroupedRange(groupedRange, fd)) {
95
+ yield row
96
+ }
97
+ }
98
+ await fd.close()
99
+ }
100
+
51
101
  async replaceLines(ranges, lines) {
52
102
  let closed
53
103
  const tmpFile = this.file + '.tmp'
@@ -23,7 +23,7 @@ export default class Serializer extends EventEmitter {
23
23
  header |= 0x02 // set V8
24
24
  line = v8.serialize(data)
25
25
  } else {
26
- let json = JSON.stringify(data)
26
+ const json = JSON.stringify(data)
27
27
  line = Buffer.from(json, 'utf-8')
28
28
  }
29
29
  if (compress) {
Binary file
Binary file
package/test/test-v8.jdb CHANGED
Binary file