cozy-pouch-link 48.25.0 → 49.0.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 +593 -237
- package/dist/CozyPouchLink.spec.js +67 -42
- package/dist/PouchManager.js +317 -254
- package/dist/PouchManager.spec.js +91 -58
- package/dist/helpers.js +79 -0
- package/dist/helpers.spec.js +85 -1
- package/dist/jsonapi.js +54 -7
- package/dist/jsonapi.spec.js +57 -14
- package/dist/localStorage.js +646 -207
- package/dist/localStorage.spec.js +48 -0
- package/dist/mango.js +72 -20
- package/dist/mango.spec.js +1 -1
- package/dist/migrations/adapter.js +1 -1
- package/dist/platformWeb.js +120 -0
- package/dist/remote.js +39 -5
- package/dist/remote.spec.js +214 -0
- package/dist/replicateOnce.js +337 -0
- package/dist/startReplication.js +70 -45
- package/dist/startReplication.spec.js +374 -39
- package/dist/types.js +80 -0
- package/dist/utils.js +11 -2
- package/package.json +9 -5
- package/types/AccessToken.d.ts +16 -0
- package/types/CozyPouchLink.d.ts +228 -0
- package/types/PouchManager.d.ts +86 -0
- package/types/__tests__/fixtures.d.ts +48 -0
- package/types/__tests__/mocks.d.ts +4 -0
- package/types/helpers.d.ts +17 -0
- package/types/index.d.ts +1 -0
- package/types/jsonapi.d.ts +19 -0
- package/types/localStorage.d.ts +124 -0
- package/types/logger.d.ts +2 -0
- package/types/loop.d.ts +60 -0
- package/types/mango.d.ts +3 -0
- package/types/migrations/adapter.d.ts +18 -0
- package/types/platformWeb.d.ts +17 -0
- package/types/remote.d.ts +6 -0
- package/types/replicateOnce.d.ts +29 -0
- package/types/startReplication.d.ts +12 -0
- package/types/types.d.ts +104 -0
- package/types/utils.d.ts +3 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.replicateOnce = void 0;
|
|
9
|
+
|
|
10
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
11
|
+
|
|
12
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
13
|
+
|
|
14
|
+
var _fromPairs = _interopRequireDefault(require("lodash/fromPairs"));
|
|
15
|
+
|
|
16
|
+
var _get = _interopRequireDefault(require("lodash/get"));
|
|
17
|
+
|
|
18
|
+
var _map = _interopRequireDefault(require("lodash/map"));
|
|
19
|
+
|
|
20
|
+
var _startsWith = _interopRequireDefault(require("lodash/startsWith"));
|
|
21
|
+
|
|
22
|
+
var _zip = _interopRequireDefault(require("lodash/zip"));
|
|
23
|
+
|
|
24
|
+
var _logger = _interopRequireDefault(require("./logger"));
|
|
25
|
+
|
|
26
|
+
var _remote = require("./remote");
|
|
27
|
+
|
|
28
|
+
var _startReplication = require("./startReplication");
|
|
29
|
+
|
|
30
|
+
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; } } }; }
|
|
31
|
+
|
|
32
|
+
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); }
|
|
33
|
+
|
|
34
|
+
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; }
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Process replication once for given PouchManager
|
|
38
|
+
*
|
|
39
|
+
* @param {import('./PouchManager').default} pouchManager - PouchManager that handle the replication
|
|
40
|
+
* @returns {Promise<any>} res
|
|
41
|
+
*/
|
|
42
|
+
var replicateOnce = /*#__PURE__*/function () {
|
|
43
|
+
var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(pouchManager) {
|
|
44
|
+
var doctypes, promises, res, zippedDoctypes, successZippedDoctypes, failedZippedDoctypes, blockingErrors, unblockingErrors, _iterator, _step, unblockingError, doctype, errors, reasons, doctypeUpdated, doctypeFailed;
|
|
45
|
+
|
|
46
|
+
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
47
|
+
while (1) {
|
|
48
|
+
switch (_context2.prev = _context2.next) {
|
|
49
|
+
case 0:
|
|
50
|
+
_context2.next = 2;
|
|
51
|
+
return pouchManager.isOnline();
|
|
52
|
+
|
|
53
|
+
case 2:
|
|
54
|
+
if (_context2.sent) {
|
|
55
|
+
_context2.next = 5;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
_logger.default.info('PouchManager: The device is offline so the replication has been skipped');
|
|
60
|
+
|
|
61
|
+
return _context2.abrupt("return", Promise.resolve());
|
|
62
|
+
|
|
63
|
+
case 5:
|
|
64
|
+
_logger.default.info('PouchManager: Starting replication iteration'); // Creating each replication
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
pouchManager.replications = (0, _map.default)(pouchManager.pouches, /*#__PURE__*/function () {
|
|
68
|
+
var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(pouch, doctype) {
|
|
69
|
+
var getReplicationURL, initialReplication, replicationFilter, seq, lastSeq, replicationOptions, res;
|
|
70
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
71
|
+
while (1) {
|
|
72
|
+
switch (_context.prev = _context.next) {
|
|
73
|
+
case 0:
|
|
74
|
+
_logger.default.info('PouchManager: Starting replication for ' + doctype);
|
|
75
|
+
|
|
76
|
+
getReplicationURL = function getReplicationURL() {
|
|
77
|
+
return pouchManager.getReplicationURL(doctype);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
initialReplication = pouchManager.getSyncStatus(doctype) !== 'synced';
|
|
81
|
+
|
|
82
|
+
replicationFilter = function replicationFilter(doc) {
|
|
83
|
+
return !(0, _startsWith.default)(doc._id, '_design');
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
seq = '';
|
|
87
|
+
|
|
88
|
+
if (!initialReplication) {
|
|
89
|
+
_context.next = 13;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
_context.next = 8;
|
|
94
|
+
return (0, _remote.fetchRemoteLastSequence)(getReplicationURL());
|
|
95
|
+
|
|
96
|
+
case 8:
|
|
97
|
+
lastSeq = _context.sent;
|
|
98
|
+
_context.next = 11;
|
|
99
|
+
return pouchManager.storage.persistDoctypeLastSequence(doctype, lastSeq);
|
|
100
|
+
|
|
101
|
+
case 11:
|
|
102
|
+
_context.next = 16;
|
|
103
|
+
break;
|
|
104
|
+
|
|
105
|
+
case 13:
|
|
106
|
+
_context.next = 15;
|
|
107
|
+
return pouchManager.storage.getDoctypeLastSequence(doctype);
|
|
108
|
+
|
|
109
|
+
case 15:
|
|
110
|
+
seq = _context.sent;
|
|
111
|
+
|
|
112
|
+
case 16:
|
|
113
|
+
replicationOptions = (0, _get.default)(pouchManager.doctypesReplicationOptions, doctype, {});
|
|
114
|
+
replicationOptions.initialReplication = initialReplication;
|
|
115
|
+
replicationOptions.filter = replicationFilter;
|
|
116
|
+
replicationOptions.since = seq;
|
|
117
|
+
replicationOptions.doctype = doctype;
|
|
118
|
+
|
|
119
|
+
if (pouchManager.options.onDoctypeSyncStart) {
|
|
120
|
+
pouchManager.options.onDoctypeSyncStart(doctype);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
_context.next = 24;
|
|
124
|
+
return (0, _startReplication.startReplication)(pouch, replicationOptions, getReplicationURL, pouchManager.storage);
|
|
125
|
+
|
|
126
|
+
case 24:
|
|
127
|
+
res = _context.sent;
|
|
128
|
+
|
|
129
|
+
if (!seq) {
|
|
130
|
+
_context.next = 28;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
_context.next = 28;
|
|
135
|
+
return pouchManager.storage.destroyDoctypeLastSequence(doctype);
|
|
136
|
+
|
|
137
|
+
case 28:
|
|
138
|
+
_context.next = 30;
|
|
139
|
+
return pouchManager.updateSyncInfo(doctype);
|
|
140
|
+
|
|
141
|
+
case 30:
|
|
142
|
+
pouchManager.checkToWarmupDoctype(doctype, replicationOptions);
|
|
143
|
+
|
|
144
|
+
if (pouchManager.options.onDoctypeSyncEnd) {
|
|
145
|
+
pouchManager.options.onDoctypeSyncEnd(doctype);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return _context.abrupt("return", res);
|
|
149
|
+
|
|
150
|
+
case 33:
|
|
151
|
+
case "end":
|
|
152
|
+
return _context.stop();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}, _callee);
|
|
156
|
+
}));
|
|
157
|
+
|
|
158
|
+
return function (_x2, _x3) {
|
|
159
|
+
return _ref2.apply(this, arguments);
|
|
160
|
+
};
|
|
161
|
+
}()); // Waiting on each replication
|
|
162
|
+
|
|
163
|
+
doctypes = Object.keys(pouchManager.pouches);
|
|
164
|
+
promises = Object.values(pouchManager.replications);
|
|
165
|
+
_context2.prev = 9;
|
|
166
|
+
_context2.next = 12;
|
|
167
|
+
return allSettled(promises);
|
|
168
|
+
|
|
169
|
+
case 12:
|
|
170
|
+
res = _context2.sent;
|
|
171
|
+
|
|
172
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
173
|
+
_logger.default.info('PouchManager: Replication ended');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (!pouchManager.options.onSync) {
|
|
177
|
+
_context2.next = 51;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
zippedDoctypes = (0, _zip.default)(doctypes, res);
|
|
182
|
+
successZippedDoctypes = zippedDoctypes.filter(function (d) {
|
|
183
|
+
return d[1].status === 'fulfilled';
|
|
184
|
+
}).map(function (d) {
|
|
185
|
+
return [d[0], d[1].value];
|
|
186
|
+
});
|
|
187
|
+
failedZippedDoctypes = zippedDoctypes.filter(function (d) {
|
|
188
|
+
return d[1].status === 'rejected';
|
|
189
|
+
}).map(function (d) {
|
|
190
|
+
return [d[0], d[1].reason];
|
|
191
|
+
});
|
|
192
|
+
blockingErrors = res.filter(function (r) {
|
|
193
|
+
return r.status === 'rejected' && !(0, _remote.isDatabaseNotFoundError)(r.reason) && !(0, _remote.isDatabaseUnradableError)(r.reason);
|
|
194
|
+
});
|
|
195
|
+
unblockingErrors = failedZippedDoctypes.filter(function (r) {
|
|
196
|
+
return (0, _remote.isDatabaseNotFoundError)(r[1]) || (0, _remote.isDatabaseUnradableError)(r[1]);
|
|
197
|
+
});
|
|
198
|
+
_iterator = _createForOfIteratorHelper(unblockingErrors);
|
|
199
|
+
_context2.prev = 21;
|
|
200
|
+
|
|
201
|
+
_iterator.s();
|
|
202
|
+
|
|
203
|
+
case 23:
|
|
204
|
+
if ((_step = _iterator.n()).done) {
|
|
205
|
+
_context2.next = 30;
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
unblockingError = _step.value;
|
|
210
|
+
doctype = unblockingError[0]; // @ts-ignore
|
|
211
|
+
|
|
212
|
+
_context2.next = 28;
|
|
213
|
+
return pouchManager.updateSyncInfo(doctype, 'not_complete');
|
|
214
|
+
|
|
215
|
+
case 28:
|
|
216
|
+
_context2.next = 23;
|
|
217
|
+
break;
|
|
218
|
+
|
|
219
|
+
case 30:
|
|
220
|
+
_context2.next = 35;
|
|
221
|
+
break;
|
|
222
|
+
|
|
223
|
+
case 32:
|
|
224
|
+
_context2.prev = 32;
|
|
225
|
+
_context2.t0 = _context2["catch"](21);
|
|
226
|
+
|
|
227
|
+
_iterator.e(_context2.t0);
|
|
228
|
+
|
|
229
|
+
case 35:
|
|
230
|
+
_context2.prev = 35;
|
|
231
|
+
|
|
232
|
+
_iterator.f();
|
|
233
|
+
|
|
234
|
+
return _context2.finish(35);
|
|
235
|
+
|
|
236
|
+
case 38:
|
|
237
|
+
if (!(blockingErrors.length > 0)) {
|
|
238
|
+
_context2.next = 45;
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
errors = blockingErrors.map(function (err) {
|
|
243
|
+
return err.reason;
|
|
244
|
+
});
|
|
245
|
+
reasons = errors.join('\n');
|
|
246
|
+
|
|
247
|
+
_logger.default.debug("ReplicateOnce's promises failed with the following errors", reasons); // @ts-ignore
|
|
248
|
+
// eslint-disable-next-line no-undef
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
throw new AggregateError(errors, 'Failed with blocking errors');
|
|
252
|
+
|
|
253
|
+
case 45:
|
|
254
|
+
_logger.default.debug("ReplicateOnce's promises succeed with no blocking errors");
|
|
255
|
+
|
|
256
|
+
case 46:
|
|
257
|
+
doctypeUpdated = (0, _fromPairs.default)(successZippedDoctypes);
|
|
258
|
+
doctypeFailed = (0, _fromPairs.default)(failedZippedDoctypes);
|
|
259
|
+
|
|
260
|
+
_logger.default.debug('Doctypes replications in error: ', Object.keys(doctypeFailed));
|
|
261
|
+
|
|
262
|
+
_logger.default.debug('Doctypes replications in success: ', Object.keys(doctypeUpdated));
|
|
263
|
+
|
|
264
|
+
pouchManager.options.onSync(doctypeUpdated);
|
|
265
|
+
|
|
266
|
+
case 51:
|
|
267
|
+
// @ts-ignore
|
|
268
|
+
res.cancel = pouchManager.cancelCurrentReplications;
|
|
269
|
+
return _context2.abrupt("return", res);
|
|
270
|
+
|
|
271
|
+
case 55:
|
|
272
|
+
_context2.prev = 55;
|
|
273
|
+
_context2.t1 = _context2["catch"](9);
|
|
274
|
+
pouchManager.handleReplicationError(_context2.t1);
|
|
275
|
+
|
|
276
|
+
case 58:
|
|
277
|
+
case "end":
|
|
278
|
+
return _context2.stop();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}, _callee2, null, [[9, 55], [21, 32, 35, 38]]);
|
|
282
|
+
}));
|
|
283
|
+
|
|
284
|
+
return function replicateOnce(_x) {
|
|
285
|
+
return _ref.apply(this, arguments);
|
|
286
|
+
};
|
|
287
|
+
}();
|
|
288
|
+
/**
|
|
289
|
+
* @typedef {object} FulfilledPromise
|
|
290
|
+
* @property {'fulfilled'} status - The status of the promise
|
|
291
|
+
* @property {undefined} reason - The Error rejected by the promise (undefined when fulfilled)
|
|
292
|
+
* @property {any} value - The resolved value of the promise
|
|
293
|
+
*/
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* @typedef {object} RejectedPromise
|
|
297
|
+
* @property {'rejected'} status - The status of the promise
|
|
298
|
+
* @property {Error} reason - The Error rejected by the promise
|
|
299
|
+
* @property {undefined} value - The resolved value of the promise (undefined when rejected)
|
|
300
|
+
*/
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Takes an iterable of promises as input and returns a single Promise.
|
|
304
|
+
* This returned promise fulfills when all of the input's promises settle (including
|
|
305
|
+
* when an empty iterable is passed), with an array of objects that describe the
|
|
306
|
+
* outcome of each promise.
|
|
307
|
+
*
|
|
308
|
+
* @param {Promise[]} promises - Promise to be awaited
|
|
309
|
+
* @returns {Promise<(FulfilledPromise|RejectedPromise)[]>}
|
|
310
|
+
*/
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
exports.replicateOnce = replicateOnce;
|
|
314
|
+
|
|
315
|
+
var allSettled = function allSettled(promises) {
|
|
316
|
+
return Promise.all(promises.map(function (promise) {
|
|
317
|
+
return promise.then(function (value) {
|
|
318
|
+
return (
|
|
319
|
+
/** @type {FulfilledPromise} */
|
|
320
|
+
{
|
|
321
|
+
status: 'fulfilled',
|
|
322
|
+
value: value
|
|
323
|
+
}
|
|
324
|
+
);
|
|
325
|
+
}).catch(function (
|
|
326
|
+
/** @type {Error} */
|
|
327
|
+
reason) {
|
|
328
|
+
return (
|
|
329
|
+
/** @type {RejectedPromise} */
|
|
330
|
+
{
|
|
331
|
+
status: 'rejected',
|
|
332
|
+
reason: reason
|
|
333
|
+
}
|
|
334
|
+
);
|
|
335
|
+
});
|
|
336
|
+
}));
|
|
337
|
+
};
|
package/dist/startReplication.js
CHANGED
|
@@ -23,8 +23,6 @@ var _logger = _interopRequireDefault(require("./logger"));
|
|
|
23
23
|
|
|
24
24
|
var _remote = require("./remote");
|
|
25
25
|
|
|
26
|
-
var _localStorage = require("./localStorage");
|
|
27
|
-
|
|
28
26
|
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; }
|
|
29
27
|
|
|
30
28
|
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; }
|
|
@@ -51,6 +49,8 @@ var humanTimeDelta = function humanTimeDelta(timeMs) {
|
|
|
51
49
|
str = "".concat(cur).concat(lastUnit[0]) + str;
|
|
52
50
|
return str;
|
|
53
51
|
};
|
|
52
|
+
/** @type {[string, number][]} */
|
|
53
|
+
|
|
54
54
|
|
|
55
55
|
var TIME_UNITS = [['ms', 1000], ['s', 60], ['m', 60], ['h', 24]];
|
|
56
56
|
/**
|
|
@@ -62,15 +62,19 @@ var TIME_UNITS = [['ms', 1000], ['s', 60], ['m', 60], ['h', 24]];
|
|
|
62
62
|
* @param {string} replicationOptions.strategy The direction of the replication. Can be "fromRemote", "toRemote" or "sync"
|
|
63
63
|
* @param {boolean} replicationOptions.initialReplication Whether or not this is an initial replication
|
|
64
64
|
* @param {string} replicationOptions.doctype The doctype to replicate
|
|
65
|
+
* @param {import('cozy-client/types/types').Query[]} replicationOptions.warmupQueries The queries to warmup
|
|
65
66
|
* @param {Function} getReplicationURL A function that should return the remote replication URL
|
|
67
|
+
* @param {import('./localStorage').PouchLocalStorage} storage Methods to access local storage
|
|
66
68
|
*
|
|
67
|
-
* @returns {
|
|
69
|
+
* @returns {import('./types').CancelablePromise} A cancelable promise that resolves at the end of the replication
|
|
68
70
|
*/
|
|
69
71
|
|
|
70
|
-
var startReplication = function startReplication(pouch, replicationOptions, getReplicationURL) {
|
|
72
|
+
var startReplication = function startReplication(pouch, replicationOptions, getReplicationURL, storage) {
|
|
71
73
|
var replication;
|
|
72
74
|
var docs = {};
|
|
73
75
|
var start = new Date();
|
|
76
|
+
/** @type {import('./types').CancelablePromise} */
|
|
77
|
+
|
|
74
78
|
var promise = new Promise(function (resolve, reject) {
|
|
75
79
|
var url = getReplicationURL();
|
|
76
80
|
var strategy = replicationOptions.strategy,
|
|
@@ -79,11 +83,15 @@ var startReplication = function startReplication(pouch, replicationOptions, getR
|
|
|
79
83
|
doctype = replicationOptions.doctype,
|
|
80
84
|
customReplicationOptions = (0, _objectWithoutProperties2.default)(replicationOptions, ["strategy", "initialReplication", "warmupQueries", "doctype"]);
|
|
81
85
|
|
|
82
|
-
var options = _objectSpread({
|
|
86
|
+
var options = _objectSpread(_objectSpread({
|
|
83
87
|
batch_size: BATCH_SIZE
|
|
84
|
-
}, customReplicationOptions)
|
|
85
|
-
|
|
86
|
-
|
|
88
|
+
}, customReplicationOptions), {}, {
|
|
89
|
+
selector: {
|
|
90
|
+
cozyLocalOnly: {
|
|
91
|
+
$exists: false
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
});
|
|
87
95
|
|
|
88
96
|
if (initialReplication && strategy !== 'toRemote') {
|
|
89
97
|
;
|
|
@@ -94,14 +102,19 @@ var startReplication = function startReplication(pouch, replicationOptions, getR
|
|
|
94
102
|
switch (_context.prev = _context.next) {
|
|
95
103
|
case 0:
|
|
96
104
|
_context.next = 2;
|
|
97
|
-
return replicateAllDocs(
|
|
105
|
+
return replicateAllDocs({
|
|
106
|
+
db: pouch,
|
|
107
|
+
baseUrl: url,
|
|
108
|
+
doctype: doctype,
|
|
109
|
+
storage: storage
|
|
110
|
+
});
|
|
98
111
|
|
|
99
112
|
case 2:
|
|
100
113
|
docs = _context.sent;
|
|
101
114
|
end = new Date();
|
|
102
115
|
|
|
103
116
|
if (process.env.NODE_ENV !== 'production') {
|
|
104
|
-
_logger.default.info("PouchManager: initial replication with all_docs for ".concat(url, " took ").concat(humanTimeDelta(end - start)));
|
|
117
|
+
_logger.default.info("PouchManager: initial replication with all_docs for ".concat(url, " took ").concat(humanTimeDelta(end.getTime() - start.getTime())));
|
|
105
118
|
}
|
|
106
119
|
|
|
107
120
|
return _context.abrupt("return", resolve(docs));
|
|
@@ -113,6 +126,7 @@ var startReplication = function startReplication(pouch, replicationOptions, getR
|
|
|
113
126
|
}
|
|
114
127
|
}, _callee);
|
|
115
128
|
}))();
|
|
129
|
+
return;
|
|
116
130
|
}
|
|
117
131
|
|
|
118
132
|
if (strategy === 'fromRemote') {
|
|
@@ -143,7 +157,7 @@ var startReplication = function startReplication(pouch, replicationOptions, getR
|
|
|
143
157
|
var end = new Date();
|
|
144
158
|
|
|
145
159
|
if (process.env.NODE_ENV !== 'production') {
|
|
146
|
-
_logger.default.info("PouchManager: replication for ".concat(url, " took ").concat(humanTimeDelta(end - start)));
|
|
160
|
+
_logger.default.info("PouchManager: replication for ".concat(url, " took ").concat(humanTimeDelta(end.getTime() - start.getTime())));
|
|
147
161
|
}
|
|
148
162
|
|
|
149
163
|
resolve(Object.values(docs));
|
|
@@ -176,117 +190,128 @@ var filterDocs = function filterDocs(docs) {
|
|
|
176
190
|
* Note it saves the last replicated _id for each run and
|
|
177
191
|
* starts from there in case the process stops before the end.
|
|
178
192
|
*
|
|
179
|
-
* @param {object}
|
|
180
|
-
* @param {
|
|
181
|
-
* @param {string}
|
|
182
|
-
* @
|
|
193
|
+
* @param {object} params - The replications parameters
|
|
194
|
+
* @param {object} params.db - Pouch instance
|
|
195
|
+
* @param {string} params.baseUrl - The remote instance
|
|
196
|
+
* @param {string} params.doctype - The doctype to replicate
|
|
197
|
+
* @param {import('./localStorage').PouchLocalStorage} params.storage - Methods to access local storage
|
|
198
|
+
* @returns {Promise<Array>} The retrieved documents
|
|
183
199
|
*/
|
|
184
200
|
|
|
185
201
|
|
|
186
202
|
var replicateAllDocs = /*#__PURE__*/function () {
|
|
187
|
-
var
|
|
188
|
-
var remoteUrlAllDocs, batchSize, hasMore, startDocId, docs, res, _res, filteredDocs;
|
|
203
|
+
var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref2) {
|
|
204
|
+
var db, baseUrl, doctype, storage, remoteUrlAllDocs, batchSize, hasMore, startDocId, docs, res, _res, filteredDocs;
|
|
189
205
|
|
|
190
206
|
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
191
207
|
while (1) {
|
|
192
208
|
switch (_context2.prev = _context2.next) {
|
|
193
209
|
case 0:
|
|
210
|
+
db = _ref2.db, baseUrl = _ref2.baseUrl, doctype = _ref2.doctype, storage = _ref2.storage;
|
|
194
211
|
remoteUrlAllDocs = new URL("".concat(baseUrl, "/_all_docs"));
|
|
195
212
|
batchSize = BATCH_SIZE;
|
|
196
213
|
hasMore = true;
|
|
197
|
-
|
|
214
|
+
_context2.next = 6;
|
|
215
|
+
return storage.getLastReplicatedDocID(doctype);
|
|
198
216
|
|
|
217
|
+
case 6:
|
|
218
|
+
startDocId = _context2.sent;
|
|
219
|
+
// Get last replicated _id in localStorage
|
|
199
220
|
docs = [];
|
|
200
221
|
|
|
201
|
-
case
|
|
222
|
+
case 8:
|
|
202
223
|
if (!hasMore) {
|
|
203
|
-
_context2.next =
|
|
224
|
+
_context2.next = 42;
|
|
204
225
|
break;
|
|
205
226
|
}
|
|
206
227
|
|
|
207
228
|
if (startDocId) {
|
|
208
|
-
_context2.next =
|
|
229
|
+
_context2.next = 26;
|
|
209
230
|
break;
|
|
210
231
|
}
|
|
211
232
|
|
|
212
|
-
_context2.next =
|
|
233
|
+
_context2.next = 12;
|
|
213
234
|
return (0, _remote.fetchRemoteInstance)(remoteUrlAllDocs, {
|
|
214
235
|
limit: batchSize,
|
|
215
236
|
include_docs: true
|
|
216
237
|
});
|
|
217
238
|
|
|
218
|
-
case
|
|
239
|
+
case 12:
|
|
219
240
|
res = _context2.sent;
|
|
220
241
|
docs = filterDocs(res.rows);
|
|
221
242
|
|
|
222
243
|
if (!(docs.length === 0)) {
|
|
223
|
-
_context2.next =
|
|
244
|
+
_context2.next = 18;
|
|
224
245
|
break;
|
|
225
246
|
}
|
|
226
247
|
|
|
227
248
|
hasMore = false;
|
|
228
|
-
_context2.next =
|
|
249
|
+
_context2.next = 24;
|
|
229
250
|
break;
|
|
230
251
|
|
|
231
|
-
case
|
|
252
|
+
case 18:
|
|
232
253
|
startDocId = docs[docs.length - 1]._id;
|
|
233
254
|
|
|
234
255
|
if (docs.length < batchSize) {
|
|
235
256
|
hasMore = false;
|
|
236
257
|
}
|
|
237
258
|
|
|
238
|
-
_context2.next =
|
|
259
|
+
_context2.next = 22;
|
|
239
260
|
return _helpers.default.insertBulkDocs(db, docs);
|
|
240
261
|
|
|
241
|
-
case
|
|
242
|
-
|
|
262
|
+
case 22:
|
|
263
|
+
_context2.next = 24;
|
|
264
|
+
return storage.persistLastReplicatedDocID(doctype, startDocId);
|
|
243
265
|
|
|
244
|
-
case
|
|
245
|
-
_context2.next =
|
|
266
|
+
case 24:
|
|
267
|
+
_context2.next = 40;
|
|
246
268
|
break;
|
|
247
269
|
|
|
248
|
-
case
|
|
249
|
-
_context2.next =
|
|
270
|
+
case 26:
|
|
271
|
+
_context2.next = 28;
|
|
250
272
|
return (0, _remote.fetchRemoteInstance)(remoteUrlAllDocs, {
|
|
251
273
|
include_docs: true,
|
|
252
274
|
limit: batchSize,
|
|
253
275
|
startkey_docid: startDocId
|
|
254
276
|
});
|
|
255
277
|
|
|
256
|
-
case
|
|
278
|
+
case 28:
|
|
257
279
|
_res = _context2.sent;
|
|
258
280
|
filteredDocs = filterDocs(_res.rows);
|
|
259
281
|
|
|
260
282
|
if (!(filteredDocs.length < 2)) {
|
|
261
|
-
_context2.next =
|
|
283
|
+
_context2.next = 32;
|
|
262
284
|
break;
|
|
263
285
|
}
|
|
264
286
|
|
|
265
287
|
return _context2.abrupt("return", docs);
|
|
266
288
|
|
|
267
|
-
case
|
|
289
|
+
case 32:
|
|
268
290
|
filteredDocs.shift(); // Remove first element, already included in previous request
|
|
269
291
|
|
|
270
292
|
startDocId = filteredDocs[filteredDocs.length - 1]._id;
|
|
271
|
-
_context2.next =
|
|
293
|
+
_context2.next = 36;
|
|
272
294
|
return _helpers.default.insertBulkDocs(db, filteredDocs);
|
|
273
295
|
|
|
274
|
-
case
|
|
275
|
-
|
|
296
|
+
case 36:
|
|
297
|
+
_context2.next = 38;
|
|
298
|
+
return storage.persistLastReplicatedDocID(doctype, startDocId);
|
|
299
|
+
|
|
300
|
+
case 38:
|
|
276
301
|
docs = docs.concat(filteredDocs);
|
|
277
302
|
|
|
278
303
|
if (_res.rows.length < batchSize) {
|
|
279
304
|
hasMore = false;
|
|
280
305
|
}
|
|
281
306
|
|
|
282
|
-
case
|
|
283
|
-
_context2.next =
|
|
307
|
+
case 40:
|
|
308
|
+
_context2.next = 8;
|
|
284
309
|
break;
|
|
285
310
|
|
|
286
|
-
case
|
|
311
|
+
case 42:
|
|
287
312
|
return _context2.abrupt("return", docs);
|
|
288
313
|
|
|
289
|
-
case
|
|
314
|
+
case 43:
|
|
290
315
|
case "end":
|
|
291
316
|
return _context2.stop();
|
|
292
317
|
}
|
|
@@ -294,8 +319,8 @@ var replicateAllDocs = /*#__PURE__*/function () {
|
|
|
294
319
|
}, _callee2);
|
|
295
320
|
}));
|
|
296
321
|
|
|
297
|
-
return function replicateAllDocs(_x
|
|
298
|
-
return
|
|
322
|
+
return function replicateAllDocs(_x) {
|
|
323
|
+
return _ref3.apply(this, arguments);
|
|
299
324
|
};
|
|
300
325
|
}();
|
|
301
326
|
|