@naturalcycles/db-lib 9.24.1 → 9.25.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.
@@ -1,5 +1,5 @@
1
1
  import { Transform } from 'node:stream';
2
- import { AsyncMapper, BaseDBEntity, CommonLogger, JsonSchemaObject, JsonSchemaRootObject, StringMap, UnixTimestampMillisNumber, Unsaved, ZodSchema } from '@naturalcycles/js-lib';
2
+ import { AsyncMapper, BaseDBEntity, CommonLogger, JsonSchemaObject, JsonSchemaRootObject, StringMap, UnixTimestampMillis, Unsaved, ZodSchema } from '@naturalcycles/js-lib';
3
3
  import { AjvSchema, ObjectSchema, ReadableTyped } from '@naturalcycles/nodejs-lib';
4
4
  import { CommonDBTransactionOptions, DBTransaction, RunQueryResult } from '../db.model';
5
5
  import { DBQuery, RunnableDBQuery } from '../query/dbQuery';
@@ -170,10 +170,10 @@ export declare class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity
170
170
  * Throws if query uses a property that is in `excludeFromIndexes` list.
171
171
  */
172
172
  private validateQueryIndexes;
173
- protected logResult(started: number, op: string, res: any, table: string): void;
174
- protected logSaveResult(started: number, op: string, table: string): void;
175
- protected logStarted(op: string, table: string, force?: boolean): UnixTimestampMillisNumber;
176
- protected logSaveStarted(op: string, items: any, table: string): UnixTimestampMillisNumber;
173
+ protected logResult(started: UnixTimestampMillis, op: string, res: any, table: string): void;
174
+ protected logSaveResult(started: UnixTimestampMillis, op: string, table: string): void;
175
+ protected logStarted(op: string, table: string, force?: boolean): UnixTimestampMillis;
176
+ protected logSaveStarted(op: string, items: any, table: string): UnixTimestampMillis;
177
177
  }
178
178
  /**
179
179
  * Transaction is committed when the function returns resolved Promise (aka "returns normally").
@@ -968,7 +968,19 @@ class CommonDao {
968
968
  }
969
969
  else {
970
970
  // Joi
971
+ const start = performance.now();
971
972
  const vr = (0, nodejs_lib_1.getValidationResult)(obj, schema, objectName);
973
+ const end = performance.now();
974
+ const tookMillis = end - start;
975
+ if (this.cfg.debugValidationTimeThreshhold &&
976
+ tookMillis >= this.cfg.debugValidationTimeThreshhold) {
977
+ this.cfg.onValidationTimeThreshold?.({
978
+ tookMillis,
979
+ error: !!vr.error,
980
+ table,
981
+ obj,
982
+ });
983
+ }
972
984
  error = vr.error;
973
985
  convertedValue = vr.value;
974
986
  }
@@ -1,4 +1,4 @@
1
- import { BaseDBEntity, CommonLogger, ErrorMode, Promisable, UnixTimestampNumber, ZodError, ZodSchema } from '@naturalcycles/js-lib';
1
+ import { AnyObject, BaseDBEntity, CommonLogger, ErrorMode, NumberOfMilliseconds, Promisable, UnixTimestamp, ZodError, ZodSchema } from '@naturalcycles/js-lib';
2
2
  import { AjvSchema, AjvValidationError, JoiValidationError, ObjectSchema, TransformLogProgressOptions, TransformMapOptions } from '@naturalcycles/nodejs-lib';
3
3
  import { CommonDB } from '../common.db';
4
4
  import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions } from '../db.model';
@@ -111,6 +111,15 @@ export interface CommonDaoCfg<BM extends BaseDBEntity, DBM extends BaseDBEntity
111
111
  * If set to false - save (write) operations will skip validation (and conversion).
112
112
  */
113
113
  validateOnSave?: boolean;
114
+ /**
115
+ * Defaults to undefined == disabled.
116
+ * If set - enable the monitoring of validation time and will alert on crossing the threshold.
117
+ */
118
+ debugValidationTimeThreshhold?: NumberOfMilliseconds;
119
+ /**
120
+ * Called when debugValidationTimeThreshhold is crossed.
121
+ */
122
+ onValidationTimeThreshold?: (info: AnyObject) => void;
114
123
  /**
115
124
  * Defaults to false.
116
125
  * Setting it to true will set saveMethod to `insert` for save/saveBatch, which will
@@ -205,7 +214,7 @@ export interface CommonDaoReadOptions extends CommonDaoOptions {
205
214
  * If provided (and supported by the DB) - will read the data at that point in time (aka "Time machine" feature).
206
215
  * This feature is named PITR (point-in-time-recovery) query in Datastore.
207
216
  */
208
- readAt?: UnixTimestampNumber;
217
+ readAt?: UnixTimestamp;
209
218
  }
210
219
  export interface CommonDaoSaveOptions<BM extends BaseDBEntity, DBM extends BaseDBEntity> extends CommonDaoSaveBatchOptions<DBM> {
211
220
  /**
@@ -1,4 +1,4 @@
1
- import { ObjectWithId, UnixTimestampNumber } from '@naturalcycles/js-lib';
1
+ import { ObjectWithId, UnixTimestamp } from '@naturalcycles/js-lib';
2
2
  import { CommonDB } from './common.db';
3
3
  /**
4
4
  * Similar to SQL INSERT, UPDATE.
@@ -50,7 +50,7 @@ export interface CommonDBReadOptions extends CommonDBOptions {
50
50
  * If provided (and supported by the DB) - will read the data at that point in time (aka "Time machine" feature).
51
51
  * This feature is named PITR (point-in-time-recovery) query in Datastore.
52
52
  */
53
- readAt?: UnixTimestampNumber;
53
+ readAt?: UnixTimestamp;
54
54
  }
55
55
  /**
56
56
  * All properties default to undefined.
@@ -1,4 +1,4 @@
1
- import { Integer, UnixTimestampNumber } from '@naturalcycles/js-lib';
1
+ import { Integer, UnixTimestamp } from '@naturalcycles/js-lib';
2
2
  import { ReadableTyped } from '@naturalcycles/nodejs-lib';
3
3
  import { CommonDBCreateOptions } from '../db.model';
4
4
  /**
@@ -56,7 +56,7 @@ export interface CommonKeyValueDBSaveBatchOptions {
56
56
  * If set (and if it's implemented by the driver) - will set expiry TTL for each key of the batch.
57
57
  * E.g EXAT in Redis.
58
58
  */
59
- expireAt?: UnixTimestampNumber;
59
+ expireAt?: UnixTimestamp;
60
60
  }
61
61
  /**
62
62
  * Manifest of supported features.
@@ -18,7 +18,9 @@ class CommonKeyValueDaoMemoCache {
18
18
  return (await this.cfg.dao.getById(k)) || js_lib_1.MISS;
19
19
  }
20
20
  async set(k, v) {
21
- const opt = this.cfg.ttl ? { expireAt: js_lib_1.localTime.nowUnix() + this.cfg.ttl } : undefined;
21
+ const opt = this.cfg.ttl
22
+ ? { expireAt: (js_lib_1.localTime.nowUnix() + this.cfg.ttl) }
23
+ : undefined;
22
24
  await this.cfg.dao.save(k, v, opt);
23
25
  }
24
26
  async clear() {
@@ -1,4 +1,4 @@
1
- import { AsyncMapper, ErrorMode, StringMap, UnixTimestampNumber } from '@naturalcycles/js-lib';
1
+ import { AsyncMapper, ErrorMode, StringMap, UnixTimestamp } from '@naturalcycles/js-lib';
2
2
  import { NDJsonStats, TransformLogProgressOptions, TransformMapOptions } from '@naturalcycles/nodejs-lib';
3
3
  import { CommonDB } from '../common.db';
4
4
  import { DBQuery } from '../index';
@@ -33,12 +33,12 @@ export interface DBPipelineBackupOptions extends TransformLogProgressOptions {
33
33
  /**
34
34
  * If set - will do "incremental backup" (not full), only for entities that updated >= `sinceUpdated`
35
35
  */
36
- sinceUpdated?: UnixTimestampNumber;
36
+ sinceUpdated?: UnixTimestamp;
37
37
  /**
38
38
  * Map for each table a `sinceUpdated` timestamp, or `undefined`.
39
39
  * If set - will do "incremental backup" (not full), only for entities that updated >= `sinceUpdated` (on a per table basis)
40
40
  */
41
- sinceUpdatedPerTable?: StringMap<UnixTimestampNumber>;
41
+ sinceUpdatedPerTable?: StringMap<UnixTimestamp>;
42
42
  /**
43
43
  * By default, dbPipelineBackup creates a Query based on sinceUpdated.
44
44
  * But if queryPerTable is set for a table - it will override the Query that is ran for that table
@@ -1,4 +1,4 @@
1
- import { AsyncMapper, ErrorMode } from '@naturalcycles/js-lib';
1
+ import { AsyncMapper, ErrorMode, UnixTimestamp } from '@naturalcycles/js-lib';
2
2
  import { NDJsonStats, TransformLogProgressOptions, TransformMapOptions } from '@naturalcycles/nodejs-lib';
3
3
  import { CommonDB } from '../common.db';
4
4
  import { CommonDBSaveOptions } from '../db.model';
@@ -39,7 +39,7 @@ export interface DBPipelineCopyOptions extends TransformLogProgressOptions {
39
39
  *
40
40
  * @default undefined
41
41
  */
42
- sinceUpdated?: number;
42
+ sinceUpdated?: UnixTimestamp;
43
43
  /**
44
44
  * Optionally you can provide mapper that is going to run for each table.
45
45
  *
@@ -1,4 +1,4 @@
1
- import { AsyncMapper, ErrorMode } from '@naturalcycles/js-lib';
1
+ import { AsyncMapper, ErrorMode, UnixTimestamp } from '@naturalcycles/js-lib';
2
2
  import { NDJsonStats, TransformLogProgressOptions, TransformMapOptions } from '@naturalcycles/nodejs-lib';
3
3
  import { CommonDB } from '../common.db';
4
4
  import { CommonDBSaveOptions } from '../index';
@@ -46,7 +46,7 @@ export interface DBPipelineRestoreOptions extends TransformLogProgressOptions {
46
46
  *
47
47
  * @default undefined
48
48
  */
49
- sinceUpdated?: number;
49
+ sinceUpdated?: UnixTimestamp;
50
50
  /**
51
51
  * @default false
52
52
  * If true - will read ${table}.schema.json files and recreate tables before importing.
package/package.json CHANGED
@@ -43,9 +43,9 @@
43
43
  "url": "https://github.com/NaturalCycles/db-lib"
44
44
  },
45
45
  "engines": {
46
- "node": ">=20.13"
46
+ "node": ">=22.10.0"
47
47
  },
48
- "version": "9.24.1",
48
+ "version": "9.25.0",
49
49
  "description": "Lowest Common Denominator API to supported Databases",
50
50
  "keywords": [
51
51
  "db",
@@ -10,6 +10,7 @@ import {
10
10
  generateJsonSchemaFromData,
11
11
  JsonSchemaRootObject,
12
12
  ObjectWithId,
13
+ UnixTimestampMillis,
13
14
  } from '@naturalcycles/js-lib'
14
15
  import { dimGrey, readableCreate, ReadableTyped } from '@naturalcycles/nodejs-lib'
15
16
  import {
@@ -240,14 +241,14 @@ export class FileDB extends BaseCommonDB implements CommonDB {
240
241
  return rows
241
242
  }
242
243
 
243
- private logStarted(op: string): number {
244
+ private logStarted(op: string): UnixTimestampMillis {
244
245
  if (this.cfg.logStarted) {
245
246
  this.cfg.logger?.log(`>> ${op}`)
246
247
  }
247
- return Date.now()
248
+ return Date.now() as UnixTimestampMillis
248
249
  }
249
250
 
250
- private logFinished(started: number, op: string): void {
251
+ private logFinished(started: UnixTimestampMillis, op: string): void {
251
252
  if (!this.cfg.logFinished) return
252
253
  this.cfg.logger?.log(`<< ${op} ${dimGrey(`in ${_since(started)}`)}`)
253
254
  }
@@ -16,6 +16,7 @@ import {
16
16
  ObjectWithId,
17
17
  pMap,
18
18
  StringMap,
19
+ UnixTimestampMillis,
19
20
  } from '@naturalcycles/js-lib'
20
21
  import {
21
22
  _pipeline,
@@ -314,7 +315,7 @@ export class InMemoryDB implements CommonDB {
314
315
  _assert(this.cfg.persistenceEnabled, 'flushToDisk() called but persistenceEnabled=false')
315
316
  const { persistentStoragePath, persistZip } = this.cfg
316
317
 
317
- const started = Date.now()
318
+ const started = Date.now() as UnixTimestampMillis
318
319
 
319
320
  await fs2.emptyDirAsync(persistentStoragePath)
320
321
 
@@ -343,7 +344,7 @@ export class InMemoryDB implements CommonDB {
343
344
  _assert(this.cfg.persistenceEnabled, 'restoreFromDisk() called but persistenceEnabled=false')
344
345
  const { persistentStoragePath } = this.cfg
345
346
 
346
- const started = Date.now()
347
+ const started = Date.now() as UnixTimestampMillis
347
348
 
348
349
  await fs2.ensureDirAsync(persistentStoragePath)
349
350
 
@@ -1,9 +1,11 @@
1
1
  import {
2
+ AnyObject,
2
3
  BaseDBEntity,
3
4
  CommonLogger,
4
5
  ErrorMode,
6
+ NumberOfMilliseconds,
5
7
  Promisable,
6
- UnixTimestampNumber,
8
+ UnixTimestamp,
7
9
  ZodError,
8
10
  ZodSchema,
9
11
  } from '@naturalcycles/js-lib'
@@ -146,6 +148,17 @@ export interface CommonDaoCfg<
146
148
  */
147
149
  validateOnSave?: boolean
148
150
 
151
+ /**
152
+ * Defaults to undefined == disabled.
153
+ * If set - enable the monitoring of validation time and will alert on crossing the threshold.
154
+ */
155
+ debugValidationTimeThreshhold?: NumberOfMilliseconds
156
+
157
+ /**
158
+ * Called when debugValidationTimeThreshhold is crossed.
159
+ */
160
+ onValidationTimeThreshold?: (info: AnyObject) => void
161
+
149
162
  /**
150
163
  * Defaults to false.
151
164
  * Setting it to true will set saveMethod to `insert` for save/saveBatch, which will
@@ -257,7 +270,7 @@ export interface CommonDaoReadOptions extends CommonDaoOptions {
257
270
  * If provided (and supported by the DB) - will read the data at that point in time (aka "Time machine" feature).
258
271
  * This feature is named PITR (point-in-time-recovery) query in Datastore.
259
272
  */
260
- readAt?: UnixTimestampNumber
273
+ readAt?: UnixTimestamp
261
274
  }
262
275
 
263
276
  export interface CommonDaoSaveOptions<BM extends BaseDBEntity, DBM extends BaseDBEntity>
@@ -23,7 +23,7 @@ import {
23
23
  pMap,
24
24
  SKIP,
25
25
  StringMap,
26
- UnixTimestampMillisNumber,
26
+ UnixTimestampMillis,
27
27
  Unsaved,
28
28
  ZodSchema,
29
29
  ZodValidationError,
@@ -1257,7 +1257,23 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
1257
1257
  })
1258
1258
  } else {
1259
1259
  // Joi
1260
+ const start = performance.now()
1260
1261
  const vr = getValidationResult(obj, schema, objectName)
1262
+ const end = performance.now()
1263
+ const tookMillis = end - start
1264
+
1265
+ if (
1266
+ this.cfg.debugValidationTimeThreshhold &&
1267
+ tookMillis >= this.cfg.debugValidationTimeThreshhold
1268
+ ) {
1269
+ this.cfg.onValidationTimeThreshold?.({
1270
+ tookMillis,
1271
+ error: !!vr.error,
1272
+ table,
1273
+ obj,
1274
+ })
1275
+ }
1276
+
1261
1277
  error = vr.error
1262
1278
  convertedValue = vr.value
1263
1279
  }
@@ -1326,7 +1342,7 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
1326
1342
  }
1327
1343
  }
1328
1344
 
1329
- protected logResult(started: number, op: string, res: any, table: string): void {
1345
+ protected logResult(started: UnixTimestampMillis, op: string, res: any, table: string): void {
1330
1346
  if (!this.cfg.logLevel) return
1331
1347
 
1332
1348
  let logRes: any
@@ -1349,19 +1365,19 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
1349
1365
  this.cfg.logger?.log(`<< ${table}.${op}: ${logRes} in ${_since(started)}`, ...args)
1350
1366
  }
1351
1367
 
1352
- protected logSaveResult(started: number, op: string, table: string): void {
1368
+ protected logSaveResult(started: UnixTimestampMillis, op: string, table: string): void {
1353
1369
  if (!this.cfg.logLevel) return
1354
1370
  this.cfg.logger?.log(`<< ${table}.${op} in ${_since(started)}`)
1355
1371
  }
1356
1372
 
1357
- protected logStarted(op: string, table: string, force = false): UnixTimestampMillisNumber {
1373
+ protected logStarted(op: string, table: string, force = false): UnixTimestampMillis {
1358
1374
  if (this.cfg.logStarted || force) {
1359
1375
  this.cfg.logger?.log(`>> ${table}.${op}`)
1360
1376
  }
1361
- return Date.now()
1377
+ return Date.now() as UnixTimestampMillis
1362
1378
  }
1363
1379
 
1364
- protected logSaveStarted(op: string, items: any, table: string): UnixTimestampMillisNumber {
1380
+ protected logSaveStarted(op: string, items: any, table: string): UnixTimestampMillis {
1365
1381
  if (this.cfg.logStarted) {
1366
1382
  const args: any[] = [`>> ${table}.${op}`]
1367
1383
  if (Array.isArray(items)) {
@@ -1379,7 +1395,7 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
1379
1395
  this.cfg.logger?.log(...args)
1380
1396
  }
1381
1397
 
1382
- return Date.now()
1398
+ return Date.now() as UnixTimestampMillis
1383
1399
  }
1384
1400
  }
1385
1401
 
package/src/db.model.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ObjectWithId, UnixTimestampNumber } from '@naturalcycles/js-lib'
1
+ import { ObjectWithId, UnixTimestamp } from '@naturalcycles/js-lib'
2
2
  import { CommonDB } from './common.db'
3
3
 
4
4
  /**
@@ -57,7 +57,7 @@ export interface CommonDBReadOptions extends CommonDBOptions {
57
57
  * If provided (and supported by the DB) - will read the data at that point in time (aka "Time machine" feature).
58
58
  * This feature is named PITR (point-in-time-recovery) query in Datastore.
59
59
  */
60
- readAt?: UnixTimestampNumber
60
+ readAt?: UnixTimestamp
61
61
  }
62
62
 
63
63
  /**
@@ -1,4 +1,4 @@
1
- import { Integer, UnixTimestampNumber } from '@naturalcycles/js-lib'
1
+ import { Integer, UnixTimestamp } from '@naturalcycles/js-lib'
2
2
  import { ReadableTyped } from '@naturalcycles/nodejs-lib'
3
3
  import { CommonDBCreateOptions } from '../db.model'
4
4
 
@@ -72,7 +72,7 @@ export interface CommonKeyValueDBSaveBatchOptions {
72
72
  * If set (and if it's implemented by the driver) - will set expiry TTL for each key of the batch.
73
73
  * E.g EXAT in Redis.
74
74
  */
75
- expireAt?: UnixTimestampNumber
75
+ expireAt?: UnixTimestamp
76
76
  }
77
77
 
78
78
  /**
@@ -1,4 +1,10 @@
1
- import { AsyncMemoCache, localTime, MISS, NumberOfSeconds } from '@naturalcycles/js-lib'
1
+ import {
2
+ AsyncMemoCache,
3
+ localTime,
4
+ MISS,
5
+ NumberOfSeconds,
6
+ UnixTimestamp,
7
+ } from '@naturalcycles/js-lib'
2
8
  import { CommonKeyValueDao } from './commonKeyValueDao'
3
9
 
4
10
  export interface CommonKeyValueDaoMemoCacheCfg<VALUE> {
@@ -26,7 +32,9 @@ export class CommonKeyValueDaoMemoCache<VALUE> implements AsyncMemoCache<string,
26
32
  }
27
33
 
28
34
  async set(k: string, v: VALUE): Promise<void> {
29
- const opt = this.cfg.ttl ? { expireAt: localTime.nowUnix() + this.cfg.ttl } : undefined
35
+ const opt = this.cfg.ttl
36
+ ? { expireAt: (localTime.nowUnix() + this.cfg.ttl) as UnixTimestamp }
37
+ : undefined
30
38
 
31
39
  await this.cfg.dao.save(k, v, opt)
32
40
  }
@@ -6,7 +6,7 @@ import {
6
6
  localTime,
7
7
  pMap,
8
8
  StringMap,
9
- UnixTimestampNumber,
9
+ UnixTimestamp,
10
10
  } from '@naturalcycles/js-lib'
11
11
  import {
12
12
  _pipeline,
@@ -61,13 +61,13 @@ export interface DBPipelineBackupOptions extends TransformLogProgressOptions {
61
61
  /**
62
62
  * If set - will do "incremental backup" (not full), only for entities that updated >= `sinceUpdated`
63
63
  */
64
- sinceUpdated?: UnixTimestampNumber
64
+ sinceUpdated?: UnixTimestamp
65
65
 
66
66
  /**
67
67
  * Map for each table a `sinceUpdated` timestamp, or `undefined`.
68
68
  * If set - will do "incremental backup" (not full), only for entities that updated >= `sinceUpdated` (on a per table basis)
69
69
  */
70
- sinceUpdatedPerTable?: StringMap<UnixTimestampNumber>
70
+ sinceUpdatedPerTable?: StringMap<UnixTimestamp>
71
71
 
72
72
  /**
73
73
  * By default, dbPipelineBackup creates a Query based on sinceUpdated.
@@ -5,6 +5,7 @@ import {
5
5
  ErrorMode,
6
6
  localTime,
7
7
  pMap,
8
+ UnixTimestamp,
8
9
  } from '@naturalcycles/js-lib'
9
10
  import {
10
11
  _pipeline,
@@ -68,7 +69,7 @@ export interface DBPipelineCopyOptions extends TransformLogProgressOptions {
68
69
  *
69
70
  * @default undefined
70
71
  */
71
- sinceUpdated?: number
72
+ sinceUpdated?: UnixTimestamp
72
73
 
73
74
  /**
74
75
  * Optionally you can provide mapper that is going to run for each table.
@@ -8,6 +8,7 @@ import {
8
8
  JsonSchemaObject,
9
9
  localTime,
10
10
  pMap,
11
+ UnixTimestamp,
11
12
  } from '@naturalcycles/js-lib'
12
13
  import {
13
14
  _pipeline,
@@ -80,7 +81,7 @@ export interface DBPipelineRestoreOptions extends TransformLogProgressOptions {
80
81
  *
81
82
  * @default undefined
82
83
  */
83
- sinceUpdated?: number
84
+ sinceUpdated?: UnixTimestamp
84
85
 
85
86
  /**
86
87
  * @default false
@@ -1,4 +1,10 @@
1
- import { _range, BaseDBEntity, jsonSchema, JsonSchemaObject } from '@naturalcycles/js-lib'
1
+ import {
2
+ _range,
3
+ BaseDBEntity,
4
+ jsonSchema,
5
+ JsonSchemaObject,
6
+ UnixTimestamp,
7
+ } from '@naturalcycles/js-lib'
2
8
  import {
3
9
  baseDBEntitySchema,
4
10
  binarySchema,
@@ -8,7 +14,7 @@ import {
8
14
  stringSchema,
9
15
  } from '@naturalcycles/nodejs-lib'
10
16
 
11
- const MOCK_TS_2018_06_21 = 1529539200
17
+ const MOCK_TS_2018_06_21 = 1529539200 as UnixTimestamp
12
18
 
13
19
  export const TEST_TABLE = 'TEST_TABLE'
14
20