@nxtedition/rocksdb 7.0.47 → 7.0.50

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/binding.cc CHANGED
@@ -1248,8 +1248,8 @@ NAPI_METHOD(updates_init) {
1248
1248
  const bool keyAsBuffer = EncodingIsBuffer(env, argv[1], "keyEncoding");
1249
1249
  const bool valueAsBuffer = EncodingIsBuffer(env, argv[1], "valueEncoding");
1250
1250
 
1251
- rocksdb::ColumnFamilyHandle* column;
1252
- NAPI_STATUS_THROWS(GetColumnFamily(nullptr, env, argv[1], &column));
1251
+ rocksdb::ColumnFamilyHandle* column = nullptr;
1252
+ // NAPI_STATUS_THROWS(GetColumnFamily(nullptr, env, argv[1], &column));
1253
1253
 
1254
1254
  auto updates = std::make_unique<Updates>(database, since, keys, values, data, column, keyAsBuffer, valueAsBuffer);
1255
1255
 
@@ -1933,8 +1933,8 @@ NAPI_METHOD(batch_iterate) {
1933
1933
  const bool keyAsBuffer = EncodingIsBuffer(env, argv[1], "keyEncoding");
1934
1934
  const bool valueAsBuffer = EncodingIsBuffer(env, argv[1], "valueEncoding");
1935
1935
 
1936
- rocksdb::ColumnFamilyHandle* column;
1937
- NAPI_STATUS_THROWS(GetColumnFamily(nullptr, env, argv[2], &column));
1936
+ rocksdb::ColumnFamilyHandle* column = nullptr;
1937
+ // NAPI_STATUS_THROWS(GetColumnFamily(nullptr, env, argv[2], &column));
1938
1938
 
1939
1939
  napi_value result;
1940
1940
  BatchIterator iterator(nullptr, keys, values, data, column, keyAsBuffer, valueAsBuffer);
package/common.js ADDED
@@ -0,0 +1,7 @@
1
+ module.exports.AbortError = class AbortError extends Error {
2
+ constructor () {
3
+ super('The operation was aborted')
4
+ this.code = 'ABORT_ERR'
5
+ this.name = 'AbortError'
6
+ }
7
+ }
package/index.js CHANGED
@@ -1,13 +1,16 @@
1
1
  'use strict'
2
2
 
3
3
  const { fromCallback } = require('catering')
4
+ const { AbortError } = require('./common')
4
5
  const { AbstractLevel } = require('abstract-level')
5
6
  const ModuleError = require('module-error')
6
7
  const fs = require('fs')
7
8
  const binding = require('./binding')
8
9
  const { ChainedBatch } = require('./chained-batch')
9
10
  const { Iterator } = require('./iterator')
11
+ const { Readable } = require('readable-stream')
10
12
  const os = require('os')
13
+ const AbortController = require('abort-controller')
11
14
 
12
15
  const kContext = Symbol('context')
13
16
  const kColumns = Symbol('columns')
@@ -281,6 +284,11 @@ class RocksLevel extends AbstractLevel {
281
284
  }
282
285
 
283
286
  async * updates (options) {
287
+ // TODO (fix): Ensure open status etc...?
288
+ if (this.status !== 'open') {
289
+ throw new Error('Database is not open')
290
+ }
291
+
284
292
  if (this.status !== 'open') {
285
293
  throw new ModuleError('Database is not open', {
286
294
  code: 'LEVEL_DATABASE_NOT_OPEN'
@@ -292,12 +300,13 @@ class RocksLevel extends AbstractLevel {
292
300
  keys: options?.keys ?? true,
293
301
  values: options?.values ?? true,
294
302
  data: options?.data ?? true,
295
- column: options?.column ?? null
303
+ live: options?.live ?? false,
304
+ column: options?.column ?? null,
305
+ signal: options?.signal ?? null
296
306
  }
297
307
 
298
- // HACK: We don't properly check for nully column in binding.
299
- if (!options.column) {
300
- delete options.column
308
+ if (options.column) {
309
+ throw new TypeError("'column' not implemented")
301
310
  }
302
311
 
303
312
  if (typeof options.since !== 'number') {
@@ -320,6 +329,85 @@ class RocksLevel extends AbstractLevel {
320
329
  throw new TypeError("'column' must be nully or a object")
321
330
  }
322
331
 
332
+ if (typeof options.live !== 'boolean') {
333
+ throw new TypeError("'live' must be nully or a boolean")
334
+ }
335
+
336
+ const ac = new AbortController()
337
+ const onAbort = () => {
338
+ ac.abort()
339
+ }
340
+
341
+ options.signal?.addEventListener('abort', onAbort)
342
+
343
+ try {
344
+ let since = options.since
345
+
346
+ const db = this
347
+ while (true) {
348
+ const buffer = new Readable({
349
+ signal: ac.signal,
350
+ objectMode: true,
351
+ readableHighWaterMark: 1024,
352
+ construct (callback) {
353
+ this._next = (batch, sequence) => {
354
+ const rows = []
355
+ for (const { type, key, value } of batch) {
356
+ rows.push(type, key, value, null)
357
+ }
358
+ if (!this.push({ rows, sequence, count: batch.length })) {
359
+ this.push(null)
360
+ db.off('write', this._next)
361
+ }
362
+ }
363
+ db.on('write', this._next)
364
+ callback()
365
+ },
366
+ read () {},
367
+ destroy (err, callback) {
368
+ db.off('write', this._next)
369
+ callback(err)
370
+ }
371
+ })
372
+
373
+ if (ac.signal.aborted) {
374
+ throw new AbortError()
375
+ }
376
+
377
+ try {
378
+ if (since <= this.sequence) {
379
+ for await (const update of this._updates(options)) {
380
+ if (ac.signal.aborted) {
381
+ throw new AbortError()
382
+ }
383
+
384
+ yield update
385
+ since = update.sequence + update.count
386
+ }
387
+ }
388
+ } catch (err) {
389
+ if (err.code !== 'LEVEL_TRYAGAIN') {
390
+ throw err
391
+ }
392
+ }
393
+
394
+ if (!options.live) {
395
+ return
396
+ }
397
+
398
+ for await (const update of buffer) {
399
+ if (update.sequence >= since) {
400
+ yield update
401
+ since = update.sequence + update.count
402
+ }
403
+ }
404
+ }
405
+ } finally {
406
+ options.signal?.removeventListener('abort', onAbort)
407
+ }
408
+ }
409
+
410
+ async * _updates (options) {
323
411
  class Updates {
324
412
  constructor (db, options) {
325
413
  this.context = binding.updates_init(db[kContext], options)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/rocksdb",
3
- "version": "7.0.47",
3
+ "version": "7.0.50",
4
4
  "description": "A low-level Node.js RocksDB binding",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -11,11 +11,13 @@
11
11
  "rebuild": "npm run install --build-from-source"
12
12
  },
13
13
  "dependencies": {
14
+ "abort-controller": "^3.0.0",
14
15
  "abstract-level": "^1.0.2",
15
16
  "catering": "^2.1.1",
16
17
  "module-error": "^1.0.2",
17
18
  "napi-macros": "~2.0.0",
18
- "node-gyp-build": "^4.3.0"
19
+ "node-gyp-build": "^4.3.0",
20
+ "readable-stream": "^4.1.0"
19
21
  },
20
22
  "devDependencies": {
21
23
  "@types/node": "^17.0.16",