@harperfast/rocksdb-js 2.6.1 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -128,7 +128,9 @@ when a non-default compression level is set. The database must be open. See
128
128
  [Compression](#compression).
129
129
 
130
130
  ```typescript
131
- const db = RocksDatabase.open('path/to/db', { compression: { algorithm: 'zstd', level: 3 } });
131
+ const db = RocksDatabase.open('path/to/db', {
132
+ compression: { algorithm: 'zstd', level: 3 },
133
+ });
132
134
  console.log(db.compression); // { algorithm: 'zstd', level: 3 }
133
135
  ```
134
136
 
@@ -260,11 +262,20 @@ per database path can be performed at a time.
260
262
  - `options: object`
261
263
  - `start?: Key` The start key of the range to compact.
262
264
  - `end?: Key` The end key of the range to compact.
265
+ - `bottommost?: boolean` Also compact the bottommost level, rewriting every file in range.
266
+ RocksDB skips that level by default when no compaction filter is installed, and it holds most
267
+ of the data — so an ordinary compaction leaves it untouched. Because a changed
268
+ [`compression`](#compression) algorithm governs only newly written files, this is the way to
269
+ re-encode data that already exists. It rewrites the whole range regardless of whether RocksDB
270
+ considers it worthwhile, so it costs as much as the data is large. Defaults to `false`.
263
271
 
264
272
  ```typescript
265
273
  await db.compact();
266
274
 
267
275
  await db.compact({ start: 'a', end: 'z' });
276
+
277
+ // Re-encode everything already on disk under the column family's current codec
278
+ await db.compact({ bottommost: true });
268
279
  ```
269
280
 
270
281
  ### `db.compactSync(options?): void`
@@ -275,6 +286,8 @@ Synchronous version of `compact()`.
275
286
  db.compactSync();
276
287
 
277
288
  db.compactSync({ start: 'a', end: 'z' });
289
+
290
+ db.compactSync({ bottommost: true });
278
291
  ```
279
292
 
280
293
  ### `db.destroy(): void`
@@ -660,6 +673,9 @@ an `ERR_TRANSACTION_ABANDONED` error. Coordinated retry requires the column fami
660
673
  The transaction callback is passed in a `Transaction` instance which contains all of the same data
661
674
  operations methods as the `RocksDatabase` instance plus:
662
675
 
676
+ - `txn.abandonWrites(): void` Releases the staged writes' verification-table write intents without
677
+ closing the transaction, and bars any further writes or commit. Reads (including read-your-own-writes)
678
+ keep working until the transaction is aborted.
663
679
  - `txn.abort()` Rolls back and closes the transaction. This method is automatically called after the
664
680
  transaction callback returns, so you shouldn't need to call it, but it's ok to do so. Once called,
665
681
  no further transaction operations are permitted. Calling this method multiple times has no effect.
@@ -673,6 +689,22 @@ operations methods as the `RocksDatabase` instance plus:
673
689
  a timestamp, it will set the timestamp to the current time. The value must be in seconds with
674
690
  higher precision in the decimal.
675
691
 
692
+ #### `txn.abandonWrites(): void`
693
+
694
+ Releases the staged writes' verification-table (VT) write intents without closing the transaction,
695
+ and bars any further writes or commit (`commit()`/`commitSync()`/`put()`/`remove()`, including
696
+ database-context writes via `{ transaction: txn }`, all reject once called). Reads — including
697
+ read-your-own-writes — keep working until the transaction is aborted. Idempotent, and a no-op after
698
+ `abort()`.
699
+
700
+ Scope is VT intents only: RocksDB's own transaction locks (pessimistic mode) are still held until
701
+ the transaction is aborted.
702
+
703
+ This is for a transaction kept open only for its outstanding read iterators after its writes were
704
+ already committed elsewhere (e.g. replayed onto another transaction) — it lets the intents release
705
+ early so other writers' coordinated-retry commits stop parking on them, instead of waiting for the
706
+ handle's eventual `abort()`.
707
+
676
708
  #### `txn.abort(): void`
677
709
 
678
710
  Rolls back and closes the transaction. This method is automatically called after the transaction
@@ -960,7 +992,9 @@ Set the algorithm per column family with the `compression` option when opening a
960
992
  const db = RocksDatabase.open('/path/to/db', { compression: 'zstd' });
961
993
 
962
994
  // Or an object with an explicit level
963
- const db2 = RocksDatabase.open('/path/to/db2', { compression: { algorithm: 'zstd', level: 3 } });
995
+ const db2 = RocksDatabase.open('/path/to/db2', {
996
+ compression: { algorithm: 'zstd', level: 3 },
997
+ });
964
998
 
965
999
  // Disable compression entirely
966
1000
  const db3 = RocksDatabase.open('/path/to/db3', { compression: 'none' });
@@ -977,6 +1011,37 @@ was compiled against, so it varies by build. Always check
977
1011
  [`supportedCompression`](#supportedcompression) at runtime — opening with an unavailable algorithm
978
1012
  throws. `'none'` is always available.
979
1013
 
1014
+ **Changing the codec of data already written.** Setting `compression` affects files written from
1015
+ that point on. Existing SST and blob files keep the codec they were written with until something
1016
+ rewrites them. An ordinary `compact()` can re-encode non-bottommost levels, but RocksDB leaves the
1017
+ bottommost level alone unless a compaction filter is installed — and that is where most of the data
1018
+ sits, so a plain compaction will not rewrite all existing data. Use
1019
+ [`compact({ bottommost: true })`](#dbcompactoptions-promisevoid) to force the rewrite, once per
1020
+ column family you want migrated. Note also that omitting `compression` on a column family that
1021
+ already exists **inherits** its current codec rather than applying the default — the default
1022
+ applies only when the family is created.
1023
+
1024
+ **Adopting a codec across a whole database.** Compression is chosen per column family, and RocksDB
1025
+ opens every family of a database in one call — so by default the families you did not name keep
1026
+ their persisted algorithm. If your first open targets some other family (a catalog, say), the rest
1027
+ are already open at their old algorithm before you can ask for a new one, and a family's compression
1028
+ cannot be changed while it is open. Pass `compressionForAllColumnFamilies: true` to apply the
1029
+ requested algorithm to all of them instead:
1030
+
1031
+ ```typescript
1032
+ // Every column family in this database adopts lz4, not just 'catalog'
1033
+ const db = RocksDatabase.open('/path/to/db', {
1034
+ name: 'catalog',
1035
+ compression: 'lz4',
1036
+ compressionForAllColumnFamilies: true,
1037
+ });
1038
+ ```
1039
+
1040
+ It requires an explicit `compression`, and only takes effect on the open that creates the database
1041
+ handle — later opens of the same path reuse that handle. As always the algorithm governs newly
1042
+ written files; use [`compact({ bottommost: true })`](#dbcompactoptions-promisevoid) to rewrite what
1043
+ is already there.
1044
+
980
1045
  **Scope and mutability.** Compression is genuinely **per-column-family**. Each `RocksDatabase`
981
1046
  targets one column family (`name`), and its `compression` applies only to that CF — opening one CF
982
1047
  never changes another's algorithm, regardless of open order. A column family keeps its own
@@ -1661,7 +1726,9 @@ live database directory would write backup files on top of RocksDB's own files.
1661
1726
  before anything is written.
1662
1727
 
1663
1728
  ```typescript
1664
- const id = await db.backup('/path/to/backups', { metadata: 'nightly-2026-06-04' });
1729
+ const id = await db.backup('/path/to/backups', {
1730
+ metadata: 'nightly-2026-06-04',
1731
+ });
1665
1732
  ```
1666
1733
 
1667
1734
  `BackupOptions`:
@@ -1711,7 +1778,9 @@ await db.backup(Writable.toWeb(createWriteStream('/path/to/backup.tar')));
1711
1778
  // Restore: `tar -xf backup.tar -C /restored`, then open '/restored'.
1712
1779
 
1713
1780
  // Or gzip it (`tar -xzf backup.tar.gz` to restore):
1714
- await db.backup(Writable.toWeb(createWriteStream('/path/to/backup.tar.gz')), { gzip: true });
1781
+ await db.backup(Writable.toWeb(createWriteStream('/path/to/backup.tar.gz')), {
1782
+ gzip: true,
1783
+ });
1715
1784
  ```
1716
1785
 
1717
1786
  `BackupStreamOptions`:
package/dist/index.cjs CHANGED
@@ -1305,6 +1305,11 @@ var Store = class {
1305
1305
  */
1306
1306
  compression;
1307
1307
  /**
1308
+ * Whether `compression` applies to every column family in the database rather than just this
1309
+ * store's. See `RocksDatabaseOptions.compressionForAllColumnFamilies`.
1310
+ */
1311
+ compressionForAllColumnFamilies = false;
1312
+ /**
1308
1313
  * Whether to disable the write ahead log.
1309
1314
  */
1310
1315
  disableWAL;
@@ -1463,6 +1468,7 @@ var Store = class {
1463
1468
  const { keyEncoding, readKey, writeKey } = initKeyEncoder(options?.keyEncoding, options?.keyEncoder);
1464
1469
  this.db = new NativeDatabase();
1465
1470
  this.compression = options?.compression;
1471
+ this.compressionForAllColumnFamilies = options?.compressionForAllColumnFamilies === true;
1466
1472
  this.dbWriteBufferSize = options?.dbWriteBufferSize;
1467
1473
  this.decoder = options?.decoder ?? null;
1468
1474
  this.disableWAL = options?.disableWAL ?? false;
@@ -1532,7 +1538,7 @@ var Store = class {
1532
1538
  const end = this.encodeKey(options.end);
1533
1539
  endBuffer = Buffer.from(end.subarray(end.start, end.end));
1534
1540
  }
1535
- return new Promise((resolve, reject) => this.db.compact(resolve, reject, startBuffer, endBuffer));
1541
+ return new Promise((resolve, reject) => this.db.compact(resolve, reject, startBuffer, endBuffer, options?.bottommost === true));
1536
1542
  }
1537
1543
  async backup(target, options) {
1538
1544
  if (typeof target !== "string" && typeof target?.getWriter === "function") return backupToStream(this.db, target, options);
@@ -1560,7 +1566,7 @@ var Store = class {
1560
1566
  const end = this.encodeKey(options.end);
1561
1567
  endBuffer = Buffer.from(end.subarray(end.start, end.end));
1562
1568
  }
1563
- this.db.compactSync(startBuffer, endBuffer);
1569
+ this.db.compactSync(startBuffer, endBuffer, options?.bottommost === true);
1564
1570
  }
1565
1571
  /**
1566
1572
  * Decodes a key from the database.
@@ -1777,6 +1783,7 @@ var Store = class {
1777
1783
  this.db.open(this.path, {
1778
1784
  compression,
1779
1785
  compressionLevel,
1786
+ compressionForAllColumnFamilies: this.compressionForAllColumnFamilies,
1780
1787
  dbWriteBufferSize: this.dbWriteBufferSize,
1781
1788
  disableWAL: this.disableWAL,
1782
1789
  enableStats: this.enableStats,
@@ -1959,7 +1966,7 @@ var Transaction = class extends DBI {
1959
1966
  if (store.readOnly) {
1960
1967
  super(store);
1961
1968
  this.#txn = { id: 0 };
1962
- this.abort = this.commitSync = this.setTimestamp = () => {};
1969
+ this.abandonWrites = this.abort = this.commitSync = this.setTimestamp = () => {};
1963
1970
  this.commit = async () => {};
1964
1971
  this.getTimestamp = () => 0;
1965
1972
  } else {
@@ -1969,6 +1976,17 @@ var Transaction = class extends DBI {
1969
1976
  }
1970
1977
  }
1971
1978
  /**
1979
+ * Release the staged writes' verification-table write intents without
1980
+ * closing the transaction, barring any later commit or write. For a
1981
+ * transaction kept open only for its outstanding read iterators after the
1982
+ * writes were replayed onto another transaction: otherwise other writers'
1983
+ * coordinated-retry commits park on those intents until it is aborted.
1984
+ * Reads keep working, including read-your-own-writes.
1985
+ */
1986
+ abandonWrites() {
1987
+ this.#txn.abandonWrites();
1988
+ }
1989
+ /**
1972
1990
  * Abort the transaction.
1973
1991
  */
1974
1992
  abort() {
@@ -3042,7 +3060,7 @@ function loadLastPosition(transactionLog, readUncommitted) {
3042
3060
  //#region src/index.ts
3043
3061
  const versions = {
3044
3062
  rocksdb: version,
3045
- "rocksdb-js": "2.6.1"
3063
+ "rocksdb-js": "2.7.0"
3046
3064
  };
3047
3065
 
3048
3066
  //#endregion