cozy-pouch-link 60.15.2 → 60.16.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.
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.replicateAllDocs = exports.startReplication = void 0;
8
+ exports.sharedDriveReplicateAllDocs = exports.replicateAllDocs = exports.startReplication = void 0;
9
9
 
10
10
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
11
 
@@ -23,6 +23,14 @@ var _logger = _interopRequireDefault(require("./logger"));
23
23
 
24
24
  var _remote = require("./remote");
25
25
 
26
+ var _cozyClient = _interopRequireDefault(require("cozy-client"));
27
+
28
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
29
+
30
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
31
+
32
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
33
+
26
34
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
27
35
 
28
36
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
@@ -61,15 +69,17 @@ var TIME_UNITS = [['ms', 1000], ['s', 60], ['m', 60], ['h', 24]];
61
69
  * @param {object} replicationOptions Any option supported by the Pouch replication API (https://pouchdb.com/api.html#replication)
62
70
  * @param {string} replicationOptions.strategy The direction of the replication. Can be "fromRemote", "toRemote" or "sync"
63
71
  * @param {boolean} replicationOptions.initialReplication Whether or not this is an initial replication
72
+ * @param {string} [replicationOptions.driveId] - ID of the shared drive to replicate (enables shared drive mode)
64
73
  * @param {string} replicationOptions.doctype The doctype to replicate
65
74
  * @param {import('cozy-client/types/types').Query[]} replicationOptions.warmupQueries The queries to warmup
66
75
  * @param {Function} getReplicationURL A function that should return the remote replication URL
67
76
  * @param {import('./localStorage').PouchLocalStorage} storage Methods to access local storage
77
+ * @param {CozyClient} client - Cozy client instance (required for shared drive replication)
68
78
  *
69
79
  * @returns {import('./types').CancelablePromise} A cancelable promise that resolves at the end of the replication
70
80
  */
71
81
 
72
- var startReplication = function startReplication(pouch, replicationOptions, getReplicationURL, storage) {
82
+ var startReplication = function startReplication(pouch, replicationOptions, getReplicationURL, storage, client) {
73
83
  var replication;
74
84
  var docs = {};
75
85
  var start = new Date();
@@ -93,83 +103,131 @@ var startReplication = function startReplication(pouch, replicationOptions, getR
93
103
  }
94
104
  });
95
105
 
96
- if (initialReplication && strategy !== 'toRemote') {
106
+ if (replicationOptions.driveId) {
97
107
  ;
98
108
  (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
99
- var end;
109
+ var _docs;
110
+
100
111
  return _regenerator.default.wrap(function _callee$(_context) {
101
112
  while (1) {
102
113
  switch (_context.prev = _context.next) {
103
114
  case 0:
104
- // For the first remote->local replication, we manually replicate all docs
105
- // as it avoids to replicate all revs history, which can lead to
106
- // performances issues
107
- _logger.default.info("PouchManager: Start first replication for ".concat(doctype));
108
-
115
+ _context.prev = 0;
109
116
  _context.next = 3;
110
- return replicateAllDocs({
111
- db: pouch,
112
- baseUrl: url,
117
+ return sharedDriveReplicateAllDocs({
118
+ pouch: pouch,
119
+ storage: storage,
113
120
  doctype: doctype,
114
- storage: storage
121
+ client: client,
122
+ initialReplication: initialReplication,
123
+ driveId: replicationOptions.driveId
115
124
  });
116
125
 
117
126
  case 3:
118
- docs = _context.sent;
119
-
120
- _logger.default.info("PouchManager: End first replication for ".concat(doctype));
121
-
122
- end = new Date();
123
-
124
- if (process.env.NODE_ENV !== 'production') {
125
- _logger.default.info("PouchManager: initial replication with all_docs for ".concat(url, " took ").concat(humanTimeDelta(end.getTime() - start.getTime())));
126
- }
127
+ _docs = _context.sent;
128
+ resolve(_docs);
129
+ _context.next = 10;
130
+ break;
127
131
 
128
- return _context.abrupt("return", resolve(docs));
132
+ case 7:
133
+ _context.prev = 7;
134
+ _context.t0 = _context["catch"](0);
135
+ reject(_context.t0);
129
136
 
130
- case 8:
137
+ case 10:
131
138
  case "end":
132
139
  return _context.stop();
133
140
  }
134
141
  }
135
- }, _callee);
142
+ }, _callee, null, [[0, 7]]);
136
143
  }))();
137
144
  return;
138
- }
139
-
140
- if (strategy === 'fromRemote') {
141
- replication = pouch.replicate.from(url, options);
142
- } else if (strategy === 'toRemote') {
143
- replication = pouch.replicate.to(url, options);
144
145
  } else {
145
- replication = pouch.sync(url, options);
146
- }
147
-
148
- replication.on('change', function (infos) {
149
- //! Since we introduced the concept of strategy we can use
150
- // PouchDB.replicate or PouchDB.sync. But both don't share the
151
- // same API for the change's event.
152
- // See https://pouchdb.com/api.html#replication
153
- // and https://pouchdb.com/api.html#sync (see example response)
154
- var change = infos.change ? infos.change : infos;
155
-
156
- if (change.docs) {
157
- change.docs.filter(function (doc) {
158
- return !isDesignDocument(doc) && !isDeletedDocument(doc);
159
- }).forEach(function (doc) {
160
- docs[doc._id] = doc;
161
- });
146
+ if (initialReplication && strategy !== 'toRemote') {
147
+ ;
148
+ (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
149
+ var end;
150
+ return _regenerator.default.wrap(function _callee2$(_context2) {
151
+ while (1) {
152
+ switch (_context2.prev = _context2.next) {
153
+ case 0:
154
+ _context2.prev = 0;
155
+
156
+ // For the first remote->local replication, we manually replicate all docs
157
+ // as it avoids to replicate all revs history, which can lead to
158
+ // performances issues
159
+ _logger.default.info("PouchManager: Start first replication for ".concat(doctype));
160
+
161
+ _context2.next = 4;
162
+ return replicateAllDocs({
163
+ db: pouch,
164
+ baseUrl: url,
165
+ doctype: doctype,
166
+ storage: storage
167
+ });
168
+
169
+ case 4:
170
+ docs = _context2.sent;
171
+
172
+ _logger.default.info("PouchManager: End first replication for ".concat(doctype));
173
+
174
+ end = new Date();
175
+
176
+ if (process.env.NODE_ENV !== 'production') {
177
+ _logger.default.info("PouchManager: initial replication with all_docs for ".concat(url, " took ").concat(humanTimeDelta(end.getTime() - start.getTime())));
178
+ }
179
+
180
+ return _context2.abrupt("return", resolve(docs));
181
+
182
+ case 11:
183
+ _context2.prev = 11;
184
+ _context2.t0 = _context2["catch"](0);
185
+ return _context2.abrupt("return", reject(_context2.t0));
186
+
187
+ case 14:
188
+ case "end":
189
+ return _context2.stop();
190
+ }
191
+ }
192
+ }, _callee2, null, [[0, 11]]);
193
+ }))();
194
+ return;
162
195
  }
163
- });
164
- replication.on('error', reject).on('complete', function () {
165
- var end = new Date();
166
196
 
167
- if (process.env.NODE_ENV !== 'production') {
168
- _logger.default.info("PouchManager: replication for ".concat(url, " took ").concat(humanTimeDelta(end.getTime() - start.getTime())));
197
+ if (strategy === 'fromRemote') {
198
+ replication = pouch.replicate.from(url, options);
199
+ } else if (strategy === 'toRemote') {
200
+ replication = pouch.replicate.to(url, options);
201
+ } else {
202
+ replication = pouch.sync(url, options);
169
203
  }
170
204
 
171
- resolve(Object.values(docs));
172
- });
205
+ replication.on('change', function (infos) {
206
+ //! Since we introduced the concept of strategy we can use
207
+ // PouchDB.replicate or PouchDB.sync. But both don't share the
208
+ // same API for the change's event.
209
+ // See https://pouchdb.com/api.html#replication
210
+ // and https://pouchdb.com/api.html#sync (see example response)
211
+ var change = infos.change ? infos.change : infos;
212
+
213
+ if (change.docs) {
214
+ change.docs.forEach(function (doc) {
215
+ if (!isDesignDocument(doc) && !isDeletedDocument(doc)) {
216
+ docs[doc._id] = doc;
217
+ }
218
+ });
219
+ }
220
+ });
221
+ replication.on('error', reject).on('complete', function () {
222
+ var end = new Date();
223
+
224
+ if (process.env.NODE_ENV !== 'production') {
225
+ _logger.default.info("PouchManager: replication for ".concat(url, " took ").concat(humanTimeDelta(end.getTime() - start.getTime())));
226
+ }
227
+
228
+ resolve(Object.values(docs));
229
+ });
230
+ }
173
231
  });
174
232
 
175
233
  var cancel = function cancel() {
@@ -208,53 +266,53 @@ var filterDocs = function filterDocs(docs) {
208
266
 
209
267
 
210
268
  var replicateAllDocs = /*#__PURE__*/function () {
211
- var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref2) {
269
+ var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(_ref3) {
212
270
  var db, baseUrl, doctype, storage, remoteUrlAllDocs, batchSize, hasMore, startDocId, docs, res, _res, filteredDocs;
213
271
 
214
- return _regenerator.default.wrap(function _callee2$(_context2) {
272
+ return _regenerator.default.wrap(function _callee3$(_context3) {
215
273
  while (1) {
216
- switch (_context2.prev = _context2.next) {
274
+ switch (_context3.prev = _context3.next) {
217
275
  case 0:
218
- db = _ref2.db, baseUrl = _ref2.baseUrl, doctype = _ref2.doctype, storage = _ref2.storage;
276
+ db = _ref3.db, baseUrl = _ref3.baseUrl, doctype = _ref3.doctype, storage = _ref3.storage;
219
277
  remoteUrlAllDocs = new URL("".concat(baseUrl, "/_all_docs"));
220
278
  batchSize = BATCH_SIZE;
221
279
  hasMore = true;
222
- _context2.next = 6;
280
+ _context3.next = 6;
223
281
  return storage.getLastReplicatedDocID(doctype);
224
282
 
225
283
  case 6:
226
- startDocId = _context2.sent;
284
+ startDocId = _context3.sent;
227
285
  // Get last replicated _id in localStorage
228
286
  docs = [];
229
287
 
230
288
  case 8:
231
289
  if (!hasMore) {
232
- _context2.next = 42;
290
+ _context3.next = 42;
233
291
  break;
234
292
  }
235
293
 
236
294
  if (startDocId) {
237
- _context2.next = 26;
295
+ _context3.next = 26;
238
296
  break;
239
297
  }
240
298
 
241
- _context2.next = 12;
299
+ _context3.next = 12;
242
300
  return (0, _remote.fetchRemoteInstance)(remoteUrlAllDocs, {
243
301
  limit: batchSize,
244
302
  include_docs: true
245
303
  });
246
304
 
247
305
  case 12:
248
- res = _context2.sent;
306
+ res = _context3.sent;
249
307
  docs = filterDocs(res.rows);
250
308
 
251
309
  if (!(docs.length === 0)) {
252
- _context2.next = 18;
310
+ _context3.next = 18;
253
311
  break;
254
312
  }
255
313
 
256
314
  hasMore = false;
257
- _context2.next = 24;
315
+ _context3.next = 24;
258
316
  break;
259
317
 
260
318
  case 18:
@@ -264,19 +322,19 @@ var replicateAllDocs = /*#__PURE__*/function () {
264
322
  hasMore = false;
265
323
  }
266
324
 
267
- _context2.next = 22;
325
+ _context3.next = 22;
268
326
  return _helpers.default.insertBulkDocs(db, docs);
269
327
 
270
328
  case 22:
271
- _context2.next = 24;
329
+ _context3.next = 24;
272
330
  return storage.persistLastReplicatedDocID(doctype, startDocId);
273
331
 
274
332
  case 24:
275
- _context2.next = 40;
333
+ _context3.next = 40;
276
334
  break;
277
335
 
278
336
  case 26:
279
- _context2.next = 28;
337
+ _context3.next = 28;
280
338
  return (0, _remote.fetchRemoteInstance)(remoteUrlAllDocs, {
281
339
  include_docs: true,
282
340
  limit: batchSize,
@@ -284,25 +342,25 @@ var replicateAllDocs = /*#__PURE__*/function () {
284
342
  });
285
343
 
286
344
  case 28:
287
- _res = _context2.sent;
345
+ _res = _context3.sent;
288
346
  filteredDocs = filterDocs(_res.rows);
289
347
 
290
348
  if (!(filteredDocs.length < 2)) {
291
- _context2.next = 32;
349
+ _context3.next = 32;
292
350
  break;
293
351
  }
294
352
 
295
- return _context2.abrupt("return", docs);
353
+ return _context3.abrupt("return", docs);
296
354
 
297
355
  case 32:
298
356
  filteredDocs.shift(); // Remove first element, already included in previous request
299
357
 
300
358
  startDocId = filteredDocs[filteredDocs.length - 1]._id;
301
- _context2.next = 36;
359
+ _context3.next = 36;
302
360
  return _helpers.default.insertBulkDocs(db, filteredDocs);
303
361
 
304
362
  case 36:
305
- _context2.next = 38;
363
+ _context3.next = 38;
306
364
  return storage.persistLastReplicatedDocID(doctype, startDocId);
307
365
 
308
366
  case 38:
@@ -313,23 +371,201 @@ var replicateAllDocs = /*#__PURE__*/function () {
313
371
  }
314
372
 
315
373
  case 40:
316
- _context2.next = 8;
374
+ _context3.next = 8;
317
375
  break;
318
376
 
319
377
  case 42:
320
- return _context2.abrupt("return", docs);
378
+ return _context3.abrupt("return", docs);
321
379
 
322
380
  case 43:
323
381
  case "end":
324
- return _context2.stop();
382
+ return _context3.stop();
325
383
  }
326
384
  }
327
- }, _callee2);
385
+ }, _callee3);
328
386
  }));
329
387
 
330
388
  return function replicateAllDocs(_x) {
331
- return _ref3.apply(this, arguments);
389
+ return _ref4.apply(this, arguments);
390
+ };
391
+ }();
392
+ /**
393
+ * Replicates all documents from a shared drive to a local PouchDB instance.
394
+ * This function fetches documents in batches from a twake drive shared drive
395
+ * and replicates them to the local database, maintaining replication state
396
+ * to allow for incremental updates.
397
+ * We do not have an _all_docs view for shared drives, so we use the fetchChanges method.
398
+ *
399
+ * @param {Object} params - The parameters object
400
+ * @param {string} params.driveId - The unique identifier of the shared drive to replicate from
401
+ * @param {Object} params.pouch - The local PouchDB instance to replicate documents to
402
+ * @param {Object} params.storage - Storage interface for persisting replication state
403
+ * @param {string} params.doctype - The document type being replicated (e.g., 'io.cozy.files')
404
+ * @param {boolean} params.initialReplication - Whether this is an initial replication
405
+ * @param {CozyClient} params.client - CozyClient instance for fetching remote documents
406
+ * @returns {Promise<Array>} A promise that resolves to an array of all replicated documents
407
+ * @throws {Error} Throws an error if driveId is not provided
408
+ */
409
+
410
+
411
+ exports.replicateAllDocs = replicateAllDocs;
412
+
413
+ var sharedDriveReplicateAllDocs = /*#__PURE__*/function () {
414
+ var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(_ref5) {
415
+ var driveId, pouch, storage, _ref5$initialReplicat, initialReplication, doctype, client, docs, hasMore, doctypeLastSequence, _yield$client$collect, newLastSeq, results, pending, toDelete, toInsert, allDocsWithDriveId, _iterator, _step, doc, docWithDriveId, updatedToDeleteDocs, toBulkDelete;
416
+
417
+ return _regenerator.default.wrap(function _callee4$(_context4) {
418
+ while (1) {
419
+ switch (_context4.prev = _context4.next) {
420
+ case 0:
421
+ driveId = _ref5.driveId, pouch = _ref5.pouch, storage = _ref5.storage, _ref5$initialReplicat = _ref5.initialReplication, initialReplication = _ref5$initialReplicat === void 0 ? false : _ref5$initialReplicat, doctype = _ref5.doctype, client = _ref5.client;
422
+
423
+ if (driveId) {
424
+ _context4.next = 3;
425
+ break;
426
+ }
427
+
428
+ throw new Error('sharedDriveReplicateAllDocs: driveId is required');
429
+
430
+ case 3:
431
+ docs = [];
432
+ hasMore = true;
433
+ _context4.next = 7;
434
+ return storage.getDoctypeLastSequence(doctype);
435
+
436
+ case 7:
437
+ doctypeLastSequence = _context4.sent;
438
+
439
+ case 8:
440
+ if (!hasMore) {
441
+ _context4.next = 38;
442
+ break;
443
+ }
444
+
445
+ _context4.next = 11;
446
+ return client.collection('io.cozy.files', {
447
+ driveId: driveId
448
+ }).fetchChanges(_objectSpread({
449
+ include_docs: true
450
+ }, doctypeLastSequence ? {
451
+ since: doctypeLastSequence
452
+ } : {}), _objectSpread(_objectSpread({
453
+ includeFilePath: false
454
+ }, initialReplication ? {
455
+ skipDeleted: true,
456
+ skipTrashed: true
457
+ } : {
458
+ skipDeleted: false,
459
+ skipTrashed: false
460
+ }), {}, {
461
+ limit: BATCH_SIZE
462
+ }));
463
+
464
+ case 11:
465
+ _yield$client$collect = _context4.sent;
466
+ newLastSeq = _yield$client$collect.newLastSeq;
467
+ results = _yield$client$collect.results;
468
+ pending = _yield$client$collect.pending;
469
+ toDelete = [];
470
+ toInsert = [];
471
+ allDocsWithDriveId = [];
472
+ _iterator = _createForOfIteratorHelper(results);
473
+
474
+ try {
475
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
476
+ doc = _step.value;
477
+ docWithDriveId = doc.doc;
478
+ docWithDriveId.driveId = driveId;
479
+ allDocsWithDriveId.push(docWithDriveId);
480
+
481
+ if (doc.doc._deleted) {
482
+ toDelete.push(doc.doc);
483
+ } else {
484
+ toInsert.push(docWithDriveId);
485
+ }
486
+ } // FIXME this is a workaround to allow to delete documents from the shared drive
487
+ // changes
488
+ // PouchDB.bulkDocs ignores _deleted documents with revision newer than the existing
489
+ // document
490
+ // The workaround is to get documents from PouchDB with correct revision and delete them
491
+ // see https://github.com/pouchdb/pouchdb/issues/7841
492
+
493
+ } catch (err) {
494
+ _iterator.e(err);
495
+ } finally {
496
+ _iterator.f();
497
+ }
498
+
499
+ if (!(toDelete.length > 0)) {
500
+ _context4.next = 29;
501
+ break;
502
+ }
503
+
504
+ _context4.next = 23;
505
+ return pouch.bulkGet({
506
+ docs: toDelete.map(function (d) {
507
+ return {
508
+ id: d._id
509
+ };
510
+ })
511
+ });
512
+
513
+ case 23:
514
+ updatedToDeleteDocs = _context4.sent;
515
+ toBulkDelete = updatedToDeleteDocs.results.map(function (doc) {
516
+ var _doc$docs, _doc$docs$;
517
+
518
+ return _objectSpread(_objectSpread({}, doc === null || doc === void 0 ? void 0 : (_doc$docs = doc.docs) === null || _doc$docs === void 0 ? void 0 : (_doc$docs$ = _doc$docs[0]) === null || _doc$docs$ === void 0 ? void 0 : _doc$docs$.ok), {}, {
519
+ _deleted: true
520
+ });
521
+ }).filter(function (doc) {
522
+ return doc._id;
523
+ });
524
+
525
+ if (!(toBulkDelete.length > 0)) {
526
+ _context4.next = 29;
527
+ break;
528
+ }
529
+
530
+ _context4.next = 28;
531
+ return pouch.bulkDocs(toBulkDelete);
532
+
533
+ case 28:
534
+ if (toBulkDelete.length !== toDelete.length) {
535
+ _logger.default.error("sharedDriveReplicateAllDocs: Error deleting documents ".concat(toDelete.map(function (d) {
536
+ return d._id;
537
+ }).join(', ')));
538
+ }
539
+
540
+ case 29:
541
+ doctypeLastSequence = newLastSeq;
542
+ _context4.next = 32;
543
+ return _helpers.default.insertBulkDocs(pouch, toInsert);
544
+
545
+ case 32:
546
+ _context4.next = 34;
547
+ return storage.persistDoctypeLastSequence(doctype, doctypeLastSequence);
548
+
549
+ case 34:
550
+ docs = docs.concat(allDocsWithDriveId);
551
+ hasMore = !!pending;
552
+ _context4.next = 8;
553
+ break;
554
+
555
+ case 38:
556
+ return _context4.abrupt("return", docs);
557
+
558
+ case 39:
559
+ case "end":
560
+ return _context4.stop();
561
+ }
562
+ }
563
+ }, _callee4);
564
+ }));
565
+
566
+ return function sharedDriveReplicateAllDocs(_x2) {
567
+ return _ref6.apply(this, arguments);
332
568
  };
333
569
  }();
334
570
 
335
- exports.replicateAllDocs = replicateAllDocs;
571
+ exports.sharedDriveReplicateAllDocs = sharedDriveReplicateAllDocs;