@naturalcycles/db-lib 10.20.3 → 10.21.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.
@@ -158,10 +158,10 @@ export declare class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity
158
158
  * Proxy to this.cfg.db.ping
159
159
  */
160
160
  ping(): Promise<void>;
161
- withId(id: ID): DaoWithId<typeof this>;
162
- withIds(ids: ID[]): DaoWithIds<typeof this>;
163
- withRowsToSave(rows: Unsaved<BM>[]): DaoWithRows<typeof this>;
164
- withRowToSave(row: Unsaved<BM>, opt?: DaoWithRowOptions<BM>): DaoWithRow<typeof this>;
161
+ withId(id: ID): DaoWithId<CommonDao<BM, DBM, ID>>;
162
+ withIds(ids: ID[]): DaoWithIds<CommonDao<BM, DBM, ID>>;
163
+ withRowsToSave(rows: Unsaved<BM>[]): DaoWithRows<CommonDao<BM, DBM, ID>>;
164
+ withRowToSave(row: Unsaved<BM>, opt?: DaoWithRowOptions<BM>): DaoWithRow<CommonDao<BM, DBM, ID>>;
165
165
  /**
166
166
  * Load rows (by their ids) from Multiple tables at once.
167
167
  * An optimized way to load data, minimizing DB round-trips.
@@ -177,8 +177,8 @@ export declare class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity
177
177
  /**
178
178
  * Very @experimental.
179
179
  */
180
- static multiDeleteByIds(inputs: DaoWithIds<any>[], _opt?: CommonDaoOptions): Promise<NonNegativeInteger>;
181
- static multiSave(inputs: (DaoWithRows<any> | DaoWithRow<any>)[], opt?: CommonDaoSaveBatchOptions<any>): Promise<void>;
180
+ static multiDeleteByIds(inputs: DaoWithIds<AnyDao>[], _opt?: CommonDaoOptions): Promise<NonNegativeInteger>;
181
+ static multiSave(inputs: (DaoWithRows<AnyDao> | DaoWithRow<AnyDao>)[], opt?: CommonDaoSaveBatchOptions<any>): Promise<void>;
182
182
  createTransaction(opt?: CommonDBTransactionOptions): Promise<CommonDaoTransaction>;
183
183
  runInTransaction<T = void>(fn: CommonDaoTransactionFn<T>, opt?: CommonDBTransactionOptions): Promise<T>;
184
184
  private ensureRequired;
@@ -6,7 +6,7 @@ import { _deepJsonEquals } from '@naturalcycles/js-lib/object/deepEquals.js';
6
6
  import { _filterUndefinedValues, _objectAssignExact, } from '@naturalcycles/js-lib/object/object.util.js';
7
7
  import { pMap } from '@naturalcycles/js-lib/promise/pMap.js';
8
8
  import { _stringMapEntries, _stringMapValues, } from '@naturalcycles/js-lib/types';
9
- import { _passthroughPredicate, _typeCast, SKIP } from '@naturalcycles/js-lib/types';
9
+ import { _passthroughPredicate, _typeCast } from '@naturalcycles/js-lib/types';
10
10
  import { stringId } from '@naturalcycles/nodejs-lib';
11
11
  import { transformFlatten, transformMapSync, } from '@naturalcycles/nodejs-lib/stream';
12
12
  import { _pipeline, transformChunk, transformLogProgress, transformMap, transformNoOp, writableVoid, } from '@naturalcycles/nodejs-lib/stream';
@@ -454,12 +454,8 @@ export class CommonDao {
454
454
  }
455
455
  this.assignIdCreatedUpdated(bm, opt); // mutates
456
456
  _typeCast(bm);
457
- let dbm = await this.bmToDBM(bm, opt); // validates BM
458
- if (this.cfg.hooks.beforeSave) {
459
- dbm = (await this.cfg.hooks.beforeSave(dbm));
460
- if (dbm === null)
461
- return bm;
462
- }
457
+ const dbm = await this.bmToDBM(bm, opt); // validates BM
458
+ this.cfg.hooks.beforeSave?.(dbm);
463
459
  const table = opt.table || this.cfg.table;
464
460
  const saveOptions = this.prepareSaveOptions(opt);
465
461
  await (opt.tx || this.cfg.db).saveBatch(table, [dbm], saveOptions);
@@ -471,12 +467,8 @@ export class CommonDao {
471
467
  async saveAsDBM(dbm, opt = {}) {
472
468
  this.requireWriteAccess();
473
469
  this.assignIdCreatedUpdated(dbm, opt); // mutates
474
- let row = this.anyToDBM(dbm, opt);
475
- if (this.cfg.hooks.beforeSave) {
476
- row = (await this.cfg.hooks.beforeSave(row));
477
- if (row === null)
478
- return dbm;
479
- }
470
+ const row = this.anyToDBM(dbm, opt);
471
+ this.cfg.hooks.beforeSave?.(row);
480
472
  const table = opt.table || this.cfg.table;
481
473
  const saveOptions = this.prepareSaveOptions(opt);
482
474
  await (opt.tx || this.cfg.db).saveBatch(table, [row], saveOptions);
@@ -490,9 +482,9 @@ export class CommonDao {
490
482
  return [];
491
483
  this.requireWriteAccess();
492
484
  bms.forEach(bm => this.assignIdCreatedUpdated(bm, opt));
493
- let dbms = await this.bmsToDBM(bms, opt);
494
- if (this.cfg.hooks.beforeSave && dbms.length) {
495
- dbms = (await pMap(dbms, async (dbm) => await this.cfg.hooks.beforeSave(dbm))).filter(_isTruthy);
485
+ const dbms = await this.bmsToDBM(bms, opt);
486
+ if (this.cfg.hooks.beforeSave) {
487
+ dbms.forEach(dbm => this.cfg.hooks.beforeSave(dbm));
496
488
  }
497
489
  const table = opt.table || this.cfg.table;
498
490
  const saveOptions = this.prepareSaveOptions(opt);
@@ -507,9 +499,9 @@ export class CommonDao {
507
499
  return [];
508
500
  this.requireWriteAccess();
509
501
  dbms.forEach(dbm => this.assignIdCreatedUpdated(dbm, opt));
510
- let rows = this.anyToDBMs(dbms, opt);
511
- if (this.cfg.hooks.beforeSave && rows.length) {
512
- rows = (await pMap(rows, async (row) => await this.cfg.hooks.beforeSave(row))).filter(_isTruthy);
502
+ const rows = this.anyToDBMs(dbms, opt);
503
+ if (this.cfg.hooks.beforeSave) {
504
+ rows.forEach(row => this.cfg.hooks.beforeSave(row));
513
505
  }
514
506
  const table = opt.table || this.cfg.table;
515
507
  const saveOptions = this.prepareSaveOptions(opt);
@@ -550,13 +542,9 @@ export class CommonDao {
550
542
  const { chunkSize = 500, chunkConcurrency = 32, errorMode } = opt;
551
543
  return [
552
544
  transformMap(async (bm) => {
553
- this.assignIdCreatedUpdated(bm, opt); // mutates
554
- let dbm = await this.bmToDBM(bm, opt);
555
- if (beforeSave) {
556
- dbm = (await beforeSave(dbm));
557
- if (dbm === null)
558
- return SKIP;
559
- }
545
+ this.assignIdCreatedUpdated(bm, opt);
546
+ const dbm = await this.bmToDBM(bm, opt);
547
+ beforeSave?.(dbm);
560
548
  return dbm;
561
549
  }, {
562
550
  errorMode,
@@ -901,12 +889,18 @@ export class CommonDao {
901
889
  }
902
890
  }
903
891
  dao.assignIdCreatedUpdated(row, opt);
904
- dbmsByTable[table].push(await dao.bmToDBM(row, opt));
892
+ const dbm = await dao.bmToDBM(row, opt);
893
+ dao.cfg.hooks.beforeSave?.(dbm);
894
+ dbmsByTable[table].push(dbm);
905
895
  }
906
896
  else {
907
897
  // Plural
908
898
  input.rows.forEach(bm => dao.assignIdCreatedUpdated(bm, opt));
909
- dbmsByTable[table].push(...(await dao.bmsToDBM(input.rows, opt)));
899
+ const dbms = await dao.bmsToDBM(input.rows, opt);
900
+ if (dao.cfg.hooks.beforeSave) {
901
+ dbms.forEach(dbm => dao.cfg.hooks.beforeSave(dbm));
902
+ }
903
+ dbmsByTable[table].push(...dbms);
910
904
  }
911
905
  });
912
906
  await db.multiSave(dbmsByTable);
@@ -1,11 +1,11 @@
1
1
  import type { ValidationFunction } from '@naturalcycles/js-lib';
2
2
  import type { AppError, ErrorMode } from '@naturalcycles/js-lib/error';
3
3
  import type { CommonLogger } from '@naturalcycles/js-lib/log';
4
- import type { BaseDBEntity, Promisable, UnixTimestamp } from '@naturalcycles/js-lib/types';
4
+ import type { BaseDBEntity, UnixTimestamp } from '@naturalcycles/js-lib/types';
5
5
  import type { TransformLogProgressOptions, TransformMapOptions } from '@naturalcycles/nodejs-lib/stream';
6
6
  import type { CommonDB } from '../commondb/common.db.js';
7
7
  import type { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions } from '../db.model.js';
8
- export interface CommonDaoHooks<BM extends BaseDBEntity, DBM extends BaseDBEntity, ID = BM['id']> {
8
+ export interface CommonDaoHooks<BM extends BaseDBEntity, DBM extends BaseDBEntity, ID extends string = BM['id']> {
9
9
  /**
10
10
  * Allows to override the id generation function.
11
11
  * By default it uses `stringId` from nodejs-lib
@@ -50,15 +50,10 @@ export interface CommonDaoHooks<BM extends BaseDBEntity, DBM extends BaseDBEntit
50
50
  *
51
51
  * Normally does nothing.
52
52
  *
53
- * You can change the DBM as you want here: ok to mutate or not, but you need to return the DBM
54
- * to pass it further.
55
- *
56
- * You can return `null` to prevent it from being saved, without throwing an error.
57
- * `.save` method will then return the BM/DBM as it has entered the method (it **won't** return the null value!).
58
- *
59
53
  * You can do validations as needed here and throw errors, they will be propagated.
54
+ * Or, you can mutate the DBM if needed.
60
55
  */
61
- beforeSave?: (dbm: DBM) => Promisable<DBM | null>;
56
+ beforeSave?: (dbm: DBM) => void;
62
57
  /**
63
58
  * Called in:
64
59
  * - dbmToBM (applied before DBM becomes BM)
@@ -95,7 +90,7 @@ export declare enum CommonDaoLogLevel {
95
90
  */
96
91
  DATA_FULL = 30
97
92
  }
98
- export interface CommonDaoCfg<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, ID = BM['id']> {
93
+ export interface CommonDaoCfg<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, ID extends string = BM['id']> {
99
94
  db: CommonDB;
100
95
  table: string;
101
96
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/db-lib",
3
3
  "type": "module",
4
- "version": "10.20.3",
4
+ "version": "10.21.0",
5
5
  "dependencies": {
6
6
  "@naturalcycles/js-lib": "^15",
7
7
  "@naturalcycles/nodejs-lib": "^15"
@@ -1,7 +1,7 @@
1
1
  import type { ValidationFunction } from '@naturalcycles/js-lib'
2
2
  import type { AppError, ErrorMode } from '@naturalcycles/js-lib/error'
3
3
  import type { CommonLogger } from '@naturalcycles/js-lib/log'
4
- import type { BaseDBEntity, Promisable, UnixTimestamp } from '@naturalcycles/js-lib/types'
4
+ import type { BaseDBEntity, UnixTimestamp } from '@naturalcycles/js-lib/types'
5
5
  import type {
6
6
  TransformLogProgressOptions,
7
7
  TransformMapOptions,
@@ -9,7 +9,11 @@ import type {
9
9
  import type { CommonDB } from '../commondb/common.db.js'
10
10
  import type { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions } from '../db.model.js'
11
11
 
12
- export interface CommonDaoHooks<BM extends BaseDBEntity, DBM extends BaseDBEntity, ID = BM['id']> {
12
+ export interface CommonDaoHooks<
13
+ BM extends BaseDBEntity,
14
+ DBM extends BaseDBEntity,
15
+ ID extends string = BM['id'],
16
+ > {
13
17
  /**
14
18
  * Allows to override the id generation function.
15
19
  * By default it uses `stringId` from nodejs-lib
@@ -61,15 +65,10 @@ export interface CommonDaoHooks<BM extends BaseDBEntity, DBM extends BaseDBEntit
61
65
  *
62
66
  * Normally does nothing.
63
67
  *
64
- * You can change the DBM as you want here: ok to mutate or not, but you need to return the DBM
65
- * to pass it further.
66
- *
67
- * You can return `null` to prevent it from being saved, without throwing an error.
68
- * `.save` method will then return the BM/DBM as it has entered the method (it **won't** return the null value!).
69
- *
70
68
  * You can do validations as needed here and throw errors, they will be propagated.
69
+ * Or, you can mutate the DBM if needed.
71
70
  */
72
- beforeSave?: (dbm: DBM) => Promisable<DBM | null>
71
+ beforeSave?: (dbm: DBM) => void
73
72
 
74
73
  /**
75
74
  * Called in:
@@ -113,7 +112,7 @@ export enum CommonDaoLogLevel {
113
112
  export interface CommonDaoCfg<
114
113
  BM extends BaseDBEntity,
115
114
  DBM extends BaseDBEntity = BM,
116
- ID = BM['id'],
115
+ ID extends string = BM['id'],
117
116
  > {
118
117
  db: CommonDB
119
118
  table: string
@@ -20,7 +20,7 @@ import {
20
20
  type StringMap,
21
21
  type Unsaved,
22
22
  } from '@naturalcycles/js-lib/types'
23
- import { _passthroughPredicate, _typeCast, SKIP } from '@naturalcycles/js-lib/types'
23
+ import { _passthroughPredicate, _typeCast } from '@naturalcycles/js-lib/types'
24
24
  import { stringId } from '@naturalcycles/nodejs-lib'
25
25
  import {
26
26
  type ReadableTyped,
@@ -616,13 +616,8 @@ export class CommonDao<
616
616
 
617
617
  this.assignIdCreatedUpdated(bm, opt) // mutates
618
618
  _typeCast<BM>(bm)
619
- let dbm = await this.bmToDBM(bm, opt) // validates BM
620
-
621
- if (this.cfg.hooks!.beforeSave) {
622
- dbm = (await this.cfg.hooks!.beforeSave(dbm))!
623
- if (dbm === null) return bm
624
- }
625
-
619
+ const dbm = await this.bmToDBM(bm, opt) // validates BM
620
+ this.cfg.hooks!.beforeSave?.(dbm)
626
621
  const table = opt.table || this.cfg.table
627
622
  const saveOptions = this.prepareSaveOptions(opt)
628
623
 
@@ -637,15 +632,9 @@ export class CommonDao<
637
632
 
638
633
  async saveAsDBM(dbm: Unsaved<DBM>, opt: CommonDaoSaveOptions<BM, DBM> = {}): Promise<DBM> {
639
634
  this.requireWriteAccess()
640
-
641
635
  this.assignIdCreatedUpdated(dbm, opt) // mutates
642
- let row = this.anyToDBM(dbm, opt)
643
-
644
- if (this.cfg.hooks!.beforeSave) {
645
- row = (await this.cfg.hooks!.beforeSave(row))!
646
- if (row === null) return dbm as DBM
647
- }
648
-
636
+ const row = this.anyToDBM(dbm, opt)
637
+ this.cfg.hooks!.beforeSave?.(row)
649
638
  const table = opt.table || this.cfg.table
650
639
  const saveOptions = this.prepareSaveOptions(opt)
651
640
 
@@ -662,14 +651,10 @@ export class CommonDao<
662
651
  if (!bms.length) return []
663
652
  this.requireWriteAccess()
664
653
  bms.forEach(bm => this.assignIdCreatedUpdated(bm, opt))
665
- let dbms = await this.bmsToDBM(bms as BM[], opt)
666
-
667
- if (this.cfg.hooks!.beforeSave && dbms.length) {
668
- dbms = (await pMap(dbms, async dbm => await this.cfg.hooks!.beforeSave!(dbm))).filter(
669
- _isTruthy,
670
- )
654
+ const dbms = await this.bmsToDBM(bms as BM[], opt)
655
+ if (this.cfg.hooks!.beforeSave) {
656
+ dbms.forEach(dbm => this.cfg.hooks!.beforeSave!(dbm))
671
657
  }
672
-
673
658
  const table = opt.table || this.cfg.table
674
659
  const saveOptions = this.prepareSaveOptions(opt)
675
660
 
@@ -689,14 +674,10 @@ export class CommonDao<
689
674
  if (!dbms.length) return []
690
675
  this.requireWriteAccess()
691
676
  dbms.forEach(dbm => this.assignIdCreatedUpdated(dbm, opt))
692
- let rows = this.anyToDBMs(dbms as DBM[], opt)
693
-
694
- if (this.cfg.hooks!.beforeSave && rows.length) {
695
- rows = (await pMap(rows, async row => await this.cfg.hooks!.beforeSave!(row))).filter(
696
- _isTruthy,
697
- )
677
+ const rows = this.anyToDBMs(dbms as DBM[], opt)
678
+ if (this.cfg.hooks!.beforeSave) {
679
+ rows.forEach(row => this.cfg.hooks!.beforeSave!(row))
698
680
  }
699
-
700
681
  const table = opt.table || this.cfg.table
701
682
  const saveOptions = this.prepareSaveOptions(opt)
702
683
 
@@ -752,15 +733,9 @@ export class CommonDao<
752
733
  return [
753
734
  transformMap<BM, DBM>(
754
735
  async bm => {
755
- this.assignIdCreatedUpdated(bm, opt) // mutates
756
-
757
- let dbm = await this.bmToDBM(bm, opt)
758
-
759
- if (beforeSave) {
760
- dbm = (await beforeSave(dbm))!
761
- if (dbm === null) return SKIP
762
- }
763
-
736
+ this.assignIdCreatedUpdated(bm, opt)
737
+ const dbm = await this.bmToDBM(bm, opt)
738
+ beforeSave?.(dbm)
764
739
  return dbm
765
740
  },
766
741
  {
@@ -1035,28 +1010,28 @@ export class CommonDao<
1035
1010
  await this.cfg.db.ping()
1036
1011
  }
1037
1012
 
1038
- withId(id: ID): DaoWithId<typeof this> {
1013
+ withId(id: ID): DaoWithId<CommonDao<BM, DBM, ID>> {
1039
1014
  return {
1040
1015
  dao: this,
1041
1016
  id,
1042
1017
  }
1043
1018
  }
1044
1019
 
1045
- withIds(ids: ID[]): DaoWithIds<typeof this> {
1020
+ withIds(ids: ID[]): DaoWithIds<CommonDao<BM, DBM, ID>> {
1046
1021
  return {
1047
1022
  dao: this,
1048
1023
  ids,
1049
1024
  }
1050
1025
  }
1051
1026
 
1052
- withRowsToSave(rows: Unsaved<BM>[]): DaoWithRows<typeof this> {
1027
+ withRowsToSave(rows: Unsaved<BM>[]): DaoWithRows<CommonDao<BM, DBM, ID>> {
1053
1028
  return {
1054
1029
  dao: this,
1055
1030
  rows: rows as any,
1056
1031
  }
1057
1032
  }
1058
1033
 
1059
- withRowToSave(row: Unsaved<BM>, opt?: DaoWithRowOptions<BM>): DaoWithRow<typeof this> {
1034
+ withRowToSave(row: Unsaved<BM>, opt?: DaoWithRowOptions<BM>): DaoWithRow<CommonDao<BM, DBM, ID>> {
1060
1035
  return {
1061
1036
  dao: this,
1062
1037
  row: row as any,
@@ -1167,7 +1142,7 @@ export class CommonDao<
1167
1142
  * Very @experimental.
1168
1143
  */
1169
1144
  static async multiDeleteByIds(
1170
- inputs: DaoWithIds<any>[],
1145
+ inputs: DaoWithIds<AnyDao>[],
1171
1146
  _opt: CommonDaoOptions = {},
1172
1147
  ): Promise<NonNegativeInteger> {
1173
1148
  if (!inputs.length) return 0
@@ -1181,7 +1156,7 @@ export class CommonDao<
1181
1156
  }
1182
1157
 
1183
1158
  static async multiSave(
1184
- inputs: (DaoWithRows<any> | DaoWithRow<any>)[],
1159
+ inputs: (DaoWithRows<AnyDao> | DaoWithRow<AnyDao>)[],
1185
1160
  opt: CommonDaoSaveBatchOptions<any> = {},
1186
1161
  ): Promise<void> {
1187
1162
  if (!inputs.length) return
@@ -1208,11 +1183,17 @@ export class CommonDao<
1208
1183
  }
1209
1184
 
1210
1185
  dao.assignIdCreatedUpdated(row, opt)
1211
- dbmsByTable[table].push(await dao.bmToDBM(row, opt))
1186
+ const dbm = await dao.bmToDBM(row, opt)
1187
+ dao.cfg.hooks!.beforeSave?.(dbm)
1188
+ dbmsByTable[table].push(dbm)
1212
1189
  } else {
1213
1190
  // Plural
1214
1191
  input.rows.forEach(bm => dao.assignIdCreatedUpdated(bm, opt))
1215
- dbmsByTable[table].push(...(await dao.bmsToDBM(input.rows, opt)))
1192
+ const dbms = await dao.bmsToDBM(input.rows, opt)
1193
+ if (dao.cfg.hooks!.beforeSave) {
1194
+ dbms.forEach(dbm => dao.cfg.hooks!.beforeSave!(dbm))
1195
+ }
1196
+ dbmsByTable[table].push(...dbms)
1216
1197
  }
1217
1198
  })
1218
1199