@naturalcycles/db-lib 9.10.0 → 9.11.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.
@@ -404,7 +404,7 @@ class CommonDao {
404
404
  // Experimental: using `.map()`
405
405
  const stream = this.cfg.db
406
406
  .streamQuery(q.select(['id']), opt)
407
- .on('error', err => stream.emit('error', err))
407
+ // .on('error', err => stream.emit('error', err))
408
408
  .map((r) => r.id);
409
409
  // const stream: ReadableTyped<string> = this.cfg.db
410
410
  // .streamQuery<DBM>(q.select(['id']), opt)
@@ -1,7 +1,15 @@
1
1
  /// <reference types="node" />
2
+ import { UnixTimestampNumber } from '@naturalcycles/js-lib';
2
3
  import { ReadableTyped } from '@naturalcycles/nodejs-lib';
3
4
  import { CommonDBCreateOptions } from '../db.model';
4
5
  export type KeyValueDBTuple = [key: string, value: Buffer];
6
+ export interface CommonKeyValueDBSaveBatchOptions {
7
+ /**
8
+ * If set (and if it's implemented by the driver) - will set expiry TTL for each key of the batch.
9
+ * E.g EXAT in Redis.
10
+ */
11
+ expireAt?: UnixTimestampNumber;
12
+ }
5
13
  /**
6
14
  * Common interface for Key-Value database implementations.
7
15
  *
@@ -24,7 +32,7 @@ export interface CommonKeyValueDB {
24
32
  */
25
33
  getByIds: (table: string, ids: string[]) => Promise<KeyValueDBTuple[]>;
26
34
  deleteByIds: (table: string, ids: string[]) => Promise<void>;
27
- saveBatch: (table: string, entries: KeyValueDBTuple[]) => Promise<void>;
35
+ saveBatch: (table: string, entries: KeyValueDBTuple[], opt?: CommonKeyValueDBSaveBatchOptions) => Promise<void>;
28
36
  streamIds: (table: string, limit?: number) => ReadableTyped<string>;
29
37
  streamValues: (table: string, limit?: number) => ReadableTyped<Buffer>;
30
38
  streamEntries: (table: string, limit?: number) => ReadableTyped<KeyValueDBTuple>;
@@ -132,7 +132,7 @@ class CommonKeyValueDao {
132
132
  }
133
133
  const stream = this.cfg.db
134
134
  .streamValues(this.cfg.table, limit)
135
- .on('error', err => stream.emit('error', err))
135
+ // .on('error', err => stream.emit('error', err))
136
136
  .flatMap(async (buf) => {
137
137
  try {
138
138
  return [await mapBufferToValue(buf)];
@@ -151,7 +151,7 @@ class CommonKeyValueDao {
151
151
  }
152
152
  const stream = this.cfg.db
153
153
  .streamEntries(this.cfg.table, limit)
154
- .on('error', err => stream.emit('error', err))
154
+ // .on('error', err => stream.emit('error', err))
155
155
  .flatMap(async ([id, buf]) => {
156
156
  try {
157
157
  return [[id, await mapBufferToValue(buf)]];
@@ -155,7 +155,7 @@ function runCommonDaoTest(db, quirks = {}) {
155
155
  (0, dbTest_1.expectMatch)(expectedItems.map(i => i.id), ids, quirks);
156
156
  });
157
157
  test('streamQueryIds all', async () => {
158
- let ids = await (0, nodejs_lib_1.readableToArray)(dao.query().streamQueryIds());
158
+ let ids = await dao.query().streamQueryIds().toArray();
159
159
  ids = ids.sort();
160
160
  (0, dbTest_1.expectMatch)(expectedItems.map(i => i.id), ids, quirks);
161
161
  });
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.expectMatch = exports.runCommonDBTest = void 0;
4
4
  const js_lib_1 = require("@naturalcycles/js-lib");
5
- const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
6
5
  const common_db_1 = require("../common.db");
7
6
  const db_model_1 = require("../db.model");
8
7
  const dbQuery_1 = require("../query/dbQuery");
@@ -152,7 +151,7 @@ function runCommonDBTest(db, quirks = {}) {
152
151
  // STREAM
153
152
  if (support.streaming) {
154
153
  test('streamQuery all', async () => {
155
- let rows = await (0, nodejs_lib_1.readableToArray)(db.streamQuery(queryAll()));
154
+ let rows = await db.streamQuery(queryAll()).toArray();
156
155
  rows = (0, js_lib_1._sortBy)(rows, r => r.id); // cause order is not specified in DBQuery
157
156
  expectMatch(items, rows, quirks);
158
157
  });
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runCommonKeyValueDBTest = void 0;
4
4
  const js_lib_1 = require("@naturalcycles/js-lib");
5
- const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
6
5
  const test_model_1 = require("./test.model");
7
6
  const testIds = (0, js_lib_1._range)(1, 4).map(n => `id${n}`);
8
7
  const testEntries = testIds.map(id => [id, Buffer.from(`${id}value`)]);
@@ -33,35 +32,35 @@ function runCommonKeyValueDBTest(db) {
33
32
  expect(await db.count(test_model_1.TEST_TABLE)).toBe(3);
34
33
  });
35
34
  test('streamIds', async () => {
36
- const ids = await (0, nodejs_lib_1.readableToArray)(db.streamIds(test_model_1.TEST_TABLE));
35
+ const ids = await db.streamIds(test_model_1.TEST_TABLE).toArray();
37
36
  ids.sort();
38
37
  expect(ids).toEqual(testIds);
39
38
  });
40
39
  test('streamIds limited', async () => {
41
- const idsLimited = await (0, nodejs_lib_1.readableToArray)(db.streamIds(test_model_1.TEST_TABLE, 2));
40
+ const idsLimited = await db.streamIds(test_model_1.TEST_TABLE, 2).toArray();
42
41
  // Order is non-deterministic, so, cannot compare values
43
42
  // idsLimited.sort()
44
43
  // expect(idsLimited).toEqual(testIds.slice(0, 2))
45
44
  expect(idsLimited.length).toBe(2);
46
45
  });
47
46
  test('streamValues', async () => {
48
- const values = await (0, nodejs_lib_1.readableToArray)(db.streamValues(test_model_1.TEST_TABLE));
47
+ const values = await db.streamValues(test_model_1.TEST_TABLE).toArray();
49
48
  values.sort();
50
49
  expect(values).toEqual(testEntries.map(e => e[1]));
51
50
  });
52
51
  test('streamValues limited', async () => {
53
- const valuesLimited = await (0, nodejs_lib_1.readableToArray)(db.streamValues(test_model_1.TEST_TABLE, 2));
52
+ const valuesLimited = await db.streamValues(test_model_1.TEST_TABLE, 2).toArray();
54
53
  // valuesLimited.sort()
55
54
  // expect(valuesLimited).toEqual(testEntries.map(e => e[1]).slice(0, 2))
56
55
  expect(valuesLimited.length).toBe(2);
57
56
  });
58
57
  test('streamEntries', async () => {
59
- const entries = await (0, nodejs_lib_1.readableToArray)(db.streamEntries(test_model_1.TEST_TABLE));
58
+ const entries = await db.streamEntries(test_model_1.TEST_TABLE).toArray();
60
59
  entries.sort();
61
60
  expect(entries).toEqual(testEntries);
62
61
  });
63
62
  test('streamEntries limited', async () => {
64
- const entriesLimited = await (0, nodejs_lib_1.readableToArray)(db.streamEntries(test_model_1.TEST_TABLE, 2));
63
+ const entriesLimited = await db.streamEntries(test_model_1.TEST_TABLE, 2).toArray();
65
64
  // entriesLimited.sort()
66
65
  // expect(entriesLimited).toEqual(testEntries.slice(0, 2))
67
66
  expect(entriesLimited.length).toBe(2);
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runCommonKeyValueDaoTest = void 0;
4
4
  const js_lib_1 = require("@naturalcycles/js-lib");
5
- const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
6
5
  const testIds = (0, js_lib_1._range)(1, 4).map(n => `id${n}`);
7
6
  const testEntries = testIds.map(id => [id, Buffer.from(`${id}value`)]);
8
7
  function runCommonKeyValueDaoTest(dao) {
@@ -26,35 +25,35 @@ function runCommonKeyValueDaoTest(dao) {
26
25
  expect(entries).toEqual(testEntries);
27
26
  });
28
27
  test('streamIds', async () => {
29
- const ids = await (0, nodejs_lib_1.readableToArray)(dao.streamIds());
28
+ const ids = await dao.streamIds().toArray();
30
29
  ids.sort();
31
30
  expect(ids).toEqual(testIds);
32
31
  });
33
32
  test('streamIds limited', async () => {
34
- const idsLimited = await (0, nodejs_lib_1.readableToArray)(dao.streamIds(2));
33
+ const idsLimited = await dao.streamIds(2).toArray();
35
34
  // Order is non-deterministic, so, cannot compare values
36
35
  // idsLimited.sort()
37
36
  // expect(idsLimited).toEqual(testIds.slice(0, 2))
38
37
  expect(idsLimited.length).toBe(2);
39
38
  });
40
39
  test('streamValues', async () => {
41
- const values = await (0, nodejs_lib_1.readableToArray)(dao.streamValues());
40
+ const values = await dao.streamValues().toArray();
42
41
  values.sort();
43
42
  expect(values).toEqual(testEntries.map(e => e[1]));
44
43
  });
45
44
  test('streamValues limited', async () => {
46
- const valuesLimited = await (0, nodejs_lib_1.readableToArray)(dao.streamValues(2));
45
+ const valuesLimited = await dao.streamValues(2).toArray();
47
46
  // valuesLimited.sort()
48
47
  // expect(valuesLimited).toEqual(testEntries.map(e => e[1]).slice(0, 2))
49
48
  expect(valuesLimited.length).toBe(2);
50
49
  });
51
50
  test('streamEntries', async () => {
52
- const entries = await (0, nodejs_lib_1.readableToArray)(dao.streamEntries());
51
+ const entries = await dao.streamEntries().toArray();
53
52
  entries.sort();
54
53
  expect(entries).toEqual(testEntries);
55
54
  });
56
55
  test('streamEntries limited', async () => {
57
- const entriesLimited = await (0, nodejs_lib_1.readableToArray)(dao.streamEntries(2));
56
+ const entriesLimited = await dao.streamEntries(2).toArray();
58
57
  // entriesLimited.sort()
59
58
  // expect(entriesLimited).toEqual(testEntries.slice(0, 2))
60
59
  expect(entriesLimited.length).toBe(2);
package/package.json CHANGED
@@ -40,7 +40,7 @@
40
40
  "engines": {
41
41
  "node": ">=18.12"
42
42
  },
43
- "version": "9.10.0",
43
+ "version": "9.11.0",
44
44
  "description": "Lowest Common Denominator API to supported Databases",
45
45
  "keywords": [
46
46
  "db",
@@ -495,7 +495,7 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM> {
495
495
 
496
496
  const stream = this.cfg.db.streamQuery<DBM>(q, opt)
497
497
  const partialQuery = !!q._selectedFieldNames
498
- if (partialQuery) return stream
498
+ if (partialQuery) return stream as any
499
499
 
500
500
  // This almost works, but hard to implement `errorMode: THROW_AGGREGATED` in this case
501
501
  // return stream.flatMap(async (dbm: DBM) => {
@@ -551,7 +551,7 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM> {
551
551
  // Experimental: using `.map()`
552
552
  const stream: ReadableTyped<string> = this.cfg.db
553
553
  .streamQuery<DBM>(q.select(['id']), opt)
554
- .on('error', err => stream.emit('error', err))
554
+ // .on('error', err => stream.emit('error', err))
555
555
  .map((r: ObjectWithId) => r.id)
556
556
 
557
557
  // const stream: ReadableTyped<string> = this.cfg.db
@@ -1,8 +1,17 @@
1
+ import { UnixTimestampNumber } from '@naturalcycles/js-lib'
1
2
  import { ReadableTyped } from '@naturalcycles/nodejs-lib'
2
3
  import { CommonDBCreateOptions } from '../db.model'
3
4
 
4
5
  export type KeyValueDBTuple = [key: string, value: Buffer]
5
6
 
7
+ export interface CommonKeyValueDBSaveBatchOptions {
8
+ /**
9
+ * If set (and if it's implemented by the driver) - will set expiry TTL for each key of the batch.
10
+ * E.g EXAT in Redis.
11
+ */
12
+ expireAt?: UnixTimestampNumber
13
+ }
14
+
6
15
  /**
7
16
  * Common interface for Key-Value database implementations.
8
17
  *
@@ -29,7 +38,11 @@ export interface CommonKeyValueDB {
29
38
 
30
39
  deleteByIds: (table: string, ids: string[]) => Promise<void>
31
40
 
32
- saveBatch: (table: string, entries: KeyValueDBTuple[]) => Promise<void>
41
+ saveBatch: (
42
+ table: string,
43
+ entries: KeyValueDBTuple[],
44
+ opt?: CommonKeyValueDBSaveBatchOptions,
45
+ ) => Promise<void>
33
46
 
34
47
  streamIds: (table: string, limit?: number) => ReadableTyped<string>
35
48
  streamValues: (table: string, limit?: number) => ReadableTyped<Buffer>
@@ -201,15 +201,15 @@ export class CommonKeyValueDao<T> {
201
201
  const { mapBufferToValue } = this.cfg.hooks
202
202
 
203
203
  if (!mapBufferToValue) {
204
- return this.cfg.db.streamValues(this.cfg.table, limit)
204
+ return this.cfg.db.streamValues(this.cfg.table, limit) as ReadableTyped<T>
205
205
  }
206
206
 
207
207
  const stream: ReadableTyped<T> = this.cfg.db
208
208
  .streamValues(this.cfg.table, limit)
209
- .on('error', err => stream.emit('error', err))
210
- .flatMap(async (buf: Buffer) => {
209
+ // .on('error', err => stream.emit('error', err))
210
+ .flatMap(async buf => {
211
211
  try {
212
- return [await mapBufferToValue(buf)] satisfies T[]
212
+ return [await mapBufferToValue(buf)]
213
213
  } catch (err) {
214
214
  this.cfg.logger.error(err)
215
215
  return [] // SKIP
@@ -223,15 +223,17 @@ export class CommonKeyValueDao<T> {
223
223
  const { mapBufferToValue } = this.cfg.hooks
224
224
 
225
225
  if (!mapBufferToValue) {
226
- return this.cfg.db.streamEntries(this.cfg.table, limit)
226
+ return this.cfg.db.streamEntries(this.cfg.table, limit) as ReadableTyped<
227
+ KeyValueTuple<string, T>
228
+ >
227
229
  }
228
230
 
229
231
  const stream: ReadableTyped<KeyValueTuple<string, T>> = this.cfg.db
230
232
  .streamEntries(this.cfg.table, limit)
231
- .on('error', err => stream.emit('error', err))
232
- .flatMap(async ([id, buf]: KeyValueTuple<string, Buffer>) => {
233
+ // .on('error', err => stream.emit('error', err))
234
+ .flatMap(async ([id, buf]) => {
233
235
  try {
234
- return [[id, await mapBufferToValue(buf)]] satisfies KeyValueTuple<string, T>[]
236
+ return [[id, await mapBufferToValue(buf)]]
235
237
  } catch (err) {
236
238
  this.cfg.logger.error(err)
237
239
  return [] // SKIP
@@ -1,6 +1,6 @@
1
1
  import { Readable } from 'node:stream'
2
2
  import { _deepCopy, _pick, _sortBy, _omit, localTimeNow } from '@naturalcycles/js-lib'
3
- import { _pipeline, readableToArray } from '@naturalcycles/nodejs-lib'
3
+ import { _pipeline } from '@naturalcycles/nodejs-lib'
4
4
  import { CommonDaoLogLevel, DBQuery } from '..'
5
5
  import { CommonDB } from '../common.db'
6
6
  import { CommonDao } from '../commondao/common.dao'
@@ -212,7 +212,7 @@ export function runCommonDaoTest(db: CommonDB, quirks: CommonDBImplementationQui
212
212
  })
213
213
 
214
214
  test('streamQueryIds all', async () => {
215
- let ids = await readableToArray(dao.query().streamQueryIds())
215
+ let ids = await dao.query().streamQueryIds().toArray()
216
216
  ids = ids.sort()
217
217
  expectMatch(
218
218
  expectedItems.map(i => i.id),
@@ -1,5 +1,4 @@
1
1
  import { _filterObject, _pick, _sortBy, pMap } from '@naturalcycles/js-lib'
2
- import { readableToArray } from '@naturalcycles/nodejs-lib'
3
2
  import { CommonDB, CommonDBType } from '../common.db'
4
3
  import { DBIncrement, DBPatch } from '../db.model'
5
4
  import { DBQuery } from '../query/dbQuery'
@@ -220,7 +219,7 @@ export function runCommonDBTest(db: CommonDB, quirks: CommonDBImplementationQuir
220
219
  // STREAM
221
220
  if (support.streaming) {
222
221
  test('streamQuery all', async () => {
223
- let rows = await readableToArray(db.streamQuery(queryAll()))
222
+ let rows = await db.streamQuery(queryAll()).toArray()
224
223
 
225
224
  rows = _sortBy(rows, r => r.id) // cause order is not specified in DBQuery
226
225
  expectMatch(items, rows, quirks)
@@ -1,5 +1,4 @@
1
1
  import { _range, _sortBy } from '@naturalcycles/js-lib'
2
- import { readableToArray } from '@naturalcycles/nodejs-lib'
3
2
  import { CommonKeyValueDB, KeyValueDBTuple } from '../kv/commonKeyValueDB'
4
3
  import { TEST_TABLE } from './test.model'
5
4
 
@@ -42,13 +41,13 @@ export function runCommonKeyValueDBTest(db: CommonKeyValueDB): void {
42
41
  })
43
42
 
44
43
  test('streamIds', async () => {
45
- const ids = await readableToArray(db.streamIds(TEST_TABLE))
44
+ const ids = await db.streamIds(TEST_TABLE).toArray()
46
45
  ids.sort()
47
46
  expect(ids).toEqual(testIds)
48
47
  })
49
48
 
50
49
  test('streamIds limited', async () => {
51
- const idsLimited = await readableToArray(db.streamIds(TEST_TABLE, 2))
50
+ const idsLimited = await db.streamIds(TEST_TABLE, 2).toArray()
52
51
  // Order is non-deterministic, so, cannot compare values
53
52
  // idsLimited.sort()
54
53
  // expect(idsLimited).toEqual(testIds.slice(0, 2))
@@ -56,26 +55,26 @@ export function runCommonKeyValueDBTest(db: CommonKeyValueDB): void {
56
55
  })
57
56
 
58
57
  test('streamValues', async () => {
59
- const values = await readableToArray(db.streamValues(TEST_TABLE))
58
+ const values = await db.streamValues(TEST_TABLE).toArray()
60
59
  values.sort()
61
60
  expect(values).toEqual(testEntries.map(e => e[1]))
62
61
  })
63
62
 
64
63
  test('streamValues limited', async () => {
65
- const valuesLimited = await readableToArray(db.streamValues(TEST_TABLE, 2))
64
+ const valuesLimited = await db.streamValues(TEST_TABLE, 2).toArray()
66
65
  // valuesLimited.sort()
67
66
  // expect(valuesLimited).toEqual(testEntries.map(e => e[1]).slice(0, 2))
68
67
  expect(valuesLimited.length).toBe(2)
69
68
  })
70
69
 
71
70
  test('streamEntries', async () => {
72
- const entries = await readableToArray(db.streamEntries(TEST_TABLE))
71
+ const entries = await db.streamEntries(TEST_TABLE).toArray()
73
72
  entries.sort()
74
73
  expect(entries).toEqual(testEntries)
75
74
  })
76
75
 
77
76
  test('streamEntries limited', async () => {
78
- const entriesLimited = await readableToArray(db.streamEntries(TEST_TABLE, 2))
77
+ const entriesLimited = await db.streamEntries(TEST_TABLE, 2).toArray()
79
78
  // entriesLimited.sort()
80
79
  // expect(entriesLimited).toEqual(testEntries.slice(0, 2))
81
80
  expect(entriesLimited.length).toBe(2)
@@ -1,5 +1,4 @@
1
1
  import { _range, _sortBy } from '@naturalcycles/js-lib'
2
- import { readableToArray } from '@naturalcycles/nodejs-lib'
3
2
  import { KeyValueDBTuple } from '../kv/commonKeyValueDB'
4
3
  import { CommonKeyValueDao } from '../kv/commonKeyValueDao'
5
4
 
@@ -33,13 +32,13 @@ export function runCommonKeyValueDaoTest(dao: CommonKeyValueDao<Buffer>): void {
33
32
  })
34
33
 
35
34
  test('streamIds', async () => {
36
- const ids = await readableToArray(dao.streamIds())
35
+ const ids = await dao.streamIds().toArray()
37
36
  ids.sort()
38
37
  expect(ids).toEqual(testIds)
39
38
  })
40
39
 
41
40
  test('streamIds limited', async () => {
42
- const idsLimited = await readableToArray(dao.streamIds(2))
41
+ const idsLimited = await dao.streamIds(2).toArray()
43
42
  // Order is non-deterministic, so, cannot compare values
44
43
  // idsLimited.sort()
45
44
  // expect(idsLimited).toEqual(testIds.slice(0, 2))
@@ -47,26 +46,26 @@ export function runCommonKeyValueDaoTest(dao: CommonKeyValueDao<Buffer>): void {
47
46
  })
48
47
 
49
48
  test('streamValues', async () => {
50
- const values = await readableToArray(dao.streamValues())
49
+ const values = await dao.streamValues().toArray()
51
50
  values.sort()
52
51
  expect(values).toEqual(testEntries.map(e => e[1]))
53
52
  })
54
53
 
55
54
  test('streamValues limited', async () => {
56
- const valuesLimited = await readableToArray(dao.streamValues(2))
55
+ const valuesLimited = await dao.streamValues(2).toArray()
57
56
  // valuesLimited.sort()
58
57
  // expect(valuesLimited).toEqual(testEntries.map(e => e[1]).slice(0, 2))
59
58
  expect(valuesLimited.length).toBe(2)
60
59
  })
61
60
 
62
61
  test('streamEntries', async () => {
63
- const entries = await readableToArray(dao.streamEntries())
62
+ const entries = await dao.streamEntries().toArray()
64
63
  entries.sort()
65
64
  expect(entries).toEqual(testEntries)
66
65
  })
67
66
 
68
67
  test('streamEntries limited', async () => {
69
- const entriesLimited = await readableToArray(dao.streamEntries(2))
68
+ const entriesLimited = await dao.streamEntries(2).toArray()
70
69
  // entriesLimited.sort()
71
70
  // expect(entriesLimited).toEqual(testEntries.slice(0, 2))
72
71
  expect(entriesLimited.length).toBe(2)