@naturalcycles/db-lib 10.0.2 → 10.1.1

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.
Files changed (110) hide show
  1. package/dist/adapter/cachedb/cache.db.d.ts +5 -5
  2. package/dist/adapter/cachedb/cache.db.js +8 -12
  3. package/dist/adapter/cachedb/cache.db.model.d.ts +2 -2
  4. package/dist/adapter/cachedb/cache.db.model.js +1 -2
  5. package/dist/adapter/cachedb/index.d.ts +2 -2
  6. package/dist/adapter/cachedb/index.js +2 -5
  7. package/dist/adapter/file/file.db.d.ts +5 -6
  8. package/dist/adapter/file/file.db.js +25 -27
  9. package/dist/adapter/file/file.db.model.d.ts +2 -2
  10. package/dist/adapter/file/file.db.model.js +1 -2
  11. package/dist/adapter/file/inMemory.persistence.plugin.d.ts +2 -2
  12. package/dist/adapter/file/inMemory.persistence.plugin.js +3 -7
  13. package/dist/adapter/file/index.d.ts +3 -3
  14. package/dist/adapter/file/index.js +3 -7
  15. package/dist/adapter/file/localFile.persistence.plugin.d.ts +2 -2
  16. package/dist/adapter/file/localFile.persistence.plugin.js +11 -15
  17. package/dist/adapter/file/noop.persistence.plugin.d.ts +2 -2
  18. package/dist/adapter/file/noop.persistence.plugin.js +1 -5
  19. package/dist/adapter/inmemory/inMemory.db.d.ts +5 -4
  20. package/dist/adapter/inmemory/inMemory.db.js +43 -41
  21. package/dist/adapter/inmemory/inMemoryKeyValueDB.d.ts +2 -2
  22. package/dist/adapter/inmemory/inMemoryKeyValueDB.js +7 -11
  23. package/dist/adapter/inmemory/queryInMemory.d.ts +1 -1
  24. package/dist/adapter/inmemory/queryInMemory.js +4 -7
  25. package/dist/base.common.db.d.ts +5 -4
  26. package/dist/base.common.db.js +8 -9
  27. package/dist/cnst.js +2 -5
  28. package/dist/common.db.d.ts +8 -2
  29. package/dist/common.db.js +3 -6
  30. package/dist/commondao/common.dao.d.ts +11 -4
  31. package/dist/commondao/common.dao.js +120 -113
  32. package/dist/commondao/common.dao.model.d.ts +2 -2
  33. package/dist/commondao/common.dao.model.js +2 -5
  34. package/dist/db.model.d.ts +6 -1
  35. package/dist/db.model.js +4 -7
  36. package/dist/index.d.ts +17 -17
  37. package/dist/index.js +17 -20
  38. package/dist/kv/commonKeyValueDB.d.ts +1 -1
  39. package/dist/kv/commonKeyValueDB.js +1 -4
  40. package/dist/kv/commonKeyValueDao.d.ts +3 -3
  41. package/dist/kv/commonKeyValueDao.js +10 -14
  42. package/dist/kv/commonKeyValueDaoMemoCache.d.ts +1 -1
  43. package/dist/kv/commonKeyValueDaoMemoCache.js +4 -8
  44. package/dist/model.util.js +9 -15
  45. package/dist/pipeline/dbPipelineBackup.d.ts +2 -2
  46. package/dist/pipeline/dbPipelineBackup.js +27 -30
  47. package/dist/pipeline/dbPipelineCopy.d.ts +2 -2
  48. package/dist/pipeline/dbPipelineCopy.js +20 -23
  49. package/dist/pipeline/dbPipelineRestore.d.ts +2 -2
  50. package/dist/pipeline/dbPipelineRestore.js +27 -30
  51. package/dist/query/dbQuery.d.ts +3 -3
  52. package/dist/query/dbQuery.js +7 -12
  53. package/dist/testing/{dbTest.d.ts → commonDBTest.d.ts} +1 -1
  54. package/dist/testing/{dbTest.js → commonDBTest.js} +81 -62
  55. package/dist/testing/commonDaoTest.d.ts +3 -0
  56. package/dist/testing/{daoTest.js → commonDaoTest.js} +101 -38
  57. package/dist/testing/index.d.ts +7 -7
  58. package/dist/testing/index.js +6 -20
  59. package/dist/testing/keyValueDBTest.d.ts +1 -1
  60. package/dist/testing/keyValueDBTest.js +28 -31
  61. package/dist/testing/keyValueDaoTest.d.ts +1 -1
  62. package/dist/testing/keyValueDaoTest.js +8 -11
  63. package/dist/testing/test.model.js +30 -37
  64. package/dist/testing/timeSeriesTest.util.d.ts +1 -1
  65. package/dist/testing/timeSeriesTest.util.js +3 -6
  66. package/dist/timeseries/commonTimeSeriesDao.d.ts +1 -1
  67. package/dist/timeseries/commonTimeSeriesDao.js +5 -9
  68. package/dist/timeseries/timeSeries.model.d.ts +1 -1
  69. package/dist/timeseries/timeSeries.model.js +1 -2
  70. package/dist/transaction/dbTransaction.util.d.ts +3 -2
  71. package/dist/transaction/dbTransaction.util.js +2 -5
  72. package/dist/validation/index.d.ts +2 -2
  73. package/dist/validation/index.js +25 -28
  74. package/package.json +3 -3
  75. package/src/adapter/cachedb/cache.db.model.ts +2 -2
  76. package/src/adapter/cachedb/cache.db.ts +6 -6
  77. package/src/adapter/cachedb/index.ts +2 -2
  78. package/src/adapter/file/file.db.model.ts +2 -2
  79. package/src/adapter/file/file.db.ts +8 -6
  80. package/src/adapter/file/inMemory.persistence.plugin.ts +2 -2
  81. package/src/adapter/file/index.ts +3 -3
  82. package/src/adapter/file/localFile.persistence.plugin.ts +2 -2
  83. package/src/adapter/file/noop.persistence.plugin.ts +2 -2
  84. package/src/adapter/inmemory/inMemory.db.ts +15 -10
  85. package/src/adapter/inmemory/inMemoryKeyValueDB.ts +7 -3
  86. package/src/adapter/inmemory/queryInMemory.ts +1 -1
  87. package/src/base.common.db.ts +10 -5
  88. package/src/common.db.ts +10 -2
  89. package/src/commondao/common.dao.model.ts +2 -2
  90. package/src/commondao/common.dao.ts +20 -6
  91. package/src/db.model.ts +7 -1
  92. package/src/index.ts +17 -17
  93. package/src/kv/commonKeyValueDB.ts +1 -1
  94. package/src/kv/commonKeyValueDao.ts +3 -3
  95. package/src/kv/commonKeyValueDaoMemoCache.ts +1 -1
  96. package/src/pipeline/dbPipelineBackup.ts +2 -2
  97. package/src/pipeline/dbPipelineCopy.ts +3 -3
  98. package/src/pipeline/dbPipelineRestore.ts +2 -2
  99. package/src/query/dbQuery.ts +3 -3
  100. package/src/testing/{dbTest.ts → commonDBTest.ts} +34 -6
  101. package/src/testing/{daoTest.ts → commonDaoTest.ts} +89 -11
  102. package/src/testing/index.ts +7 -7
  103. package/src/testing/keyValueDBTest.ts +2 -2
  104. package/src/testing/keyValueDaoTest.ts +3 -3
  105. package/src/testing/timeSeriesTest.util.ts +1 -1
  106. package/src/timeseries/commonTimeSeriesDao.ts +2 -2
  107. package/src/timeseries/timeSeries.model.ts +1 -1
  108. package/src/transaction/dbTransaction.util.ts +3 -2
  109. package/src/validation/index.ts +8 -3
  110. package/dist/testing/daoTest.d.ts +0 -3
@@ -1,12 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CommonDaoTransaction = exports.CommonDao = void 0;
4
- const js_lib_1 = require("@naturalcycles/js-lib");
5
- const index_js_1 = require("@naturalcycles/js-lib/dist/zod/index.js");
6
- const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
7
- const cnst_1 = require("../cnst");
8
- const dbQuery_1 = require("../query/dbQuery");
9
- const common_dao_model_1 = require("./common.dao.model");
1
+ import { _assert, _deepCopy, _deepJsonEquals, _filterUndefinedValues, _isTruthy, _objectAssignExact, _passthroughPredicate, _since, _truncate, _typeCast, _uniqBy, AppError, ErrorMode, localTime, pMap, SKIP, } from '@naturalcycles/js-lib';
2
+ import { ZodSchema, zSafeValidate } from '@naturalcycles/js-lib/dist/zod/index.js';
3
+ import { _pipeline, AjvSchema, getValidationResult, stringId, transformChunk, transformLogProgress, transformMap, transformNoOp, writableVoid, } from '@naturalcycles/nodejs-lib';
4
+ import { DBLibError } from '../cnst.js';
5
+ import { RunnableDBQuery } from '../query/dbQuery.js';
6
+ import { CommonDaoLogLevel } from './common.dao.model.js';
10
7
  const isGAE = !!process.env['GAE_INSTANCE'];
11
8
  const isCI = !!process.env['CI'];
12
9
  /**
@@ -16,7 +13,7 @@ const isCI = !!process.env['CI'];
16
13
  * BM = Backend model (optimized for API access)
17
14
  * TM = Transport model (optimized to be sent over the wire)
18
15
  */
19
- class CommonDao {
16
+ export class CommonDao {
20
17
  cfg;
21
18
  constructor(cfg) {
22
19
  this.cfg = cfg;
@@ -24,7 +21,7 @@ class CommonDao {
24
21
  // Default is to NOT log in AppEngine and in CI,
25
22
  // otherwise to log Operations
26
23
  // e.g in Dev (local machine), Test - it will log operations (useful for debugging)
27
- logLevel: isGAE || isCI ? common_dao_model_1.CommonDaoLogLevel.NONE : common_dao_model_1.CommonDaoLogLevel.OPERATIONS,
24
+ logLevel: isGAE || isCI ? CommonDaoLogLevel.NONE : CommonDaoLogLevel.OPERATIONS,
28
25
  generateId: true,
29
26
  assignGeneratedIds: false,
30
27
  useCreatedProperty: true,
@@ -42,7 +39,7 @@ class CommonDao {
42
39
  },
43
40
  };
44
41
  if (this.cfg.generateId) {
45
- this.cfg.hooks.createRandomId ||= () => (0, nodejs_lib_1.stringId)();
42
+ this.cfg.hooks.createRandomId ||= () => stringId();
46
43
  }
47
44
  else {
48
45
  delete this.cfg.hooks.createRandomId;
@@ -98,12 +95,12 @@ class CommonDao {
98
95
  async getByIds(ids, opt = {}) {
99
96
  if (!ids.length)
100
97
  return [];
101
- const op = `getByIds ${ids.length} id(s) (${(0, js_lib_1._truncate)(ids.slice(0, 10).join(', '), 50)})`;
98
+ const op = `getByIds ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`;
102
99
  const table = opt.table || this.cfg.table;
103
100
  const started = this.logStarted(op, table);
104
101
  let dbms = await (opt.tx || this.cfg.db).getByIds(table, ids, opt);
105
102
  if (this.cfg.hooks.afterLoad && dbms.length) {
106
- dbms = (await (0, js_lib_1.pMap)(dbms, async (dbm) => await this.cfg.hooks.afterLoad(dbm))).filter(js_lib_1._isTruthy);
103
+ dbms = (await pMap(dbms, async (dbm) => await this.cfg.hooks.afterLoad(dbm))).filter(_isTruthy);
107
104
  }
108
105
  const bms = await this.dbmsToBM(dbms, opt);
109
106
  this.logResult(started, op, bms, table);
@@ -112,12 +109,12 @@ class CommonDao {
112
109
  async getByIdsAsDBM(ids, opt = {}) {
113
110
  if (!ids.length)
114
111
  return [];
115
- const op = `getByIdsAsDBM ${ids.length} id(s) (${(0, js_lib_1._truncate)(ids.slice(0, 10).join(', '), 50)})`;
112
+ const op = `getByIdsAsDBM ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`;
116
113
  const table = opt.table || this.cfg.table;
117
114
  const started = this.logStarted(op, table);
118
115
  let dbms = await (opt.tx || this.cfg.db).getByIds(table, ids, opt);
119
116
  if (this.cfg.hooks.afterLoad && dbms.length) {
120
- dbms = (await (0, js_lib_1.pMap)(dbms, async (dbm) => await this.cfg.hooks.afterLoad(dbm))).filter(js_lib_1._isTruthy);
117
+ dbms = (await pMap(dbms, async (dbm) => await this.cfg.hooks.afterLoad(dbm))).filter(_isTruthy);
121
118
  }
122
119
  this.logResult(started, op, dbms, table);
123
120
  return dbms;
@@ -138,7 +135,7 @@ class CommonDao {
138
135
  }
139
136
  throwRequiredError(id, opt) {
140
137
  const table = opt.table || this.cfg.table;
141
- throw new js_lib_1.AppError(`DB row required, but not found in ${table}`, {
138
+ throw new AppError(`DB row required, but not found in ${table}`, {
142
139
  table,
143
140
  id,
144
141
  });
@@ -148,7 +145,7 @@ class CommonDao {
148
145
  */
149
146
  requireWriteAccess() {
150
147
  if (this.cfg.readOnly) {
151
- throw new js_lib_1.AppError(cnst_1.DBLibError.DAO_IS_READ_ONLY, {
148
+ throw new AppError(DBLibError.DAO_IS_READ_ONLY, {
152
149
  table: this.cfg.table,
153
150
  });
154
151
  }
@@ -158,7 +155,7 @@ class CommonDao {
158
155
  */
159
156
  requireObjectMutability(opt) {
160
157
  if (this.cfg.immutable && !opt.allowMutability) {
161
- throw new js_lib_1.AppError(cnst_1.DBLibError.OBJECT_IS_IMMUTABLE, {
158
+ throw new AppError(DBLibError.OBJECT_IS_IMMUTABLE, {
162
159
  table: this.cfg.table,
163
160
  });
164
161
  }
@@ -167,7 +164,7 @@ class CommonDao {
167
164
  // todo: retry N times
168
165
  const existing = await this.cfg.db.getByIds(table, [dbm.id]);
169
166
  if (existing.length) {
170
- throw new js_lib_1.AppError(cnst_1.DBLibError.NON_UNIQUE_ID, {
167
+ throw new AppError(DBLibError.NON_UNIQUE_ID, {
171
168
  table,
172
169
  ids: existing.map(i => i.id),
173
170
  });
@@ -188,14 +185,14 @@ class CommonDao {
188
185
  * Pass `table` to override table
189
186
  */
190
187
  query(table) {
191
- return new dbQuery_1.RunnableDBQuery(this, table);
188
+ return new RunnableDBQuery(this, table);
192
189
  }
193
190
  async runQuery(q, opt) {
194
191
  const { rows } = await this.runQueryExtended(q, opt);
195
192
  return rows;
196
193
  }
197
194
  async runQuerySingleColumn(q, opt) {
198
- (0, js_lib_1._assert)(q._selectedFieldNames?.length === 1, `runQuerySingleColumn requires exactly 1 column to be selected: ${q.pretty()}`);
195
+ _assert(q._selectedFieldNames?.length === 1, `runQuerySingleColumn requires exactly 1 column to be selected: ${q.pretty()}`);
199
196
  const col = q._selectedFieldNames[0];
200
197
  const { rows } = await this.runQueryExtended(q, opt);
201
198
  return rows.map((r) => r[col]);
@@ -206,8 +203,8 @@ class CommonDao {
206
203
  * Order is not guaranteed, as queries run in parallel.
207
204
  */
208
205
  async runUnionQueries(queries, opt) {
209
- const results = (await (0, js_lib_1.pMap)(queries, async (q) => (await this.runQueryExtended(q, opt)).rows)).flat();
210
- return (0, js_lib_1._uniqBy)(results, r => r.id);
206
+ const results = (await pMap(queries, async (q) => (await this.runQueryExtended(q, opt)).rows)).flat();
207
+ return _uniqBy(results, r => r.id);
211
208
  }
212
209
  async runQueryExtended(q, opt = {}) {
213
210
  this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property
@@ -217,7 +214,7 @@ class CommonDao {
217
214
  let { rows, ...queryResult } = await this.cfg.db.runQuery(q, opt);
218
215
  const partialQuery = !!q._selectedFieldNames;
219
216
  if (this.cfg.hooks.afterLoad && rows.length) {
220
- rows = (await (0, js_lib_1.pMap)(rows, async (dbm) => await this.cfg.hooks.afterLoad(dbm))).filter(js_lib_1._isTruthy);
217
+ rows = (await pMap(rows, async (dbm) => await this.cfg.hooks.afterLoad(dbm))).filter(_isTruthy);
221
218
  }
222
219
  const bms = partialQuery ? rows : await this.dbmsToBM(rows, opt);
223
220
  this.logResult(started, op, bms, q.table);
@@ -237,7 +234,7 @@ class CommonDao {
237
234
  const started = this.logStarted(op, q.table);
238
235
  let { rows, ...queryResult } = await this.cfg.db.runQuery(q, opt);
239
236
  if (this.cfg.hooks.afterLoad && rows.length) {
240
- rows = (await (0, js_lib_1.pMap)(rows, async (dbm) => await this.cfg.hooks.afterLoad(dbm))).filter(js_lib_1._isTruthy);
237
+ rows = (await pMap(rows, async (dbm) => await this.cfg.hooks.afterLoad(dbm))).filter(_isTruthy);
241
238
  }
242
239
  const partialQuery = !!q._selectedFieldNames;
243
240
  const dbms = partialQuery ? rows : this.anyToDBMs(rows, opt);
@@ -250,8 +247,8 @@ class CommonDao {
250
247
  const op = `runQueryCount(${q.pretty()})`;
251
248
  const started = this.logStarted(op, q.table);
252
249
  const count = await this.cfg.db.runQueryCount(q, opt);
253
- if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.OPERATIONS) {
254
- this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
250
+ if (this.cfg.logLevel >= CommonDaoLogLevel.OPERATIONS) {
251
+ this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${_since(started)}`);
255
252
  }
256
253
  return count;
257
254
  }
@@ -259,78 +256,78 @@ class CommonDao {
259
256
  this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property
260
257
  q.table = opt.table || q.table;
261
258
  opt.skipValidation = opt.skipValidation !== false; // default true
262
- opt.errorMode ||= js_lib_1.ErrorMode.SUPPRESS;
259
+ opt.errorMode ||= ErrorMode.SUPPRESS;
263
260
  const partialQuery = !!q._selectedFieldNames;
264
261
  const op = `streamQueryForEach(${q.pretty()})`;
265
262
  const started = this.logStarted(op, q.table, true);
266
263
  let count = 0;
267
- await (0, nodejs_lib_1._pipeline)([
264
+ await _pipeline([
268
265
  this.cfg.db.streamQuery(q, opt),
269
- (0, nodejs_lib_1.transformMap)(async (dbm) => {
266
+ transformMap(async (dbm) => {
270
267
  count++;
271
268
  if (partialQuery)
272
269
  return dbm;
273
270
  if (this.cfg.hooks.afterLoad) {
274
271
  dbm = (await this.cfg.hooks.afterLoad(dbm));
275
272
  if (dbm === null)
276
- return js_lib_1.SKIP;
273
+ return SKIP;
277
274
  }
278
275
  return await this.dbmToBM(dbm, opt);
279
276
  }, {
280
277
  errorMode: opt.errorMode,
281
278
  }),
282
- (0, nodejs_lib_1.transformMap)(mapper, {
279
+ transformMap(mapper, {
283
280
  ...opt,
284
- predicate: js_lib_1._passthroughPredicate, // to be able to logProgress
281
+ predicate: _passthroughPredicate, // to be able to logProgress
285
282
  }),
286
283
  // LogProgress should be AFTER the mapper, to be able to report correct stats
287
- (0, nodejs_lib_1.transformLogProgress)({
284
+ transformLogProgress({
288
285
  metric: q.table,
289
286
  ...opt,
290
287
  }),
291
- (0, nodejs_lib_1.writableVoid)(),
288
+ writableVoid(),
292
289
  ]);
293
- if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.OPERATIONS) {
294
- this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
290
+ if (this.cfg.logLevel >= CommonDaoLogLevel.OPERATIONS) {
291
+ this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${_since(started)}`);
295
292
  }
296
293
  }
297
294
  async streamQueryAsDBMForEach(q, mapper, opt = {}) {
298
295
  this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property
299
296
  q.table = opt.table || q.table;
300
297
  opt.skipValidation = opt.skipValidation !== false; // default true
301
- opt.errorMode ||= js_lib_1.ErrorMode.SUPPRESS;
298
+ opt.errorMode ||= ErrorMode.SUPPRESS;
302
299
  const partialQuery = !!q._selectedFieldNames;
303
300
  const op = `streamQueryAsDBMForEach(${q.pretty()})`;
304
301
  const started = this.logStarted(op, q.table, true);
305
302
  let count = 0;
306
- await (0, nodejs_lib_1._pipeline)([
303
+ await _pipeline([
307
304
  this.cfg.db.streamQuery(q, opt),
308
- (0, nodejs_lib_1.transformMap)(async (dbm) => {
305
+ transformMap(async (dbm) => {
309
306
  count++;
310
307
  if (partialQuery)
311
308
  return dbm;
312
309
  if (this.cfg.hooks.afterLoad) {
313
310
  dbm = (await this.cfg.hooks.afterLoad(dbm));
314
311
  if (dbm === null)
315
- return js_lib_1.SKIP;
312
+ return SKIP;
316
313
  }
317
314
  return this.anyToDBM(dbm, opt);
318
315
  }, {
319
316
  errorMode: opt.errorMode,
320
317
  }),
321
- (0, nodejs_lib_1.transformMap)(mapper, {
318
+ transformMap(mapper, {
322
319
  ...opt,
323
- predicate: js_lib_1._passthroughPredicate, // to be able to logProgress
320
+ predicate: _passthroughPredicate, // to be able to logProgress
324
321
  }),
325
322
  // LogProgress should be AFTER the mapper, to be able to report correct stats
326
- (0, nodejs_lib_1.transformLogProgress)({
323
+ transformLogProgress({
327
324
  metric: q.table,
328
325
  ...opt,
329
326
  }),
330
- (0, nodejs_lib_1.writableVoid)(),
327
+ writableVoid(),
331
328
  ]);
332
- if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.OPERATIONS) {
333
- this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
329
+ if (this.cfg.logLevel >= CommonDaoLogLevel.OPERATIONS) {
330
+ this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${_since(started)}`);
334
331
  }
335
332
  }
336
333
  /**
@@ -340,18 +337,18 @@ class CommonDao {
340
337
  this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property
341
338
  q.table = opt.table || q.table;
342
339
  opt.skipValidation = opt.skipValidation !== false; // default true
343
- opt.errorMode ||= js_lib_1.ErrorMode.SUPPRESS;
340
+ opt.errorMode ||= ErrorMode.SUPPRESS;
344
341
  const partialQuery = !!q._selectedFieldNames;
345
342
  const stream = this.cfg.db.streamQuery(q, opt);
346
343
  if (partialQuery)
347
344
  return stream;
348
345
  return stream
349
346
  .on('error', err => stream.emit('error', err))
350
- .pipe((0, nodejs_lib_1.transformMap)(async (dbm) => {
347
+ .pipe(transformMap(async (dbm) => {
351
348
  if (this.cfg.hooks.afterLoad) {
352
349
  dbm = (await this.cfg.hooks.afterLoad(dbm));
353
350
  if (dbm === null)
354
- return js_lib_1.SKIP;
351
+ return SKIP;
355
352
  }
356
353
  return this.anyToDBM(dbm, opt);
357
354
  }, {
@@ -371,7 +368,7 @@ class CommonDao {
371
368
  this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property
372
369
  q.table = opt.table || q.table;
373
370
  opt.skipValidation = opt.skipValidation !== false; // default true
374
- opt.errorMode ||= js_lib_1.ErrorMode.SUPPRESS;
371
+ opt.errorMode ||= ErrorMode.SUPPRESS;
375
372
  const stream = this.cfg.db.streamQuery(q, opt);
376
373
  const partialQuery = !!q._selectedFieldNames;
377
374
  if (partialQuery)
@@ -392,11 +389,11 @@ class CommonDao {
392
389
  // .pipe(transformMap<any, DBM>(dbm => this.anyToDBM(dbm, opt), safeOpt))
393
390
  // .pipe(transformMap<DBM, BM>(dbm => this.dbmToBM(dbm, opt), safeOpt))
394
391
  .on('error', err => stream.emit('error', err))
395
- .pipe((0, nodejs_lib_1.transformMap)(async (dbm) => {
392
+ .pipe(transformMap(async (dbm) => {
396
393
  if (this.cfg.hooks.afterLoad) {
397
394
  dbm = (await this.cfg.hooks.afterLoad(dbm));
398
395
  if (dbm === null)
399
- return js_lib_1.SKIP;
396
+ return SKIP;
400
397
  }
401
398
  return await this.dbmToBM(dbm, opt);
402
399
  }, {
@@ -406,7 +403,7 @@ class CommonDao {
406
403
  // but not applying it now for perf reasons
407
404
  // UPD: applying, to be compliant with `.toArray()`, etc.
408
405
  .on('error', err => stream.emit('error', err))
409
- .pipe((0, nodejs_lib_1.transformNoOp)()));
406
+ .pipe(transformNoOp()));
410
407
  }
411
408
  async queryIds(q, opt = {}) {
412
409
  this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property
@@ -417,7 +414,7 @@ class CommonDao {
417
414
  streamQueryIds(q, opt = {}) {
418
415
  this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property
419
416
  q.table = opt.table || q.table;
420
- opt.errorMode ||= js_lib_1.ErrorMode.SUPPRESS;
417
+ opt.errorMode ||= ErrorMode.SUPPRESS;
421
418
  // Experimental: using `.map()`
422
419
  const stream = this.cfg.db
423
420
  .streamQuery(q.select(['id']), opt)
@@ -436,28 +433,28 @@ class CommonDao {
436
433
  async streamQueryIdsForEach(q, mapper, opt = {}) {
437
434
  this.validateQueryIndexes(q); // throws if query uses `excludeFromIndexes` property
438
435
  q.table = opt.table || q.table;
439
- opt.errorMode ||= js_lib_1.ErrorMode.SUPPRESS;
436
+ opt.errorMode ||= ErrorMode.SUPPRESS;
440
437
  const op = `streamQueryIdsForEach(${q.pretty()})`;
441
438
  const started = this.logStarted(op, q.table, true);
442
439
  let count = 0;
443
- await (0, nodejs_lib_1._pipeline)([
440
+ await _pipeline([
444
441
  this.cfg.db.streamQuery(q.select(['id']), opt).map(r => {
445
442
  count++;
446
443
  return r.id;
447
444
  }),
448
- (0, nodejs_lib_1.transformMap)(mapper, {
445
+ transformMap(mapper, {
449
446
  ...opt,
450
- predicate: js_lib_1._passthroughPredicate,
447
+ predicate: _passthroughPredicate,
451
448
  }),
452
449
  // LogProgress should be AFTER the mapper, to be able to report correct stats
453
- (0, nodejs_lib_1.transformLogProgress)({
450
+ transformLogProgress({
454
451
  metric: q.table,
455
452
  ...opt,
456
453
  }),
457
- (0, nodejs_lib_1.writableVoid)(),
454
+ writableVoid(),
458
455
  ]);
459
- if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.OPERATIONS) {
460
- this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} id(s) in ${(0, js_lib_1._since)(started)}`);
456
+ if (this.cfg.logLevel >= CommonDaoLogLevel.OPERATIONS) {
457
+ this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} id(s) in ${_since(started)}`);
461
458
  }
462
459
  }
463
460
  /**
@@ -465,7 +462,7 @@ class CommonDao {
465
462
  * "Returns", just to have a type of "Saved"
466
463
  */
467
464
  assignIdCreatedUpdated(obj, opt = {}) {
468
- const now = js_lib_1.localTime.nowUnix();
465
+ const now = localTime.nowUnix();
469
466
  if (this.cfg.useCreatedProperty) {
470
467
  obj.created ||= obj.updated || now;
471
468
  }
@@ -504,14 +501,14 @@ class CommonDao {
504
501
  });
505
502
  if (loaded) {
506
503
  patched = { ...loaded, ...patch };
507
- if ((0, js_lib_1._deepJsonEquals)(loaded, patched)) {
504
+ if (_deepJsonEquals(loaded, patched)) {
508
505
  // Skipping the save operation, as data is the same
509
506
  return patched;
510
507
  }
511
508
  }
512
509
  else {
513
510
  const table = opt.table || this.cfg.table;
514
- (0, js_lib_1._assert)(opt.createIfMissing, `DB row required, but not found in ${table}`, {
511
+ _assert(opt.createIfMissing, `DB row required, but not found in ${table}`, {
515
512
  id,
516
513
  table,
517
514
  });
@@ -545,7 +542,7 @@ class CommonDao {
545
542
  ...bm,
546
543
  ...patch,
547
544
  };
548
- if ((0, js_lib_1._deepJsonEquals)(bm, patched)) {
545
+ if (_deepJsonEquals(bm, patched)) {
549
546
  // Skipping the save operation, as data is the same
550
547
  return bm;
551
548
  }
@@ -563,8 +560,8 @@ class CommonDao {
563
560
  ...patch,
564
561
  };
565
562
  // Make `bm` exactly the same as `loadedWithPatch`
566
- (0, js_lib_1._objectAssignExact)(bm, loadedWithPatch);
567
- if ((0, js_lib_1._deepJsonEquals)(loaded, loadedWithPatch)) {
563
+ _objectAssignExact(bm, loadedWithPatch);
564
+ if (_deepJsonEquals(loaded, loadedWithPatch)) {
568
565
  // Skipping the save operation, as data is the same
569
566
  return bm;
570
567
  }
@@ -589,14 +586,14 @@ class CommonDao {
589
586
  // which should be removed post-validation, but it breaks the "equality check"
590
587
  // Post-validation the equality check should work as intended
591
588
  const convertedBM = this.validateAndConvert(bm, this.cfg.bmSchema, 'save', opt);
592
- if ((0, js_lib_1._deepJsonEquals)(convertedBM, opt.skipIfEquals)) {
589
+ if (_deepJsonEquals(convertedBM, opt.skipIfEquals)) {
593
590
  // Skipping the save operation
594
591
  return bm;
595
592
  }
596
593
  }
597
594
  const idWasGenerated = !bm.id && this.cfg.generateId;
598
595
  this.assignIdCreatedUpdated(bm, opt); // mutates
599
- (0, js_lib_1._typeCast)(bm);
596
+ _typeCast(bm);
600
597
  let dbm = await this.bmToDBM(bm, opt); // validates BM
601
598
  if (this.cfg.hooks.beforeSave) {
602
599
  dbm = (await this.cfg.hooks.beforeSave(dbm));
@@ -665,14 +662,14 @@ class CommonDao {
665
662
  bms.forEach(bm => this.assignIdCreatedUpdated(bm, opt));
666
663
  let dbms = await this.bmsToDBM(bms, opt);
667
664
  if (this.cfg.hooks.beforeSave && dbms.length) {
668
- dbms = (await (0, js_lib_1.pMap)(dbms, async (dbm) => await this.cfg.hooks.beforeSave(dbm))).filter(js_lib_1._isTruthy);
665
+ dbms = (await pMap(dbms, async (dbm) => await this.cfg.hooks.beforeSave(dbm))).filter(_isTruthy);
669
666
  }
670
667
  if (opt.ensureUniqueId)
671
- throw new js_lib_1.AppError('ensureUniqueId is not supported in saveBatch');
668
+ throw new AppError('ensureUniqueId is not supported in saveBatch');
672
669
  if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
673
670
  opt = { ...opt, saveMethod: 'insert' };
674
671
  }
675
- const op = `saveBatch ${dbms.length} row(s) (${(0, js_lib_1._truncate)(dbms
672
+ const op = `saveBatch ${dbms.length} row(s) (${_truncate(dbms
676
673
  .slice(0, 10)
677
674
  .map(bm => bm.id)
678
675
  .join(', '), 50)})`;
@@ -698,11 +695,11 @@ class CommonDao {
698
695
  dbms.forEach(dbm => this.assignIdCreatedUpdated(dbm, opt)); // mutates
699
696
  let rows = this.anyToDBMs(dbms, opt);
700
697
  if (opt.ensureUniqueId)
701
- throw new js_lib_1.AppError('ensureUniqueId is not supported in saveBatch');
698
+ throw new AppError('ensureUniqueId is not supported in saveBatch');
702
699
  if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
703
700
  opt = { ...opt, saveMethod: 'insert' };
704
701
  }
705
- const op = `saveBatchAsDBM ${rows.length} row(s) (${(0, js_lib_1._truncate)(rows
702
+ const op = `saveBatchAsDBM ${rows.length} row(s) (${_truncate(rows
706
703
  .slice(0, 10)
707
704
  .map(bm => bm.id)
708
705
  .join(', '), 50)})`;
@@ -710,7 +707,7 @@ class CommonDao {
710
707
  const { excludeFromIndexes } = this.cfg;
711
708
  const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds;
712
709
  if (this.cfg.hooks.beforeSave && rows.length) {
713
- rows = (await (0, js_lib_1.pMap)(rows, async (row) => await this.cfg.hooks.beforeSave(row))).filter(js_lib_1._isTruthy);
710
+ rows = (await pMap(rows, async (row) => await this.cfg.hooks.beforeSave(row))).filter(_isTruthy);
714
711
  }
715
712
  await (opt.tx || this.cfg.db).saveBatch(table, rows, {
716
713
  excludeFromIndexes,
@@ -733,7 +730,7 @@ class CommonDao {
733
730
  this.requireWriteAccess();
734
731
  const table = opt.table || this.cfg.table;
735
732
  opt.skipValidation ??= true;
736
- opt.errorMode ||= js_lib_1.ErrorMode.SUPPRESS;
733
+ opt.errorMode ||= ErrorMode.SUPPRESS;
737
734
  if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
738
735
  opt = { ...opt, saveMethod: 'insert' };
739
736
  }
@@ -741,20 +738,20 @@ class CommonDao {
741
738
  const { beforeSave } = this.cfg.hooks;
742
739
  const { chunkSize = 500, chunkConcurrency = 32, errorMode } = opt;
743
740
  return [
744
- (0, nodejs_lib_1.transformMap)(async (bm) => {
741
+ transformMap(async (bm) => {
745
742
  this.assignIdCreatedUpdated(bm, opt); // mutates
746
743
  let dbm = await this.bmToDBM(bm, opt);
747
744
  if (beforeSave) {
748
745
  dbm = (await beforeSave(dbm));
749
746
  if (dbm === null)
750
- return js_lib_1.SKIP;
747
+ return SKIP;
751
748
  }
752
749
  return dbm;
753
750
  }, {
754
751
  errorMode,
755
752
  }),
756
- (0, nodejs_lib_1.transformChunk)({ chunkSize }),
757
- (0, nodejs_lib_1.transformMap)(async (batch) => {
753
+ transformChunk({ chunkSize }),
754
+ transformMap(async (batch) => {
758
755
  await this.cfg.db.saveBatch(table, batch, {
759
756
  ...opt,
760
757
  excludeFromIndexes,
@@ -765,13 +762,13 @@ class CommonDao {
765
762
  errorMode,
766
763
  flattenArrayOutput: true,
767
764
  }),
768
- (0, nodejs_lib_1.transformLogProgress)({
765
+ transformLogProgress({
769
766
  metric: 'saved',
770
767
  ...opt,
771
768
  }),
772
769
  // just to satisfy and simplify typings
773
770
  // It's easier to return Transform[], rather than (Transform | Writable)[]
774
- (0, nodejs_lib_1.writableVoid)(),
771
+ writableVoid(),
775
772
  ];
776
773
  }
777
774
  // DELETE
@@ -810,24 +807,24 @@ class CommonDao {
810
807
  let deleted = 0;
811
808
  if (opt.chunkSize) {
812
809
  const { chunkSize, chunkConcurrency = 32 } = opt;
813
- await (0, nodejs_lib_1._pipeline)([
810
+ await _pipeline([
814
811
  this.cfg.db.streamQuery(q.select(['id']), opt).map(r => r.id),
815
- (0, nodejs_lib_1.transformChunk)({ chunkSize }),
816
- (0, nodejs_lib_1.transformMap)(async (ids) => {
812
+ transformChunk({ chunkSize }),
813
+ transformMap(async (ids) => {
817
814
  await this.cfg.db.deleteByIds(q.table, ids, opt);
818
815
  deleted += ids.length;
819
816
  }, {
820
- predicate: js_lib_1._passthroughPredicate,
817
+ predicate: _passthroughPredicate,
821
818
  concurrency: chunkConcurrency,
822
819
  }),
823
820
  // LogProgress should be AFTER the mapper, to be able to report correct stats
824
- (0, nodejs_lib_1.transformLogProgress)({
821
+ transformLogProgress({
825
822
  metric: q.table,
826
823
  logEvery: 2, // 500 * 2 === 1000
827
824
  chunkSize,
828
825
  ...opt,
829
826
  }),
830
- (0, nodejs_lib_1.writableVoid)(),
827
+ writableVoid(),
831
828
  ]);
832
829
  }
833
830
  else {
@@ -899,7 +896,7 @@ class CommonDao {
899
896
  return this.validateAndConvert(bm, this.cfg.bmSchema, 'load', opt);
900
897
  }
901
898
  async dbmsToBM(dbms, opt = {}) {
902
- return await (0, js_lib_1.pMap)(dbms, async (dbm) => await this.dbmToBM(dbm, opt));
899
+ return await pMap(dbms, async (dbm) => await this.dbmToBM(dbm, opt));
903
900
  }
904
901
  async bmToDBM(bm, opt) {
905
902
  if (bm === undefined)
@@ -911,7 +908,7 @@ class CommonDao {
911
908
  }
912
909
  async bmsToDBM(bms, opt = {}) {
913
910
  // try/catch?
914
- return await (0, js_lib_1.pMap)(bms, async (bm) => await this.bmToDBM(bm, opt));
911
+ return await pMap(bms, async (bm) => await this.bmToDBM(bm, opt));
915
912
  }
916
913
  anyToDBM(dbm, opt = {}) {
917
914
  if (!dbm)
@@ -947,7 +944,7 @@ class CommonDao {
947
944
  // obj = _filterNullishValues(obj as any)
948
945
  // We still filter `undefined` values here, because `beforeDBMToBM` can return undefined values
949
946
  // and they can be annoying with snapshot tests
950
- obj = (0, js_lib_1._filterUndefinedValues)(obj);
947
+ obj = _filterUndefinedValues(obj);
951
948
  // Return as is if no schema is passed or if `skipConversion` is set
952
949
  if (!schema ||
953
950
  opt.skipValidation ||
@@ -960,13 +957,13 @@ class CommonDao {
960
957
  const objectName = table;
961
958
  let error;
962
959
  let convertedValue;
963
- if (schema instanceof index_js_1.ZodSchema) {
960
+ if (schema instanceof ZodSchema) {
964
961
  // Zod schema
965
- const vr = (0, index_js_1.zSafeValidate)(obj, schema);
962
+ const vr = zSafeValidate(obj, schema);
966
963
  error = vr.error;
967
964
  convertedValue = vr.data;
968
965
  }
969
- else if (schema instanceof nodejs_lib_1.AjvSchema) {
966
+ else if (schema instanceof AjvSchema) {
970
967
  // Ajv schema
971
968
  convertedValue = obj; // because Ajv mutates original object
972
969
  error = schema.getValidationError(obj, {
@@ -975,9 +972,9 @@ class CommonDao {
975
972
  }
976
973
  else {
977
974
  // Joi
978
- const start = js_lib_1.localTime.nowUnixMillis();
979
- const vr = (0, nodejs_lib_1.getValidationResult)(obj, schema, objectName);
980
- const tookMillis = js_lib_1.localTime.nowUnixMillis() - start;
975
+ const start = localTime.nowUnixMillis();
976
+ const vr = getValidationResult(obj, schema, objectName);
977
+ const tookMillis = localTime.nowUnixMillis() - start;
981
978
  this.cfg.onValidationTime?.({
982
979
  tookMillis,
983
980
  table,
@@ -1007,6 +1004,10 @@ class CommonDao {
1007
1004
  async ping() {
1008
1005
  await this.cfg.db.ping();
1009
1006
  }
1007
+ async createTransaction(opt) {
1008
+ const tx = await this.cfg.db.createTransaction(opt);
1009
+ return new CommonDaoTransaction(tx, this.cfg.logger);
1010
+ }
1010
1011
  async runInTransaction(fn, opt) {
1011
1012
  let r;
1012
1013
  await this.cfg.db.runInTransaction(async (tx) => {
@@ -1029,7 +1030,7 @@ class CommonDao {
1029
1030
  if (!excludeFromIndexes)
1030
1031
  return;
1031
1032
  for (const f of q._filters) {
1032
- (0, js_lib_1._assert)(!excludeFromIndexes.includes(f.name), `cannot query on non-indexed property: ${this.cfg.table}.${f.name}`, {
1033
+ _assert(!excludeFromIndexes.includes(f.name), `cannot query on non-indexed property: ${this.cfg.table}.${f.name}`, {
1033
1034
  query: q.pretty(),
1034
1035
  });
1035
1036
  }
@@ -1041,37 +1042,37 @@ class CommonDao {
1041
1042
  const args = [];
1042
1043
  if (Array.isArray(res)) {
1043
1044
  logRes = `${res.length} row(s)`;
1044
- if (res.length && this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.DATA_FULL) {
1045
+ if (res.length && this.cfg.logLevel >= CommonDaoLogLevel.DATA_FULL) {
1045
1046
  args.push('\n', ...res.slice(0, 10)); // max 10 items
1046
1047
  }
1047
1048
  }
1048
1049
  else if (res) {
1049
1050
  logRes = `1 row`;
1050
- if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.DATA_SINGLE) {
1051
+ if (this.cfg.logLevel >= CommonDaoLogLevel.DATA_SINGLE) {
1051
1052
  args.push('\n', res);
1052
1053
  }
1053
1054
  }
1054
1055
  else {
1055
1056
  logRes = `undefined`;
1056
1057
  }
1057
- this.cfg.logger?.log(`<< ${table}.${op}: ${logRes} in ${(0, js_lib_1._since)(started)}`, ...args);
1058
+ this.cfg.logger?.log(`<< ${table}.${op}: ${logRes} in ${_since(started)}`, ...args);
1058
1059
  }
1059
1060
  logSaveResult(started, op, table) {
1060
1061
  if (!this.cfg.logLevel)
1061
1062
  return;
1062
- this.cfg.logger?.log(`<< ${table}.${op} in ${(0, js_lib_1._since)(started)}`);
1063
+ this.cfg.logger?.log(`<< ${table}.${op} in ${_since(started)}`);
1063
1064
  }
1064
1065
  logStarted(op, table, force = false) {
1065
1066
  if (this.cfg.logStarted || force) {
1066
1067
  this.cfg.logger?.log(`>> ${table}.${op}`);
1067
1068
  }
1068
- return js_lib_1.localTime.nowUnixMillis();
1069
+ return localTime.nowUnixMillis();
1069
1070
  }
1070
1071
  logSaveStarted(op, items, table) {
1071
1072
  if (this.cfg.logStarted) {
1072
1073
  const args = [`>> ${table}.${op}`];
1073
1074
  if (Array.isArray(items)) {
1074
- if (items.length && this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.DATA_FULL) {
1075
+ if (items.length && this.cfg.logLevel >= CommonDaoLogLevel.DATA_FULL) {
1075
1076
  args.push('\n', ...items.slice(0, 10));
1076
1077
  }
1077
1078
  else {
@@ -1079,29 +1080,36 @@ class CommonDao {
1079
1080
  }
1080
1081
  }
1081
1082
  else {
1082
- if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.DATA_SINGLE) {
1083
+ if (this.cfg.logLevel >= CommonDaoLogLevel.DATA_SINGLE) {
1083
1084
  args.push(items);
1084
1085
  }
1085
1086
  }
1086
1087
  this.cfg.logger?.log(...args);
1087
1088
  }
1088
- return js_lib_1.localTime.nowUnixMillis();
1089
+ return localTime.nowUnixMillis();
1089
1090
  }
1090
1091
  }
1091
- exports.CommonDao = CommonDao;
1092
1092
  /**
1093
1093
  * Transaction context.
1094
1094
  * Has similar API than CommonDao, but all operations are performed in the context of the transaction.
1095
1095
  */
1096
- class CommonDaoTransaction {
1096
+ export class CommonDaoTransaction {
1097
1097
  tx;
1098
1098
  logger;
1099
1099
  constructor(tx, logger) {
1100
1100
  this.tx = tx;
1101
1101
  this.logger = logger;
1102
1102
  }
1103
+ /**
1104
+ * Commits the underlying DBTransaction.
1105
+ * May throw.
1106
+ */
1107
+ async commit() {
1108
+ await this.tx.commit();
1109
+ }
1103
1110
  /**
1104
1111
  * Perform a graceful rollback without throwing/re-throwing any error.
1112
+ * Never throws.
1105
1113
  */
1106
1114
  async rollback() {
1107
1115
  try {
@@ -1145,7 +1153,7 @@ class CommonDaoTransaction {
1145
1153
  * So, this method is a rather simple convenience "Object.assign and then save".
1146
1154
  */
1147
1155
  async patch(dao, bm, patch, opt) {
1148
- const skipIfEquals = (0, js_lib_1._deepCopy)(bm);
1156
+ const skipIfEquals = _deepCopy(bm);
1149
1157
  Object.assign(bm, patch);
1150
1158
  return await dao.save(bm, { ...opt, skipIfEquals, tx: this.tx });
1151
1159
  }
@@ -1158,4 +1166,3 @@ class CommonDaoTransaction {
1158
1166
  return await dao.deleteByIds(ids, { ...opt, tx: this.tx });
1159
1167
  }
1160
1168
  }
1161
- exports.CommonDaoTransaction = CommonDaoTransaction;