cozy-client 51.6.1 → 51.7.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.
@@ -71,6 +71,8 @@ var _CozyLink = require("./CozyLink");
71
71
 
72
72
  var _ObservableQuery = _interopRequireDefault(require("./ObservableQuery"));
73
73
 
74
+ var _defaultPerformanceApi = require("./performances/defaultPerformanceApi");
75
+
74
76
  var _snapshots = require("./testing/snapshots");
75
77
 
76
78
  var _logger = _interopRequireDefault(require("./logger"));
@@ -159,6 +161,7 @@ var DOC_UPDATE = 'update';
159
161
  * @property {import("./types").AppMetadata} [appMetadata] - Metadata about the application that will be used in ensureCozyMetadata
160
162
  * @property {import("./types").ClientCapabilities} [capabilities] - Capabilities sent by the stack
161
163
  * @property {boolean} [store] - If set to false, the client will not instantiate a Redux store automatically. Use this if you want to merge cozy-client's store with your own redux store. See [here](https://docs.cozy.io/en/cozy-client/react-integration/#1b-use-your-own-redux-store) for more information.
164
+ * @property {import('./performances/types').PerformanceAPI} [performanceApi] - The performance API that can be used to measure performances
162
165
  */
163
166
 
164
167
  /**
@@ -238,12 +241,16 @@ var CozyClient = /*#__PURE__*/function () {
238
241
  _rawOptions$appMetada = rawOptions.appMetadata,
239
242
  appMetadata = _rawOptions$appMetada === void 0 ? {} : _rawOptions$appMetada,
240
243
  capabilities = rawOptions.capabilities,
241
- _options = (0, _objectWithoutProperties2.default)(rawOptions, ["link", "links", "schema", "appMetadata", "capabilities"]);
244
+ performanceApi = rawOptions.performanceApi,
245
+ _options = (0, _objectWithoutProperties2.default)(rawOptions, ["link", "links", "schema", "appMetadata", "capabilities", "performanceApi"]);
242
246
 
243
247
  if (link) {
244
248
  _logger.default.warn('`link` is deprecated, use `links`');
245
249
  }
250
+ /** @type {import('./performances/types').PerformanceAPI} */
251
+
246
252
 
253
+ this.performanceApi = performanceApi || _defaultPerformanceApi.defaultPerformanceApi;
247
254
  this.appMetadata = appMetadata;
248
255
  this.loginPromise = null;
249
256
  _options.uri = securiseUri(_options.uri);
@@ -263,7 +270,9 @@ var CozyClient = /*#__PURE__*/function () {
263
270
 
264
271
  return _this.emit.apply(_this, ['error'].concat(args));
265
272
  });
266
- this.setLinks(ensureArray(link || links || new _StackLink.default()));
273
+ this.setLinks(ensureArray(link || links || new _StackLink.default({
274
+ performanceApi: this.performanceApi
275
+ })));
267
276
  this.schema = new _Schema.default(schema, stackClient);
268
277
  /**
269
278
  * @type {import("./types").ClientCapabilities}
@@ -1264,6 +1273,7 @@ var CozyClient = /*#__PURE__*/function () {
1264
1273
  update,
1265
1274
  executeFromStore,
1266
1275
  options,
1276
+ markQuery,
1267
1277
  queryId,
1268
1278
  existingQuery,
1269
1279
  shouldFetch,
@@ -1278,53 +1288,54 @@ var CozyClient = /*#__PURE__*/function () {
1278
1288
  case 0:
1279
1289
  _ref5 = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {};
1280
1290
  update = _ref5.update, executeFromStore = _ref5.executeFromStore, options = (0, _objectWithoutProperties2.default)(_ref5, ["update", "executeFromStore"]);
1291
+ markQuery = this.performanceApi.mark("client.query(".concat(queryDefinition.doctype, ")"));
1281
1292
  this.ensureStore();
1282
1293
  queryId = options.as || this.queryIdGenerator.generateId(queryDefinition);
1283
1294
  existingQuery = this.getQueryFromState(queryId, options);
1284
1295
 
1285
1296
  if (!(options.enabled !== undefined)) {
1286
- _context8.next = 8;
1297
+ _context8.next = 9;
1287
1298
  break;
1288
1299
  }
1289
1300
 
1290
1301
  if (!('boolean' !== typeof options.enabled)) {
1291
- _context8.next = 8;
1302
+ _context8.next = 9;
1292
1303
  break;
1293
1304
  }
1294
1305
 
1295
1306
  throw new Error("option.enabled should be a boolean for this query: ".concat(JSON.stringify(queryDefinition)));
1296
1307
 
1297
- case 8:
1308
+ case 9:
1298
1309
  if (!options.fetchPolicy) {
1299
- _context8.next = 14;
1310
+ _context8.next = 15;
1300
1311
  break;
1301
1312
  }
1302
1313
 
1303
1314
  if (options.as) {
1304
- _context8.next = 11;
1315
+ _context8.next = 12;
1305
1316
  break;
1306
1317
  }
1307
1318
 
1308
1319
  throw new Error('Cannot use `fetchPolicy` without naming the query, please use `as` to name the query');
1309
1320
 
1310
- case 11:
1321
+ case 12:
1311
1322
  shouldFetch = options.fetchPolicy(existingQuery);
1312
1323
 
1313
1324
  if (shouldFetch) {
1314
- _context8.next = 14;
1325
+ _context8.next = 15;
1315
1326
  break;
1316
1327
  }
1317
1328
 
1318
1329
  return _context8.abrupt("return");
1319
1330
 
1320
- case 14:
1331
+ case 15:
1321
1332
  if (!(existingQuery && Object.keys(existingQuery).length > 0)) {
1322
- _context8.next = 17;
1333
+ _context8.next = 18;
1323
1334
  break;
1324
1335
  }
1325
1336
 
1326
1337
  if (!(existingQuery.fetchStatus === 'loading')) {
1327
- _context8.next = 17;
1338
+ _context8.next = 18;
1328
1339
  break;
1329
1340
  }
1330
1341
 
@@ -1332,9 +1343,9 @@ var CozyClient = /*#__PURE__*/function () {
1332
1343
  return (0, _jsonStableStringify.default)(queryDefinition);
1333
1344
  }));
1334
1345
 
1335
- case 17:
1346
+ case 18:
1336
1347
  this.ensureQueryExists(queryId, queryDefinition, options);
1337
- _context8.prev = 18;
1348
+ _context8.prev = 19;
1338
1349
  backgroundFetching = options.backgroundFetching !== undefined ? options.backgroundFetching : this.options.backgroundFetching;
1339
1350
  this.dispatch((0, _store.loadQuery)(queryId, {
1340
1351
  backgroundFetching: backgroundFetching
@@ -1344,53 +1355,63 @@ var CozyClient = /*#__PURE__*/function () {
1344
1355
  } : function () {
1345
1356
  return _this4.requestQuery(queryDefinition);
1346
1357
  };
1347
- _context8.next = 24;
1358
+ _context8.next = 25;
1348
1359
  return this._promiseCache.exec(requestFn, function () {
1349
1360
  return (0, _jsonStableStringify.default)(queryDefinition);
1350
1361
  });
1351
1362
 
1352
- case 24:
1363
+ case 25:
1353
1364
  response = _context8.sent;
1354
1365
  this.dispatch((0, _store.receiveQueryResult)(queryId, response, {
1355
1366
  update: update,
1356
1367
  backgroundFetching: backgroundFetching
1357
1368
  }));
1369
+ this.performanceApi.measure({
1370
+ markName: markQuery,
1371
+ measureName: "".concat(markQuery, " success"),
1372
+ color: 'primary'
1373
+ });
1358
1374
  return _context8.abrupt("return", response);
1359
1375
 
1360
- case 29:
1361
- _context8.prev = 29;
1362
- _context8.t0 = _context8["catch"](18);
1376
+ case 31:
1377
+ _context8.prev = 31;
1378
+ _context8.t0 = _context8["catch"](19);
1379
+ this.performanceApi.measure({
1380
+ markName: markQuery,
1381
+ measureName: "".concat(markQuery, " error"),
1382
+ color: 'error'
1383
+ });
1363
1384
  this.dispatch((0, _store.receiveQueryError)(queryId, _context8.t0)); // specific onError
1364
1385
 
1365
1386
  if (!options.onError) {
1366
- _context8.next = 36;
1387
+ _context8.next = 39;
1367
1388
  break;
1368
1389
  }
1369
1390
 
1370
1391
  options.onError(_context8.t0); // defaulted onError
1371
1392
 
1372
- _context8.next = 41;
1393
+ _context8.next = 44;
1373
1394
  break;
1374
1395
 
1375
- case 36:
1396
+ case 39:
1376
1397
  if (!this.options.onError) {
1377
- _context8.next = 40;
1398
+ _context8.next = 43;
1378
1399
  break;
1379
1400
  }
1380
1401
 
1381
1402
  this.options.onError(_context8.t0);
1382
- _context8.next = 41;
1403
+ _context8.next = 44;
1383
1404
  break;
1384
1405
 
1385
- case 40:
1406
+ case 43:
1386
1407
  throw _context8.t0;
1387
1408
 
1388
- case 41:
1409
+ case 44:
1389
1410
  case "end":
1390
1411
  return _context8.stop();
1391
1412
  }
1392
1413
  }
1393
- }, _callee8, this, [[18, 29]]);
1414
+ }, _callee8, this, [[19, 31]]);
1394
1415
  }));
1395
1416
 
1396
1417
  function query(_x9) {
@@ -2420,7 +2441,7 @@ var CozyClient = /*#__PURE__*/function () {
2420
2441
  key: "ensureStore",
2421
2442
  value: function ensureStore() {
2422
2443
  if (!this.store) {
2423
- this.setStore((0, _store.createStore)());
2444
+ this.setStore((0, _store.createStore)(this.performanceApi));
2424
2445
  }
2425
2446
  }
2426
2447
  /**
@@ -2552,7 +2573,7 @@ var CozyClient = /*#__PURE__*/function () {
2552
2573
  }, {
2553
2574
  key: "reducer",
2554
2575
  value: function reducer() {
2555
- return _store.default;
2576
+ return (0, _store.default)(this.performanceApi);
2556
2577
  }
2557
2578
  }, {
2558
2579
  key: "dispatch",
@@ -2708,7 +2729,9 @@ var CozyClient = /*#__PURE__*/function () {
2708
2729
  }, {
2709
2730
  key: "setLinks",
2710
2731
  value: function setLinks(links) {
2711
- this.links = links ? links : [new _StackLink.default()];
2732
+ this.links = links ? links : [new _StackLink.default({
2733
+ performanceApi: this.performanceApi
2734
+ })];
2712
2735
  this.registerClientOnLinks();
2713
2736
  this.chain = (0, _CozyLink.chain)(this.links);
2714
2737
 
@@ -3026,7 +3049,7 @@ var CozyClient = /*#__PURE__*/function () {
3026
3049
  CozyClient.hooks = CozyClient.hooks || {};
3027
3050
  CozyClient.fetchPolicies = _policies.default; //COZY_CLIENT_VERSION_PACKAGE in replaced by babel. See babel config
3028
3051
 
3029
- CozyClient.version = "51.6.1";
3052
+ CozyClient.version = "51.7.0";
3030
3053
 
3031
3054
  _microee.default.mixin(CozyClient);
3032
3055
 
package/dist/StackLink.js CHANGED
@@ -39,6 +39,8 @@ var _logger = _interopRequireDefault(require("./logger"));
39
39
 
40
40
  var _utils = require("./utils");
41
41
 
42
+ var _defaultPerformanceApi = require("./performances/defaultPerformanceApi");
43
+
42
44
  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); }; }
43
45
 
44
46
  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; } }
@@ -99,6 +101,7 @@ var transformBulkDocsResponse = function transformBulkDocsResponse(bulkResponse,
99
101
  * @property {object} [stackClient] - A StackClient
100
102
  * @property {object} [client] - A StackClient (deprecated)
101
103
  * @property {import('cozy-pouch-link/dist/types').LinkPlatform} [platform] - Platform specific adapters and methods
104
+ * @property {import('./performances/types').PerformanceAPI} [performanceApi] - The performance API that can be used to measure performances
102
105
  */
103
106
 
104
107
  /**
@@ -122,7 +125,8 @@ var StackLink = /*#__PURE__*/function (_CozyLink) {
122
125
  var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
123
126
  client = _ref.client,
124
127
  stackClient = _ref.stackClient,
125
- platform = _ref.platform;
128
+ platform = _ref.platform,
129
+ performanceApi = _ref.performanceApi;
126
130
 
127
131
  (0, _classCallCheck2.default)(this, StackLink);
128
132
  _this = _super.call(this);
@@ -133,6 +137,9 @@ var StackLink = /*#__PURE__*/function (_CozyLink) {
133
137
 
134
138
  _this.stackClient = stackClient || client;
135
139
  _this.isOnline = platform === null || platform === void 0 ? void 0 : platform.isOnline;
140
+ /** @type {import('./performances/types').PerformanceAPI} */
141
+
142
+ _this.performanceApi = performanceApi || _defaultPerformanceApi.defaultPerformanceApi;
136
143
  return _this;
137
144
  }
138
145
 
@@ -1,5 +1,6 @@
1
1
  import CozyClient from './CozyClient'
2
2
  import CozyLink from './CozyLink'
3
+ import { defaultPerformanceApi } from './performances/defaultPerformanceApi'
3
4
  import { createStore, getQueryFromStore } from './store'
4
5
  import { receiveQueryResult, initQuery } from './store/queries'
5
6
 
@@ -21,7 +22,7 @@ describe('Associations', () => {
21
22
  .shift()
22
23
 
23
24
  beforeEach(async () => {
24
- const store = createStore()
25
+ const store = createStore(defaultPerformanceApi)
25
26
  client.setStore(store, { force: true })
26
27
  await store.dispatch(initQuery('allTodos', { doctype: 'io.cozy.todos' }))
27
28
  await store.dispatch(
package/dist/index.js CHANGED
@@ -58,7 +58,9 @@ var _exportNames = {
58
58
  withClient: true,
59
59
  models: true,
60
60
  fetchPolicies: true,
61
- BulkEditError: true
61
+ BulkEditError: true,
62
+ webPerformanceApi: true,
63
+ defaultPerformanceApi: true
62
64
  };
63
65
  Object.defineProperty(exports, "default", {
64
66
  enumerable: true,
@@ -360,6 +362,18 @@ Object.defineProperty(exports, "BulkEditError", {
360
362
  return _errors.BulkEditError;
361
363
  }
362
364
  });
365
+ Object.defineProperty(exports, "webPerformanceApi", {
366
+ enumerable: true,
367
+ get: function get() {
368
+ return _webPerformanceApi.webPerformanceApi;
369
+ }
370
+ });
371
+ Object.defineProperty(exports, "defaultPerformanceApi", {
372
+ enumerable: true,
373
+ get: function get() {
374
+ return _defaultPerformanceApi.defaultPerformanceApi;
375
+ }
376
+ });
363
377
  exports.models = exports.manifest = void 0;
364
378
 
365
379
  var _CozyClient = _interopRequireDefault(require("./CozyClient"));
@@ -436,4 +450,8 @@ Object.keys(_hooks).forEach(function (key) {
436
450
  });
437
451
  });
438
452
 
439
- var _errors = require("./errors");
453
+ var _errors = require("./errors");
454
+
455
+ var _webPerformanceApi = require("./performances/webPerformanceApi");
456
+
457
+ var _defaultPerformanceApi = require("./performances/defaultPerformanceApi");
@@ -38,7 +38,9 @@ var _exportNames = {
38
38
  manifest: true,
39
39
  BulkEditError: true,
40
40
  models: true,
41
- fetchPolicies: true
41
+ fetchPolicies: true,
42
+ webPerformanceApi: true,
43
+ defaultPerformanceApi: true
42
44
  };
43
45
  Object.defineProperty(exports, "default", {
44
46
  enumerable: true,
@@ -220,6 +222,18 @@ Object.defineProperty(exports, "fetchPolicies", {
220
222
  return _policies.default;
221
223
  }
222
224
  });
225
+ Object.defineProperty(exports, "webPerformanceApi", {
226
+ enumerable: true,
227
+ get: function get() {
228
+ return _webPerformanceApi.webPerformanceApi;
229
+ }
230
+ });
231
+ Object.defineProperty(exports, "defaultPerformanceApi", {
232
+ enumerable: true,
233
+ get: function get() {
234
+ return _defaultPerformanceApi.defaultPerformanceApi;
235
+ }
236
+ });
223
237
  exports.models = exports.manifest = void 0;
224
238
 
225
239
  var _CozyClient = _interopRequireDefault(require("./CozyClient"));
@@ -282,4 +296,8 @@ var models = _interopRequireWildcard(require("./models"));
282
296
 
283
297
  exports.models = models;
284
298
 
285
- var _policies = _interopRequireDefault(require("./policies"));
299
+ var _policies = _interopRequireDefault(require("./policies"));
300
+
301
+ var _webPerformanceApi = require("./performances/webPerformanceApi");
302
+
303
+ var _defaultPerformanceApi = require("./performances/defaultPerformanceApi");
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.defaultPerformanceApi = void 0;
7
+
8
+ /** @type {import('./types').PerformanceAPI} */
9
+ var defaultPerformanceApi = {
10
+ measure: function measure(options) {},
11
+ mark: function mark(markName) {
12
+ return markName;
13
+ }
14
+ };
15
+ exports.defaultPerformanceApi = defaultPerformanceApi;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ /**
9
+ * @typedef {'primary' | 'primary-light' | 'primary-dark' | 'secondary' | 'secondary-light' | 'secondary-dark' | 'tertiary' | 'tertiary-light' | 'tertiary-dark' | 'error'} MeasureColor
10
+ */
11
+
12
+ /**
13
+ * @typedef {object} MeasureOptions
14
+ * @property {string} markName - Mark name used as the start point for performance measurement
15
+ * @property {string} [measureName] - Measure name that will be displayed in the performance graph. If not provided, markName will be used by default
16
+ * @property {string} [category] - Category where the measure will be displayed int he performance graph
17
+ * @property {MeasureColor} [color] - Category where the measure will be displayed int he performance graph
18
+ */
19
+
20
+ /**
21
+ * @typedef {object} PerformanceAPI
22
+ * @property {function(MeasureOptions): void} measure
23
+ * @property {function(string): string} mark
24
+ */
25
+ var _default = {};
26
+ exports.default = _default;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.webPerformanceApi = void 0;
9
+
10
+ var _uniqueId = _interopRequireDefault(require("lodash/uniqueId"));
11
+
12
+ /**
13
+ * Measure performances since the given markName
14
+ *
15
+ * @param {import('./types').MeasureOptions} options - Options for the measurement
16
+ */
17
+ var measure = function measure(_ref) {
18
+ var measureName = _ref.measureName,
19
+ markName = _ref.markName,
20
+ category = _ref.category,
21
+ color = _ref.color;
22
+ var name = measureName !== null && measureName !== void 0 ? measureName : markName; // @ts-ignore
23
+
24
+ performance.measure(name, {
25
+ start: markName,
26
+ detail: {
27
+ devtools: {
28
+ track: category !== null && category !== void 0 ? category : 'CozyClient',
29
+ color: color !== null && color !== void 0 ? color : 'secondary'
30
+ }
31
+ }
32
+ });
33
+ };
34
+ /**
35
+ * Set a mark with the given name
36
+ *
37
+ * In order to ensure uniqueness of mark names,
38
+ * the given markName is prefixed with a unique id
39
+ *
40
+ * This method returns the computed mark name containing
41
+ * the unique id. This new ID should be used when
42
+ * calling `measure()`
43
+ *
44
+ * @param {string} markName - the name of the mark
45
+ */
46
+
47
+
48
+ var mark = function mark(markName) {
49
+ var uniqMarkName = "".concat((0, _uniqueId.default)(), " ").concat(markName);
50
+ performance.mark(uniqMarkName);
51
+ return uniqMarkName;
52
+ };
53
+ /** @type {import('./types').PerformanceAPI} */
54
+
55
+
56
+ var webPerformanceApi = {
57
+ measure: measure,
58
+ mark: mark
59
+ };
60
+ exports.webPerformanceApi = webPerformanceApi;
@@ -199,32 +199,57 @@ var initialState = {
199
199
  queries: {}
200
200
  };
201
201
 
202
- var combinedReducer = function combinedReducer() {
203
- var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
204
- var action = arguments.length > 1 ? arguments[1] : undefined;
202
+ var combinedReducer = function combinedReducer(performanceApi) {
203
+ return function () {
204
+ var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
205
+ var action = arguments.length > 1 ? arguments[1] : undefined;
206
+ var markName = performanceApi.mark('combinedReducer');
205
207
 
206
- if (action.type == RESET_ACTION_TYPE) {
207
- return initialState;
208
- }
208
+ if (action.type == RESET_ACTION_TYPE) {
209
+ performanceApi.measure({
210
+ markName: markName,
211
+ measureName: "".concat(markName, " reset"),
212
+ category: 'CozyClientStore'
213
+ });
214
+ return initialState;
215
+ }
209
216
 
210
- if (!(0, _queries.isQueryAction)(action) && !(0, _mutations.isMutationAction)(action)) {
211
- return state;
212
- }
217
+ if (!(0, _queries.isQueryAction)(action) && !(0, _mutations.isMutationAction)(action)) {
218
+ performanceApi.measure({
219
+ markName: markName,
220
+ measureName: "".concat(markName, " no query nor mutate action"),
221
+ category: 'CozyClientStore'
222
+ });
223
+ return state;
224
+ }
213
225
 
214
- if (action.update) {
215
- var proxy = new StoreProxy(state);
216
- action.update(proxy, action.response);
217
- return {
218
- documents: proxy.getState().documents,
219
- queries: (0, _queries.default)(proxy.getState().queries, action, proxy.getState().documents)
220
- };
221
- }
226
+ if (action.update) {
227
+ var proxy = new StoreProxy(state);
228
+ action.update(proxy, action.response);
229
+ var newState = {
230
+ documents: proxy.getState().documents,
231
+ queries: (0, _queries.default)(performanceApi, proxy.getState().queries, action, proxy.getState().documents)
232
+ };
233
+ performanceApi.measure({
234
+ markName: markName,
235
+ measureName: "".concat(markName, " update action"),
236
+ category: 'CozyClientStore'
237
+ });
238
+ return newState;
239
+ }
222
240
 
223
- var nextDocuments = (0, _documents.default)(state.documents, action);
224
- var haveDocumentsChanged = nextDocuments !== state.documents;
225
- return {
226
- documents: nextDocuments,
227
- queries: (0, _queries.default)(state.queries, action, nextDocuments, haveDocumentsChanged)
241
+ var nextDocuments = (0, _documents.default)(state.documents, action);
242
+ var haveDocumentsChanged = nextDocuments !== state.documents;
243
+ var queriesResult = {
244
+ documents: nextDocuments,
245
+ queries: (0, _queries.default)(performanceApi, state.queries, action, nextDocuments, haveDocumentsChanged)
246
+ };
247
+ performanceApi.measure({
248
+ markName: markName,
249
+ measureName: "".concat(markName, " queries"),
250
+ category: 'CozyClientStore'
251
+ });
252
+ return queriesResult;
228
253
  };
229
254
  };
230
255
 
@@ -236,9 +261,9 @@ var composedEnhancer = // @ts-ignore '__REDUX_DEVTOOLS_EXTENSION_COMPOSE__' does
236
261
  // see https://github.com/reduxjs/redux-devtools/tree/main/extension#11-basic-store
237
262
  (0, _cozyFlags.default)('debug') && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || _redux.compose;
238
263
 
239
- var createStore = function createStore() {
264
+ var createStore = function createStore(performanceApi) {
240
265
  return (0, _redux.createStore)((0, _redux.combineReducers)({
241
- cozy: combinedReducer
266
+ cozy: combinedReducer(performanceApi)
242
267
  }), composedEnhancer((0, _redux.applyMiddleware)(_reduxThunk.default)));
243
268
  };
244
269
 
@@ -167,6 +167,7 @@ var updateQueryDataFromResponse = function updateQueryDataFromResponse(queryStat
167
167
  /**
168
168
  * Reducer for a query slice
169
169
  *
170
+ * @param {import('../performances/types').PerformanceAPI} performanceApi - The performance API that can be used to measure performances
170
171
  * @param {import("../types").QueryState} state - Current state
171
172
  * @param {any} action - Redux action
172
173
  * @param {import("../types").DocumentsStateSlice} documents - Reference to the next documents slice
@@ -174,10 +175,10 @@ var updateQueryDataFromResponse = function updateQueryDataFromResponse(queryStat
174
175
  */
175
176
 
176
177
 
177
- var query = function query() {
178
- var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : queryInitialState;
179
- var action = arguments.length > 1 ? arguments[1] : undefined;
180
- var documents = arguments.length > 2 ? arguments[2] : undefined;
178
+ var query = function query(performanceApi) {
179
+ var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : queryInitialState;
180
+ var action = arguments.length > 2 ? arguments[2] : undefined;
181
+ var documents = arguments.length > 3 ? arguments[3] : undefined;
181
182
 
182
183
  switch (action.type) {
183
184
  case INIT_QUERY:
@@ -210,11 +211,17 @@ var query = function query() {
210
211
 
211
212
  case RECEIVE_QUERY_RESULT:
212
213
  {
214
+ var markName = performanceApi.mark('RECEIVE_QUERY_RESULT');
213
215
  var response = action.response; // Data can be null when we get a 404 not found
214
216
  // see Collection.get()
215
217
  // but we still need to update the fetchStatus.
216
218
 
217
219
  if (!response.data) {
220
+ performanceApi.measure({
221
+ markName: markName,
222
+ measureName: "".concat(markName, " with no data"),
223
+ category: 'CozyClientStore'
224
+ });
218
225
  return _objectSpread(_objectSpread({}, state), {}, {
219
226
  fetchStatus: 'loaded',
220
227
  isFetching: action.backgroundFetching ? false : null,
@@ -235,6 +242,11 @@ var query = function query() {
235
242
  });
236
243
 
237
244
  if (!Array.isArray(response.data)) {
245
+ performanceApi.measure({
246
+ markName: markName,
247
+ measureName: "".concat(markName, " with object"),
248
+ category: 'CozyClientStore'
249
+ });
238
250
  return _objectSpread(_objectSpread(_objectSpread({}, state), common), {}, {
239
251
  hasMore: false,
240
252
  count: 1,
@@ -245,6 +257,11 @@ var query = function query() {
245
257
  var count = response.meta && response.meta.count ? response.meta.count : response.data.length;
246
258
 
247
259
  if (action.backgroundFetching) {
260
+ performanceApi.measure({
261
+ markName: markName,
262
+ measureName: "".concat(markName, " with background fetching"),
263
+ category: 'CozyClientStore'
264
+ });
248
265
  return _objectSpread(_objectSpread(_objectSpread({}, state), common), {}, {
249
266
  bookmark: response.bookmark || null,
250
267
  hasMore: response.next !== undefined ? response.next : state.hasMore,
@@ -258,6 +275,11 @@ var query = function query() {
258
275
  count: count,
259
276
  fetchedPagesCount: fetchedPagesCount
260
277
  });
278
+ performanceApi.measure({
279
+ markName: markName,
280
+ measureName: "".concat(markName, " default"),
281
+ category: 'CozyClientStore'
282
+ });
261
283
  return _objectSpread(_objectSpread(_objectSpread({}, state), common), {}, {
262
284
  bookmark: response.bookmark || null,
263
285
  hasMore: response.next !== undefined ? response.next : state.hasMore,
@@ -575,6 +597,7 @@ var manualQueryUpdater = function manualQueryUpdater(action, documents) {
575
597
  };
576
598
  };
577
599
  /**
600
+ * @param {import('../performances/types').PerformanceAPI} performanceApi - The performance API that can be used to measure performances
578
601
  * @param {import("../types").QueriesStateSlice} state - Redux slice containing all the query states indexed by name
579
602
  * @param {object} action - Income redux action
580
603
  * @param {import("../types").DocumentsStateSlice} documents - Reference to documents slice
@@ -583,14 +606,14 @@ var manualQueryUpdater = function manualQueryUpdater(action, documents) {
583
606
  */
584
607
 
585
608
 
586
- var queries = function queries() {
587
- var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
588
- var action = arguments.length > 1 ? arguments[1] : undefined;
589
- var documents = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
590
- var haveDocumentsChanged = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
609
+ var queries = function queries(performanceApi) {
610
+ var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
611
+ var action = arguments.length > 2 ? arguments[2] : undefined;
612
+ var documents = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
613
+ var haveDocumentsChanged = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
591
614
 
592
615
  if (action.type == INIT_QUERY) {
593
- var newQueryState = query(state[action.queryId], action, documents); // Do not create new object unnecessarily
616
+ var newQueryState = query(performanceApi, state[action.queryId], action, documents); // Do not create new object unnecessarily
594
617
 
595
618
  if (newQueryState === state[action.queryId]) {
596
619
  return state;
@@ -603,7 +626,7 @@ var queries = function queries() {
603
626
  var updater = autoQueryUpdater(action, documents);
604
627
  return (0, _mapValues.default)(state, function (queryState) {
605
628
  if (queryState.id == action.queryId) {
606
- return query(queryState, action, documents);
629
+ return query(performanceApi, queryState, action, documents);
607
630
  } else if (haveDocumentsChanged) {
608
631
  return updater(queryState);
609
632
  } else {
@@ -1,3 +1,4 @@
1
+ import { defaultPerformanceApi } from '../performances/defaultPerformanceApi'
1
2
  import queries, {
2
3
  initQuery,
3
4
  receiveQueryResult,
@@ -19,7 +20,7 @@ describe('queries reducer', () => {
19
20
  data: [TODO_1, TODO_2]
20
21
  }
21
22
  const applyAction = action => {
22
- state = queries(state, action)
23
+ state = queries(defaultPerformanceApi, state, action)
23
24
  }
24
25
  beforeEach(() => {
25
26
  state = {}
@@ -1,6 +1,7 @@
1
1
  import { createStore, combineReducers } from 'redux'
2
2
  import sortBy from 'lodash/sortBy'
3
3
 
4
+ import { defaultPerformanceApi } from './performances/defaultPerformanceApi'
4
5
  import reducer, {
5
6
  initQuery,
6
7
  getCollectionFromState,
@@ -25,7 +26,9 @@ import {
25
26
  describe('Store', () => {
26
27
  let store
27
28
  beforeEach(() => {
28
- store = createStore(combineReducers({ cozy: reducer }))
29
+ store = createStore(
30
+ combineReducers({ cozy: reducer(defaultPerformanceApi) })
31
+ )
29
32
  })
30
33
 
31
34
  describe('documents state', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-client",
3
- "version": "51.6.1",
3
+ "version": "51.7.0",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.node.js",
6
6
  "browser": "dist/index.js",
@@ -72,5 +72,5 @@
72
72
  "react-native-ios11-devicecheck": "https://github.com/cozy/react-native-devicecheck#app-attest-v0.1"
73
73
  },
74
74
  "sideEffects": false,
75
- "gitHead": "b46c9c9248b140429972790624fa46b1b547226f"
75
+ "gitHead": "86418c696e22dcf873aa9d84ed195253ec058783"
76
76
  }
@@ -76,6 +76,10 @@ export type ClientOptions = {
76
76
  * - If set to false, the client will not instantiate a Redux store automatically. Use this if you want to merge cozy-client's store with your own redux store. See [here](https://docs.cozy.io/en/cozy-client/react-integration/#1b-use-your-own-redux-store) for more information.
77
77
  */
78
78
  store?: boolean;
79
+ /**
80
+ * - The performance API that can be used to measure performances
81
+ */
82
+ performanceApi?: import('./performances/types').PerformanceAPI;
79
83
  };
80
84
  /**
81
85
  * @typedef {import("./types").CozyClientDocument} CozyClientDocument
@@ -99,6 +103,7 @@ export type ClientOptions = {
99
103
  * @property {import("./types").AppMetadata} [appMetadata] - Metadata about the application that will be used in ensureCozyMetadata
100
104
  * @property {import("./types").ClientCapabilities} [capabilities] - Capabilities sent by the stack
101
105
  * @property {boolean} [store] - If set to false, the client will not instantiate a Redux store automatically. Use this if you want to merge cozy-client's store with your own redux store. See [here](https://docs.cozy.io/en/cozy-client/react-integration/#1b-use-your-own-redux-store) for more information.
106
+ * @property {import('./performances/types').PerformanceAPI} [performanceApi] - The performance API that can be used to measure performances
102
107
  */
103
108
  /**
104
109
  * Responsible for
@@ -189,6 +194,8 @@ declare class CozyClient {
189
194
  * Cozy-Client will automatically call `this.login()` if provided with a token and an uri
190
195
  */
191
196
  constructor(rawOptions?: ClientOptions);
197
+ /** @type {import('./performances/types').PerformanceAPI} */
198
+ performanceApi: import('./performances/types').PerformanceAPI;
192
199
  appMetadata: import("./types").AppMetadata;
193
200
  loginPromise: Promise<void>;
194
201
  options: {
@@ -6,6 +6,7 @@ export function transformBulkDocsResponse(bulkResponse: import("./types").CouchD
6
6
  * @property {object} [stackClient] - A StackClient
7
7
  * @property {object} [client] - A StackClient (deprecated)
8
8
  * @property {import('cozy-pouch-link/dist/types').LinkPlatform} [platform] - Platform specific adapters and methods
9
+ * @property {import('./performances/types').PerformanceAPI} [performanceApi] - The performance API that can be used to measure performances
9
10
  */
10
11
  /**
11
12
  * Transfers queries and mutations to a remote stack
@@ -14,9 +15,11 @@ export default class StackLink extends CozyLink {
14
15
  /**
15
16
  * @param {StackLinkOptions} [options] - Options
16
17
  */
17
- constructor({ client, stackClient, platform }?: StackLinkOptions);
18
+ constructor({ client, stackClient, platform, performanceApi }?: StackLinkOptions);
18
19
  stackClient: any;
19
20
  isOnline: any;
21
+ /** @type {import('./performances/types').PerformanceAPI} */
22
+ performanceApi: import('./performances/types').PerformanceAPI;
20
23
  registerClient(client: any): void;
21
24
  /**
22
25
  *
@@ -39,6 +42,10 @@ export type StackLinkOptions = {
39
42
  * - Platform specific adapters and methods
40
43
  */
41
44
  platform?: any;
45
+ /**
46
+ * - The performance API that can be used to measure performances
47
+ */
48
+ performanceApi?: import('./performances/types').PerformanceAPI;
42
49
  };
43
50
  import CozyLink from "./CozyLink";
44
51
  import { QueryDefinition } from "./queries/dsl";
package/types/index.d.ts CHANGED
@@ -13,6 +13,8 @@ export { default as fetchPolicies } from "./policies";
13
13
  export * from "./mock";
14
14
  export * from "./hooks";
15
15
  export { BulkEditError } from "./errors";
16
+ export { webPerformanceApi } from "./performances/webPerformanceApi";
17
+ export { defaultPerformanceApi } from "./performances/defaultPerformanceApi";
16
18
  import * as manifest from "./models/manifest";
17
19
  import * as models from "./models";
18
20
  export { manifest, models };
@@ -10,6 +10,8 @@ export * from "./mock";
10
10
  export * from "./cli";
11
11
  export { BulkEditError } from "./errors";
12
12
  export { default as fetchPolicies } from "./policies";
13
+ export { webPerformanceApi } from "./performances/webPerformanceApi";
14
+ export { defaultPerformanceApi } from "./performances/defaultPerformanceApi";
13
15
  import * as manifest from "./models/manifest";
14
16
  import * as models from "./models";
15
17
  export { manifest, models };
@@ -0,0 +1,2 @@
1
+ /** @type {import('./types').PerformanceAPI} */
2
+ export const defaultPerformanceApi: import('./types').PerformanceAPI;
@@ -0,0 +1,25 @@
1
+ declare var _default: {};
2
+ export default _default;
3
+ export type MeasureColor = "error" | "primary" | "primary-light" | "primary-dark" | "secondary" | "secondary-light" | "secondary-dark" | "tertiary" | "tertiary-light" | "tertiary-dark";
4
+ export type MeasureOptions = {
5
+ /**
6
+ * - Mark name used as the start point for performance measurement
7
+ */
8
+ markName: string;
9
+ /**
10
+ * - Measure name that will be displayed in the performance graph. If not provided, markName will be used by default
11
+ */
12
+ measureName?: string;
13
+ /**
14
+ * - Category where the measure will be displayed int he performance graph
15
+ */
16
+ category?: string;
17
+ /**
18
+ * - Category where the measure will be displayed int he performance graph
19
+ */
20
+ color?: MeasureColor;
21
+ };
22
+ export type PerformanceAPI = {
23
+ measure: (arg0: MeasureOptions) => void;
24
+ mark: (arg0: string) => string;
25
+ };
@@ -0,0 +1,2 @@
1
+ /** @type {import('./types').PerformanceAPI} */
2
+ export const webPerformanceApi: import('./types').PerformanceAPI;
@@ -7,11 +7,11 @@ export class StoreProxy {
7
7
  getState(): any;
8
8
  }
9
9
  export default combinedReducer;
10
- export function createStore(): any;
11
- declare function combinedReducer(state: {
10
+ export function createStore(performanceApi: any): any;
11
+ declare function combinedReducer(performanceApi: any): (state: {
12
12
  documents: {};
13
13
  queries: {};
14
- }, action: any): {
14
+ }, action: any) => {
15
15
  documents: any;
16
16
  queries: Record<string, import("../types").QueryState>;
17
17
  };
@@ -39,10 +39,11 @@ export namespace QueryIDGenerator {
39
39
  }
40
40
  import { QueryDefinition } from "../queries/dsl";
41
41
  /**
42
+ * @param {import('../performances/types').PerformanceAPI} performanceApi - The performance API that can be used to measure performances
42
43
  * @param {import("../types").QueriesStateSlice} state - Redux slice containing all the query states indexed by name
43
44
  * @param {object} action - Income redux action
44
45
  * @param {import("../types").DocumentsStateSlice} documents - Reference to documents slice
45
46
  * @param {boolean} haveDocumentsChanged - Has the document slice changed with current action
46
47
  * @returns {import("../types").QueriesStateSlice}
47
48
  */
48
- declare function queries(state: import("../types").QueriesStateSlice, action: object, documents?: import("../types").DocumentsStateSlice, haveDocumentsChanged?: boolean): import("../types").QueriesStateSlice;
49
+ declare function queries(performanceApi: import('../performances/types').PerformanceAPI, state: import("../types").QueriesStateSlice, action: object, documents?: import("../types").DocumentsStateSlice, haveDocumentsChanged?: boolean): import("../types").QueriesStateSlice;