@harperfast/rocksdb-js 1.0.1 → 1.1.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
@@ -54,6 +54,9 @@ Creates a new database instance.
54
54
  Defaults to `1`.
55
55
  - `pessimistic: boolean` When `true`, throws conflict errors when they occur instead of waiting
56
56
  until commit. Defaults to `false`.
57
+ - `readOnly: boolean` When `true`, the database is opened in read-only mode. Read operations are
58
+ permitted. Write operations will throw an error with code `ERR_DATABASE_READONLY`. Transactions
59
+ are a no-op in read-only mode.
57
60
  - `statsLevel: StatsLevel` Controls which type of statistics to skip and reduce statistic
58
61
  overhead. Defaults to `StatsLevel.ExceptDetailedTimers`.
59
62
  - `store: Store` A custom store that handles all interaction between the `RocksDatabase` or
@@ -441,6 +444,24 @@ db.transactionSync((txn: Transaction) => {
441
444
  });
442
445
  ```
443
446
 
447
+ ### Optimistic and Pessimistic Modes
448
+
449
+ `rocksdb-js` supports two different transaction modes: optimistic and pessimistic. The default mode
450
+ is optimistic.
451
+
452
+ - Optimistic: Conflicts detected at commit time.
453
+ - Pessimistic: Conflicts throw immediately on detection.
454
+
455
+ When a database is opened in optimistic mode, transactions are not locked and can be retried if
456
+ they fail with a conflict. When a database is opened in pessimistic mode, transactions are aborted
457
+ and cannot be retried if they fail with a conflict.
458
+
459
+ Optimistic mode is the default mode and is recommended for most use cases. Pessimistic mode is
460
+ recommended for use cases where you need to know immediately if a conflict occurs.
461
+
462
+ If a database is opened in one mode, it cannot be opened in a different mode. An error will be
463
+ thrown when trying to open it in a different mode without closing the database first.
464
+
444
465
  ### `TransactionCallback<T>`
445
466
 
446
467
  `(txn: Transaction, attempt: number) => T | PromiseLike<T>`
@@ -486,7 +507,7 @@ operations methods as the `RocksDatabase` instance plus:
486
507
  - `txn.commitSync()` Synchronously commits and closes the transaction.
487
508
  - `txn.getTimestamp(): number` Retrieves the transaction start timestamp in seconds as a decimal. It
488
509
  defaults to the time at which the transaction was created.
489
- - `txn.id: number` The readonly transaction ID. Transaction IDs are unique to the RocksDB database
510
+ - `txn.id: number` The read-only transaction ID. Transaction IDs are unique to the RocksDB database
490
511
  path, regardless the database name/column family.
491
512
  - `txn.setTimestamp(ts?: number): void` Overrides the transaction start timestamp. If called without
492
513
  a timestamp, it will set the timestamp to the current time. The value must be in seconds with
@@ -662,18 +683,20 @@ const db = RocksDatabase.open('/path/to/db', {
662
683
  console.log(db.getStats());
663
684
  ```
664
685
 
665
- ### `db.getStat(statName: string): number`
686
+ ### `db.getStat(statName: string): RocksDBStat`
666
687
 
667
- Retrieves a single statistic value.
688
+ Retrieves a single statistic value. Return value is either a `number` or `StatsHistogramData`
689
+ object.
668
690
 
669
691
  ```typescript
670
692
  console.log(db.getStat('rocksdb.block.cache.miss'));
671
693
  ```
672
694
 
673
- ### `db.getStats(all?: boolean): Object<string, number | StatsHistogramData>`
695
+ ### `db.getStats(all?: boolean): RocksDBStats`
674
696
 
675
697
  Returns an object containing a curated list of column family-level properties, internal tickers
676
- stats, and internal histogram stats.
698
+ stats, and internal histogram stats. Return value is an object with the stat name as the key and
699
+ a `RocksDBStat` as the value.
677
700
 
678
701
  By default, it only returns the most meaningful internal stats. When `all = true`, it returns the
679
702
  same column family-level properties, but includes all internal tickers and histogram stats.
@@ -723,6 +746,14 @@ The `stats.StatsLevel` contains constants used to set which types of skip and re
723
746
  - `StatsLevel.ExceptTimeForMutex` Skip time waiting for mutex locks.
724
747
  - `StatsLevel.All` Collects all stats.
725
748
 
749
+ ### `type RocksDBStat = number | StatsHistogramData`
750
+
751
+ A `RocksDBStat` is either a `number` or `StatsHistogramData` object.
752
+
753
+ ### `type RocksDBStats = Record<string, RocksDBStat>`
754
+
755
+ A `RocksDBStats` is an object with the stat name as the key and a `RocksDBStat` as the value.
756
+
726
757
  ### `type StatsHistogramData`
727
758
 
728
759
  An object is a record with the following properties:
package/dist/index.cjs CHANGED
@@ -654,6 +654,11 @@ var Store = class {
654
654
  */
655
655
  pessimistic;
656
656
  /**
657
+ * Whether the database is open in readonly mode. When `true`, write
658
+ * operations will throw an error with code `ERR_DATABASE_READONLY`.
659
+ */
660
+ readOnly;
661
+ /**
657
662
  * Encoder specific flag used to signal that the encoder should use a random
658
663
  * access structure.
659
664
  */
@@ -722,6 +727,7 @@ var Store = class {
722
727
  this.parallelismThreads = options?.parallelismThreads ?? 1;
723
728
  this.path = path;
724
729
  this.pessimistic = options?.pessimistic ?? false;
730
+ this.readOnly = options?.readOnly ?? false;
725
731
  this.randomAccessStructure = options?.randomAccessStructure ?? false;
726
732
  this.readKey = readKey;
727
733
  this.sharedStructuresKey = options?.sharedStructuresKey;
@@ -792,6 +798,7 @@ var Store = class {
792
798
  const keyParam = getKeyParam(this.encodeKey(key));
793
799
  let flags = 0;
794
800
  if (alwaysCreateNewBuffer) flags |= ALWAYS_CREATE_NEW_BUFFER_FLAG;
801
+ if (this.readOnly) txnId = void 0;
795
802
  const result = context.getSync(keyParam, flags | ONLY_IF_IN_MEMORY_CACHE_FLAG, txnId);
796
803
  if (typeof result === "number") {
797
804
  if (result === NOT_IN_MEMORY_CACHE_FLAG) return new Promise((resolve, reject) => {
@@ -864,7 +871,7 @@ var Store = class {
864
871
  */
865
872
  getTxnId(options) {
866
873
  let txnId;
867
- if (options?.transaction) {
874
+ if (!this.readOnly && options?.transaction) {
868
875
  txnId = options.transaction.id;
869
876
  if (txnId === void 0) throw new TypeError("Invalid transaction");
870
877
  }
@@ -932,6 +939,7 @@ var Store = class {
932
939
  name: this.name,
933
940
  noBlockCache: this.noBlockCache,
934
941
  parallelismThreads: this.parallelismThreads,
942
+ readOnly: this.readOnly,
935
943
  statsLevel: this.statsLevel,
936
944
  transactionLogMaxAgeThreshold: this.transactionLogMaxAgeThreshold,
937
945
  transactionLogMaxSize: this.transactionLogMaxSize,
@@ -1047,9 +1055,17 @@ var Transaction = class extends DBI {
1047
1055
  * @param options - The options for the transaction.
1048
1056
  */
1049
1057
  constructor(store, options) {
1050
- const txn = new NativeTransaction(store.db, options);
1051
- super(store, txn);
1052
- this.#txn = txn;
1058
+ if (store.readOnly) {
1059
+ super(store);
1060
+ this.#txn = { id: 0 };
1061
+ this.abort = this.commitSync = this.setTimestamp = () => {};
1062
+ this.commit = async () => {};
1063
+ this.getTimestamp = () => 0;
1064
+ } else {
1065
+ const txn = new NativeTransaction(store.db, options);
1066
+ super(store, txn);
1067
+ this.#txn = txn;
1068
+ }
1053
1069
  }
1054
1070
  /**
1055
1071
  * Abort the transaction.
@@ -1379,6 +1395,12 @@ var RocksDatabase = class RocksDatabase extends DBI {
1379
1395
  return this.#name;
1380
1396
  }
1381
1397
  /**
1398
+ * Whether the database is open in readonly mode.
1399
+ */
1400
+ get readOnly() {
1401
+ return this.store.readOnly;
1402
+ }
1403
+ /**
1382
1404
  * Sugar method for opening a database.
1383
1405
  *
1384
1406
  * @param pathOrStore - The filesystem path to the database or a custom store.
@@ -1909,7 +1931,7 @@ function loadLastPosition(transactionLog, readUncommitted) {
1909
1931
  //#region src/index.ts
1910
1932
  const versions = {
1911
1933
  rocksdb: version,
1912
- "rocksdb-js": "1.0.1"
1934
+ "rocksdb-js": "1.1.0"
1913
1935
  };
1914
1936
 
1915
1937
  //#endregion