cozy-pouch-link 48.25.0 → 49.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.
Files changed (41) hide show
  1. package/dist/CozyPouchLink.js +604 -237
  2. package/dist/CozyPouchLink.spec.js +100 -42
  3. package/dist/PouchManager.js +326 -255
  4. package/dist/PouchManager.spec.js +91 -58
  5. package/dist/helpers.js +79 -0
  6. package/dist/helpers.spec.js +85 -1
  7. package/dist/jsonapi.js +54 -7
  8. package/dist/jsonapi.spec.js +57 -14
  9. package/dist/localStorage.js +646 -207
  10. package/dist/localStorage.spec.js +48 -0
  11. package/dist/mango.js +72 -20
  12. package/dist/mango.spec.js +1 -1
  13. package/dist/migrations/adapter.js +1 -1
  14. package/dist/platformWeb.js +120 -0
  15. package/dist/remote.js +39 -5
  16. package/dist/remote.spec.js +214 -0
  17. package/dist/replicateOnce.js +337 -0
  18. package/dist/startReplication.js +70 -45
  19. package/dist/startReplication.spec.js +374 -39
  20. package/dist/types.js +80 -0
  21. package/dist/utils.js +11 -2
  22. package/package.json +9 -5
  23. package/types/AccessToken.d.ts +16 -0
  24. package/types/CozyPouchLink.d.ts +228 -0
  25. package/types/PouchManager.d.ts +86 -0
  26. package/types/__tests__/fixtures.d.ts +48 -0
  27. package/types/__tests__/mocks.d.ts +4 -0
  28. package/types/helpers.d.ts +17 -0
  29. package/types/index.d.ts +1 -0
  30. package/types/jsonapi.d.ts +19 -0
  31. package/types/localStorage.d.ts +124 -0
  32. package/types/logger.d.ts +2 -0
  33. package/types/loop.d.ts +60 -0
  34. package/types/mango.d.ts +3 -0
  35. package/types/migrations/adapter.d.ts +18 -0
  36. package/types/platformWeb.d.ts +17 -0
  37. package/types/remote.d.ts +6 -0
  38. package/types/replicateOnce.d.ts +29 -0
  39. package/types/startReplication.d.ts +12 -0
  40. package/types/types.d.ts +104 -0
  41. package/types/utils.d.ts +3 -0
@@ -51,13 +51,15 @@ var jsonapi = _interopRequireWildcard(require("./jsonapi"));
51
51
 
52
52
  var _PouchManager = _interopRequireDefault(require("./PouchManager"));
53
53
 
54
+ var _localStorage = require("./localStorage");
55
+
54
56
  var _logger = _interopRequireDefault(require("./logger"));
55
57
 
56
58
  var _adapter = require("./migrations/adapter");
57
59
 
58
- var _utils = require("./utils");
60
+ var _platformWeb = require("./platformWeb");
59
61
 
60
- var _localStorage = require("./localStorage");
62
+ var _utils = require("./utils");
61
63
 
62
64
  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; } } }; }
63
65
 
@@ -107,7 +109,9 @@ var _getReplicationURL = function getReplicationURL(uri, token, doctype) {
107
109
 
108
110
  exports.getReplicationURL = _getReplicationURL;
109
111
 
110
- var doNothing = function doNothing() {};
112
+ var doNothing = function doNothing(operation) {
113
+ var result = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
114
+ };
111
115
 
112
116
  var expiredTokenError = /Expired token/;
113
117
 
@@ -117,13 +121,25 @@ var isExpiredTokenError = function isExpiredTokenError(pouchError) {
117
121
 
118
122
  exports.isExpiredTokenError = isExpiredTokenError;
119
123
 
120
- var normalizeAll = function normalizeAll(docs, doctype) {
121
- return docs.map(function (doc) {
122
- return jsonapi.normalizeDoc(doc, doctype);
123
- });
124
+ var normalizeAll = function normalizeAll(client) {
125
+ return function (docs, doctype) {
126
+ return docs.map(function (doc) {
127
+ return jsonapi.normalizeDoc(doc, doctype, client);
128
+ });
129
+ };
124
130
  };
125
131
  /**
126
- * @typedef {"idle"|"replicating"} SyncStatus
132
+ * @typedef {import('cozy-client/src/types').CozyClientDocument} CozyClientDocument
133
+ *
134
+ * @typedef {"idle"|"replicating"} ReplicationStatus
135
+ */
136
+
137
+ /**
138
+ * @typedef {object} PouchLinkOptions
139
+ * @property {number} [replicationInterval] Milliseconds between replications
140
+ * @property {string[]} doctypes Doctypes to replicate
141
+ * @property {Record<string, object>} doctypesReplicationOptions A mapping from doctypes to replication options. All pouch replication options can be used, as well as the "strategy" option that determines which way the replication is done (can be "sync", "fromRemote" or "toRemote")
142
+ * @property {import('./types').LinkPlatform} platform Platform specific adapters and methods
127
143
  */
128
144
 
129
145
  /**
@@ -141,16 +157,13 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
141
157
  /**
142
158
  * constructor - Initializes a new PouchLink
143
159
  *
144
- * @param {object} [opts={}]
145
- * @param {number} [opts.replicationInterval] Milliseconds between replications
146
- * @param {string[]} opts.doctypes Doctypes to replicate
147
- * @param {object[]} opts.doctypesReplicationOptions A mapping from doctypes to replication options. All pouch replication options can be used, as well as the "strategy" option that determines which way the replication is done (can be "sync", "fromRemote" or "toRemote")
148
- * @returns {object} The PouchLink instance
160
+ * @param {PouchLinkOptions} [opts={}]
149
161
  */
150
- function PouchLink() {
162
+ function PouchLink(opts) {
163
+ var _options$platform;
164
+
151
165
  var _this;
152
166
 
153
- var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
154
167
  (0, _classCallCheck2.default)(this, PouchLink);
155
168
  var options = (0, _defaults.default)({}, opts, DEFAULT_OPTIONS);
156
169
  _this = _super.call(this, options);
@@ -165,7 +178,8 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
165
178
  _this.doctypes = doctypes;
166
179
  _this.doctypesReplicationOptions = doctypesReplicationOptions;
167
180
  _this.indexes = {};
168
- /** @type {Record<string, SyncStatus>} - Stores replication states per doctype */
181
+ _this.storage = new _localStorage.PouchLocalStorage(((_options$platform = options.platform) === null || _options$platform === void 0 ? void 0 : _options$platform.storage) || _platformWeb.platformWeb.storage);
182
+ /** @type {Record<string, ReplicationStatus>} - Stores replication states per doctype */
169
183
 
170
184
  _this.replicationStatus = _this.replicationStatus || {};
171
185
  return _this;
@@ -174,7 +188,8 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
174
188
  * Return the PouchDB adapter name.
175
189
  * Should be IndexedDB for newest adapters.
176
190
  *
177
- * @returns {string} The adapter name
191
+ * @param {import('./types').LocalStorage} localStorage Methods to access local storage
192
+ * @returns {Promise<string>} The adapter name
178
193
  */
179
194
 
180
195
 
@@ -256,49 +271,57 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
256
271
  _iterator.f();
257
272
  }
258
273
 
259
- doctypes = (0, _localStorage.getPersistedSyncedDoctypes)();
260
- _i = 0, _Object$keys = Object.keys(doctypes);
274
+ _context2.next = 6;
275
+ return this.storage.getPersistedSyncedDoctypes();
261
276
 
262
277
  case 6:
278
+ doctypes = _context2.sent;
279
+ _i = 0, _Object$keys = Object.keys(doctypes);
280
+
281
+ case 8:
263
282
  if (!(_i < _Object$keys.length)) {
264
- _context2.next = 16;
283
+ _context2.next = 19;
265
284
  break;
266
285
  }
267
286
 
268
287
  doctype = _Object$keys[_i];
269
288
  prefix = (0, _utils.getPrefix)(url);
270
289
  dbName = (0, _utils.getDatabaseName)(prefix, doctype);
271
- _context2.next = 12;
290
+ _context2.next = 14;
272
291
  return (0, _adapter.migratePouch)({
273
292
  dbName: dbName,
274
293
  fromAdapter: fromAdapter,
275
294
  toAdapter: toAdapter
276
295
  });
277
296
 
278
- case 12:
279
- (0, _localStorage.destroyWarmedUpQueries)(); // force recomputing indexes
297
+ case 14:
298
+ _context2.next = 16;
299
+ return this.storage.destroyWarmedUpQueries();
280
300
 
281
- case 13:
301
+ case 16:
282
302
  _i++;
283
- _context2.next = 6;
303
+ _context2.next = 8;
284
304
  break;
285
305
 
286
- case 16:
287
- (0, _localStorage.persistAdapterName)('indexeddb');
288
- _context2.next = 22;
306
+ case 19:
307
+ _context2.next = 21;
308
+ return this.storage.persistAdapterName('indexeddb');
309
+
310
+ case 21:
311
+ _context2.next = 26;
289
312
  break;
290
313
 
291
- case 19:
292
- _context2.prev = 19;
314
+ case 23:
315
+ _context2.prev = 23;
293
316
  _context2.t0 = _context2["catch"](1);
294
317
  console.error('PouchLink: PouchDB migration failed. ', _context2.t0);
295
318
 
296
- case 22:
319
+ case 26:
297
320
  case "end":
298
321
  return _context2.stop();
299
322
  }
300
323
  }
301
- }, _callee2, null, [[1, 19]]);
324
+ }, _callee2, this, [[1, 23]]);
302
325
  }));
303
326
 
304
327
  function migrateAdapter(_x2) {
@@ -367,11 +390,20 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
367
390
  _logger.default.log('Create pouches with ' + prefix + ' prefix');
368
391
  }
369
392
 
370
- if (!(0, _localStorage.getAdapterName)()) {
371
- adapter = (0, _get.default)(this.options, 'pouch.options.adapter');
372
- (0, _localStorage.persistAdapterName)(adapter);
393
+ _context3.next = 20;
394
+ return this.storage.getAdapterName();
395
+
396
+ case 20:
397
+ if (_context3.sent) {
398
+ _context3.next = 24;
399
+ break;
373
400
  }
374
401
 
402
+ adapter = (0, _get.default)(this.options, 'pouch.options.adapter');
403
+ _context3.next = 24;
404
+ return this.storage.persistAdapterName(adapter);
405
+
406
+ case 24:
375
407
  this.pouches = new _PouchManager.default(this.doctypes, {
376
408
  pouch: this.options.pouch,
377
409
  getReplicationURL: this.getReplicationURL.bind(this),
@@ -383,14 +415,18 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
383
415
  onDoctypeSyncStart: this.handleDoctypeSyncStart.bind(this),
384
416
  onDoctypeSyncEnd: this.handleDoctypeSyncEnd.bind(this),
385
417
  prefix: prefix,
386
- executeQuery: this.executeQuery.bind(this)
418
+ executeQuery: this.executeQuery.bind(this),
419
+ platform: this.options.platform
387
420
  });
421
+ _context3.next = 27;
422
+ return this.pouches.init();
388
423
 
424
+ case 27:
389
425
  if (this.client && this.options.initialSync) {
390
426
  this.startReplication();
391
427
  }
392
428
 
393
- case 21:
429
+ case 28:
394
430
  case "end":
395
431
  return _context3.stop();
396
432
  }
@@ -449,7 +485,7 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
449
485
  }, {
450
486
  key: "handleOnSync",
451
487
  value: function handleOnSync(doctypeUpdates) {
452
- var normalizedData = (0, _mapValues.default)(doctypeUpdates, normalizeAll);
488
+ var normalizedData = (0, _mapValues.default)(doctypeUpdates, normalizeAll(this.client));
453
489
 
454
490
  if (this.client) {
455
491
  this.client.setData(normalizedData);
@@ -596,128 +632,419 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
596
632
  }
597
633
  }, {
598
634
  key: "request",
599
- value: function request(operation) {
600
- var result = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
601
- var forward = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : doNothing;
602
- var doctype = (0, _cozyClient.getDoctypeFromOperation)(operation);
635
+ value: function () {
636
+ var _request = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(operation) {
637
+ var result,
638
+ forward,
639
+ doctype,
640
+ _args6 = arguments;
641
+ return _regenerator.default.wrap(function _callee6$(_context6) {
642
+ while (1) {
643
+ switch (_context6.prev = _context6.next) {
644
+ case 0:
645
+ result = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : null;
646
+ forward = _args6.length > 2 && _args6[2] !== undefined ? _args6[2] : doNothing;
647
+ doctype = (0, _cozyClient.getDoctypeFromOperation)(operation);
603
648
 
604
- if (!this.pouches) {
605
- if (process.env.NODE_ENV !== 'production') {
606
- _logger.default.info("Tried to access local ".concat(doctype, " but Cozy Pouch is not initialized yet. Forwarding the operation to next link"));
607
- }
649
+ if (this.pouches) {
650
+ _context6.next = 6;
651
+ break;
652
+ }
608
653
 
609
- return forward(operation);
610
- }
654
+ if (process.env.NODE_ENV !== 'production') {
655
+ _logger.default.info("Tried to access local ".concat(doctype, " but Cozy Pouch is not initialized yet. Forwarding the operation to next link"));
656
+ }
657
+
658
+ return _context6.abrupt("return", forward(operation));
659
+
660
+ case 6:
661
+ if (!(this.pouches.getSyncStatus(doctype) === 'not_synced')) {
662
+ _context6.next = 9;
663
+ break;
664
+ }
665
+
666
+ if (process.env.NODE_ENV !== 'production') {
667
+ _logger.default.info("Tried to access local ".concat(doctype, " but Cozy Pouch is not synced yet. Forwarding the operation to next link"));
668
+ }
669
+
670
+ return _context6.abrupt("return", forward(operation));
671
+
672
+ case 9:
673
+ _context6.next = 11;
674
+ return this.needsToWaitWarmup(doctype);
675
+
676
+ case 11:
677
+ if (!_context6.sent) {
678
+ _context6.next = 14;
679
+ break;
680
+ }
681
+
682
+ if (process.env.NODE_ENV !== 'production') {
683
+ _logger.default.info("Tried to access local ".concat(doctype, " but not warmuped yet. Forwarding the operation to next link"));
684
+ }
685
+
686
+ return _context6.abrupt("return", forward(operation));
687
+
688
+ case 14:
689
+ if (this.supportsOperation(operation)) {
690
+ _context6.next = 17;
691
+ break;
692
+ }
693
+
694
+ if (process.env.NODE_ENV !== 'production') {
695
+ _logger.default.info("The doctype '".concat(doctype, "' is not supported. Forwarding the operation to next link"));
696
+ }
697
+
698
+ return _context6.abrupt("return", forward(operation));
699
+
700
+ case 17:
701
+ if (!operation.mutationType) {
702
+ _context6.next = 21;
703
+ break;
704
+ }
611
705
 
612
- if (!this.pouches.isSynced(doctype)) {
613
- if (process.env.NODE_ENV !== 'production') {
614
- _logger.default.info("Tried to access local ".concat(doctype, " but Cozy Pouch is not synced yet. Forwarding the operation to next link"));
615
- }
706
+ return _context6.abrupt("return", this.executeMutation(operation, result, forward));
616
707
 
617
- return forward(operation);
708
+ case 21:
709
+ return _context6.abrupt("return", this.executeQuery(operation));
710
+
711
+ case 22:
712
+ case "end":
713
+ return _context6.stop();
714
+ }
715
+ }
716
+ }, _callee6, this);
717
+ }));
718
+
719
+ function request(_x4) {
720
+ return _request.apply(this, arguments);
618
721
  }
619
722
 
620
- if (this.needsToWaitWarmup(doctype)) {
621
- if (process.env.NODE_ENV !== 'production') {
622
- _logger.default.info("Tried to access local ".concat(doctype, " but not warmuped yet. Forwarding the operation to next link"));
623
- }
723
+ return request;
724
+ }()
725
+ }, {
726
+ key: "sanitizeJsonApi",
727
+ value: function sanitizeJsonApi(data) {
728
+ var docWithoutType = sanitized(data);
729
+ /*
730
+ We persist in the local Pouch database all the documents that do not
731
+ exist on the remote Couch database
732
+ Those documents are computed by the cozy-stack then are sent to the
733
+ client using JSON-API format containing `attributes` and `meta`
734
+ attributes
735
+ Then the cozy-stack-client would normalize those documents by spreading
736
+ `attributes` and `meta` content into the document's root
737
+ So we don't need to store `attributes` and `meta` data into the Pouch
738
+ database as their data already exists in the document's root
739
+ Note that this is also the case for `links` and `relationships`
740
+ attributes, but we don't remove them for now. They are also part of the
741
+ JSON-API, but the normalization do not spread them in the document's
742
+ root, so we have to check their usefulnes first
743
+ */
744
+
745
+ var sanitizedDoc = (0, _omit.default)(docWithoutType, ['attributes', 'meta']);
746
+ return sanitizedDoc;
747
+ }
748
+ }, {
749
+ key: "persistCozyData",
750
+ value: function () {
751
+ var _persistCozyData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(data) {
752
+ var forward,
753
+ sanitizedDoc,
754
+ oldDoc,
755
+ db,
756
+ _args7 = arguments;
757
+ return _regenerator.default.wrap(function _callee7$(_context7) {
758
+ while (1) {
759
+ switch (_context7.prev = _context7.next) {
760
+ case 0:
761
+ forward = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : doNothing;
762
+ sanitizedDoc = this.sanitizeJsonApi(data);
763
+ sanitizedDoc.cozyLocalOnly = true;
764
+ _context7.next = 5;
765
+ return this.getExistingDocument(data._id, data._type);
766
+
767
+ case 5:
768
+ oldDoc = _context7.sent;
624
769
 
625
- return forward(operation);
626
- } // Forwards if doctype not supported
770
+ if (oldDoc) {
771
+ sanitizedDoc._rev = oldDoc._rev;
772
+ }
627
773
 
774
+ db = this.pouches.getPouch(data._type);
775
+ _context7.next = 10;
776
+ return db.put(sanitizedDoc);
628
777
 
629
- if (!this.supportsOperation(operation)) {
630
- if (process.env.NODE_ENV !== 'production') {
631
- _logger.default.info("The doctype '".concat(doctype, "' is not supported. Forwarding the operation to next link"));
632
- }
778
+ case 10:
779
+ case "end":
780
+ return _context7.stop();
781
+ }
782
+ }
783
+ }, _callee7, this);
784
+ }));
633
785
 
634
- return forward(operation);
786
+ function persistCozyData(_x5) {
787
+ return _persistCozyData.apply(this, arguments);
635
788
  }
636
789
 
637
- if (operation.mutationType) {
638
- return this.executeMutation(operation, result, forward);
639
- } else {
640
- return this.executeQuery(operation);
790
+ return persistCozyData;
791
+ }()
792
+ /**
793
+ * Retrieve the existing document from Pouch
794
+ *
795
+ * @private
796
+ * @param {*} id - ID of the document to retrieve
797
+ * @param {*} type - Doctype of the document to retrieve
798
+ * @param {*} throwIfNotFound - If true the method will throw when the document is not found. Otherwise it will return null
799
+ * @returns {Promise<CozyClientDocument | null>}
800
+ */
801
+
802
+ }, {
803
+ key: "getExistingDocument",
804
+ value: function () {
805
+ var _getExistingDocument = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(id, type) {
806
+ var throwIfNotFound,
807
+ db,
808
+ existingDoc,
809
+ _args8 = arguments;
810
+ return _regenerator.default.wrap(function _callee8$(_context8) {
811
+ while (1) {
812
+ switch (_context8.prev = _context8.next) {
813
+ case 0:
814
+ throwIfNotFound = _args8.length > 2 && _args8[2] !== undefined ? _args8[2] : false;
815
+ _context8.prev = 1;
816
+ db = this.pouches.getPouch(type);
817
+ _context8.next = 5;
818
+ return db.get(id);
819
+
820
+ case 5:
821
+ existingDoc = _context8.sent;
822
+ return _context8.abrupt("return", existingDoc);
823
+
824
+ case 9:
825
+ _context8.prev = 9;
826
+ _context8.t0 = _context8["catch"](1);
827
+
828
+ if (!(_context8.t0.name === 'not_found' && !throwIfNotFound)) {
829
+ _context8.next = 15;
830
+ break;
831
+ }
832
+
833
+ return _context8.abrupt("return", null);
834
+
835
+ case 15:
836
+ throw _context8.t0;
837
+
838
+ case 16:
839
+ case "end":
840
+ return _context8.stop();
841
+ }
842
+ }
843
+ }, _callee8, this, [[1, 9]]);
844
+ }));
845
+
846
+ function getExistingDocument(_x6, _x7) {
847
+ return _getExistingDocument.apply(this, arguments);
641
848
  }
642
- }
849
+
850
+ return getExistingDocument;
851
+ }()
643
852
  /**
644
853
  *
645
854
  * Check if there is warmup queries for this doctype
646
855
  * and return if those queries are already warmed up or not
647
856
  *
648
857
  * @param {string} doctype - Doctype to check
649
- * @returns {boolean} the need to wait for the warmup
858
+ * @returns {Promise<boolean>} the need to wait for the warmup
650
859
  */
651
860
 
652
861
  }, {
653
862
  key: "needsToWaitWarmup",
654
- value: function needsToWaitWarmup(doctype) {
655
- if (this.doctypesReplicationOptions && this.doctypesReplicationOptions[doctype] && this.doctypesReplicationOptions[doctype].warmupQueries) {
656
- return !this.pouches.areQueriesWarmedUp(doctype, this.doctypesReplicationOptions[doctype].warmupQueries);
863
+ value: function () {
864
+ var _needsToWaitWarmup = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(doctype) {
865
+ return _regenerator.default.wrap(function _callee9$(_context9) {
866
+ while (1) {
867
+ switch (_context9.prev = _context9.next) {
868
+ case 0:
869
+ if (!(this.doctypesReplicationOptions && this.doctypesReplicationOptions[doctype] && this.doctypesReplicationOptions[doctype].warmupQueries)) {
870
+ _context9.next = 4;
871
+ break;
872
+ }
873
+
874
+ _context9.next = 3;
875
+ return this.pouches.areQueriesWarmedUp(doctype, this.doctypesReplicationOptions[doctype].warmupQueries);
876
+
877
+ case 3:
878
+ return _context9.abrupt("return", !_context9.sent);
879
+
880
+ case 4:
881
+ return _context9.abrupt("return", false);
882
+
883
+ case 5:
884
+ case "end":
885
+ return _context9.stop();
886
+ }
887
+ }
888
+ }, _callee9, this);
889
+ }));
890
+
891
+ function needsToWaitWarmup(_x8) {
892
+ return _needsToWaitWarmup.apply(this, arguments);
657
893
  }
658
894
 
659
- return false;
660
- }
895
+ return needsToWaitWarmup;
896
+ }()
661
897
  }, {
662
898
  key: "hasIndex",
663
899
  value: function hasIndex(name) {
664
900
  return Boolean(this.indexes[name]);
665
- } // This merge is necessary because PouchDB does not support partial indexes
901
+ }
902
+ /**
903
+ * Create the PouchDB index if not existing
904
+ *
905
+ * @param {Array} fields - Fields to index
906
+ * @param {object} indexOption - Options for the index
907
+ * @param {object} [indexOption.partialFilter] - partialFilter
908
+ * @param {string} [indexOption.indexName] - indexName
909
+ * @param {string} [indexOption.doctype] - doctype
910
+ * @returns {Promise<import('./types').PouchDbIndex>}
911
+ */
666
912
 
667
913
  }, {
668
- key: "mergePartialIndexInSelector",
669
- value: function mergePartialIndexInSelector(selector, partialFilter) {
670
- if (partialFilter) {
671
- _logger.default.info("PouchLink: The query contains a partial index but PouchDB does not support it. " + "Hence, the partial index definition is used in the selector for in-memory evaluation, " + "which might impact expected performances. If this support is important in your use-case, " + "please let us know or help us contribute to PouchDB!");
914
+ key: "createIndex",
915
+ value: function () {
916
+ var _createIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(fields) {
917
+ var _ref2,
918
+ partialFilter,
919
+ indexName,
920
+ doctype,
921
+ absName,
922
+ db,
923
+ index,
924
+ _args10 = arguments;
925
+
926
+ return _regenerator.default.wrap(function _callee10$(_context10) {
927
+ while (1) {
928
+ switch (_context10.prev = _context10.next) {
929
+ case 0:
930
+ _ref2 = _args10.length > 1 && _args10[1] !== undefined ? _args10[1] : {}, partialFilter = _ref2.partialFilter, indexName = _ref2.indexName, doctype = _ref2.doctype;
931
+ absName = "".concat(doctype, "/").concat(indexName);
932
+ db = this.pouches.getPouch(doctype);
933
+ _context10.next = 5;
934
+ return db.createIndex({
935
+ index: {
936
+ fields: fields,
937
+ ddoc: indexName,
938
+ indexName: indexName,
939
+ partial_filter_selector: partialFilter
940
+ }
941
+ });
672
942
 
673
- return _objectSpread(_objectSpread({}, selector), partialFilter);
943
+ case 5:
944
+ index = _context10.sent;
945
+ this.indexes[absName] = index;
946
+ return _context10.abrupt("return", index);
947
+
948
+ case 8:
949
+ case "end":
950
+ return _context10.stop();
951
+ }
952
+ }
953
+ }, _callee10, this);
954
+ }));
955
+
956
+ function createIndex(_x9) {
957
+ return _createIndex.apply(this, arguments);
674
958
  }
675
959
 
676
- return selector;
960
+ return createIndex;
961
+ }()
962
+ /**
963
+ * Retrieve the PouchDB index if exist, undefined otherwise
964
+ *
965
+ * @param {string} doctype - The query's doctype
966
+ * @param {import('./types').MangoQueryOptions} options - The find options
967
+ * @param {string} indexName - The index name
968
+ * @returns {import('./types').PouchDbIndex | undefined}
969
+ */
970
+
971
+ }, {
972
+ key: "findExistingIndex",
973
+ value: function findExistingIndex(doctype, options, indexName) {
974
+ var absName = "".concat(doctype, "/").concat(indexName);
975
+ return this.indexes[absName];
677
976
  }
977
+ /**
978
+ * Handle index creation if it is missing.
979
+ *
980
+ * When an index is missing, we first check if there is one with a different
981
+ * name but the same definition. If there is none, we create the new index.
982
+ *
983
+ * /!\ Warning: this method is similar to DocumentCollection.handleMissingIndex()
984
+ * If you edit this method, please check if the change is also needed in DocumentCollection
985
+ *
986
+ * @param {string} doctype The mango selector
987
+ * @param {import('./types').MangoQueryOptions} options The find options
988
+ * @returns {Promise<import('./types').PouchDbIndex>} index
989
+ * @private
990
+ */
991
+
678
992
  }, {
679
993
  key: "ensureIndex",
680
994
  value: function () {
681
- var _ensureIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(doctype, query) {
682
- var fields, name, absName, db, index;
683
- return _regenerator.default.wrap(function _callee6$(_context6) {
995
+ var _ensureIndex = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(doctype, options) {
996
+ var indexedFields, partialFilter, indexName, existingIndex;
997
+ return _regenerator.default.wrap(function _callee11$(_context11) {
684
998
  while (1) {
685
- switch (_context6.prev = _context6.next) {
999
+ switch (_context11.prev = _context11.next) {
686
1000
  case 0:
687
- fields = query.indexedFields || (0, _mango.getIndexFields)(query);
688
- name = (0, _mango.getIndexNameFromFields)(fields);
689
- absName = "".concat(doctype, "/").concat(name);
690
- db = this.pouches.getPouch(doctype);
1001
+ indexedFields = options.indexedFields, partialFilter = options.partialFilter;
1002
+
1003
+ if (!indexedFields) {
1004
+ indexedFields = (0, _mango.getIndexFields)(options);
1005
+ } else if (partialFilter) {
1006
+ // Some pouch adapters does not support partialIndex, e.g. with websql in react-native
1007
+ // Therefore, we need to force the indexing the partialIndex fields to ensure they will be
1008
+ // included in the actual index. Thanks to this, docs with missing fields will be excluded
1009
+ // from the index.
1010
+ // Note the $exists: false case should be handled in-memory.
1011
+ indexedFields = Array.from(new Set([].concat((0, _toConsumableArray2.default)(indexedFields), (0, _toConsumableArray2.default)(Object.keys(partialFilter))))); // FIXME: should properly handle n-level attributes
1012
+
1013
+ indexedFields = indexedFields.filter(function (field) {
1014
+ return field !== '$and' && field !== '$or';
1015
+ });
1016
+ }
691
1017
 
692
- if (!this.indexes[absName]) {
693
- _context6.next = 8;
1018
+ indexName = (0, _mango.getIndexNameFromFields)(indexedFields, partialFilter);
1019
+ existingIndex = this.findExistingIndex(doctype, options, indexName);
1020
+
1021
+ if (existingIndex) {
1022
+ _context11.next = 10;
694
1023
  break;
695
1024
  }
696
1025
 
697
- return _context6.abrupt("return", this.indexes[absName]);
698
-
699
- case 8:
700
- _context6.next = 10;
701
- return db.createIndex({
702
- index: {
703
- fields: fields
704
- }
1026
+ _context11.next = 7;
1027
+ return this.createIndex(indexedFields, {
1028
+ partialFilter: partialFilter,
1029
+ indexName: indexName,
1030
+ doctype: doctype
705
1031
  });
706
1032
 
1033
+ case 7:
1034
+ return _context11.abrupt("return", _context11.sent);
1035
+
707
1036
  case 10:
708
- index = _context6.sent;
709
- this.indexes[absName] = index;
710
- return _context6.abrupt("return", index);
1037
+ return _context11.abrupt("return", existingIndex);
711
1038
 
712
- case 13:
1039
+ case 11:
713
1040
  case "end":
714
- return _context6.stop();
1041
+ return _context11.stop();
715
1042
  }
716
1043
  }
717
- }, _callee6, this);
1044
+ }, _callee11, this);
718
1045
  }));
719
1046
 
720
- function ensureIndex(_x4, _x5) {
1047
+ function ensureIndex(_x10, _x11) {
721
1048
  return _ensureIndex.apply(this, arguments);
722
1049
  }
723
1050
 
@@ -726,110 +1053,120 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
726
1053
  }, {
727
1054
  key: "executeQuery",
728
1055
  value: function () {
729
- var _executeQuery = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(_ref2) {
730
- var doctype, selector, sort, fields, limit, id, ids, skip, indexedFields, partialFilter, db, mergedSelector, res, withRows, findOpts, index;
731
- return _regenerator.default.wrap(function _callee7$(_context7) {
1056
+ var _executeQuery = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(_ref3) {
1057
+ var doctype, selector, sort, fields, limit, id, ids, skip, indexedFields, partialFilter, db, res, withRows, findSelector, findOpts, index;
1058
+ return _regenerator.default.wrap(function _callee12$(_context12) {
732
1059
  while (1) {
733
- switch (_context7.prev = _context7.next) {
1060
+ switch (_context12.prev = _context12.next) {
734
1061
  case 0:
735
- doctype = _ref2.doctype, selector = _ref2.selector, sort = _ref2.sort, fields = _ref2.fields, limit = _ref2.limit, id = _ref2.id, ids = _ref2.ids, skip = _ref2.skip, indexedFields = _ref2.indexedFields, partialFilter = _ref2.partialFilter;
736
- db = this.getPouch(doctype); // The partial index is not supported by PouchDB, so we ensure the selector includes it
737
-
738
- mergedSelector = this.mergePartialIndexInSelector(selector, partialFilter);
1062
+ doctype = _ref3.doctype, selector = _ref3.selector, sort = _ref3.sort, fields = _ref3.fields, limit = _ref3.limit, id = _ref3.id, ids = _ref3.ids, skip = _ref3.skip, indexedFields = _ref3.indexedFields, partialFilter = _ref3.partialFilter;
1063
+ db = this.getPouch(doctype);
739
1064
 
740
1065
  if (!id) {
741
- _context7.next = 10;
1066
+ _context12.next = 9;
742
1067
  break;
743
1068
  }
744
1069
 
745
- _context7.next = 6;
1070
+ _context12.next = 5;
746
1071
  return db.get(id);
747
1072
 
748
- case 6:
749
- res = _context7.sent;
1073
+ case 5:
1074
+ res = _context12.sent;
750
1075
  withRows = false;
751
- _context7.next = 38;
1076
+ _context12.next = 38;
752
1077
  break;
753
1078
 
754
- case 10:
1079
+ case 9:
755
1080
  if (!ids) {
756
- _context7.next = 19;
1081
+ _context12.next = 18;
757
1082
  break;
758
1083
  }
759
1084
 
760
- _context7.next = 13;
1085
+ _context12.next = 12;
761
1086
  return allDocs(db, {
762
1087
  include_docs: true,
763
1088
  keys: ids
764
1089
  });
765
1090
 
766
- case 13:
767
- res = _context7.sent;
1091
+ case 12:
1092
+ res = _context12.sent;
768
1093
  res = withoutDesignDocuments(res);
769
1094
  res.total_rows = null; // pouch indicates the total number of docs in res.total_rows, even though we use "keys". Setting it to null avoids cozy-client thinking there are more docs to fetch.
770
1095
 
771
1096
  withRows = true;
772
- _context7.next = 38;
1097
+ _context12.next = 38;
773
1098
  break;
774
1099
 
775
- case 19:
776
- if (!(!mergedSelector && !fields && !sort)) {
777
- _context7.next = 27;
1100
+ case 18:
1101
+ if (!(!selector && !partialFilter && !fields && !sort)) {
1102
+ _context12.next = 26;
778
1103
  break;
779
1104
  }
780
1105
 
781
- _context7.next = 22;
1106
+ _context12.next = 21;
782
1107
  return allDocs(db, {
783
1108
  include_docs: true,
784
1109
  limit: limit
785
1110
  });
786
1111
 
787
- case 22:
788
- res = _context7.sent;
1112
+ case 21:
1113
+ res = _context12.sent;
789
1114
  res = withoutDesignDocuments(res);
790
1115
  withRows = true;
791
- _context7.next = 38;
1116
+ _context12.next = 38;
792
1117
  break;
793
1118
 
794
- case 27:
1119
+ case 26:
1120
+ findSelector = _helpers.default.normalizeFindSelector({
1121
+ selector: selector,
1122
+ sort: sort,
1123
+ indexedFields: indexedFields,
1124
+ partialFilter: partialFilter
1125
+ });
795
1126
  findOpts = {
796
1127
  sort: sort,
797
- selector: mergedSelector,
798
- // same selector as Document Collection. We force _id.
799
- // Fix https://github.com/cozy/cozy-client/issues/985
800
- fields: fields ? [].concat((0, _toConsumableArray2.default)(fields), ['_id', '_type', 'class']) : undefined,
1128
+ selector: findSelector,
1129
+ // same selector as Document Collection.
1130
+ // _id is necessary for the store, and _rev is required for offline. See https://github.com/cozy/cozy-client/blob/95978d39546023920b0c01d689fed5dd41577a02/packages/cozy-client/src/CozyClient.js#L1153
1131
+ fields: fields ? [].concat((0, _toConsumableArray2.default)(fields), ['_id', '_rev']) : undefined,
801
1132
  limit: limit,
802
1133
  skip: skip
803
1134
  };
804
- _context7.next = 30;
1135
+ _context12.next = 30;
805
1136
  return this.ensureIndex(doctype, _objectSpread(_objectSpread({}, findOpts), {}, {
806
- indexedFields: indexedFields
1137
+ indexedFields: indexedFields,
1138
+ partialFilter: partialFilter
807
1139
  }));
808
1140
 
809
1141
  case 30:
810
- index = _context7.sent;
1142
+ index = _context12.sent;
811
1143
  findOpts.use_index = index.id;
812
- _context7.next = 34;
1144
+ _context12.next = 34;
813
1145
  return find(db, findOpts);
814
1146
 
815
1147
  case 34:
816
- res = _context7.sent;
1148
+ res = _context12.sent;
817
1149
  res.offset = skip;
818
1150
  res.limit = limit;
819
1151
  withRows = true;
820
1152
 
821
1153
  case 38:
822
- return _context7.abrupt("return", jsonapi.fromPouchResult(res, withRows, doctype));
1154
+ return _context12.abrupt("return", jsonapi.fromPouchResult({
1155
+ res: res,
1156
+ withRows: withRows,
1157
+ doctype: doctype,
1158
+ client: this.client
1159
+ }));
823
1160
 
824
1161
  case 39:
825
1162
  case "end":
826
- return _context7.stop();
1163
+ return _context12.stop();
827
1164
  }
828
1165
  }
829
- }, _callee7, this);
1166
+ }, _callee12, this);
830
1167
  }));
831
1168
 
832
- function executeQuery(_x6) {
1169
+ function executeQuery(_x12) {
833
1170
  return _executeQuery.apply(this, arguments);
834
1171
  }
835
1172
 
@@ -838,71 +1175,76 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
838
1175
  }, {
839
1176
  key: "executeMutation",
840
1177
  value: function () {
841
- var _executeMutation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(mutation, result, forward) {
1178
+ var _executeMutation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(mutation, result, forward) {
842
1179
  var pouchRes;
843
- return _regenerator.default.wrap(function _callee8$(_context8) {
1180
+ return _regenerator.default.wrap(function _callee13$(_context13) {
844
1181
  while (1) {
845
- switch (_context8.prev = _context8.next) {
1182
+ switch (_context13.prev = _context13.next) {
846
1183
  case 0:
847
- _context8.t0 = mutation.mutationType;
848
- _context8.next = _context8.t0 === _cozyClient.MutationTypes.CREATE_DOCUMENT ? 3 : _context8.t0 === _cozyClient.MutationTypes.UPDATE_DOCUMENT ? 7 : _context8.t0 === _cozyClient.MutationTypes.UPDATE_DOCUMENTS ? 11 : _context8.t0 === _cozyClient.MutationTypes.DELETE_DOCUMENT ? 15 : _context8.t0 === _cozyClient.MutationTypes.ADD_REFERENCES_TO ? 19 : 23;
1184
+ _context13.t0 = mutation.mutationType;
1185
+ _context13.next = _context13.t0 === _cozyClient.MutationTypes.CREATE_DOCUMENT ? 3 : _context13.t0 === _cozyClient.MutationTypes.UPDATE_DOCUMENT ? 7 : _context13.t0 === _cozyClient.MutationTypes.UPDATE_DOCUMENTS ? 11 : _context13.t0 === _cozyClient.MutationTypes.DELETE_DOCUMENT ? 15 : _context13.t0 === _cozyClient.MutationTypes.ADD_REFERENCES_TO ? 19 : 23;
849
1186
  break;
850
1187
 
851
1188
  case 3:
852
- _context8.next = 5;
1189
+ _context13.next = 5;
853
1190
  return this.createDocument(mutation);
854
1191
 
855
1192
  case 5:
856
- pouchRes = _context8.sent;
857
- return _context8.abrupt("break", 24);
1193
+ pouchRes = _context13.sent;
1194
+ return _context13.abrupt("break", 24);
858
1195
 
859
1196
  case 7:
860
- _context8.next = 9;
1197
+ _context13.next = 9;
861
1198
  return this.updateDocument(mutation);
862
1199
 
863
1200
  case 9:
864
- pouchRes = _context8.sent;
865
- return _context8.abrupt("break", 24);
1201
+ pouchRes = _context13.sent;
1202
+ return _context13.abrupt("break", 24);
866
1203
 
867
1204
  case 11:
868
- _context8.next = 13;
1205
+ _context13.next = 13;
869
1206
  return this.updateDocuments(mutation);
870
1207
 
871
1208
  case 13:
872
- pouchRes = _context8.sent;
873
- return _context8.abrupt("break", 24);
1209
+ pouchRes = _context13.sent;
1210
+ return _context13.abrupt("break", 24);
874
1211
 
875
1212
  case 15:
876
- _context8.next = 17;
1213
+ _context13.next = 17;
877
1214
  return this.deleteDocument(mutation);
878
1215
 
879
1216
  case 17:
880
- pouchRes = _context8.sent;
881
- return _context8.abrupt("break", 24);
1217
+ pouchRes = _context13.sent;
1218
+ return _context13.abrupt("break", 24);
882
1219
 
883
1220
  case 19:
884
- _context8.next = 21;
1221
+ _context13.next = 21;
885
1222
  return this.addReferencesTo(mutation);
886
1223
 
887
1224
  case 21:
888
- pouchRes = _context8.sent;
889
- return _context8.abrupt("break", 24);
1225
+ pouchRes = _context13.sent;
1226
+ return _context13.abrupt("break", 24);
890
1227
 
891
1228
  case 23:
892
- return _context8.abrupt("return", forward(mutation, result));
1229
+ return _context13.abrupt("return", forward(mutation, result));
893
1230
 
894
1231
  case 24:
895
- return _context8.abrupt("return", jsonapi.fromPouchResult(pouchRes, false, (0, _cozyClient.getDoctypeFromOperation)(mutation)));
1232
+ return _context13.abrupt("return", jsonapi.fromPouchResult({
1233
+ res: pouchRes,
1234
+ withRows: false,
1235
+ doctype: (0, _cozyClient.getDoctypeFromOperation)(mutation),
1236
+ client: this.client
1237
+ }));
896
1238
 
897
1239
  case 25:
898
1240
  case "end":
899
- return _context8.stop();
1241
+ return _context13.stop();
900
1242
  }
901
1243
  }
902
- }, _callee8, this);
1244
+ }, _callee13, this);
903
1245
  }));
904
1246
 
905
- function executeMutation(_x7, _x8, _x9) {
1247
+ function executeMutation(_x13, _x14, _x15) {
906
1248
  return _executeMutation.apply(this, arguments);
907
1249
  }
908
1250
 
@@ -911,28 +1253,28 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
911
1253
  }, {
912
1254
  key: "createDocument",
913
1255
  value: function () {
914
- var _createDocument = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(mutation) {
1256
+ var _createDocument = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14(mutation) {
915
1257
  var res;
916
- return _regenerator.default.wrap(function _callee9$(_context9) {
1258
+ return _regenerator.default.wrap(function _callee14$(_context14) {
917
1259
  while (1) {
918
- switch (_context9.prev = _context9.next) {
1260
+ switch (_context14.prev = _context14.next) {
919
1261
  case 0:
920
- _context9.next = 2;
1262
+ _context14.next = 2;
921
1263
  return this.dbMethod('post', mutation);
922
1264
 
923
1265
  case 2:
924
- res = _context9.sent;
925
- return _context9.abrupt("return", parseMutationResult(mutation.document, res));
1266
+ res = _context14.sent;
1267
+ return _context14.abrupt("return", parseMutationResult(mutation.document, res));
926
1268
 
927
1269
  case 4:
928
1270
  case "end":
929
- return _context9.stop();
1271
+ return _context14.stop();
930
1272
  }
931
1273
  }
932
- }, _callee9, this);
1274
+ }, _callee14, this);
933
1275
  }));
934
1276
 
935
- function createDocument(_x10) {
1277
+ function createDocument(_x16) {
936
1278
  return _createDocument.apply(this, arguments);
937
1279
  }
938
1280
 
@@ -941,28 +1283,28 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
941
1283
  }, {
942
1284
  key: "updateDocument",
943
1285
  value: function () {
944
- var _updateDocument = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(mutation) {
1286
+ var _updateDocument = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee15(mutation) {
945
1287
  var res;
946
- return _regenerator.default.wrap(function _callee10$(_context10) {
1288
+ return _regenerator.default.wrap(function _callee15$(_context15) {
947
1289
  while (1) {
948
- switch (_context10.prev = _context10.next) {
1290
+ switch (_context15.prev = _context15.next) {
949
1291
  case 0:
950
- _context10.next = 2;
1292
+ _context15.next = 2;
951
1293
  return this.dbMethod('put', mutation);
952
1294
 
953
1295
  case 2:
954
- res = _context10.sent;
955
- return _context10.abrupt("return", parseMutationResult(mutation.document, res));
1296
+ res = _context15.sent;
1297
+ return _context15.abrupt("return", parseMutationResult(mutation.document, res));
956
1298
 
957
1299
  case 4:
958
1300
  case "end":
959
- return _context10.stop();
1301
+ return _context15.stop();
960
1302
  }
961
1303
  }
962
- }, _callee10, this);
1304
+ }, _callee15, this);
963
1305
  }));
964
1306
 
965
- function updateDocument(_x11) {
1307
+ function updateDocument(_x17) {
966
1308
  return _updateDocument.apply(this, arguments);
967
1309
  }
968
1310
 
@@ -971,18 +1313,18 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
971
1313
  }, {
972
1314
  key: "updateDocuments",
973
1315
  value: function () {
974
- var _updateDocuments = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(mutation) {
1316
+ var _updateDocuments = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee16(mutation) {
975
1317
  var docs, bulkResponse, updatedDocs;
976
- return _regenerator.default.wrap(function _callee11$(_context11) {
1318
+ return _regenerator.default.wrap(function _callee16$(_context16) {
977
1319
  while (1) {
978
- switch (_context11.prev = _context11.next) {
1320
+ switch (_context16.prev = _context16.next) {
979
1321
  case 0:
980
1322
  docs = mutation.documents;
981
- _context11.next = 3;
1323
+ _context16.next = 3;
982
1324
  return this.dbMethod('bulkDocs', mutation);
983
1325
 
984
1326
  case 3:
985
- bulkResponse = _context11.sent;
1327
+ bulkResponse = _context16.sent;
986
1328
  updatedDocs = (0, _zipWith.default)(bulkResponse, docs, function (bulkResult, originalDoc) {
987
1329
  return _objectSpread(_objectSpread({}, originalDoc), {}, {
988
1330
  _id: bulkResult.id,
@@ -993,24 +1335,24 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
993
1335
  if (!bulkResponse.find(function (x) {
994
1336
  return !x.ok;
995
1337
  })) {
996
- _context11.next = 7;
1338
+ _context16.next = 7;
997
1339
  break;
998
1340
  }
999
1341
 
1000
1342
  throw new _cozyClient.BulkEditError(bulkResponse, updatedDocs);
1001
1343
 
1002
1344
  case 7:
1003
- return _context11.abrupt("return", updatedDocs);
1345
+ return _context16.abrupt("return", updatedDocs);
1004
1346
 
1005
1347
  case 8:
1006
1348
  case "end":
1007
- return _context11.stop();
1349
+ return _context16.stop();
1008
1350
  }
1009
1351
  }
1010
- }, _callee11, this);
1352
+ }, _callee16, this);
1011
1353
  }));
1012
1354
 
1013
- function updateDocuments(_x12) {
1355
+ function updateDocuments(_x18) {
1014
1356
  return _updateDocuments.apply(this, arguments);
1015
1357
  }
1016
1358
 
@@ -1019,101 +1361,125 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
1019
1361
  }, {
1020
1362
  key: "deleteDocument",
1021
1363
  value: function () {
1022
- var _deleteDocument = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(mutation) {
1364
+ var _deleteDocument = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee17(mutation) {
1023
1365
  var res, document;
1024
- return _regenerator.default.wrap(function _callee12$(_context12) {
1366
+ return _regenerator.default.wrap(function _callee17$(_context17) {
1025
1367
  while (1) {
1026
- switch (_context12.prev = _context12.next) {
1368
+ switch (_context17.prev = _context17.next) {
1027
1369
  case 0:
1028
- _context12.next = 2;
1370
+ _context17.next = 2;
1029
1371
  return this.dbMethod('remove', mutation);
1030
1372
 
1031
1373
  case 2:
1032
- res = _context12.sent;
1374
+ res = _context17.sent;
1033
1375
  document = _objectSpread(_objectSpread({}, mutation.document), {}, {
1034
1376
  _id: res.id,
1035
1377
  _rev: res.rev,
1036
1378
  _deleted: true
1037
1379
  });
1038
- return _context12.abrupt("return", parseMutationResult(document, res));
1380
+ return _context17.abrupt("return", parseMutationResult(document, res));
1039
1381
 
1040
1382
  case 5:
1041
1383
  case "end":
1042
- return _context12.stop();
1384
+ return _context17.stop();
1043
1385
  }
1044
1386
  }
1045
- }, _callee12, this);
1387
+ }, _callee17, this);
1046
1388
  }));
1047
1389
 
1048
- function deleteDocument(_x13) {
1390
+ function deleteDocument(_x19) {
1049
1391
  return _deleteDocument.apply(this, arguments);
1050
1392
  }
1051
1393
 
1052
1394
  return deleteDocument;
1053
1395
  }()
1396
+ }, {
1397
+ key: "addReferencesTo",
1398
+ value: function () {
1399
+ var _addReferencesTo = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee18(mutation) {
1400
+ return _regenerator.default.wrap(function _callee18$(_context18) {
1401
+ while (1) {
1402
+ switch (_context18.prev = _context18.next) {
1403
+ case 0:
1404
+ throw new Error('addReferencesTo is not implemented in CozyPouchLink');
1405
+
1406
+ case 1:
1407
+ case "end":
1408
+ return _context18.stop();
1409
+ }
1410
+ }
1411
+ }, _callee18);
1412
+ }));
1413
+
1414
+ function addReferencesTo(_x20) {
1415
+ return _addReferencesTo.apply(this, arguments);
1416
+ }
1417
+
1418
+ return addReferencesTo;
1419
+ }()
1054
1420
  }, {
1055
1421
  key: "dbMethod",
1056
1422
  value: function () {
1057
- var _dbMethod = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee13(method, mutation) {
1423
+ var _dbMethod = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee19(method, mutation) {
1058
1424
  var doctype, doc, docs, db, res;
1059
- return _regenerator.default.wrap(function _callee13$(_context13) {
1425
+ return _regenerator.default.wrap(function _callee19$(_context19) {
1060
1426
  while (1) {
1061
- switch (_context13.prev = _context13.next) {
1427
+ switch (_context19.prev = _context19.next) {
1062
1428
  case 0:
1063
1429
  doctype = (0, _cozyClient.getDoctypeFromOperation)(mutation);
1064
1430
  doc = mutation.document, docs = mutation.documents;
1065
1431
  db = this.getPouch(doctype);
1066
- _context13.prev = 3;
1432
+ _context19.prev = 3;
1067
1433
 
1068
1434
  if (!docs) {
1069
- _context13.next = 10;
1435
+ _context19.next = 10;
1070
1436
  break;
1071
1437
  }
1072
1438
 
1073
- _context13.next = 7;
1439
+ _context19.next = 7;
1074
1440
  return db[method](docs.map(function (doc) {
1075
1441
  return sanitized(doc);
1076
1442
  }));
1077
1443
 
1078
1444
  case 7:
1079
- res = _context13.sent;
1080
- _context13.next = 17;
1445
+ res = _context19.sent;
1446
+ _context19.next = 17;
1081
1447
  break;
1082
1448
 
1083
1449
  case 10:
1084
1450
  if (!doc) {
1085
- _context13.next = 16;
1451
+ _context19.next = 16;
1086
1452
  break;
1087
1453
  }
1088
1454
 
1089
- _context13.next = 13;
1455
+ _context19.next = 13;
1090
1456
  return db[method](sanitized(doc));
1091
1457
 
1092
1458
  case 13:
1093
- res = _context13.sent;
1094
- _context13.next = 17;
1459
+ res = _context19.sent;
1460
+ _context19.next = 17;
1095
1461
  break;
1096
1462
 
1097
1463
  case 16:
1098
1464
  throw new Error('A mutation should either have document or documents member.');
1099
1465
 
1100
1466
  case 17:
1101
- return _context13.abrupt("return", res);
1467
+ return _context19.abrupt("return", res);
1102
1468
 
1103
1469
  case 20:
1104
- _context13.prev = 20;
1105
- _context13.t0 = _context13["catch"](3);
1106
- throw new Error("Coud not apply mutation: ".concat(_context13.t0.message));
1470
+ _context19.prev = 20;
1471
+ _context19.t0 = _context19["catch"](3);
1472
+ throw new Error("Coud not apply mutation: ".concat(_context19.t0.message));
1107
1473
 
1108
1474
  case 23:
1109
1475
  case "end":
1110
- return _context13.stop();
1476
+ return _context19.stop();
1111
1477
  }
1112
1478
  }
1113
- }, _callee13, this, [[3, 20]]);
1479
+ }, _callee19, this, [[3, 20]]);
1114
1480
  }));
1115
1481
 
1116
- function dbMethod(_x14, _x15) {
1482
+ function dbMethod(_x21, _x22) {
1117
1483
  return _dbMethod.apply(this, arguments);
1118
1484
  }
1119
1485
 
@@ -1122,29 +1488,29 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
1122
1488
  }, {
1123
1489
  key: "syncImmediately",
1124
1490
  value: function () {
1125
- var _syncImmediately = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee14() {
1126
- return _regenerator.default.wrap(function _callee14$(_context14) {
1491
+ var _syncImmediately = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee20() {
1492
+ return _regenerator.default.wrap(function _callee20$(_context20) {
1127
1493
  while (1) {
1128
- switch (_context14.prev = _context14.next) {
1494
+ switch (_context20.prev = _context20.next) {
1129
1495
  case 0:
1130
1496
  if (this.pouches) {
1131
- _context14.next = 3;
1497
+ _context20.next = 3;
1132
1498
  break;
1133
1499
  }
1134
1500
 
1135
1501
  _logger.default.warn('Cannot sync immediately, no PouchManager');
1136
1502
 
1137
- return _context14.abrupt("return");
1503
+ return _context20.abrupt("return");
1138
1504
 
1139
1505
  case 3:
1140
1506
  this.pouches.syncImmediately();
1141
1507
 
1142
1508
  case 4:
1143
1509
  case "end":
1144
- return _context14.stop();
1510
+ return _context20.stop();
1145
1511
  }
1146
1512
  }
1147
- }, _callee14, this);
1513
+ }, _callee20, this);
1148
1514
  }));
1149
1515
 
1150
1516
  function syncImmediately() {
@@ -1157,8 +1523,9 @@ var PouchLink = /*#__PURE__*/function (_CozyLink) {
1157
1523
  return PouchLink;
1158
1524
  }(_cozyClient.CozyLink);
1159
1525
 
1160
- (0, _defineProperty2.default)(PouchLink, "getPouchAdapterName", function () {
1161
- return (0, _localStorage.getAdapterName)();
1526
+ (0, _defineProperty2.default)(PouchLink, "getPouchAdapterName", function (localStorage) {
1527
+ var storage = new _localStorage.PouchLocalStorage(localStorage || _platformWeb.platformWeb.storage);
1528
+ return storage.getAdapterName();
1162
1529
  });
1163
1530
  var _default = PouchLink;
1164
1531
  exports.default = _default;