cozy-client 60.1.1 → 60.2.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.
@@ -3126,7 +3126,7 @@ var CozyClient = /*#__PURE__*/function () {
3126
3126
  CozyClient.hooks = CozyClient.hooks || {};
3127
3127
  CozyClient.fetchPolicies = _policies.default; //COZY_CLIENT_VERSION_PACKAGE in replaced by babel. See babel config
3128
3128
 
3129
- CozyClient.version = "60.1.1";
3129
+ CozyClient.version = "60.2.0";
3130
3130
 
3131
3131
  _microee.default.mixin(CozyClient);
3132
3132
 
@@ -15,14 +15,20 @@ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/cl
15
15
 
16
16
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
17
17
 
18
+ var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
19
+
18
20
  var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
19
21
 
20
22
  var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
21
23
 
22
24
  var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
23
25
 
26
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
27
+
24
28
  var _CozyLink2 = _interopRequireDefault(require("./CozyLink"));
25
29
 
30
+ var _cozyLogger = _interopRequireDefault(require("cozy-logger"));
31
+
26
32
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
27
33
 
28
34
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
@@ -44,7 +50,30 @@ var DataProxyLink = /*#__PURE__*/function (_CozyLink) {
44
50
 
45
51
  (0, _classCallCheck2.default)(this, DataProxyLink);
46
52
  _this = _super.call(this);
53
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "_onReceiveMessage", function (event) {
54
+ // See https://github.com/cozy/cozy-web-data-proxy/blob/1fc3deef767536aa264074c8a377f422b588409d/src/dataproxy/parent/ParentWindowProvider.tsx#L27
55
+ if (!event.origin.includes('dataproxy')) {
56
+ return;
57
+ }
58
+
59
+ var eventData = event === null || event === void 0 ? void 0 : event.data;
60
+
61
+ if (eventData && typeof eventData === 'object') {
62
+ if (eventData.type === 'DATAPROXYMESSAGE' && eventData.payload === 'READY') {
63
+ _cozyLogger.default.info("Received message: DataProxy is ready");
64
+
65
+ _this._flushQueue();
66
+ }
67
+ }
68
+ });
47
69
  _this.dataproxy = dataproxy || null;
70
+ _this._queue = [];
71
+ _this._drainingRequests = false;
72
+
73
+ if (window) {
74
+ window.addEventListener('message', _this._onReceiveMessage);
75
+ }
76
+
48
77
  return _this;
49
78
  }
50
79
 
@@ -64,6 +93,8 @@ var DataProxyLink = /*#__PURE__*/function (_CozyLink) {
64
93
  key: "registerDataProxy",
65
94
  value: function registerDataProxy(dataproxy) {
66
95
  this.dataproxy = dataproxy;
96
+
97
+ this._flushQueue();
67
98
  }
68
99
  }, {
69
100
  key: "reset",
@@ -90,24 +121,31 @@ var DataProxyLink = /*#__PURE__*/function (_CozyLink) {
90
121
  key: "request",
91
122
  value: function () {
92
123
  var _request = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(operation, options, result, forward) {
93
- var opts;
124
+ var _this$dataproxy,
125
+ _this2 = this;
126
+
94
127
  return _regenerator.default.wrap(function _callee2$(_context2) {
95
128
  while (1) {
96
129
  switch (_context2.prev = _context2.next) {
97
130
  case 0:
98
- if (!this.dataproxy) {
99
- _context2.next = 5;
131
+ if (!((_this$dataproxy = this.dataproxy) !== null && _this$dataproxy !== void 0 && _this$dataproxy.requestLink)) {
132
+ _context2.next = 2;
100
133
  break;
101
134
  }
102
135
 
103
- // Send the request to the DataProxy, that will handle both web and mobile environments
104
- opts = options || {};
105
- return _context2.abrupt("return", this.dataproxy.requestLink(operation, opts));
136
+ return _context2.abrupt("return", this.doRequest(operation, options));
106
137
 
107
- case 5:
108
- return _context2.abrupt("return", forward(operation, options));
138
+ case 2:
139
+ return _context2.abrupt("return", new Promise(function (resolve, reject) {
140
+ _this2._queue.push({
141
+ operation: operation,
142
+ options: options,
143
+ resolve: resolve,
144
+ reject: reject
145
+ });
146
+ }));
109
147
 
110
- case 6:
148
+ case 3:
111
149
  case "end":
112
150
  return _context2.stop();
113
151
  }
@@ -122,29 +160,141 @@ var DataProxyLink = /*#__PURE__*/function (_CozyLink) {
122
160
  return request;
123
161
  }()
124
162
  }, {
125
- key: "persistCozyData",
163
+ key: "doRequest",
126
164
  value: function () {
127
- var _persistCozyData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(data, forward) {
165
+ var _doRequest = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(operation, options) {
166
+ var opts, startQuery, resp, endQuery;
128
167
  return _regenerator.default.wrap(function _callee3$(_context3) {
129
168
  while (1) {
130
169
  switch (_context3.prev = _context3.next) {
131
170
  case 0:
132
- return _context3.abrupt("return");
171
+ opts = options || {};
172
+ startQuery = performance.now(); // Send the request to the DataProxy, that will handle both web and mobile environments
133
173
 
134
- case 1:
174
+ _context3.next = 4;
175
+ return this.dataproxy.requestLink(operation, opts);
176
+
177
+ case 4:
178
+ resp = _context3.sent;
179
+ endQuery = performance.now();
180
+
181
+ _cozyLogger.default.info("Request query took ".concat(endQuery - startQuery, " ms"));
182
+
183
+ return _context3.abrupt("return", resp);
184
+
185
+ case 8:
135
186
  case "end":
136
187
  return _context3.stop();
137
188
  }
138
189
  }
139
- }, _callee3);
190
+ }, _callee3, this);
140
191
  }));
141
192
 
142
- function persistCozyData(_x5, _x6) {
193
+ function doRequest(_x5, _x6) {
194
+ return _doRequest.apply(this, arguments);
195
+ }
196
+
197
+ return doRequest;
198
+ }()
199
+ }, {
200
+ key: "persistCozyData",
201
+ value: function () {
202
+ var _persistCozyData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(data, forward) {
203
+ return _regenerator.default.wrap(function _callee4$(_context4) {
204
+ while (1) {
205
+ switch (_context4.prev = _context4.next) {
206
+ case 0:
207
+ return _context4.abrupt("return");
208
+
209
+ case 1:
210
+ case "end":
211
+ return _context4.stop();
212
+ }
213
+ }
214
+ }, _callee4);
215
+ }));
216
+
217
+ function persistCozyData(_x7, _x8) {
143
218
  return _persistCozyData.apply(this, arguments);
144
219
  }
145
220
 
146
221
  return persistCozyData;
147
222
  }()
223
+ }, {
224
+ key: "_flushQueue",
225
+ value: function () {
226
+ var _flushQueue2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
227
+ var _this$dataproxy2;
228
+
229
+ var _this$_queue$shift, operation, options, resolve, reject, resp;
230
+
231
+ return _regenerator.default.wrap(function _callee5$(_context5) {
232
+ while (1) {
233
+ switch (_context5.prev = _context5.next) {
234
+ case 0:
235
+ if (!(!((_this$dataproxy2 = this.dataproxy) !== null && _this$dataproxy2 !== void 0 && _this$dataproxy2.requestLink) || this._queue.length < 1)) {
236
+ _context5.next = 2;
237
+ break;
238
+ }
239
+
240
+ return _context5.abrupt("return");
241
+
242
+ case 2:
243
+ _cozyLogger.default.info("Execute ".concat(this._queue.length, " delayed requests"));
244
+
245
+ this._drainingRequests = true;
246
+ _context5.prev = 4;
247
+
248
+ case 5:
249
+ if (!(this._queue.length > 0)) {
250
+ _context5.next = 19;
251
+ break;
252
+ }
253
+
254
+ _this$_queue$shift = this._queue.shift(), operation = _this$_queue$shift.operation, options = _this$_queue$shift.options, resolve = _this$_queue$shift.resolve, reject = _this$_queue$shift.reject;
255
+ _context5.prev = 7;
256
+ _context5.next = 10;
257
+ return this.doRequest(operation, options);
258
+
259
+ case 10:
260
+ resp = _context5.sent;
261
+ resolve(resp);
262
+ _context5.next = 17;
263
+ break;
264
+
265
+ case 14:
266
+ _context5.prev = 14;
267
+ _context5.t0 = _context5["catch"](7);
268
+ reject(_context5.t0);
269
+
270
+ case 17:
271
+ _context5.next = 5;
272
+ break;
273
+
274
+ case 19:
275
+ _context5.prev = 19;
276
+ this._drainingRequests = false; // Run it again in case queue has filled again during the flush
277
+
278
+ if (this._queue.length > 0) {
279
+ this._flushQueue();
280
+ }
281
+
282
+ return _context5.finish(19);
283
+
284
+ case 23:
285
+ case "end":
286
+ return _context5.stop();
287
+ }
288
+ }
289
+ }, _callee5, this, [[4,, 19, 23], [7, 14]]);
290
+ }));
291
+
292
+ function _flushQueue() {
293
+ return _flushQueue2.apply(this, arguments);
294
+ }
295
+
296
+ return _flushQueue;
297
+ }()
148
298
  }]);
149
299
  return DataProxyLink;
150
300
  }(_CozyLink2.default);
@@ -0,0 +1,86 @@
1
+ /** @jest-environment jsdom */
2
+ import DataProxyLink from './DataProxyLink'
3
+
4
+ describe('DataProxyLink queueing', () => {
5
+ it('should directly call dataproxy requestLink if available', async () => {
6
+ const requestLink = jest.fn().mockResolvedValue('OK')
7
+ const dataproxy = { requestLink }
8
+ const link = new DataProxyLink({ dataproxy })
9
+
10
+ const res = await link.request({ op: 'op1' }, {}, undefined, undefined)
11
+
12
+ expect(res).toBe('OK')
13
+ expect(requestLink).toHaveBeenCalledTimes(1)
14
+ expect(requestLink).toHaveBeenCalledWith({ op: 'op1' }, {})
15
+ })
16
+
17
+ it('should fill the event queue as long as dataproxy is not ready and run all of them once it registers', async () => {
18
+ const link = new DataProxyLink() // no dataproxy
19
+
20
+ const p1 = link.request({ op: 'op1' }, {}, undefined, undefined)
21
+ const p2 = link.request({ op: 'op2' }, {}, undefined, undefined)
22
+
23
+ expect(link._queue.length).toEqual(2)
24
+
25
+ const requestLink = jest
26
+ .fn()
27
+ .mockResolvedValueOnce('Res1')
28
+ .mockResolvedValueOnce('Res2')
29
+
30
+ link.registerDataProxy({ requestLink })
31
+
32
+ await expect(p1).resolves.toBe('Res1')
33
+ await expect(p2).resolves.toBe('Res2')
34
+
35
+ expect(requestLink.mock.calls.map(c => c[0].op)).toEqual(['op1', 'op2'])
36
+ expect(link._queue.length).toEqual(0)
37
+ })
38
+
39
+ it('should correctly deal with rejected promises ', async () => {
40
+ const link = new DataProxyLink()
41
+
42
+ const pOk1 = link.request({ op: 'op1' }, {})
43
+ const pFail = link.request({ op: 'op2' }, {})
44
+ const pOk2 = link.request({ op: 'op3' }, {})
45
+
46
+ const requestLink = jest
47
+ .fn()
48
+ .mockResolvedValueOnce('Res1')
49
+ .mockRejectedValueOnce(new Error('boom'))
50
+ .mockResolvedValueOnce('Res3')
51
+
52
+ link.registerDataProxy({ requestLink })
53
+
54
+ await expect(pOk1).resolves.toBe('Res1')
55
+ await expect(pFail).rejects.toThrow('boom')
56
+ await expect(pOk2).resolves.toBe('Res3')
57
+
58
+ expect(requestLink.mock.calls.map(c => c[0].op)).toEqual([
59
+ 'op1',
60
+ 'op2',
61
+ 'op3'
62
+ ])
63
+ })
64
+
65
+ it('should flush events when ready message is received', async () => {
66
+ const link = new DataProxyLink()
67
+
68
+ const p1 = link.request({ op: 'op1' }, {})
69
+ const p2 = link.request({ op: 'op2' }, {})
70
+
71
+ const requestLink = jest
72
+ .fn()
73
+ .mockResolvedValueOnce('Res1')
74
+ .mockResolvedValueOnce('Res2')
75
+ link.dataproxy = { requestLink }
76
+
77
+ const ev = new MessageEvent('message', {
78
+ data: { type: 'DATAPROXYMESSAGE', payload: 'READY' },
79
+ origin: 'http://dataproxy.cozy.localhost:8080'
80
+ })
81
+ window.dispatchEvent(ev)
82
+
83
+ await expect(p1).resolves.toBe('Res1')
84
+ await expect(p2).resolves.toBe('Res2')
85
+ })
86
+ })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-client",
3
- "version": "60.1.1",
3
+ "version": "60.2.0",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.node.js",
6
6
  "browser": "dist/index.js",
@@ -74,5 +74,5 @@
74
74
  "react-native-ios11-devicecheck": "^0.0.3"
75
75
  },
76
76
  "sideEffects": false,
77
- "gitHead": "a944c176ad97aa07f7145d97642716a9dc231990"
77
+ "gitHead": "48687a04cfb284dadd0d208451ca4f6a514519f2"
78
78
  }
@@ -7,6 +7,8 @@ export default class DataProxyLink extends CozyLink {
7
7
  dataproxy: object;
8
8
  });
9
9
  dataproxy: any;
10
+ _queue: any[];
11
+ _drainingRequests: boolean;
10
12
  registerClient(client: any): void;
11
13
  /**
12
14
  * When the link is given to a cozy-client instance, the dataproxy might not be ready yet.
@@ -16,5 +18,8 @@ export default class DataProxyLink extends CozyLink {
16
18
  * @param {object} dataproxy - The dataproxy instance
17
19
  */
18
20
  registerDataProxy(dataproxy: object): void;
21
+ doRequest(operation: any, options: any): Promise<any>;
22
+ _flushQueue(): Promise<void>;
23
+ _onReceiveMessage: (event: any) => void;
19
24
  }
20
25
  import CozyLink from "./CozyLink";