sharedb-mongo 2.0.0 → 2.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.
@@ -7,12 +7,17 @@ on:
7
7
  pull_request:
8
8
  branches:
9
9
  - master
10
+ # Allow manually triggering tests
11
+ workflow_dispatch:
12
+ branches:
13
+ - master
10
14
 
11
15
  jobs:
12
16
  test:
13
17
  name: Node.js ${{ matrix.node }} + mongoDB ${{ matrix.mongodb }}
14
18
  runs-on: ubuntu-latest
15
19
  strategy:
20
+ fail-fast: false
16
21
  matrix:
17
22
  node:
18
23
  - 14
@@ -30,8 +35,8 @@ jobs:
30
35
  - 27017:27017
31
36
  timeout-minutes: 10
32
37
  steps:
33
- - uses: actions/checkout@v2
34
- - uses: actions/setup-node@v1
38
+ - uses: actions/checkout@v3
39
+ - uses: actions/setup-node@v3
35
40
  with:
36
41
  node-version: ${{ matrix.node }}
37
42
  - name: Install
package/index.js CHANGED
@@ -1,4 +1,3 @@
1
- var async = require('async');
2
1
  var mongodb = require('./mongodb');
3
2
  var DB = require('sharedb').DB;
4
3
  var OpLinkValidator = require('./op-link-validator');
@@ -55,15 +54,21 @@ function ShareDbMongo(mongo, options) {
55
54
  // Track whether the close method has been called
56
55
  this.closed = false;
57
56
 
57
+ this.mongo = null;
58
+ this._mongoClient = null;
59
+ this.mongoPoll = null;
60
+ this._mongoPollClient = null;
61
+
58
62
  if (typeof mongo === 'string' || typeof mongo === 'function') {
59
- // We can only get the mongodb client instance in a callback, so
60
- // buffer up any requests received in the meantime
61
- this.mongo = null;
62
- this._mongoClient = null;
63
- this.mongoPoll = null;
64
- this._mongoPollClient = null;
65
- this.pendingConnect = [];
66
- this._connect(mongo, options);
63
+ var self = this;
64
+ this._connection = this._connect(mongo, options)
65
+ .then(function(result) {
66
+ self.mongo = result.mongo;
67
+ self._mongoClient = result.mongoClient;
68
+ self.mongoPoll = result.mongoPoll;
69
+ self._mongoPollClient = result.mongoPollClient;
70
+ return result;
71
+ });
67
72
  } else {
68
73
  throw new Error('deprecated: pass mongo as url string or function with callback');
69
74
  }
@@ -115,19 +120,10 @@ ShareDbMongo.prototype.getDbs = function(callback) {
115
120
  var err = ShareDbMongo.alreadyClosedError();
116
121
  return callback(err);
117
122
  }
118
- // We consider ouself ready to reply if this.mongo is defined and don't check
119
- // this.mongoPoll, since it is optional and is null by default. Thus, it's
120
- // important that these two properties are only set together synchronously
121
- if (this.mongo) return callback(null, this.mongo, this.mongoPoll);
122
- this.pendingConnect.push(callback);
123
- };
124
-
125
- ShareDbMongo.prototype._flushPendingConnect = function() {
126
- var pendingConnect = this.pendingConnect;
127
- this.pendingConnect = null;
128
- for (var i = 0; i < pendingConnect.length; i++) {
129
- pendingConnect[i](null, this.mongo, this.mongoPoll);
130
- }
123
+ this._connection
124
+ .then(function(result) {
125
+ callback(null, result.mongo, result.mongoPoll);
126
+ }, callback);
131
127
  };
132
128
 
133
129
  function isLegacyMongoClient(client) {
@@ -145,72 +141,55 @@ ShareDbMongo.prototype._connect = function(mongo, options) {
145
141
  //
146
142
  // Throw errors in this function if we fail to connect, since we aren't
147
143
  // implementing a way to retry
148
- var self = this;
144
+ var connections = [connect(mongo, options.mongoOptions)];
149
145
  var mongoPoll = options.mongoPoll;
150
- if (mongoPoll) {
151
- var tasks = {
152
- mongoClient: connect(mongo, options.mongoOptions),
153
- mongoPollClient: connect(mongoPoll, options.mongoPollOptions)
146
+ if (mongoPoll) connections.push(connect(mongoPoll, options.mongoPollOptions));
147
+
148
+ return Promise.all(connections).then(function(clients) {
149
+ var mongoClient = clients[0];
150
+ var mongoPollClient = clients[1];
151
+ var result = {
152
+ mongo: mongoClient,
153
+ mongoClient: mongoClient,
154
+ mongoPoll: mongoPollClient,
155
+ mongoPollClient: mongoPollClient
154
156
  };
155
- async.parallel(tasks, function(err, results) {
156
- if (err) throw err;
157
- var mongoClient = results.mongoClient;
158
- var mongoPollClient = results.mongoPollClient;
159
- if (isLegacyMongoClient(mongoClient)) {
160
- self.mongo = self._mongoClient = mongoClient;
161
- self.mongoPoll = self._mongoPollClient = mongoPollClient;
162
- } else {
163
- self.mongo = mongoClient.db();
164
- self._mongoClient = mongoClient;
165
- self.mongoPoll = mongoPollClient.db();
166
- self._mongoPollClient = mongoPollClient;
167
- }
168
- self._flushPendingConnect();
169
- });
170
- return;
171
- }
172
- var finish = function(err, client) {
173
- if (err) throw err;
174
- if (isLegacyMongoClient(client)) {
175
- self.mongo = self._mongoClient = client;
176
- } else {
177
- self.mongo = client.db();
178
- self._mongoClient = client;
157
+ if (!isLegacyMongoClient(mongoClient)) {
158
+ result.mongo = mongoClient.db();
159
+ if (mongoPollClient) result.mongoPoll = mongoPollClient.db();
179
160
  }
180
- self._flushPendingConnect();
181
- };
182
- if (typeof mongo === 'function') {
183
- mongo(finish);
184
- return;
185
- }
186
- // TODO: Don't pass options directly to mongodb.connect();
187
- // only pass options.mongoOptions
188
- var mongoOptions = options.mongoOptions || options;
189
- connect(mongo, mongoOptions)(finish);
161
+ return result;
162
+ });
190
163
  };
191
164
 
192
165
  function connect(mongo, options) {
193
- if (typeof mongo === 'function') return mongo;
194
- return function(callback) {
195
- options = Object.assign({}, options);
196
- delete options.mongo;
197
- delete options.mongoPoll;
198
- delete options.mongoPollOptions;
199
- delete options.pollDelay;
200
- delete options.disableIndexCreation;
201
- delete options.allowAllQueries;
202
- delete options.allowJSQueries;
203
- delete options.allowAllQueries;
204
- delete options.allowAggregateQueries;
205
- delete options.getOpsWithoutStrictLinking;
206
-
207
- if (typeof mongodb.connect === 'function') {
208
- mongodb.connect(mongo, options, callback);
209
- } else {
210
- var client = new mongodb.MongoClient(mongo, options);
211
- client.connect(callback);
212
- }
213
- };
166
+ if (typeof mongo === 'function') {
167
+ return new Promise(function(resolve, reject) {
168
+ mongo(function(error, client) {
169
+ if (error) return reject(error);
170
+ resolve(client);
171
+ });
172
+ });
173
+ }
174
+
175
+ options = Object.assign({}, options);
176
+ delete options.mongo;
177
+ delete options.mongoPoll;
178
+ delete options.mongoPollOptions;
179
+ delete options.pollDelay;
180
+ delete options.disableIndexCreation;
181
+ delete options.allowAllQueries;
182
+ delete options.allowJSQueries;
183
+ delete options.allowAllQueries;
184
+ delete options.allowAggregateQueries;
185
+ delete options.getOpsWithoutStrictLinking;
186
+
187
+ if (typeof mongodb.connect === 'function') {
188
+ return mongodb.connect(mongo, options);
189
+ } else {
190
+ var client = new mongodb.MongoClient(mongo, options);
191
+ return client.connect();
192
+ }
214
193
  }
215
194
 
216
195
  ShareDbMongo.prototype.close = function(callback) {
@@ -225,11 +204,13 @@ ShareDbMongo.prototype.close = function(callback) {
225
204
  if (err && err.code === 5101) return callback();
226
205
  if (err) return callback(err);
227
206
  self.closed = true;
228
- self._mongoClient.close(function(err) {
229
- if (err) return callback(err);
230
- if (!self._mongoPollClient) return callback();
231
- self._mongoPollClient.close(callback);
232
- });
207
+ self._mongoClient.close()
208
+ .then(function() {
209
+ return self._mongoPollClient && self._mongoPollClient.close();
210
+ })
211
+ .then(function() {
212
+ callback(null);
213
+ }, callback);
233
214
  });
234
215
  };
235
216
 
@@ -280,14 +261,20 @@ ShareDbMongo.prototype._writeOp = function(collectionName, id, op, snapshot, cal
280
261
  var doc = shallowClone(op);
281
262
  doc.d = id;
282
263
  doc.o = snapshot._opLink;
283
- opCollection.insertOne(doc, callback);
264
+ opCollection.insertOne(doc)
265
+ .then(function(result) {
266
+ callback(null, result);
267
+ }, callback);
284
268
  });
285
269
  };
286
270
 
287
271
  ShareDbMongo.prototype._deleteOp = function(collectionName, opId, callback) {
288
272
  this.getOpCollection(collectionName, function(err, opCollection) {
289
273
  if (err) return callback(err);
290
- opCollection.deleteOne({_id: opId}, callback);
274
+ opCollection.deleteOne({_id: opId})
275
+ .then(function(result) {
276
+ callback(null, result);
277
+ }, callback);
291
278
  });
292
279
  };
293
280
 
@@ -301,17 +288,20 @@ ShareDbMongo.prototype._writeSnapshot = function(request, id, snapshot, opId, ca
301
288
  if (middlewareErr) {
302
289
  return callback(middlewareErr);
303
290
  }
304
- collection.insertOne(request.documentToWrite, function(err) {
305
- if (err) {
306
- // Return non-success instead of duplicate key error, since this is
307
- // expected to occur during simultaneous creates on the same id
308
- if (err.code === 11000 && /\b_id_\b/.test(err.message)) {
309
- return callback(null, false);
291
+ collection.insertOne(request.documentToWrite)
292
+ .then(
293
+ function() {
294
+ callback(null, true);
295
+ },
296
+ function(err) {
297
+ // Return non-success instead of duplicate key error, since this is
298
+ // expected to occur during simultaneous creates on the same id
299
+ if (err.code === 11000 && /\b_id_\b/.test(err.message)) {
300
+ return callback(null, false);
301
+ }
302
+ return callback(err);
310
303
  }
311
- return callback(err);
312
- }
313
- callback(null, true);
314
- });
304
+ );
315
305
  });
316
306
  } else {
317
307
  request.query = {_id: id, _v: request.documentToWrite._v - 1};
@@ -319,11 +309,11 @@ ShareDbMongo.prototype._writeSnapshot = function(request, id, snapshot, opId, ca
319
309
  if (middlewareErr) {
320
310
  return callback(middlewareErr);
321
311
  }
322
- collection.replaceOne(request.query, request.documentToWrite, function(err, result) {
323
- if (err) return callback(err);
324
- var succeeded = !!result.modifiedCount;
325
- callback(null, succeeded);
326
- });
312
+ collection.replaceOne(request.query, request.documentToWrite)
313
+ .then(function(result) {
314
+ var succeeded = !!result.modifiedCount;
315
+ callback(null, succeeded);
316
+ }, callback);
327
317
  });
328
318
  }
329
319
  });
@@ -343,11 +333,11 @@ ShareDbMongo.prototype.getSnapshot = function(collectionName, id, fields, option
343
333
  self._middleware.trigger(MiddlewareHandler.Actions.beforeSnapshotLookup, request, function(middlewareErr) {
344
334
  if (middlewareErr) return callback(middlewareErr);
345
335
 
346
- collection.find(request.query, request.findOptions).limit(1).project(projection).next(function(err, doc) {
347
- if (err) return callback(err);
348
- var snapshot = (doc) ? castToSnapshot(doc) : new MongoSnapshot(id, 0, null, undefined);
349
- callback(null, snapshot);
350
- });
336
+ collection.find(request.query, request.findOptions).limit(1).project(projection).next()
337
+ .then(function(doc) {
338
+ var snapshot = (doc) ? castToSnapshot(doc) : new MongoSnapshot(id, 0, null, undefined);
339
+ callback(null, snapshot);
340
+ }, callback);
351
341
  });
352
342
  });
353
343
  };
@@ -363,20 +353,20 @@ ShareDbMongo.prototype.getSnapshotBulk = function(collectionName, ids, fields, o
363
353
  self._middleware.trigger(MiddlewareHandler.Actions.beforeSnapshotLookup, request, function(middlewareErr) {
364
354
  if (middlewareErr) return callback(middlewareErr);
365
355
 
366
- collection.find(request.query, request.findOptions).project(projection).toArray(function(err, docs) {
367
- if (err) return callback(err);
368
- var snapshotMap = {};
369
- for (var i = 0; i < docs.length; i++) {
370
- var snapshot = castToSnapshot(docs[i]);
371
- snapshotMap[snapshot.id] = snapshot;
372
- }
373
- for (var i = 0; i < ids.length; i++) {
374
- var id = ids[i];
375
- if (snapshotMap[id]) continue;
376
- snapshotMap[id] = new MongoSnapshot(id, 0, null, undefined);
377
- }
378
- callback(null, snapshotMap);
379
- });
356
+ collection.find(request.query, request.findOptions).project(projection).toArray()
357
+ .then(function(docs) {
358
+ var snapshotMap = {};
359
+ for (var i = 0; i < docs.length; i++) {
360
+ var snapshot = castToSnapshot(docs[i]);
361
+ snapshotMap[snapshot.id] = snapshot;
362
+ }
363
+ for (var i = 0; i < ids.length; i++) {
364
+ var id = ids[i];
365
+ if (snapshotMap[id]) continue;
366
+ snapshotMap[id] = new MongoSnapshot(id, 0, null, undefined);
367
+ }
368
+ callback(null, snapshotMap);
369
+ }, callback);
380
370
  });
381
371
  });
382
372
  };
@@ -423,14 +413,14 @@ ShareDbMongo.prototype.getOpCollection = function(collectionName, callback) {
423
413
  // collection this won't be a problem, but this is a dangerous mechanism.
424
414
  // Perhaps we should only warn instead of creating the indexes, especially
425
415
  // when there is a lot of data in the collection.
426
- collection.createIndex({d: 1, v: 1}, {background: true}, function(err) {
427
- if (err) return callback(err);
428
- collection.createIndex({src: 1, seq: 1, v: 1}, {background: true}, function(err) {
429
- if (err) return callback(err);
416
+ collection.createIndex({d: 1, v: 1}, {background: true})
417
+ .then(function() {
418
+ return collection.createIndex({src: 1, seq: 1, v: 1}, {background: true});
419
+ })
420
+ .then(function() {
430
421
  self.opIndexes[collectionName] = true;
431
422
  callback(null, collection);
432
- });
433
- });
423
+ }, callback);
434
424
  });
435
425
  };
436
426
 
@@ -544,27 +534,27 @@ ShareDbMongo.prototype.getCommittedOpVersion = function(collectionName, id, snap
544
534
  // Since ops are optimistically written prior to writing the snapshot, the
545
535
  // op could end up being written multiple times or have been written but
546
536
  // not count as committed if not backreferenced from the snapshot
547
- opCollection.find(query).project(projection).sort(sort).limit(1).next(function(err, doc) {
548
- if (err) return callback(err);
549
- // If we find no op with the same src and seq, we definitely don't have
550
- // any match. This should prevent us from accidentally querying a huge
551
- // history of ops
552
- if (!doc) return callback();
553
- // If we do find an op with the same src and seq, we still have to get
554
- // the ops from the snapshot to figure out if the op was actually
555
- // committed already, and at what version in case of multiple matches
556
- var from = doc.v;
557
- self.getOpsToSnapshot(collectionName, id, from, snapshot, options, function(err, ops) {
558
- if (err) return callback(err);
559
- for (var i = ops.length; i--;) {
560
- var item = ops[i];
561
- if (op.src === item.src && op.seq === item.seq) {
562
- return callback(null, item.v);
537
+ opCollection.find(query).project(projection).sort(sort).limit(1).next()
538
+ .then(function(doc) {
539
+ // If we find no op with the same src and seq, we definitely don't have
540
+ // any match. This should prevent us from accidentally querying a huge
541
+ // history of ops
542
+ if (!doc) return callback();
543
+ // If we do find an op with the same src and seq, we still have to get
544
+ // the ops from the snapshot to figure out if the op was actually
545
+ // committed already, and at what version in case of multiple matches
546
+ var from = doc.v;
547
+ self.getOpsToSnapshot(collectionName, id, from, snapshot, options, function(err, ops) {
548
+ if (err) return callback(err);
549
+ for (var i = ops.length; i--;) {
550
+ var item = ops[i];
551
+ if (op.src === item.src && op.seq === item.seq) {
552
+ return callback(null, item.v);
553
+ }
563
554
  }
564
- }
565
- callback();
566
- });
567
- });
555
+ callback();
556
+ });
557
+ }, callback);
568
558
  });
569
559
  };
570
560
 
@@ -677,7 +667,10 @@ ShareDbMongo.prototype._getOps = function(collectionName, id, from, to, options,
677
667
  // for tracking purposes
678
668
  var projection = (options && options.metadata) ? {d: 0} : {d: 0, m: 0};
679
669
  var sort = {v: 1};
680
- opCollection.find(query).project(projection).sort(sort).toArray(callback);
670
+ opCollection.find(query).project(projection).sort(sort).toArray()
671
+ .then(function(result) {
672
+ callback(null, result);
673
+ }, callback);
681
674
  });
682
675
  };
683
676
 
@@ -776,21 +769,23 @@ function getFirstOpWithUniqueVersion(cursor, opLinkValidator, callback) {
776
769
  return closeCursor(cursor, callback, error, opWithUniqueVersion);
777
770
  }
778
771
 
779
- cursor.next(function(error, op) {
780
- if (error) {
781
- return closeCursor(cursor, callback, error);
782
- }
783
-
784
- opLinkValidator.push(op);
785
- getFirstOpWithUniqueVersion(cursor, opLinkValidator, callback);
786
- });
772
+ cursor.next()
773
+ .then(
774
+ function(op) {
775
+ opLinkValidator.push(op);
776
+ getFirstOpWithUniqueVersion(cursor, opLinkValidator, callback);
777
+ },
778
+ function(error) {
779
+ closeCursor(cursor, callback, error);
780
+ }
781
+ );
787
782
  }
788
783
 
789
784
  function closeCursor(cursor, callback, error, returnValue) {
790
- cursor.close(function(closeError) {
791
- error = error || closeError;
792
- callback(error, returnValue);
793
- });
785
+ cursor.close()
786
+ .then(function() {
787
+ callback(error, returnValue);
788
+ }, callback);
794
789
  }
795
790
 
796
791
  ShareDbMongo.prototype._getSnapshotOpLink = function(collectionName, id, options, callback) {
@@ -804,7 +799,10 @@ ShareDbMongo.prototype._getSnapshotOpLink = function(collectionName, id, options
804
799
  request.query = query;
805
800
  self._middleware.trigger(MiddlewareHandler.Actions.beforeSnapshotLookup, request, function(middlewareErr) {
806
801
  if (middlewareErr) return callback(middlewareErr);
807
- collection.find(query, request.findOptions).limit(1).project(projection).next(callback);
802
+ collection.find(query, request.findOptions).limit(1).project(projection).next()
803
+ .then(function(result) {
804
+ callback(null, result);
805
+ }, callback);
808
806
  });
809
807
  });
810
808
  };
@@ -820,7 +818,10 @@ ShareDbMongo.prototype._getSnapshotOpLinkBulk = function(collectionName, ids, op
820
818
  request.query = query;
821
819
  self._middleware.trigger(MiddlewareHandler.Actions.beforeSnapshotLookup, request, function(middlewareErr) {
822
820
  if (middlewareErr) return callback(middlewareErr);
823
- collection.find(query, request.findOptions).project(projection).toArray(callback);
821
+ collection.find(query, request.findOptions).project(projection).toArray()
822
+ .then(function(result) {
823
+ callback(null, result);
824
+ }, callback);
824
825
  });
825
826
  });
826
827
  };
@@ -882,7 +883,10 @@ ShareDbMongo.prototype._query = function(collection, inputQuery, projection, cal
882
883
  // If no collection operation or cursor operations were used, return
883
884
  // an array of snapshots that are passed in the "results" argument
884
885
  // in the callback
885
- cursor.toArray(callback);
886
+ cursor.toArray()
887
+ .then(function(result) {
888
+ callback(null, result);
889
+ }, callback);
886
890
  };
887
891
 
888
892
  ShareDbMongo.prototype.query = function(collectionName, inputQuery, fields, options, callback) {
@@ -955,9 +959,10 @@ ShareDbMongo.prototype.queryPollDoc = function(collectionName, id, inputQuery, o
955
959
  parsed.query._id = id;
956
960
  }
957
961
 
958
- collection.find(parsed.query).limit(1).project({_id: 1}).next(function(err, doc) {
959
- callback(err, !!doc);
960
- });
962
+ collection.find(parsed.query).limit(1).project({_id: 1}).next()
963
+ .then(function(doc) {
964
+ callback(null, !!doc);
965
+ }, callback);
961
966
  });
962
967
  };
963
968
 
@@ -1482,36 +1487,58 @@ function getProjection(fields, options) {
1482
1487
 
1483
1488
  var collectionOperationsMap = {
1484
1489
  $distinct: function(collection, query, value, cb) {
1485
- collection.distinct(value.field, query, cb);
1490
+ collection.distinct(value.field, query)
1491
+ .then(function(result) {
1492
+ cb(null, result);
1493
+ }, cb);
1486
1494
  },
1487
1495
  $aggregate: function(collection, query, value, cb) {
1488
1496
  var cursor = collection.aggregate(value);
1489
- cursor.toArray(cb);
1497
+ cursor.toArray()
1498
+ .then(function(result) {
1499
+ cb(null, result);
1500
+ }, cb);
1490
1501
  },
1491
1502
  $mapReduce: function(collection, query, value, cb) {
1492
1503
  if (typeof value !== 'object') {
1493
1504
  var err = ShareDbMongo.malformedQueryOperatorError('$mapReduce');
1494
1505
  return cb(err);
1495
1506
  }
1507
+ // This function was removed in mongodb5:
1508
+ // https://github.com/mongodb/node-mongodb-native/pull/3511
1509
+ if (typeof collection.mapReduce !== 'function') {
1510
+ var err = ShareDbMongo.$mapReduceDisabledError();
1511
+ }
1496
1512
  var mapReduceOptions = {
1497
1513
  query: query,
1498
1514
  out: {inline: 1},
1499
1515
  scope: value.scope || {}
1500
1516
  };
1501
- collection.mapReduce(
1502
- value.map, value.reduce, mapReduceOptions, cb);
1517
+ collection.mapReduce(value.map, value.reduce, mapReduceOptions)
1518
+ .then(function(result) {
1519
+ cb(null, result);
1520
+ }, cb);
1503
1521
  }
1504
1522
  };
1505
1523
 
1506
1524
  var cursorOperationsMap = {
1507
1525
  $count: function(cursor, value, cb) {
1508
- cursor.count(cb);
1526
+ cursor.count()
1527
+ .then(function(result) {
1528
+ cb(null, result);
1529
+ }, cb);
1509
1530
  },
1510
1531
  $explain: function(cursor, verbosity, cb) {
1511
- cursor.explain(verbosity, cb);
1532
+ cursor.explain(verbosity)
1533
+ .then(function(result) {
1534
+ cb(null, result);
1535
+ }, cb);
1512
1536
  },
1513
1537
  $map: function(cursor, fn, cb) {
1514
- cursor.map(fn, cb);
1538
+ cursor.map(fn)
1539
+ .then(function(result) {
1540
+ cb(null, result);
1541
+ }, cb);
1515
1542
  }
1516
1543
  };
1517
1544
 
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "sharedb-mongo",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "MongoDB database adapter for ShareDB",
5
5
  "main": "index.js",
6
6
  "dependencies": {
7
- "async": "^2.6.3",
8
- "mongodb": "^2.1.2 || ^3.1.13 || ^4.0.0",
7
+ "mongodb": "^2.1.2 || ^3.1.13 || ^4.0.0 || ^5.0.0",
9
8
  "sharedb": "^1.9.1 || ^2.0.0 || ^3.0.0"
10
9
  },
11
10
  "devDependencies": {
@@ -17,6 +16,7 @@
17
16
  "mongodb2": "npm:mongodb@^2.1.2",
18
17
  "mongodb3": "npm:mongodb@^3.0.0",
19
18
  "mongodb4": "npm:mongodb@^4.0.0",
19
+ "mongodb5": "npm:mongodb@^5.0.0",
20
20
  "nyc": "^14.1.1",
21
21
  "ot-json1": "^1.0.1",
22
22
  "sharedb-mingo-memory": "^1.1.1",
@@ -30,7 +30,8 @@
30
30
  "test:mongodb2": "_SHAREDB_MONGODB_DRIVER=mongodb2 npm test",
31
31
  "test:mongodb3": "_SHAREDB_MONGODB_DRIVER=mongodb3 npm test",
32
32
  "test:mongodb4": "_SHAREDB_MONGODB_DRIVER=mongodb4 npm test",
33
- "test:all": "npm run test:mongodb2 && npm run test:mongodb3 && npm run test:mongodb4",
33
+ "test:mongodb5": "_SHAREDB_MONGODB_DRIVER=mongodb5 npm test",
34
+ "test:all": "npm run test:mongodb2 && npm run test:mongodb3 && npm run test:mongodb4 && npm run test:mongodb5",
34
35
  "test-cover": "nyc --temp-dir=coverage -r text -r lcov npm run test:all"
35
36
  },
36
37
  "repository": "git://github.com/share/sharedb-mongo.git",
@@ -12,10 +12,11 @@ function create(options, callback) {
12
12
  var db = new ShareDbMongo(mongoUrl, opts);
13
13
  db.getDbs(function(err, mongo) {
14
14
  if (err) return callback(err);
15
- mongo.dropDatabase(function(err) {
16
- if (err) return callback(err);
17
- callback(null, db, mongo);
18
- });
15
+ mongo.dropDatabase()
16
+ .then(function() {
17
+ callback(null, db, mongo);
18
+ })
19
+ .catch(callback);
19
20
  });
20
21
  };
21
22
 
@@ -62,7 +63,9 @@ function create(options, callback) {
62
63
 
63
64
  commitOpChain(db, mongo, collection, id, ops, function(error) {
64
65
  if (error) done(error);
65
- mongo.collection('o_' + collection).deleteOne({v: 1}, done);
66
+ mongo.collection('o_' + collection).deleteOne({v: 1}).then(function() {
67
+ done();
68
+ });
66
69
  });
67
70
  });
68
71
 
@@ -127,8 +130,7 @@ function commitOpChain(db, mongo, collection, id, ops, previousOpId, version, ca
127
130
  var snapshot = {id: id, v: version + 1, type: 'json0', data: {}, m: null, _opLink: previousOpId};
128
131
  db.commit(collection, id, op, snapshot, null, function(error) {
129
132
  if (error) return callback(error);
130
- mongo.collection('o_' + collection).find({d: id, v: version}).next(function(error, op) {
131
- if (error) return callback(error);
133
+ mongo.collection('o_' + collection).find({d: id, v: version}).next().then(function(op) {
132
134
  commitOpChain(db, mongo, collection, id, ops, (op ? op._id : null), ++version, callback);
133
135
  });
134
136
  });
@@ -12,10 +12,11 @@ function create(callback) {
12
12
  });
13
13
  db.getDbs(function(err, mongo) {
14
14
  if (err) return callback(err);
15
- mongo.dropDatabase(function(err) {
16
- if (err) return callback(err);
17
- callback(null, db, mongo);
18
- });
15
+ mongo.dropDatabase()
16
+ .then(function() {
17
+ callback(null, db, mongo);
18
+ })
19
+ .catch(callback);
19
20
  });
20
21
  };
21
22
 
@@ -78,7 +79,11 @@ describe('getOpsWithoutStrictLinking: true', function() {
78
79
 
79
80
  callInSeries([
80
81
  function(next) {
81
- mongo.collection('o_' + collection).insertOne(spuriousOp, next);
82
+ mongo.collection('o_' + collection).insertOne(spuriousOp)
83
+ .then(function(result) {
84
+ next(null, result);
85
+ })
86
+ .catch(next);
82
87
  },
83
88
  function(result, next) {
84
89
  db.getOps(collection, id, 0, 2, null, next);
@@ -99,7 +104,11 @@ describe('getOpsWithoutStrictLinking: true', function() {
99
104
 
100
105
  callInSeries([
101
106
  function(next) {
102
- mongo.collection('o_' + collection).insertOne(spuriousOp, next);
107
+ mongo.collection('o_' + collection).insertOne(spuriousOp)
108
+ .then(function(result) {
109
+ next(null, result);
110
+ })
111
+ .catch(next);
103
112
  },
104
113
  function(result, next) {
105
114
  db.getOps(collection, id, 0, 2, null, next);
@@ -125,7 +134,11 @@ describe('getOpsWithoutStrictLinking: true', function() {
125
134
 
126
135
  callInSeries([
127
136
  function(next) {
128
- mongo.collection('o_' + collection).insertMany(spuriousOps, next);
137
+ mongo.collection('o_' + collection).insertMany(spuriousOps)
138
+ .then(function(result) {
139
+ next(null, result);
140
+ })
141
+ .catch(next);
129
142
  },
130
143
  function(result, next) {
131
144
  db.getOps(collection, id, 0, 2, null, next);
@@ -160,10 +173,11 @@ function commitOpChain(db, mongo, collection, id, ops, previousOpId, version, ca
160
173
  var snapshot = {id: id, v: version + 1, type: 'json0', data: {}, m: null, _opLink: previousOpId};
161
174
  db.commit(collection, id, op, snapshot, null, function(error) {
162
175
  if (error) return callback(error);
163
- mongo.collection('o_' + collection).find({d: id, v: version}).next(function(error, op) {
164
- if (error) return callback(error);
165
- commitOpChain(db, mongo, collection, id, ops, op._id, ++version, callback);
166
- });
176
+ mongo.collection('o_' + collection).find({d: id, v: version}).next()
177
+ .then(function(op) {
178
+ commitOpChain(db, mongo, collection, id, ops, op._id, ++version, callback);
179
+ })
180
+ .catch(callback);
167
181
  });
168
182
  }
169
183
 
@@ -9,10 +9,11 @@ function create(callback) {
9
9
  var db = new ShareDbMongo(mongoUrl);
10
10
  db.getDbs(function(err, mongo) {
11
11
  if (err) return callback(err);
12
- mongo.dropDatabase(function(err) {
13
- if (err) return callback(err);
14
- callback(null, db, mongo);
15
- });
12
+ mongo.dropDatabase()
13
+ .then(function() {
14
+ callback(null, db, mongo);
15
+ })
16
+ .catch(callback);
16
17
  });
17
18
  };
18
19
 
@@ -38,8 +39,7 @@ describe('mongo db', function() {
38
39
  var mongo = this.mongo;
39
40
  this.db.commit('testcollection', 'foo', {v: 0, create: {}}, {}, null, function(err) {
40
41
  if (err) return done(err);
41
- mongo.collection('o_testcollection').indexInformation(function(err, indexes) {
42
- if (err) return done(err);
42
+ mongo.collection('o_testcollection').indexInformation().then(function(indexes) {
43
43
  // Index for getting document(s) ops
44
44
  expect(indexes['d_1_v_1']).ok;
45
45
  // Index for checking committed op(s) by src and seq
@@ -51,8 +51,7 @@ describe('mongo db', function() {
51
51
 
52
52
  it('respects unique indexes', function(done) {
53
53
  var db = this.db;
54
- this.mongo.collection('testcollection').createIndex({x: 1}, {unique: true}, function(err) {
55
- if (err) return done(err);
54
+ this.mongo.collection('testcollection').createIndex({x: 1}, {unique: true}).then(function() {
56
55
  db.commit('testcollection', 'foo', {v: 0, create: {}}, {v: 1, data: {x: 7}}, null, function(err) {
57
56
  if (err) return done(err);
58
57
  db.commit('testcollection', 'bar', {v: 0, create: {}}, {v: 1, data: {x: 7}}, null, function(err) {
@@ -335,6 +334,11 @@ describe('mongo db', function() {
335
334
  });
336
335
 
337
336
  it('$mapReduce queries should work when allowJavaScriptQuery == true', function(done) {
337
+ if (process.env._SHAREDB_MONGODB_DRIVER === 'mongodb5') {
338
+ // This function was removed in mongodb5:
339
+ // https://github.com/mongodb/node-mongodb-native/pull/3511
340
+ return done();
341
+ }
338
342
  var snapshots = [
339
343
  {type: 'json0', v: 1, data: {player: 'a', round: 1, score: 5}},
340
344
  {type: 'json0', v: 1, data: {player: 'a', round: 2, score: 7}},
@@ -381,10 +385,11 @@ describe('mongo db connection', function() {
381
385
  // logic.
382
386
  this.db.getDbs(function(err, mongo) {
383
387
  if (err) return done(err);
384
- mongo.dropDatabase(function(err) {
385
- if (err) return done(err);
386
- done();
387
- });
388
+ mongo.dropDatabase()
389
+ .then(function() {
390
+ done();
391
+ })
392
+ .catch(done);
388
393
  });
389
394
  });
390
395
 
@@ -16,10 +16,11 @@ function create(callback) {
16
16
  var db = new ShareDbMongo(mongoUrl);
17
17
  db.getDbs(function(err, mongo) {
18
18
  if (err) return callback(err);
19
- mongo.dropDatabase(function(err) {
20
- if (err) return callback(err);
21
- callback(null, db, mongo);
22
- });
19
+ mongo.dropDatabase()
20
+ .then(function() {
21
+ callback(null, db, mongo);
22
+ })
23
+ .catch(callback);
23
24
  });
24
25
  }
25
26