@harperfast/rocksdb-js 2.9.1 → 2.10.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.d.cts CHANGED
@@ -1378,6 +1378,7 @@ type StatsBasics = {
1378
1378
  "txnlog.replayGapBytes": number;
1379
1379
  "commitPipeline.logQueueDepth": number;
1380
1380
  "commitPipeline.commitQueueDepth": number;
1381
+ "columnFamily.pendingReclaims": number;
1381
1382
  "writeBufferManager.bufferSize": number;
1382
1383
  "writeBufferManager.memoryUsage": number;
1383
1384
  "writeBufferManager.mutableMemoryUsage": number;
@@ -2220,7 +2221,7 @@ type NativeDatabase = {
2220
2221
  compactSync(start?: Key, end?: Key, bottommost?: boolean): void;
2221
2222
  columns: string[];
2222
2223
  createCheckpoint(resolve: ResolveCallback<void>, reject: RejectCallback, targetPath: string): void;
2223
- destroy(): void;
2224
+ destroy(readOnly?: boolean): void;
2224
2225
  drop(resolve: ResolveCallback<void>, reject: RejectCallback): void;
2225
2226
  dropSync(): void;
2226
2227
  flush(resolve: ResolveCallback<void>, reject: RejectCallback, options?: FlushOptions): void;
@@ -2255,6 +2256,7 @@ type NativeDatabase = {
2255
2256
  identityPath: string | undefined;
2256
2257
  listeners(event: string | BufferWithDataView): number;
2257
2258
  listLogs(): string[];
2259
+ closing: boolean;
2258
2260
  opened: boolean;
2259
2261
  open(path: string, options?: NativeDatabaseOptions): void;
2260
2262
  populateVersion(keyLengthOrKeyBuffer: number | Buffer, version: number): void;
@@ -2289,6 +2291,11 @@ type RocksDatabaseConfig = {
2289
2291
  */
2290
2292
  verificationTableEntries?: number;
2291
2293
  compactOnClose?: boolean;
2294
+ /**
2295
+ * Maximum seconds an open, destroy, or shutdown call waits for another
2296
+ * lifecycle operation. Defaults to 30.
2297
+ */
2298
+ lifecycleWaitSeconds?: number;
2292
2299
  /**
2293
2300
  * Total memtable memory limit (bytes) shared across every database opened
2294
2301
  * in this process. When set, RocksDB uses a single `WriteBufferManager` so
@@ -2332,6 +2339,10 @@ type RegistryStatusTransaction = {
2332
2339
  };
2333
2340
  type RegistryStatusDB = {
2334
2341
  path: string;
2342
+ closeError?: string;
2343
+ /** A prior close failed and `shutdown()`/`destroy()` is currently retrying it. */
2344
+ closeRetrying?: boolean;
2345
+ destroyCleanupPending?: boolean;
2335
2346
  refCount: number;
2336
2347
  columnFamilies: string[];
2337
2348
  transactions: number;
@@ -2486,8 +2497,48 @@ declare const NativeDatabase: NativeDatabase;
2486
2497
  declare const NativeTransaction: NativeTransaction;
2487
2498
  export declare const TransactionLog: TransactionLog;
2488
2499
  export declare const registryStatus: () => RegistryStatus;
2500
+ /**
2501
+ * Flushes every open database and waits for outstanding compactions, then
2502
+ * releases the registry.
2503
+ *
2504
+ * **Throws** the first failure it encounters: a close whose native teardown
2505
+ * failed (that descriptor stays quarantined — call `shutdown()` again to retry
2506
+ * it), or a `lifecycleWaitSeconds` timeout waiting on a concurrent
2507
+ * open/destroy/shutdown. A quarantining close also emits
2508
+ * `database:closeFailed`; a timeout has no event, so the throw is its only
2509
+ * signal.
2510
+ *
2511
+ * A `process.on('exit')` listener must therefore wrap it: an exception thrown
2512
+ * from an `exit` listener skips every `exit` listener registered after it (and
2513
+ * sets exit code 1 unless an `uncaughtException` handler is installed).
2514
+ *
2515
+ * ```typescript
2516
+ * process.on('exit', () => {
2517
+ * try {
2518
+ * shutdown();
2519
+ * } catch (error) {
2520
+ * console.error('rocksdb-js shutdown failed', error);
2521
+ * }
2522
+ * });
2523
+ * ```
2524
+ */
2489
2525
  export declare const shutdown: () => void;
2490
2526
  export declare const currentThreadId: () => number;
2527
+ /**
2528
+ * Reads the process-wide steady clock: `std::chrono::steady_clock` as
2529
+ * fractional milliseconds from an unspecified origin that is fixed for the life
2530
+ * of the process. Every sample in the process — main thread and every
2531
+ * `worker_threads` worker, whenever started or restarted, on Node, Bun and Deno
2532
+ * — is in one domain, and the difference between two samples is real elapsed
2533
+ * time unaffected by wall-clock steps. Non-decreasing but not unique (two
2534
+ * samples may be equal; treat `==` as "not later"). Windows QPC samples from
2535
+ * different threads within one native tick also have ambiguous ordering.
2536
+ * Clock readings alone do not prove causality. Not comparable with
2537
+ * `Date.now()`, `db.getMonotonicTimestamp()` or transaction timestamps, and not
2538
+ * meaningful across processes or restarts. Time spent in host suspend is
2539
+ * platform-defined. No open database is needed.
2540
+ */
2541
+ export declare const steadyClockNow: () => number;
2491
2542
  /**
2492
2543
  * Advises the kernel that the file-backed pages of every mapped transaction log
2493
2544
  * are cold (Linux MADV_COLD), so they are reclaimed first under memory pressure
@@ -2825,7 +2876,10 @@ export declare class RocksDatabase extends DBI<DBITransactional> {
2825
2876
  * native binding use namespaced keys (e.g. `'transactionLog:warning'`).
2826
2877
  *
2827
2878
  * Listeners are not tied to any specific database — they fire for every
2828
- * matching event emitted in this process.
2879
+ * matching event emitted in this process. Native lifecycle failures use
2880
+ * `'database:closeFailed'` with `(path, error)` string arguments. The event
2881
+ * reports both completed and incomplete teardowns; an incomplete close can
2882
+ * be retried by `shutdown()` or explicitly deleted by `destroy()`.
2829
2883
  *
2830
2884
  * @example
2831
2885
  * ```typescript
package/dist/index.d.mts CHANGED
@@ -1378,6 +1378,7 @@ type StatsBasics = {
1378
1378
  "txnlog.replayGapBytes": number;
1379
1379
  "commitPipeline.logQueueDepth": number;
1380
1380
  "commitPipeline.commitQueueDepth": number;
1381
+ "columnFamily.pendingReclaims": number;
1381
1382
  "writeBufferManager.bufferSize": number;
1382
1383
  "writeBufferManager.memoryUsage": number;
1383
1384
  "writeBufferManager.mutableMemoryUsage": number;
@@ -2220,7 +2221,7 @@ type NativeDatabase = {
2220
2221
  compactSync(start?: Key, end?: Key, bottommost?: boolean): void;
2221
2222
  columns: string[];
2222
2223
  createCheckpoint(resolve: ResolveCallback<void>, reject: RejectCallback, targetPath: string): void;
2223
- destroy(): void;
2224
+ destroy(readOnly?: boolean): void;
2224
2225
  drop(resolve: ResolveCallback<void>, reject: RejectCallback): void;
2225
2226
  dropSync(): void;
2226
2227
  flush(resolve: ResolveCallback<void>, reject: RejectCallback, options?: FlushOptions): void;
@@ -2255,6 +2256,7 @@ type NativeDatabase = {
2255
2256
  identityPath: string | undefined;
2256
2257
  listeners(event: string | BufferWithDataView): number;
2257
2258
  listLogs(): string[];
2259
+ closing: boolean;
2258
2260
  opened: boolean;
2259
2261
  open(path: string, options?: NativeDatabaseOptions): void;
2260
2262
  populateVersion(keyLengthOrKeyBuffer: number | Buffer, version: number): void;
@@ -2289,6 +2291,11 @@ type RocksDatabaseConfig = {
2289
2291
  */
2290
2292
  verificationTableEntries?: number;
2291
2293
  compactOnClose?: boolean;
2294
+ /**
2295
+ * Maximum seconds an open, destroy, or shutdown call waits for another
2296
+ * lifecycle operation. Defaults to 30.
2297
+ */
2298
+ lifecycleWaitSeconds?: number;
2292
2299
  /**
2293
2300
  * Total memtable memory limit (bytes) shared across every database opened
2294
2301
  * in this process. When set, RocksDB uses a single `WriteBufferManager` so
@@ -2332,6 +2339,10 @@ type RegistryStatusTransaction = {
2332
2339
  };
2333
2340
  type RegistryStatusDB = {
2334
2341
  path: string;
2342
+ closeError?: string;
2343
+ /** A prior close failed and `shutdown()`/`destroy()` is currently retrying it. */
2344
+ closeRetrying?: boolean;
2345
+ destroyCleanupPending?: boolean;
2335
2346
  refCount: number;
2336
2347
  columnFamilies: string[];
2337
2348
  transactions: number;
@@ -2486,8 +2497,48 @@ declare const NativeDatabase: NativeDatabase;
2486
2497
  declare const NativeTransaction: NativeTransaction;
2487
2498
  export declare const TransactionLog: TransactionLog;
2488
2499
  export declare const registryStatus: () => RegistryStatus;
2500
+ /**
2501
+ * Flushes every open database and waits for outstanding compactions, then
2502
+ * releases the registry.
2503
+ *
2504
+ * **Throws** the first failure it encounters: a close whose native teardown
2505
+ * failed (that descriptor stays quarantined — call `shutdown()` again to retry
2506
+ * it), or a `lifecycleWaitSeconds` timeout waiting on a concurrent
2507
+ * open/destroy/shutdown. A quarantining close also emits
2508
+ * `database:closeFailed`; a timeout has no event, so the throw is its only
2509
+ * signal.
2510
+ *
2511
+ * A `process.on('exit')` listener must therefore wrap it: an exception thrown
2512
+ * from an `exit` listener skips every `exit` listener registered after it (and
2513
+ * sets exit code 1 unless an `uncaughtException` handler is installed).
2514
+ *
2515
+ * ```typescript
2516
+ * process.on('exit', () => {
2517
+ * try {
2518
+ * shutdown();
2519
+ * } catch (error) {
2520
+ * console.error('rocksdb-js shutdown failed', error);
2521
+ * }
2522
+ * });
2523
+ * ```
2524
+ */
2489
2525
  export declare const shutdown: () => void;
2490
2526
  export declare const currentThreadId: () => number;
2527
+ /**
2528
+ * Reads the process-wide steady clock: `std::chrono::steady_clock` as
2529
+ * fractional milliseconds from an unspecified origin that is fixed for the life
2530
+ * of the process. Every sample in the process — main thread and every
2531
+ * `worker_threads` worker, whenever started or restarted, on Node, Bun and Deno
2532
+ * — is in one domain, and the difference between two samples is real elapsed
2533
+ * time unaffected by wall-clock steps. Non-decreasing but not unique (two
2534
+ * samples may be equal; treat `==` as "not later"). Windows QPC samples from
2535
+ * different threads within one native tick also have ambiguous ordering.
2536
+ * Clock readings alone do not prove causality. Not comparable with
2537
+ * `Date.now()`, `db.getMonotonicTimestamp()` or transaction timestamps, and not
2538
+ * meaningful across processes or restarts. Time spent in host suspend is
2539
+ * platform-defined. No open database is needed.
2540
+ */
2541
+ export declare const steadyClockNow: () => number;
2491
2542
  /**
2492
2543
  * Advises the kernel that the file-backed pages of every mapped transaction log
2493
2544
  * are cold (Linux MADV_COLD), so they are reclaimed first under memory pressure
@@ -2825,7 +2876,10 @@ export declare class RocksDatabase extends DBI<DBITransactional> {
2825
2876
  * native binding use namespaced keys (e.g. `'transactionLog:warning'`).
2826
2877
  *
2827
2878
  * Listeners are not tied to any specific database — they fire for every
2828
- * matching event emitted in this process.
2879
+ * matching event emitted in this process. Native lifecycle failures use
2880
+ * `'database:closeFailed'` with `(path, error)` string arguments. The event
2881
+ * reports both completed and incomplete teardowns; an incomplete close can
2882
+ * be retried by `shutdown()` or explicitly deleted by `destroy()`.
2829
2883
  *
2830
2884
  * @example
2831
2885
  * ```typescript
package/dist/index.mjs CHANGED
@@ -106,9 +106,49 @@ const NativeIterator = binding.Iterator;
106
106
  const NativeTransaction = binding.Transaction;
107
107
  const TransactionLog = binding.TransactionLog;
108
108
  const registryStatus = binding.registryStatus;
109
+ /**
110
+ * Flushes every open database and waits for outstanding compactions, then
111
+ * releases the registry.
112
+ *
113
+ * **Throws** the first failure it encounters: a close whose native teardown
114
+ * failed (that descriptor stays quarantined — call `shutdown()` again to retry
115
+ * it), or a `lifecycleWaitSeconds` timeout waiting on a concurrent
116
+ * open/destroy/shutdown. A quarantining close also emits
117
+ * `database:closeFailed`; a timeout has no event, so the throw is its only
118
+ * signal.
119
+ *
120
+ * A `process.on('exit')` listener must therefore wrap it: an exception thrown
121
+ * from an `exit` listener skips every `exit` listener registered after it (and
122
+ * sets exit code 1 unless an `uncaughtException` handler is installed).
123
+ *
124
+ * ```typescript
125
+ * process.on('exit', () => {
126
+ * try {
127
+ * shutdown();
128
+ * } catch (error) {
129
+ * console.error('rocksdb-js shutdown failed', error);
130
+ * }
131
+ * });
132
+ * ```
133
+ */
109
134
  const shutdown = binding.shutdown;
110
135
  const currentThreadId = binding.currentThreadId;
111
136
  /**
137
+ * Reads the process-wide steady clock: `std::chrono::steady_clock` as
138
+ * fractional milliseconds from an unspecified origin that is fixed for the life
139
+ * of the process. Every sample in the process — main thread and every
140
+ * `worker_threads` worker, whenever started or restarted, on Node, Bun and Deno
141
+ * — is in one domain, and the difference between two samples is real elapsed
142
+ * time unaffected by wall-clock steps. Non-decreasing but not unique (two
143
+ * samples may be equal; treat `==` as "not later"). Windows QPC samples from
144
+ * different threads within one native tick also have ambiguous ordering.
145
+ * Clock readings alone do not prove causality. Not comparable with
146
+ * `Date.now()`, `db.getMonotonicTimestamp()` or transaction timestamps, and not
147
+ * meaningful across processes or restarts. Time spent in host suspend is
148
+ * platform-defined. No open database is needed.
149
+ */
150
+ const steadyClockNow = binding.steadyClockNow;
151
+ /**
112
152
  * Advises the kernel that the file-backed pages of every mapped transaction log
113
153
  * are cold (Linux MADV_COLD), so they are reclaimed first under memory pressure
114
154
  * without being freed — useful during replication catch-up, where a full read of
@@ -134,6 +174,21 @@ const transactionLogMapCount = binding.transactionLogMapCount;
134
174
  * disarm. Used by the ERR_TRY_AGAIN retry regression test.
135
175
  */
136
176
  const forceTryAgainForTesting = binding.forceTryAgainForTesting;
177
+ /**
178
+ * Test-only seam: makes the physical column-family drop report failure.
179
+ * `0` = inert, `1` = fail without dropping (the retry performs the drop),
180
+ * `2` = drop for real and then report failure (the retry resolves as
181
+ * "already dropped"). Process-global, like `forceTryAgainForTesting`.
182
+ */
183
+ const forceDropFailureForTesting = binding.forceDropFailureForTesting;
184
+ /** Parks one selected transaction write after its retirement precheck. */
185
+ const setTransactionStagingDelayForTesting = binding.setTransactionStagingDelayForTesting;
186
+ /** Reports whether the selected transaction write is parked. */
187
+ const isTransactionStagingDelayedForTesting = binding.isTransactionStagingDelayedForTesting;
188
+ /** Reports whether a transaction is parked at the native commit seam. */
189
+ const isTransactionCommitExecuteDelayedForTesting = binding.isTransactionCommitExecuteDelayedForTesting;
190
+ const setTransactionCommitAdmissionDelayForTesting = binding.setTransactionCommitAdmissionDelayForTesting;
191
+ const isTransactionCommitAdmissionDelayedForTesting = binding.isTransactionCommitAdmissionDelayedForTesting;
137
192
  /** Delays one selected watchdog join in the concurrent-shutdown regression test. */
138
193
  const setWriteBufferManagerJoinDelayForTesting = binding.setWriteBufferManagerJoinDelayForTesting;
139
194
  /**
@@ -2094,12 +2149,12 @@ var Store = class {
2094
2149
  return false;
2095
2150
  }
2096
2151
  putSync(context, key, value, options) {
2097
- if (!this.db.opened) throw new Error("Database not open");
2152
+ if (!this.db.opened) throw new Error(this.db.closing ? "Database is closing" : "Database not open");
2098
2153
  const valueBuffer = this.encodeValue(value);
2099
2154
  context.putSync(this.encodeKey(key), valueBuffer, this.getTxnId(options));
2100
2155
  }
2101
2156
  removeSync(context, key, options) {
2102
- if (!this.db.opened) throw new Error("Database not open");
2157
+ if (!this.db.opened) throw new Error(this.db.closing ? "Database is closing" : "Database not open");
2103
2158
  context.removeSync(this.encodeKey(key), this.getTxnId(options));
2104
2159
  }
2105
2160
  /**
@@ -2603,7 +2658,10 @@ var RocksDatabase = class RocksDatabase extends DBI {
2603
2658
  * native binding use namespaced keys (e.g. `'transactionLog:warning'`).
2604
2659
  *
2605
2660
  * Listeners are not tied to any specific database — they fire for every
2606
- * matching event emitted in this process.
2661
+ * matching event emitted in this process. Native lifecycle failures use
2662
+ * `'database:closeFailed'` with `(path, error)` string arguments. The event
2663
+ * reports both completed and incomplete teardowns; an incomplete close can
2664
+ * be retried by `shutdown()` or explicitly deleted by `destroy()`.
2607
2665
  *
2608
2666
  * @example
2609
2667
  * ```typescript
@@ -2687,7 +2745,7 @@ var RocksDatabase = class RocksDatabase extends DBI {
2687
2745
  this.store.db.catchUpWithPrimarySync();
2688
2746
  }
2689
2747
  destroy() {
2690
- this.store.db.destroy();
2748
+ this.store.db.destroy(this.store.readOnly);
2691
2749
  }
2692
2750
  async drop() {
2693
2751
  return new Promise((resolve, reject) => {
@@ -3553,8 +3611,8 @@ function frameFits(dataView, pos, dataEnd) {
3553
3611
  * terminator, let a chain "end" anywhere in megabytes of padding. Against the written extent the
3554
3612
  * end is a single offset, so a chain landing on it is ~1/2^32 to be coincidence.
3555
3613
  *
3556
- * The JS counterpart of `validFramingResumes()` in `transaction_log_recovery.cpp`, which answers
3557
- * the same question at open time but keeps only the yes/no, discarding the offset.
3614
+ * The JS counterpart of `findFramingResumeOffset()` in `transaction_log_recovery.cpp`, which the
3615
+ * open-time scan and the timestamp index use to keep walking past the same break.
3558
3616
  */
3559
3617
  function findResyncPosition(dataView, from, dataEnd) {
3560
3618
  const lastStart = dataEnd - TRANSACTION_LOG_ENTRY_HEADER_SIZE;
@@ -3778,9 +3836,9 @@ function loadLastPosition(transactionLog, readUncommitted) {
3778
3836
  //#region src/index.ts
3779
3837
  const versions = {
3780
3838
  rocksdb: version,
3781
- "rocksdb-js": "2.9.1"
3839
+ "rocksdb-js": "2.10.0"
3782
3840
  };
3783
3841
 
3784
3842
  //#endregion
3785
- export { BackgroundError, CorruptFrameError, CountEstimator, DBI, DBIterator, RocksDatabase, Store, Transaction, TransactionLog, backups, constants, coolTransactionLogs, currentThreadId, fileLockRelease, getWriteBufferManagerStats, parseTransactionLog, registryStatus, shutdown, stats, supportedCompression, tryFileLock, validateTransactionLogStore, versions };
3843
+ export { BackgroundError, CorruptFrameError, CountEstimator, DBI, DBIterator, RocksDatabase, Store, Transaction, TransactionLog, backups, constants, coolTransactionLogs, currentThreadId, fileLockRelease, getWriteBufferManagerStats, parseTransactionLog, registryStatus, shutdown, stats, steadyClockNow, supportedCompression, tryFileLock, validateTransactionLogStore, versions };
3786
3844
  //# sourceMappingURL=index.mjs.map