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