@harperfast/rocksdb-js 2.1.0 → 2.2.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/dist/index.cjs CHANGED
@@ -31,6 +31,7 @@ let node_fs = require("node:fs");
31
31
  let node_module = require("node:module");
32
32
  let node_path = require("node:path");
33
33
  let node_url = require("node:url");
34
+ let node_fs_promises = require("node:fs/promises");
34
35
  let ordered_binary = require("ordered-binary");
35
36
  ordered_binary = __toESM(ordered_binary, 1);
36
37
  let _harperfast_extended_iterable = require("@harperfast/extended-iterable");
@@ -80,6 +81,7 @@ function locateBinding() {
80
81
  }
81
82
  const binding = req(locateBinding());
82
83
  const config = binding.config;
84
+ const FRESH_VERSION_FLAG$1 = binding.constants.FRESH_VERSION_FLAG;
83
85
  const addGlobalListener = binding.addListener;
84
86
  const removeGlobalListener = binding.removeListener;
85
87
  const globalListenerCount = binding.listenerCount;
@@ -92,9 +94,95 @@ const TransactionLog = binding.TransactionLog;
92
94
  const registryStatus = binding.registryStatus;
93
95
  const shutdown = binding.shutdown;
94
96
  const currentThreadId = binding.currentThreadId;
97
+ /**
98
+ * Advises the kernel that the file-backed pages of every mapped transaction log
99
+ * are cold (Linux MADV_COLD), so they are reclaimed first under memory pressure
100
+ * without being freed — useful during replication catch-up, where a full read of
101
+ * the logs would otherwise inflate the container's reclaimable cache toward its
102
+ * cgroup limit. No-op on kernels < 5.4, macOS, and Windows.
103
+ *
104
+ * The transaction log registry is a process-global singleton shared across all
105
+ * worker threads, so a single call cools every worker's maps. Call it on an
106
+ * interval from one thread (e.g. an `unref()`ed timer on the main thread).
107
+ *
108
+ * @returns the number of maps cooled and total file-backed bytes advised.
109
+ */
110
+ const coolTransactionLogs = binding.coolTransactionLogs;
111
+ /**
112
+ * Number of live transaction-log memory maps across the process. Internal —
113
+ * used by tests to verify that releasing a frozen log's external buffer unmaps
114
+ * the underlying mapping rather than leaving it retained.
115
+ */
116
+ const transactionLogMapCount = binding.transactionLogMapCount;
117
+ const nativeBackupRestore = binding.backupRestore;
118
+ const nativeBackupList = binding.backupList;
119
+ const nativeBackupDelete = binding.backupDelete;
120
+ const nativeBackupPurge = binding.backupPurge;
121
+ const nativeBackupVerify = binding.backupVerify;
95
122
  const stats = binding.stats;
96
123
  const version = binding.version;
97
124
 
125
+ //#endregion
126
+ //#region src/backup.ts
127
+ /**
128
+ * Backup management operations that act on a backup directory and do not
129
+ * require an open database. To create a backup, use the `db.backup()` instance
130
+ * method instead (it needs a live database for a consistent snapshot).
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * import { backups } from '@harperfast/rocksdb-js';
135
+ *
136
+ * const id = await db.backup('/path/to/backups');
137
+ * db.close();
138
+ * await backups.restore('/path/to/backups', '/path/to/restored-db');
139
+ * ```
140
+ */
141
+ const backups = {
142
+ /**
143
+ * Restores a database from a backup directory into a (closed) database
144
+ * directory. The default mode purges the destination directory, so it must
145
+ * not point at a live database.
146
+ */
147
+ async restore(backupDir, dbDir, options) {
148
+ if ((0, node_path.resolve)(backupDir) === (0, node_path.resolve)(dbDir)) throw new Error("Backup directory and database directory must be different");
149
+ const walDir = options?.walDir ?? dbDir;
150
+ await (0, node_fs_promises.mkdir)(dbDir, { recursive: true });
151
+ if (walDir !== dbDir) await (0, node_fs_promises.mkdir)(walDir, { recursive: true });
152
+ return new Promise((resolve, reject) => nativeBackupRestore(resolve, reject, backupDir, dbDir, walDir, {
153
+ backupId: options?.backupId,
154
+ keepLogFiles: options?.keepLogFiles,
155
+ mode: options?.mode
156
+ }));
157
+ },
158
+ /**
159
+ * Lists the non-corrupt backups in a backup directory, ordered by id.
160
+ */
161
+ list(backupDir) {
162
+ return new Promise((resolve, reject) => nativeBackupList(resolve, reject, backupDir));
163
+ },
164
+ /**
165
+ * Deletes a specific backup. Shared files are reference-counted and only
166
+ * removed once no remaining backup references them.
167
+ */
168
+ delete(backupDir, backupId) {
169
+ return new Promise((resolve, reject) => nativeBackupDelete(resolve, reject, backupDir, backupId));
170
+ },
171
+ /**
172
+ * Deletes all but the newest `keepCount` backups.
173
+ */
174
+ purge(backupDir, keepCount) {
175
+ return new Promise((resolve, reject) => nativeBackupPurge(resolve, reject, backupDir, keepCount));
176
+ },
177
+ /**
178
+ * Verifies a backup's file sizes, and optionally their checksums (which
179
+ * requires reading all backed-up data).
180
+ */
181
+ verify(backupDir, backupId, options) {
182
+ return new Promise((resolve, reject) => nativeBackupVerify(resolve, reject, backupDir, backupId, options?.verifyWithChecksum ?? false));
183
+ }
184
+ };
185
+
98
186
  //#endregion
99
187
  //#region src/util.ts
100
188
  /**
@@ -213,11 +301,11 @@ var DBI = class DBI {
213
301
  */
214
302
  get(key, options) {
215
303
  if (this.store.decoderCopies) return when(() => this.getBinaryFast(key, options), (result) => {
216
- if (result === void 0) return;
304
+ if (result === void 0 || result === FRESH_VERSION_FLAG$1) return result;
217
305
  if (options?.skipDecode) return result;
218
306
  return this.store.decodeValue(result);
219
307
  });
220
- return when(() => this.getBinary(key, options), (result) => result === void 0 ? void 0 : this.store.encoding === "binary" || !this.store.decoder || options?.skipDecode ? result : this.store.decodeValue(result));
308
+ return when(() => this.getBinary(key, options), (result) => result === void 0 || result === FRESH_VERSION_FLAG$1 ? result : this.store.encoding === "binary" || !this.store.decoder || options?.skipDecode ? result : this.store.decodeValue(result));
221
309
  }
222
310
  /**
223
311
  * Retrieves the binary data for the given key. This is just like `get()`,
@@ -227,7 +315,7 @@ var DBI = class DBI {
227
315
  */
228
316
  getBinary(key, options) {
229
317
  if (!this.store.isOpen()) return Promise.reject(/* @__PURE__ */ new Error("Database not open"));
230
- return this.store.get(this._context, key, true, this.store.getTxnId(options));
318
+ return this.store.get(this._context, key, true, options);
231
319
  }
232
320
  /**
233
321
  * Synchronously retrieves the binary data for the given key.
@@ -248,7 +336,7 @@ var DBI = class DBI {
248
336
  */
249
337
  getBinaryFast(key, options) {
250
338
  if (!this.store.isOpen()) return Promise.reject(/* @__PURE__ */ new Error("Database not open"));
251
- return this.store.get(this._context, key, false, this.store.getTxnId(options));
339
+ return this.store.get(this._context, key, false, options);
252
340
  }
253
341
  /**
254
342
  * Synchronously retrieves the binary data for the given key using a
@@ -307,12 +395,12 @@ var DBI = class DBI {
307
395
  getSync(key, options) {
308
396
  if (this.store.decoderCopies) {
309
397
  const bytes = this.getBinaryFastSync(key, options);
310
- return bytes === void 0 ? void 0 : this.store.decodeValue(bytes);
398
+ return bytes === void 0 || bytes === FRESH_VERSION_FLAG$1 ? bytes : this.store.decodeValue(bytes);
311
399
  }
312
400
  if (this.store.encoding === "binary") return this.getBinarySync(key, options);
313
401
  if (this.store.decoder) {
314
402
  const result = this.getBinarySync(key, options);
315
- return result ? this.store.decodeValue(result) : void 0;
403
+ return !result || result === FRESH_VERSION_FLAG$1 ? result : this.store.decodeValue(result);
316
404
  }
317
405
  if (!this.store.isOpen()) throw new Error("Database not open");
318
406
  return this.store.decodeValue(this.store.getSync(this._context, key, true, options));
@@ -475,17 +563,25 @@ var DBIterator = class {
475
563
  iterator;
476
564
  store;
477
565
  #includeValues;
478
- constructor(iterator, store, includeValues) {
566
+ #limit;
567
+ #yielded = 0;
568
+ constructor(iterator, store, includeValues, limit) {
479
569
  this.iterator = iterator;
480
570
  this.store = store;
481
571
  this.#includeValues = includeValues;
572
+ this.#limit = limit ?? void 0;
482
573
  }
483
574
  [Symbol.iterator]() {
484
575
  return this;
485
576
  }
486
577
  next() {
578
+ if (this.#limit !== void 0 && this.#yielded >= this.#limit) {
579
+ this.iterator.return?.();
580
+ return DONE_RESULT;
581
+ }
487
582
  const result = this.iterator.next();
488
583
  if (result === ITERATOR_RESULT_DONE) return DONE_RESULT;
584
+ this.#yielded++;
489
585
  const includeValues = this.#includeValues;
490
586
  const value = {};
491
587
  if (result === ITERATOR_RESULT_FAST) {
@@ -587,7 +683,7 @@ function createFixedBuffer(size) {
587
683
 
588
684
  //#endregion
589
685
  //#region src/store.ts
590
- const { ONLY_IF_IN_MEMORY_CACHE_FLAG, NOT_IN_MEMORY_CACHE_FLAG, ALWAYS_CREATE_NEW_BUFFER_FLAG, ITERATOR_REVERSE_FLAG, ITERATOR_INCLUSIVE_END_FLAG, ITERATOR_EXCLUSIVE_START_FLAG, ITERATOR_INCLUDE_VALUES_FLAG, ITERATOR_NEEDS_STABLE_VALUE_BUFFER_FLAG, ITERATOR_CONTEXT_IS_TRANSACTION_FLAG } = constants;
686
+ const { ONLY_IF_IN_MEMORY_CACHE_FLAG, NOT_IN_MEMORY_CACHE_FLAG, ALWAYS_CREATE_NEW_BUFFER_FLAG, FRESH_VERSION_FLAG, POPULATE_VERSION_FLAG, ITERATOR_REVERSE_FLAG, ITERATOR_INCLUSIVE_END_FLAG, ITERATOR_EXCLUSIVE_START_FLAG, ITERATOR_INCLUDE_VALUES_FLAG, ITERATOR_NEEDS_STABLE_VALUE_BUFFER_FLAG, ITERATOR_CONTEXT_IS_TRANSACTION_FLAG } = constants;
591
687
  const KEY_BUFFER_SIZE = 4096;
592
688
  const KEY_BUFFER = createFixedBuffer(KEY_BUFFER_SIZE);
593
689
  const VALUE_BUFFER = createFixedBuffer(64 * 1024);
@@ -746,6 +842,10 @@ var Store = class {
746
842
  */
747
843
  transactionLogsPath;
748
844
  /**
845
+ * Whether this store's column family participates in the VerificationTable.
846
+ */
847
+ verificationTable;
848
+ /**
749
849
  * The per-column-family memtable size in bytes at which the memtable is
750
850
  * sealed and flushed.
751
851
  */
@@ -792,6 +892,7 @@ var Store = class {
792
892
  this.transactionLogMaxSize = options?.transactionLogMaxSize;
793
893
  this.transactionLogRetention = options?.transactionLogRetention;
794
894
  this.transactionLogsPath = options?.transactionLogsPath;
895
+ this.verificationTable = options?.verificationTable;
795
896
  this.writeBufferSize = options?.writeBufferSize;
796
897
  this.writeKey = writeKey;
797
898
  }
@@ -825,6 +926,20 @@ var Store = class {
825
926
  return new Promise((resolve, reject) => this.db.compact(resolve, reject, startBuffer, endBuffer));
826
927
  }
827
928
  /**
929
+ * Creates a backup of the entire database (all column families) into the
930
+ * given directory and resolves with the new backup id. Parent directories
931
+ * are created as needed. See `backups` for restore and management.
932
+ *
933
+ * @example
934
+ * ```typescript
935
+ * const id = await db.backup('/path/to/backups');
936
+ * ```
937
+ */
938
+ async backup(backupDir, options) {
939
+ await (0, node_fs_promises.mkdir)(backupDir, { recursive: true });
940
+ return new Promise((resolve, reject) => this.db.backup(resolve, reject, backupDir, options));
941
+ }
942
+ /**
828
943
  * Compacts the entire key range of the database synchronously.
829
944
  * This triggers manual compaction which removes tombstones and reclaims space.
830
945
  *
@@ -897,16 +1012,19 @@ var Store = class {
897
1012
  if (value instanceof Uint8Array) return value;
898
1013
  throw new Error(`Invalid value put in database (${typeof value}), consider using an encoder`);
899
1014
  }
900
- get(context, key, alwaysCreateNewBuffer = false, txnId) {
1015
+ get(context, key, alwaysCreateNewBuffer = false, options) {
901
1016
  const keyParam = getKeyParam(this.encodeKey(key));
902
1017
  let flags = 0;
903
1018
  if (alwaysCreateNewBuffer) flags |= ALWAYS_CREATE_NEW_BUFFER_FLAG;
904
- if (this.readOnly) txnId = void 0;
905
- const result = context.getSync(keyParam, flags | ONLY_IF_IN_MEMORY_CACHE_FLAG, txnId);
1019
+ if (options?.populateVersion) flags |= POPULATE_VERSION_FLAG;
1020
+ const txnId = this.getTxnId(options);
1021
+ const expectedVersion = options?.expectedVersion;
1022
+ const result = context.getSync(keyParam, flags | ONLY_IF_IN_MEMORY_CACHE_FLAG, txnId, expectedVersion);
906
1023
  if (typeof result === "number") {
907
1024
  if (result === NOT_IN_MEMORY_CACHE_FLAG) return new Promise((resolve, reject) => {
908
- context.get(keyParam, resolve, reject, txnId);
1025
+ context.get(keyParam, resolve, reject, txnId, expectedVersion);
909
1026
  });
1027
+ if (result === FRESH_VERSION_FLAG) return result;
910
1028
  VALUE_BUFFER.end = result;
911
1029
  return VALUE_BUFFER;
912
1030
  }
@@ -973,14 +1091,16 @@ var Store = class {
973
1091
  if (includeValues && !this.decoderCopies) flags |= ITERATOR_NEEDS_STABLE_VALUE_BUFFER_FLAG;
974
1092
  if (context !== this.db) flags |= ITERATOR_CONTEXT_IS_TRANSACTION_FLAG;
975
1093
  const advancedOptions = options !== void 0 && (options.adaptiveReadahead !== void 0 || options.asyncIO !== void 0 || options.autoReadaheadSize !== void 0 || options.backgroundPurgeOnIteratorCleanup !== void 0 || options.fillCache !== void 0 || options.readaheadSize !== void 0 || options.tailing !== void 0) ? options : void 0;
976
- return new _harperfast_extended_iterable.ExtendedIterable(new DBIterator(new NativeIterator(context, flags, startKeyEnd, endKeyStart, endKeyEnd, advancedOptions), this, includeValues));
1094
+ return new _harperfast_extended_iterable.ExtendedIterable(new DBIterator(new NativeIterator(context, flags, startKeyEnd, endKeyStart, endKeyEnd, advancedOptions), this, includeValues, options?.limit));
977
1095
  }
978
1096
  getSync(context, key, alwaysCreateNewBuffer = false, options) {
979
1097
  const keyParam = getKeyParam(this.encodeKey(key));
980
1098
  let flags = 0;
981
1099
  if (alwaysCreateNewBuffer) flags |= ALWAYS_CREATE_NEW_BUFFER_FLAG;
982
- const result = context.getSync(keyParam, flags, this.getTxnId(options));
1100
+ if (options?.populateVersion) flags |= POPULATE_VERSION_FLAG;
1101
+ const result = context.getSync(keyParam, flags, this.getTxnId(options), options?.expectedVersion);
983
1102
  if (typeof result === "number") {
1103
+ if (result === FRESH_VERSION_FLAG) return result;
984
1104
  VALUE_BUFFER.end = result;
985
1105
  return VALUE_BUFFER;
986
1106
  }
@@ -1069,6 +1189,7 @@ var Store = class {
1069
1189
  transactionLogMaxSize: this.transactionLogMaxSize,
1070
1190
  transactionLogRetentionMs: this.transactionLogRetention ? parseDuration(this.transactionLogRetention) : void 0,
1071
1191
  transactionLogsPath: this.transactionLogsPath,
1192
+ verificationTable: this.verificationTable,
1072
1193
  writeBufferSize: this.writeBufferSize
1073
1194
  });
1074
1195
  return false;
@@ -1118,6 +1239,25 @@ var Store = class {
1118
1239
  return context.useLog(String(name));
1119
1240
  }
1120
1241
  /**
1242
+ * Checks the process-global verification table for a fresh version match
1243
+ * on `key`. Returns `true` when the table currently records `version` for
1244
+ * this database+column-family. Provides a fast cache-freshness check
1245
+ * before falling back to a full read.
1246
+ */
1247
+ verifyVersion(key, version) {
1248
+ const keyParam = getKeyParam(this.encodeKey(key));
1249
+ return this.db.verifyVersion(keyParam, version);
1250
+ }
1251
+ /**
1252
+ * Seeds the verification-table slot for `key` with `version`. Has no
1253
+ * effect if the slot is currently lock-tagged or the table is disabled.
1254
+ * Useful after a full read where the caller already knows the version.
1255
+ */
1256
+ populateVersion(key, version) {
1257
+ const keyParam = getKeyParam(this.encodeKey(key));
1258
+ this.db.populateVersion(keyParam, version);
1259
+ }
1260
+ /**
1121
1261
  * Acquires a lock on the given key and calls the callback.
1122
1262
  *
1123
1263
  * @param key - The key to lock.
@@ -1145,6 +1285,13 @@ function getKeyParam(keyBuffer) {
1145
1285
 
1146
1286
  //#endregion
1147
1287
  //#region src/transaction.ts
1288
+ /**
1289
+ * Sentinel value returned by `commit()` when `coordinatedRetry: true` and the
1290
+ * transaction encountered an IsBusy conflict. The native layer parks on VT
1291
+ * slots and resolves only after the conflicting transaction releases its write
1292
+ * intent, so callers should retry immediately without any backoff delay.
1293
+ */
1294
+ const RETRY_NOW = constants.RETRY_NOW_VALUE;
1148
1295
  var TransactionAlreadyAbortedError = class extends Error {
1149
1296
  code = "ERR_ALREADY_ABORTED";
1150
1297
  };
@@ -1205,13 +1352,16 @@ var Transaction = class extends DBI {
1205
1352
  }
1206
1353
  /**
1207
1354
  * Commit the transaction.
1355
+ *
1356
+ * Returns `RETRY_NOW` when `coordinatedRetry: true` and an IsBusy conflict
1357
+ * was detected. The caller should retry the transaction body immediately.
1208
1358
  */
1209
1359
  async commit() {
1210
1360
  try {
1211
- await new Promise((resolve, reject) => {
1361
+ if (await new Promise((resolve, reject) => {
1212
1362
  this.notify("beforecommit");
1213
1363
  this.#txn.commit(resolve, reject);
1214
- });
1364
+ }) === RETRY_NOW) return RETRY_NOW;
1215
1365
  } catch (err) {
1216
1366
  throw this.#handleCommitError(err);
1217
1367
  } finally {
@@ -1357,6 +1507,26 @@ var RocksDatabase = class RocksDatabase extends DBI {
1357
1507
  return this.store.compact(options);
1358
1508
  }
1359
1509
  /**
1510
+ * Creates a backup of the entire database (all column families) into the
1511
+ * given directory, creating parent directories as needed, and resolves with
1512
+ * the new backup id. Use the `backups` namespace to restore, list, delete,
1513
+ * purge, or verify backups.
1514
+ *
1515
+ * When the database was opened with `disableWAL`, the memtable is flushed
1516
+ * before the backup by default so unflushed data is not lost.
1517
+ *
1518
+ * @example
1519
+ * ```typescript
1520
+ * import { backups } from '@harperfast/rocksdb-js';
1521
+ *
1522
+ * const db = RocksDatabase.open('/path/to/database');
1523
+ * const id = await db.backup('/path/to/backups');
1524
+ * ```
1525
+ */
1526
+ backup(backupDir, options) {
1527
+ return this.store.backup(backupDir, options);
1528
+ }
1529
+ /**
1360
1530
  * Compacts the entire key range of the database synchronously.
1361
1531
  * This triggers manual compaction which removes tombstones and reclaims space.
1362
1532
  *
@@ -1588,6 +1758,30 @@ var RocksDatabase = class RocksDatabase extends DBI {
1588
1758
  }
1589
1759
  async ifNoExists(_key) {}
1590
1760
  /**
1761
+ * Checks the process-global verification table for a fresh version match
1762
+ * on `key`. Returns `true` when the table currently records `version`. Use
1763
+ * this as a fast cache-freshness check before falling back to a full read:
1764
+ *
1765
+ * ```typescript
1766
+ * if (db.verifyVersion(key, cachedEntry.version)) {
1767
+ * return cachedEntry.value;
1768
+ * }
1769
+ * const value = db.getSync(key);
1770
+ * db.populateVersion(key, extractVersion(value));
1771
+ * ```
1772
+ */
1773
+ verifyVersion(key, version) {
1774
+ return this.store.verifyVersion(key, version);
1775
+ }
1776
+ /**
1777
+ * Seeds the verification-table slot for `key` with `version`. Has no
1778
+ * effect if the slot is currently lock-tagged or if the verification
1779
+ * table is disabled.
1780
+ */
1781
+ populateVersion(key, version) {
1782
+ this.store.populateVersion(key, version);
1783
+ }
1784
+ /**
1591
1785
  * Returns whether the database is open.
1592
1786
  *
1593
1787
  * @returns `true` if the database is open, `false` otherwise.
@@ -1727,9 +1921,6 @@ var RocksDatabase = class RocksDatabase extends DBI {
1727
1921
  get path() {
1728
1922
  return this.store.path;
1729
1923
  }
1730
- /**
1731
- * Purges transaction logs.
1732
- */
1733
1924
  purgeLogs(options) {
1734
1925
  return this.store.db.purgeLogs(options);
1735
1926
  }
@@ -1765,13 +1956,19 @@ var RocksDatabase = class RocksDatabase extends DBI {
1765
1956
  } catch (callbackErr) {
1766
1957
  return this.#abortTransaction(txn, callbackErr);
1767
1958
  }
1959
+ let commitResult;
1768
1960
  try {
1769
- await txn.commit();
1770
- return result;
1961
+ commitResult = await txn.commit();
1771
1962
  } catch (commitErr) {
1772
1963
  if (commitErr instanceof TransactionAlreadyAbortedError) return;
1773
- if (commitErr instanceof TransactionIsBusyError && (options?.retryOnBusy ?? commitErr.hasLog) && attempt <= maxRetries) continue;
1964
+ if (commitErr instanceof TransactionIsBusyError && (options?.retryOnBusy ?? commitErr.hasLog) && attempt < maxRetries) continue;
1774
1965
  this.#abandonTransaction(txn, commitErr);
1966
+ return;
1967
+ }
1968
+ if (commitResult !== RETRY_NOW) return result;
1969
+ if (attempt >= maxRetries) {
1970
+ this.#abandonTransaction(txn, /* @__PURE__ */ new Error(`Transaction did not commit after ${maxRetries} coordinated retries`));
1971
+ return;
1775
1972
  }
1776
1973
  }
1777
1974
  }
@@ -2084,7 +2281,7 @@ Object.defineProperty(TransactionLog.prototype, "query", { value({ start, end, e
2084
2281
  done: true,
2085
2282
  value: void 0
2086
2283
  };
2087
- const limit = readUncommitted ? logBuffer.length : size;
2284
+ const limit = readUncommitted ? logBuffer.length : Math.min(size, logBuffer.length);
2088
2285
  if (position + TRANSACTION_LOG_ENTRY_HEADER_SIZE > limit) throw new RangeError(`Corrupt transaction log: truncated entry header at position ${position.toString(16)} of log ${logBuffer.logId} (available=${limit - position})`);
2089
2286
  const length = dataView.getUint32(position + 8);
2090
2287
  if (position + TRANSACTION_LOG_ENTRY_HEADER_SIZE + length > limit) throw new RangeError(`Corrupt transaction log entry at position ${position.toString(16)} of log ${logBuffer.logId}: declared length ${length} overruns the log (limit=${limit})`);
@@ -2178,7 +2375,7 @@ function loadLastPosition(transactionLog, readUncommitted) {
2178
2375
  //#region src/index.ts
2179
2376
  const versions = {
2180
2377
  rocksdb: version,
2181
- "rocksdb-js": "2.1.0"
2378
+ "rocksdb-js": "2.2.0"
2182
2379
  };
2183
2380
 
2184
2381
  //#endregion
@@ -2188,7 +2385,9 @@ exports.RocksDatabase = RocksDatabase;
2188
2385
  exports.Store = Store;
2189
2386
  exports.Transaction = Transaction;
2190
2387
  exports.TransactionLog = TransactionLog;
2388
+ exports.backups = backups;
2191
2389
  exports.constants = constants;
2390
+ exports.coolTransactionLogs = coolTransactionLogs;
2192
2391
  exports.currentThreadId = currentThreadId;
2193
2392
  exports.parseTransactionLog = parseTransactionLog;
2194
2393
  exports.registryStatus = registryStatus;