cozy-pouch-link 60.15.1 → 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.
- package/dist/CozyPouchLink.js +123 -3
- package/dist/CozyPouchLink.spec.js +5 -0
- package/dist/PouchManager.js +168 -28
- package/dist/PouchManager.spec.js +1 -1
- package/dist/remote.spec.js +0 -2
- package/dist/replicateOnce.js +40 -28
- package/dist/startReplication.js +318 -82
- package/dist/startReplication.spec.js +385 -11
- package/package.json +3 -3
- package/types/CozyPouchLink.d.ts +34 -2
- package/types/PouchManager.d.ts +28 -2
- package/types/startReplication.d.ts +11 -1
package/dist/startReplication.js
CHANGED
|
@@ -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 (
|
|
106
|
+
if (replicationOptions.driveId) {
|
|
97
107
|
;
|
|
98
108
|
(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
|
|
99
|
-
var
|
|
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
|
-
|
|
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
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
return sharedDriveReplicateAllDocs({
|
|
118
|
+
pouch: pouch,
|
|
119
|
+
storage: storage,
|
|
113
120
|
doctype: doctype,
|
|
114
|
-
|
|
121
|
+
client: client,
|
|
122
|
+
initialReplication: initialReplication,
|
|
123
|
+
driveId: replicationOptions.driveId
|
|
115
124
|
});
|
|
116
125
|
|
|
117
126
|
case 3:
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
132
|
+
case 7:
|
|
133
|
+
_context.prev = 7;
|
|
134
|
+
_context.t0 = _context["catch"](0);
|
|
135
|
+
reject(_context.t0);
|
|
129
136
|
|
|
130
|
-
case
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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 (
|
|
168
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
272
|
+
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
215
273
|
while (1) {
|
|
216
|
-
switch (
|
|
274
|
+
switch (_context3.prev = _context3.next) {
|
|
217
275
|
case 0:
|
|
218
|
-
db =
|
|
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
|
-
|
|
280
|
+
_context3.next = 6;
|
|
223
281
|
return storage.getLastReplicatedDocID(doctype);
|
|
224
282
|
|
|
225
283
|
case 6:
|
|
226
|
-
startDocId =
|
|
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
|
-
|
|
290
|
+
_context3.next = 42;
|
|
233
291
|
break;
|
|
234
292
|
}
|
|
235
293
|
|
|
236
294
|
if (startDocId) {
|
|
237
|
-
|
|
295
|
+
_context3.next = 26;
|
|
238
296
|
break;
|
|
239
297
|
}
|
|
240
298
|
|
|
241
|
-
|
|
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 =
|
|
306
|
+
res = _context3.sent;
|
|
249
307
|
docs = filterDocs(res.rows);
|
|
250
308
|
|
|
251
309
|
if (!(docs.length === 0)) {
|
|
252
|
-
|
|
310
|
+
_context3.next = 18;
|
|
253
311
|
break;
|
|
254
312
|
}
|
|
255
313
|
|
|
256
314
|
hasMore = false;
|
|
257
|
-
|
|
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
|
-
|
|
325
|
+
_context3.next = 22;
|
|
268
326
|
return _helpers.default.insertBulkDocs(db, docs);
|
|
269
327
|
|
|
270
328
|
case 22:
|
|
271
|
-
|
|
329
|
+
_context3.next = 24;
|
|
272
330
|
return storage.persistLastReplicatedDocID(doctype, startDocId);
|
|
273
331
|
|
|
274
332
|
case 24:
|
|
275
|
-
|
|
333
|
+
_context3.next = 40;
|
|
276
334
|
break;
|
|
277
335
|
|
|
278
336
|
case 26:
|
|
279
|
-
|
|
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 =
|
|
345
|
+
_res = _context3.sent;
|
|
288
346
|
filteredDocs = filterDocs(_res.rows);
|
|
289
347
|
|
|
290
348
|
if (!(filteredDocs.length < 2)) {
|
|
291
|
-
|
|
349
|
+
_context3.next = 32;
|
|
292
350
|
break;
|
|
293
351
|
}
|
|
294
352
|
|
|
295
|
-
return
|
|
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
|
-
|
|
359
|
+
_context3.next = 36;
|
|
302
360
|
return _helpers.default.insertBulkDocs(db, filteredDocs);
|
|
303
361
|
|
|
304
362
|
case 36:
|
|
305
|
-
|
|
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
|
-
|
|
374
|
+
_context3.next = 8;
|
|
317
375
|
break;
|
|
318
376
|
|
|
319
377
|
case 42:
|
|
320
|
-
return
|
|
378
|
+
return _context3.abrupt("return", docs);
|
|
321
379
|
|
|
322
380
|
case 43:
|
|
323
381
|
case "end":
|
|
324
|
-
return
|
|
382
|
+
return _context3.stop();
|
|
325
383
|
}
|
|
326
384
|
}
|
|
327
|
-
},
|
|
385
|
+
}, _callee3);
|
|
328
386
|
}));
|
|
329
387
|
|
|
330
388
|
return function replicateAllDocs(_x) {
|
|
331
|
-
return
|
|
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.
|
|
571
|
+
exports.sharedDriveReplicateAllDocs = sharedDriveReplicateAllDocs;
|