wingbot-mongodb 3.2.6-alpha.1 → 4.0.0-alpha.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.
@@ -1 +1 @@
1
- {"parent":null,"pid":38479,"argv":["/usr/local/bin/node","/Users/david/Development/wingbot-mongodb/node_modules/.bin/mocha","./test"],"execArgv":[],"cwd":"/Users/david/Development/wingbot-mongodb","time":1692102034748,"ppid":38478,"coverageFilename":"/Users/david/Development/wingbot-mongodb/.nyc_output/1091dc07-773b-48f1-9817-b8048f05d575.json","externalId":"","uuid":"1091dc07-773b-48f1-9817-b8048f05d575","files":["/Users/david/Development/wingbot-mongodb/src/BaseStorage.js","/Users/david/Development/wingbot-mongodb/src/defaultLogger.js","/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js","/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js","/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js","/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js","/Users/david/Development/wingbot-mongodb/src/tokenFactory.js","/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js","/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js","/Users/david/Development/wingbot-mongodb/src/StateStorage.js"]}
1
+ {"parent":null,"pid":94202,"argv":["/usr/local/bin/node","/Users/david/Development/wingbot-mongodb/node_modules/.bin/mocha","./test"],"execArgv":[],"cwd":"/Users/david/Development/wingbot-mongodb","time":1695123947917,"ppid":94201,"coverageFilename":"/Users/david/Development/wingbot-mongodb/.nyc_output/c5005d32-ad45-472c-811c-860ccef899fe.json","externalId":"","uuid":"c5005d32-ad45-472c-811c-860ccef899fe","files":["/Users/david/Development/wingbot-mongodb/src/BaseStorage.js","/Users/david/Development/wingbot-mongodb/src/defaultLogger.js","/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js","/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js","/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js","/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js","/Users/david/Development/wingbot-mongodb/src/tokenFactory.js","/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js","/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js","/Users/david/Development/wingbot-mongodb/src/StateStorage.js"]}
@@ -1 +1 @@
1
- {"processes":{"1091dc07-773b-48f1-9817-b8048f05d575":{"parent":null,"children":[]}},"files":{"/Users/david/Development/wingbot-mongodb/src/BaseStorage.js":["1091dc07-773b-48f1-9817-b8048f05d575"],"/Users/david/Development/wingbot-mongodb/src/defaultLogger.js":["1091dc07-773b-48f1-9817-b8048f05d575"],"/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js":["1091dc07-773b-48f1-9817-b8048f05d575"],"/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js":["1091dc07-773b-48f1-9817-b8048f05d575"],"/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js":["1091dc07-773b-48f1-9817-b8048f05d575"],"/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js":["1091dc07-773b-48f1-9817-b8048f05d575"],"/Users/david/Development/wingbot-mongodb/src/tokenFactory.js":["1091dc07-773b-48f1-9817-b8048f05d575"],"/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js":["1091dc07-773b-48f1-9817-b8048f05d575"],"/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js":["1091dc07-773b-48f1-9817-b8048f05d575"],"/Users/david/Development/wingbot-mongodb/src/StateStorage.js":["1091dc07-773b-48f1-9817-b8048f05d575"]},"externalIds":{}}
1
+ {"processes":{"c5005d32-ad45-472c-811c-860ccef899fe":{"parent":null,"children":[]}},"files":{"/Users/david/Development/wingbot-mongodb/src/BaseStorage.js":["c5005d32-ad45-472c-811c-860ccef899fe"],"/Users/david/Development/wingbot-mongodb/src/defaultLogger.js":["c5005d32-ad45-472c-811c-860ccef899fe"],"/Users/david/Development/wingbot-mongodb/src/AttachmentCache.js":["c5005d32-ad45-472c-811c-860ccef899fe"],"/Users/david/Development/wingbot-mongodb/src/AuditLogStorage.js":["c5005d32-ad45-472c-811c-860ccef899fe"],"/Users/david/Development/wingbot-mongodb/src/BotConfigStorage.js":["c5005d32-ad45-472c-811c-860ccef899fe"],"/Users/david/Development/wingbot-mongodb/src/BotTokenStorage.js":["c5005d32-ad45-472c-811c-860ccef899fe"],"/Users/david/Development/wingbot-mongodb/src/tokenFactory.js":["c5005d32-ad45-472c-811c-860ccef899fe"],"/Users/david/Development/wingbot-mongodb/src/ChatLogStorage.js":["c5005d32-ad45-472c-811c-860ccef899fe"],"/Users/david/Development/wingbot-mongodb/src/NotificationsStorage.js":["c5005d32-ad45-472c-811c-860ccef899fe"],"/Users/david/Development/wingbot-mongodb/src/StateStorage.js":["c5005d32-ad45-472c-811c-860ccef899fe"]},"externalIds":{}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wingbot-mongodb",
3
- "version": "3.2.6-alpha.1",
3
+ "version": "4.0.0-alpha.1",
4
4
  "description": "MongoDB storage for wingbot.ai",
5
5
  "main": "src/main.js",
6
6
  "scripts": {
@@ -27,7 +27,7 @@
27
27
  "author": "wingbot.ai",
28
28
  "license": "MIT",
29
29
  "engines": {
30
- "node": ">=12.0.0"
30
+ "node": ">=14.0.0"
31
31
  },
32
32
  "bugs": {
33
33
  "url": "https://github.com/wingbotai/wingbot-mongodb/issues"
@@ -45,12 +45,12 @@
45
45
  "jsdoc-to-markdown": "^7.1.1",
46
46
  "jsdoc-tsimport-plugin": "^1.0.5",
47
47
  "mocha": "^10.1.0",
48
- "mongodb": "^4.12.1",
48
+ "mongodb": "^6.1.0",
49
49
  "nyc": "^15.1.0",
50
50
  "wingbot": "^3.46.3"
51
51
  },
52
52
  "peerDependencies": {
53
- "mongodb": "^4.0.0"
53
+ "mongodb": "^6.0.0"
54
54
  },
55
55
  "optionalDependencies": {
56
56
  "wingbot": "^3.0.0"
@@ -4,6 +4,7 @@
4
4
  'use strict';
5
5
 
6
6
  const { ObjectId } = require('mongodb');
7
+ const { default: assert } = require('assert');
7
8
  const crypto = require('crypto');
8
9
  const defaultLogger = require('./defaultLogger');
9
10
 
@@ -130,6 +131,9 @@ class BaseStorage {
130
131
  }
131
132
  });
132
133
  }
134
+
135
+ this._indexing = null;
136
+ this._shouldIndexBeforeRead = null;
133
137
  }
134
138
 
135
139
  /**
@@ -178,7 +182,7 @@ class BaseStorage {
178
182
  /**
179
183
  * Insert defalt document to DB
180
184
  *
181
- * @param {...any} objects
185
+ * @param {...{ _id: string|number|ObjectId }} objects
182
186
  */
183
187
  addFixtureDoc (...objects) {
184
188
  this._fixtures.push(...objects);
@@ -256,7 +260,17 @@ class BaseStorage {
256
260
  collection = db.collection(name);
257
261
  }
258
262
 
259
- await this._ensureIndexes(this._indexes, collection);
263
+ this._shouldIndexBeforeRead = this._fixtures.length !== 0;
264
+
265
+ this._indexing = this._ensureIndexes(this._indexes, collection)
266
+ .then(() => {
267
+ this._indexing = false;
268
+ })
269
+ .catch((e) => {
270
+ this._collection = null;
271
+ this._log.log(`DB.${this._collectionName} - init failed`, e);
272
+ return e;
273
+ });
260
274
 
261
275
  return collection;
262
276
  }
@@ -265,9 +279,10 @@ class BaseStorage {
265
279
  * Returns the collection to operate with
266
280
  *
267
281
  * @protected
282
+ * @param {boolean} [forRead]
268
283
  * @returns {Promise<Collection>}
269
284
  */
270
- async _getCollection () {
285
+ async _getCollection (forRead = false) {
271
286
  if (this._collection === null) {
272
287
  let c;
273
288
  try {
@@ -280,6 +295,13 @@ class BaseStorage {
280
295
  throw e;
281
296
  }
282
297
  }
298
+
299
+ if (this._indexing && (!forRead || this._shouldIndexBeforeRead)) {
300
+ const err = await this._indexing;
301
+ this._indexing = false;
302
+ if (err) throw err;
303
+ }
304
+
283
305
  return this._collection;
284
306
  }
285
307
 
@@ -290,12 +312,10 @@ class BaseStorage {
290
312
  * @returns {Promise}
291
313
  */
292
314
  async _ensureIndexes (indexes, collection) {
293
- let existing;
294
- try {
295
- existing = await collection.indexes();
296
- } catch (e) {
297
- existing = [];
298
- }
315
+ const [existing, fixtures] = await Promise.all([
316
+ this._checkExistingIndexes(collection),
317
+ this._checkFixtures(collection)
318
+ ]);
299
319
 
300
320
  await existing
301
321
  .filter((e) => !this.systemIndexes.includes(e.name)
@@ -309,7 +329,7 @@ class BaseStorage {
309
329
  });
310
330
  }, Promise.resolve());
311
331
 
312
- let updated = await indexes
332
+ await indexes
313
333
  .filter((i) => !existing.some((e) => e.name === i.options.name))
314
334
  .reduce((p, i) => {
315
335
  this._log.log(`DB.${this._collectionName} creating index ${i.options.name}`);
@@ -324,31 +344,7 @@ class BaseStorage {
324
344
  .then(() => true);
325
345
  }, Promise.resolve(false));
326
346
 
327
- if (!updated) {
328
- updated = existing.every((i) => this.systemIndexes.includes(i.name));
329
- }
330
-
331
- let fixtures = this._fixtures;
332
-
333
- const $in = fixtures
334
- .map((f) => f._id)
335
- .filter((f) => !!f);
336
-
337
- if (!updated && $in.length !== 0) {
338
- const found = await collection
339
- .find({ _id: { $in } })
340
- .project({ _id: 1 })
341
- .map((doc) => doc._id.toString())
342
- .toArray();
343
-
344
- if (found.length !== $in.length) {
345
- updated = true;
346
- fixtures = fixtures
347
- .filter((f) => !f._id || !found.includes(f._id.toString()));
348
- }
349
- }
350
-
351
- if (!updated || fixtures.length === 0) {
347
+ if (fixtures.length === 0) {
352
348
  return;
353
349
  }
354
350
 
@@ -367,6 +363,45 @@ class BaseStorage {
367
363
  );
368
364
  }
369
365
 
366
+ async _checkExistingIndexes (collection) {
367
+ let existing;
368
+ try {
369
+ existing = await collection.indexes();
370
+ } catch (e) {
371
+ existing = [];
372
+ }
373
+ return existing;
374
+ }
375
+
376
+ async _checkFixtures (collection) {
377
+ if (this._fixtures.length === 0) {
378
+ return this._fixtures;
379
+ }
380
+
381
+ const fixtures = this._fixtures
382
+ .map((f) => {
383
+ assert(f._id, `DB.${this._collectionName} fixture must have _id property`);
384
+ return {
385
+ ...f,
386
+ _id: this._id(f._id)
387
+ };
388
+ });
389
+
390
+ const $in = fixtures.map((f) => f._id);
391
+
392
+ const found = await collection
393
+ .find({ _id: { $in } })
394
+ .project({ _id: 1 })
395
+ .map((doc) => doc._id.toString())
396
+ .toArray();
397
+
398
+ if (found.length === $in.length) {
399
+ return [];
400
+ }
401
+
402
+ return fixtures.filter((f) => !found.includes(f._id.toString()));
403
+ }
404
+
370
405
  /**
371
406
  *
372
407
  * @template T
@@ -134,9 +134,6 @@ class BotTokenStorage {
134
134
  returnDocument: 'after'
135
135
  });
136
136
 
137
- // @ts-ignore
138
- res = res.value;
139
-
140
137
  // @ts-ignore
141
138
  if (res.token === temporaryInsecureToken) {
142
139
 
@@ -403,8 +403,8 @@ class NotificationsStorage {
403
403
  sort: { enqueue: 1 },
404
404
  returnDocument: 'after'
405
405
  });
406
- if (found.value) {
407
- pop.push(this._mapGenericObject(found.value));
406
+ if (found) {
407
+ pop.push(this._mapGenericObject(found));
408
408
  go = pop.length < limit;
409
409
  } else {
410
410
  go = false;
@@ -498,7 +498,7 @@ class NotificationsStorage {
498
498
  returnDocument: 'after'
499
499
  });
500
500
 
501
- return this._mapGenericObject(res.value);
501
+ return this._mapGenericObject(res);
502
502
  }
503
503
 
504
504
  /**
@@ -590,7 +590,7 @@ class NotificationsStorage {
590
590
  );
591
591
 
592
592
  return result
593
- .map((res) => (res.value ? this._mapGenericObject(res.value) : null))
593
+ .map((res) => (res ? this._mapGenericObject(res) : null))
594
594
  .filter((r) => r !== null);
595
595
  }
596
596
 
@@ -624,7 +624,7 @@ class NotificationsStorage {
624
624
  upsert: true,
625
625
  returnDocument: 'after'
626
626
  });
627
- ret = this._mapCampaign(res.value);
627
+ ret = this._mapCampaign(res);
628
628
  } else {
629
629
  const id = new ObjectId();
630
630
  ret = { id: id.toHexString(), _id: id, ...campaign };
@@ -684,7 +684,7 @@ class NotificationsStorage {
684
684
  returnDocument: 'after'
685
685
  });
686
686
 
687
- return this._mapCampaign(res.value);
687
+ return this._mapCampaign(res);
688
688
  }
689
689
 
690
690
  /**
@@ -704,7 +704,7 @@ class NotificationsStorage {
704
704
  returnDocument: 'before'
705
705
  });
706
706
 
707
- return this._mapCampaign(res.value);
707
+ return this._mapCampaign(res);
708
708
  }
709
709
 
710
710
  /**
@@ -845,9 +845,9 @@ class NotificationsStorage {
845
845
  returnDocument: 'after'
846
846
  });
847
847
 
848
- if (res.value) {
848
+ if (res) {
849
849
  ret.push(tag);
850
- removeWholeSubscribtion = res.value.subs.length === 0;
850
+ removeWholeSubscribtion = res.subs.length === 0;
851
851
  } else {
852
852
  return [];
853
853
  }
@@ -855,8 +855,8 @@ class NotificationsStorage {
855
855
 
856
856
  if (removeWholeSubscribtion) {
857
857
  const res = await c.findOneAndDelete({ pageId, senderId });
858
- if (res.value) {
859
- ret.push(...res.value.subs);
858
+ if (res) {
859
+ ret.push(...res.subs);
860
860
  }
861
861
  }
862
862
 
@@ -137,7 +137,7 @@ class StateStorage extends BaseStorage {
137
137
  }
138
138
  }));
139
139
 
140
- if (this._uniqueIndexFailed && !res.value.lastInteraction) {
140
+ if (this._uniqueIndexFailed && !res.lastInteraction) {
141
141
  // check if there was a locked state
142
142
  const existing = await c.find({
143
143
  senderId,
@@ -155,7 +155,7 @@ class StateStorage extends BaseStorage {
155
155
 
156
156
  const logLevel = this.logCollisionsAsErrors ? 'error' : 'log';
157
157
  this._log[logLevel]('StateStorage: unique index workaround DETECTED', {
158
- v: res.value, existing, $in: $in.map((i) => i.toString())
158
+ v: res, existing, $in: $in.map((i) => i.toString())
159
159
  });
160
160
 
161
161
  if ($in.length > 0) {
@@ -164,11 +164,11 @@ class StateStorage extends BaseStorage {
164
164
 
165
165
  throw Object.assign(new Error('State was locked'), { code: 11000 });
166
166
  } else {
167
- this._log.log('StateStorage: unique index workaround OK', res.value);
167
+ this._log.log('StateStorage: unique index workaround OK', res);
168
168
  }
169
169
  }
170
170
 
171
- return res.value;
171
+ return res;
172
172
  }
173
173
 
174
174
  /**