diff --git a/docs/api/cozy-client/README.md b/docs/api/cozy-client/README.md index 93ceffd7cb..cc9e56e223 100644 --- a/docs/api/cozy-client/README.md +++ b/docs/api/cozy-client/README.md @@ -956,7 +956,7 @@ Retrieve intance info like context, uuid, disk usage etc *Defined in* -[packages/cozy-client/src/hooks/useQuery.js:93](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/hooks/useQuery.js#L93) +[packages/cozy-client/src/hooks/useQuery.js:94](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/hooks/useQuery.js#L94) *** @@ -979,7 +979,7 @@ Fetches a queryDefinition and returns the queryState *Defined in* -[packages/cozy-client/src/hooks/useQuery.js:28](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/hooks/useQuery.js#L28) +[packages/cozy-client/src/hooks/useQuery.js:29](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/hooks/useQuery.js#L29) *** diff --git a/docs/api/cozy-client/classes/CozyClient.md b/docs/api/cozy-client/classes/CozyClient.md index 5bca19802a..ac16246cfd 100644 --- a/docs/api/cozy-client/classes/CozyClient.md +++ b/docs/api/cozy-client/classes/CozyClient.md @@ -43,7 +43,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:155](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L155) +[packages/cozy-client/src/CozyClient.js:156](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L156) ## Properties @@ -53,7 +53,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:168](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L168) +[packages/cozy-client/src/CozyClient.js:169](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L169) *** @@ -63,7 +63,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:192](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L192) +[packages/cozy-client/src/CozyClient.js:193](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L193) *** @@ -73,7 +73,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:1834](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1834) +[packages/cozy-client/src/CozyClient.js:1853](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1853) *** @@ -83,7 +83,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:1696](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1696) +[packages/cozy-client/src/CozyClient.js:1715](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1715) *** @@ -93,7 +93,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:176](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L176) +[packages/cozy-client/src/CozyClient.js:177](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L177) *** @@ -103,7 +103,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:175](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L175) +[packages/cozy-client/src/CozyClient.js:176](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L176) *** @@ -113,7 +113,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:486](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L486) +[packages/cozy-client/src/CozyClient.js:487](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L487) *** @@ -123,7 +123,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:1832](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1832) +[packages/cozy-client/src/CozyClient.js:1851](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1851) *** @@ -133,7 +133,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:169](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L169) +[packages/cozy-client/src/CozyClient.js:170](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L170) *** @@ -148,6 +148,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and | `autoHydrate` | `boolean` | - | | `backgroundFetching` | `boolean` | If set to true, backgroundFetching will be enabled by default on every query. Meaning that, when the fetchStatus has already been loaded, it won't be updated during future fetches. Instead, a `isFetching` attribute will be used to indicate when background fetching is started. | | `client` | `any` | - | +| `forceHydratation` | `boolean` | If set to true, all documents will be hydrated w.r.t. the provided schema's relationships, even if the relationship does not exist on the doc. | | `oauth` | `any` | - | | `onError` | `Function` | Default callback if a query is errored | | `onTokenRefresh` | `Function` | - | @@ -159,7 +160,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:172](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L172) +[packages/cozy-client/src/CozyClient.js:173](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L173) *** @@ -169,7 +170,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:195](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L195) +[packages/cozy-client/src/CozyClient.js:196](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L196) *** @@ -179,7 +180,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:174](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L174) +[packages/cozy-client/src/CozyClient.js:175](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L175) *** @@ -189,7 +190,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:187](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L187) +[packages/cozy-client/src/CozyClient.js:188](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L188) *** @@ -199,7 +200,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:1671](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1671) +[packages/cozy-client/src/CozyClient.js:1690](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1690) *** @@ -209,7 +210,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:1601](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1601) +[packages/cozy-client/src/CozyClient.js:1620](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1620) *** @@ -219,7 +220,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:220](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L220) +[packages/cozy-client/src/CozyClient.js:221](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L221) *** @@ -239,7 +240,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:1354](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1354) +[packages/cozy-client/src/CozyClient.js:1357](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1357) *** @@ -284,7 +285,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:465](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L465) +[packages/cozy-client/src/CozyClient.js:466](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L466) *** @@ -304,7 +305,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:421](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L421) +[packages/cozy-client/src/CozyClient.js:422](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L422) *** @@ -324,7 +325,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:566](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L566) +[packages/cozy-client/src/CozyClient.js:567](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L567) *** @@ -353,7 +354,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:1517](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1517) +[packages/cozy-client/src/CozyClient.js:1536](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1536) *** @@ -371,7 +372,7 @@ This mechanism is described in https://github.com/cozy/cozy-client/blob/master/p *Defined in* -[packages/cozy-client/src/CozyClient.js:1498](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1498) +[packages/cozy-client/src/CozyClient.js:1517](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1517) *** @@ -387,7 +388,7 @@ Returns whether the client has been revoked on the server *Defined in* -[packages/cozy-client/src/CozyClient.js:1613](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1613) +[packages/cozy-client/src/CozyClient.js:1632](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1632) *** @@ -412,7 +413,7 @@ Collection corresponding to the doctype *Defined in* -[packages/cozy-client/src/CozyClient.js:558](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L558) +[packages/cozy-client/src/CozyClient.js:559](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L559) *** @@ -450,7 +451,7 @@ await client.create('io.cozy.todos', { *Defined in* -[packages/cozy-client/src/CozyClient.js:613](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L613) +[packages/cozy-client/src/CozyClient.js:614](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L614) *** @@ -471,7 +472,7 @@ If `oauth` options are passed, stackClient is an OAuthStackClient. *Defined in* -[packages/cozy-client/src/CozyClient.js:1651](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1651) +[packages/cozy-client/src/CozyClient.js:1670](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1670) *** @@ -496,7 +497,7 @@ The document that has been deleted *Defined in* -[packages/cozy-client/src/CozyClient.js:869](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L869) +[packages/cozy-client/src/CozyClient.js:870](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L870) *** @@ -516,7 +517,7 @@ The document that has been deleted *Defined in* -[packages/cozy-client/src/CozyClient.js:1722](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1722) +[packages/cozy-client/src/CozyClient.js:1741](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1741) *** @@ -542,7 +543,7 @@ a method from cozy-client *Defined in* -[packages/cozy-client/src/CozyClient.js:234](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L234) +[packages/cozy-client/src/CozyClient.js:235](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L235) *** @@ -564,7 +565,7 @@ a method from cozy-client *Defined in* -[packages/cozy-client/src/CozyClient.js:683](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L683) +[packages/cozy-client/src/CozyClient.js:684](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L684) *** @@ -588,7 +589,7 @@ Makes sure that the query exists in the store *Defined in* -[packages/cozy-client/src/CozyClient.js:890](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L890) +[packages/cozy-client/src/CozyClient.js:891](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L891) *** @@ -602,7 +603,7 @@ Makes sure that the query exists in the store *Defined in* -[packages/cozy-client/src/CozyClient.js:1604](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1604) +[packages/cozy-client/src/CozyClient.js:1623](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1623) *** @@ -625,7 +626,7 @@ Makes sure that the query exists in the store *Defined in* -[packages/cozy-client/src/CozyClient.js:562](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L562) +[packages/cozy-client/src/CozyClient.js:563](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L563) *** @@ -654,7 +655,7 @@ Query state *Defined in* -[packages/cozy-client/src/CozyClient.js:1451](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1451) +[packages/cozy-client/src/CozyClient.js:1470](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1470) *** @@ -675,7 +676,7 @@ Query state *Defined in* -[packages/cozy-client/src/CozyClient.js:575](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L575) +[packages/cozy-client/src/CozyClient.js:576](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L576) *** @@ -689,7 +690,7 @@ Query state *Defined in* -[packages/cozy-client/src/CozyClient.js:1329](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1329) +[packages/cozy-client/src/CozyClient.js:1332](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1332) *** @@ -710,7 +711,7 @@ Query state *Defined in* -[packages/cozy-client/src/CozyClient.js:582](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L582) +[packages/cozy-client/src/CozyClient.js:583](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L583) *** @@ -733,7 +734,7 @@ Creates an association that is linked to the store. *Defined in* -[packages/cozy-client/src/CozyClient.js:1336](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1336) +[packages/cozy-client/src/CozyClient.js:1339](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1339) *** @@ -747,7 +748,7 @@ Creates an association that is linked to the store. *Defined in* -[packages/cozy-client/src/CozyClient.js:1704](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1704) +[packages/cozy-client/src/CozyClient.js:1723](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1723) *** @@ -771,7 +772,7 @@ Array of documents or null if the collection does not exist. *Defined in* -[packages/cozy-client/src/CozyClient.js:1372](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1372) +[packages/cozy-client/src/CozyClient.js:1375](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1375) *** @@ -796,7 +797,7 @@ Document or null if the object does not exist. *Defined in* -[packages/cozy-client/src/CozyClient.js:1389](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1389) +[packages/cozy-client/src/CozyClient.js:1392](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1392) *** @@ -831,7 +832,7 @@ One or more mutation to execute *Defined in* -[packages/cozy-client/src/CozyClient.js:782](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L782) +[packages/cozy-client/src/CozyClient.js:783](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L783) *** @@ -851,7 +852,7 @@ One or more mutation to execute *Defined in* -[packages/cozy-client/src/CozyClient.js:1256](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1256) +[packages/cozy-client/src/CozyClient.js:1257](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1257) *** @@ -867,7 +868,7 @@ getInstanceOptions - Returns current instance options, such as domain or app slu *Defined in* -[packages/cozy-client/src/CozyClient.js:1731](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1731) +[packages/cozy-client/src/CozyClient.js:1750](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1750) *** @@ -894,7 +895,7 @@ Get a query from the internal store. *Defined in* -[packages/cozy-client/src/CozyClient.js:1410](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1410) +[packages/cozy-client/src/CozyClient.js:1413](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1413) *** @@ -923,7 +924,7 @@ the store up, which in turn will update the ``s and re-render the data. *Defined in* -[packages/cozy-client/src/CozyClient.js:1352](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1352) +[packages/cozy-client/src/CozyClient.js:1355](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1355) *** @@ -955,7 +956,7 @@ extract the value corresponding to the given `key` *Defined in* -[packages/cozy-client/src/CozyClient.js:1858](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1858) +[packages/cozy-client/src/CozyClient.js:1877](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1877) *** @@ -969,7 +970,7 @@ extract the value corresponding to the given `key` *Defined in* -[packages/cozy-client/src/CozyClient.js:1711](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1711) +[packages/cozy-client/src/CozyClient.js:1730](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1730) *** @@ -991,7 +992,7 @@ Sets public attribute and emits event related to revocation *Defined in* -[packages/cozy-client/src/CozyClient.js:1622](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1622) +[packages/cozy-client/src/CozyClient.js:1641](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1641) *** @@ -1013,7 +1014,7 @@ Emits event when token is refreshed *Defined in* -[packages/cozy-client/src/CozyClient.js:1633](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1633) +[packages/cozy-client/src/CozyClient.js:1652](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1652) *** @@ -1039,7 +1040,7 @@ the relationship *Defined in* -[packages/cozy-client/src/CozyClient.js:1299](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1299) +[packages/cozy-client/src/CozyClient.js:1300](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1300) *** @@ -1064,7 +1065,7 @@ Instead, the relationships will have null documents. *Defined in* -[packages/cozy-client/src/CozyClient.js:1276](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1276) +[packages/cozy-client/src/CozyClient.js:1277](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1277) *** @@ -1085,7 +1086,7 @@ Instead, the relationships will have null documents. *Defined in* -[packages/cozy-client/src/CozyClient.js:1310](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1310) +[packages/cozy-client/src/CozyClient.js:1311](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1311) *** @@ -1099,7 +1100,7 @@ Instead, the relationships will have null documents. *Defined in* -[packages/cozy-client/src/CozyClient.js:1474](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1474) +[packages/cozy-client/src/CozyClient.js:1493](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1493) *** @@ -1121,7 +1122,7 @@ loadInstanceOptionsFromDOM - Loads the dataset injected by the Stack in web page *Defined in* -[packages/cozy-client/src/CozyClient.js:1742](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1742) +[packages/cozy-client/src/CozyClient.js:1761](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1761) *** @@ -1139,7 +1140,7 @@ This method is not iso with loadInstanceOptionsFromDOM for now. *Defined in* -[packages/cozy-client/src/CozyClient.js:1763](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1763) +[packages/cozy-client/src/CozyClient.js:1782](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1782) *** @@ -1173,7 +1174,7 @@ Emits *Defined in* -[packages/cozy-client/src/CozyClient.js:454](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L454) +[packages/cozy-client/src/CozyClient.js:455](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L455) *** @@ -1196,7 +1197,7 @@ Emits *Defined in* -[packages/cozy-client/src/CozyClient.js:505](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L505) +[packages/cozy-client/src/CozyClient.js:506](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L506) *** @@ -1220,7 +1221,7 @@ and working. *Defined in* -[packages/cozy-client/src/CozyClient.js:1322](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1322) +[packages/cozy-client/src/CozyClient.js:1325](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1325) *** @@ -1241,7 +1242,7 @@ and working. *Defined in* -[packages/cozy-client/src/CozyClient.js:1039](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1039) +[packages/cozy-client/src/CozyClient.js:1040](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1040) *** @@ -1267,7 +1268,7 @@ Mutate a document *Defined in* -[packages/cozy-client/src/CozyClient.js:1057](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1057) +[packages/cozy-client/src/CozyClient.js:1058](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1058) *** @@ -1287,7 +1288,7 @@ Mutate a document *Defined in* -[packages/cozy-client/src/CozyClient.js:235](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L235) +[packages/cozy-client/src/CozyClient.js:236](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L236) *** @@ -1309,7 +1310,7 @@ Dehydrates and adds metadata before saving a document *Defined in* -[packages/cozy-client/src/CozyClient.js:753](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L753) +[packages/cozy-client/src/CozyClient.js:754](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L754) *** @@ -1340,7 +1341,7 @@ please use `fetchQueryAndGetFromState` instead *Defined in* -[packages/cozy-client/src/CozyClient.js:917](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L917) +[packages/cozy-client/src/CozyClient.js:918](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L918) *** @@ -1367,7 +1368,7 @@ All documents matching the query *Defined in* -[packages/cozy-client/src/CozyClient.js:999](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L999) +[packages/cozy-client/src/CozyClient.js:1000](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1000) *** @@ -1401,7 +1402,7 @@ All documents matching the query *Defined in* -[packages/cozy-client/src/CozyClient.js:1718](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1718) +[packages/cozy-client/src/CozyClient.js:1737](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1737) *** @@ -1427,7 +1428,7 @@ Contains the fetched token and the client information. *Defined in* -[packages/cozy-client/src/CozyClient.js:1468](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1468) +[packages/cozy-client/src/CozyClient.js:1487](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1487) *** @@ -1441,7 +1442,7 @@ Contains the fetched token and the client information. *Defined in* -[packages/cozy-client/src/CozyClient.js:425](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L425) +[packages/cozy-client/src/CozyClient.js:426](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L426) *** @@ -1509,7 +1510,7 @@ client.plugins.alerts *Defined in* -[packages/cozy-client/src/CozyClient.js:285](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L285) +[packages/cozy-client/src/CozyClient.js:286](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L286) *** @@ -1529,7 +1530,7 @@ client.plugins.alerts *Defined in* -[packages/cozy-client/src/CozyClient.js:236](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L236) +[packages/cozy-client/src/CozyClient.js:237](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L237) *** @@ -1548,7 +1549,7 @@ Contains the fetched token and the client information. *Defined in* -[packages/cozy-client/src/CozyClient.js:1563](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1563) +[packages/cozy-client/src/CozyClient.js:1582](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1582) *** @@ -1568,7 +1569,7 @@ Contains the fetched token and the client information. *Defined in* -[packages/cozy-client/src/CozyClient.js:1240](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1240) +[packages/cozy-client/src/CozyClient.js:1241](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1241) *** @@ -1594,7 +1595,7 @@ This method will reset the query state to its initial state and refetch it. *Defined in* -[packages/cozy-client/src/CozyClient.js:1887](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1887) +[packages/cozy-client/src/CozyClient.js:1906](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1906) *** @@ -1617,7 +1618,7 @@ Create or update a document on the server *Defined in* -[packages/cozy-client/src/CozyClient.js:635](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L635) +[packages/cozy-client/src/CozyClient.js:636](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L636) *** @@ -1652,7 +1653,7 @@ save the new resulting settings into database *Defined in* -[packages/cozy-client/src/CozyClient.js:1875](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1875) +[packages/cozy-client/src/CozyClient.js:1894](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1894) *** @@ -1681,7 +1682,7 @@ Saves multiple documents in one batch *Defined in* -[packages/cozy-client/src/CozyClient.js:656](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L656) +[packages/cozy-client/src/CozyClient.js:657](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L657) *** @@ -1701,7 +1702,7 @@ Saves multiple documents in one batch *Defined in* -[packages/cozy-client/src/CozyClient.js:1817](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1817) +[packages/cozy-client/src/CozyClient.js:1836](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1836) *** @@ -1725,7 +1726,7 @@ set some data in the store. *Defined in* -[packages/cozy-client/src/CozyClient.js:1790](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1790) +[packages/cozy-client/src/CozyClient.js:1809](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1809) *** @@ -1749,7 +1750,7 @@ we manually call the links onLogin methods *Defined in* -[packages/cozy-client/src/CozyClient.js:1831](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1831) +[packages/cozy-client/src/CozyClient.js:1850](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1850) *** @@ -1773,7 +1774,7 @@ At any time put an error function *Defined in* -[packages/cozy-client/src/CozyClient.js:1803](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1803) +[packages/cozy-client/src/CozyClient.js:1822](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1822) *** @@ -1811,7 +1812,7 @@ use options.force = true. *Defined in* -[packages/cozy-client/src/CozyClient.js:1589](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1589) +[packages/cozy-client/src/CozyClient.js:1608](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1608) *** @@ -1835,7 +1836,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:1484](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1484) +[packages/cozy-client/src/CozyClient.js:1503](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1503) *** @@ -1849,7 +1850,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:1810](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1810) +[packages/cozy-client/src/CozyClient.js:1829](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1829) *** @@ -1870,7 +1871,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:854](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L854) +[packages/cozy-client/src/CozyClient.js:855](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L855) *** @@ -1892,7 +1893,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:879](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L879) +[packages/cozy-client/src/CozyClient.js:880](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L880) *** @@ -1912,7 +1913,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:624](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L624) +[packages/cozy-client/src/CozyClient.js:625](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L625) *** @@ -1932,7 +1933,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:1032](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1032) +[packages/cozy-client/src/CozyClient.js:1033](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1033) *** @@ -1958,7 +1959,7 @@ the DOM. *Defined in* -[packages/cozy-client/src/CozyClient.js:388](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L388) +[packages/cozy-client/src/CozyClient.js:389](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L389) *** @@ -1982,7 +1983,7 @@ environment variables *Defined in* -[packages/cozy-client/src/CozyClient.js:359](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L359) +[packages/cozy-client/src/CozyClient.js:360](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L360) *** @@ -2006,7 +2007,7 @@ a client with a cookie-based instance of cozy-client-js. *Defined in* -[packages/cozy-client/src/CozyClient.js:309](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L309) +[packages/cozy-client/src/CozyClient.js:310](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L310) *** @@ -2034,7 +2035,7 @@ An instance of a client, configured from the old client *Defined in* -[packages/cozy-client/src/CozyClient.js:327](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L327) +[packages/cozy-client/src/CozyClient.js:328](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L328) *** @@ -2068,4 +2069,4 @@ There are at the moment only 2 hooks available. *Defined in* -[packages/cozy-client/src/CozyClient.js:848](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L848) +[packages/cozy-client/src/CozyClient.js:849](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L849) diff --git a/packages/cozy-client/src/CozyClient.js b/packages/cozy-client/src/CozyClient.js index febd1702bf..b348f1bc05 100644 --- a/packages/cozy-client/src/CozyClient.js +++ b/packages/cozy-client/src/CozyClient.js @@ -1424,13 +1424,29 @@ client.query(Q('io.cozy.bills'))`) return queryResults } - const data = + const hydratedData = hydrated && doctype ? this.hydrateDocuments(doctype, queryResults.data) : queryResults.data + + const relationships = this.schema.getDoctypeSchema(doctype)?.relationships + const relationshipNames = relationships + ? Object.keys(relationships) + : null + + // The `data` array contains the hydrated data with the relationships, if any. + // The `storeData` array contains the documents from the store: this is useful to preserve + // referential equality, to be later evaluated to determine whether or not the + // documents had changed. return { ...queryResults, - data: isSingleDocQuery && singleDocData ? data[0] : data + data: + isSingleDocQuery && singleDocData ? hydratedData[0] : hydratedData, + storeData: + isSingleDocQuery && singleDocData + ? queryResults.data[0] + : queryResults.data, + relationshipNames } } catch (e) { logger.warn( diff --git a/packages/cozy-client/src/hooks/useQuery.js b/packages/cozy-client/src/hooks/useQuery.js index 7bff34c242..1e104afcc9 100644 --- a/packages/cozy-client/src/hooks/useQuery.js +++ b/packages/cozy-client/src/hooks/useQuery.js @@ -5,6 +5,7 @@ import useClient from './useClient' import logger from '../logger' import { clientContext } from '../context' import { QueryDefinition } from '../queries/dsl' +import { equalityCheckForQuery } from './utils' const useSelector = createSelectorHook(clientContext) @@ -61,7 +62,7 @@ const useQuery = (queryDefinition, options) => { hydrated: get(options, 'hydrated', true), singleDocData: get(options, 'singleDocData', false) }) - }) + }, equalityCheckForQuery) useEffect( () => { diff --git a/packages/cozy-client/src/hooks/utils.js b/packages/cozy-client/src/hooks/utils.js new file mode 100644 index 0000000000..8904f6997f --- /dev/null +++ b/packages/cozy-client/src/hooks/utils.js @@ -0,0 +1,107 @@ +/** + * Equality check + * + * Note we do not make a shallow equality check on documents, as it is less efficient and should + * not be necessary: the queryResult.data is built by extracting documents from the state, thus + * preserving references. + * + * @param {import("../types").QueryStateResult} queryResA - A query result to compare + * @param {import("../types").QueryStateResult} queryResB - A query result to compare + * @returns + */ +export const equalityCheckForQuery = (queryResA, queryResB) => { + //console.log('Call equality check : ', queryResA, queryResB) + if (queryResA === queryResB) { + // Referential equality + return true + } + + if ( + typeof queryResA !== 'object' || + queryResA === null || + typeof queryResB !== 'object' || + queryResB === null + ) { + // queryResA or queryResB is not an object or null + return false + } + + if (queryResA.id !== queryResB.id) { + return false + } + if (queryResA.fetchStatus !== queryResB.fetchStatus) { + return false + } + + const docsA = queryResA.storeData + const docsB = queryResB.storeData + if (!docsA || !docsB) { + // No data to check + return false + } + if (!Array.isArray(docsA) && !Array.isArray(docsB) && docsA !== docsB) { + // Only one doc + return false + } + + if ( + Array.isArray(docsA) && + Array.isArray(docsB) && + !arraysHaveSameLength(docsA, docsB) + ) { + // A document was added or removed + return false + } + + if (Array.isArray(docsA) && Array.isArray(docsB)) { + for (let i = 0; i < docsA.length; i++) { + if (docsA[i] !== docsB[i]) { + // References should be the same for non-updated documents + return false + } + } + } + + if (queryResA.relationshipNames) { + // In case of relationships, we cannot check referential equality, because we + // "hydrate" the data by creating a new instance of the related relationship class. + // Thus, we check the document revision instead. + const hydratedDataA = queryResA.data + const hydratedDataB = queryResB.data + if (!Array.isArray(hydratedDataA) && !Array.isArray(hydratedDataB)) { + // One doc with changed relationship + return revsAreEqual(hydratedDataA, hydratedDataB) + } + if (!arraysHaveSameLength(hydratedDataA, hydratedDataB)) { + // A relationship have been added or removed + return false + } + if (Array.isArray(hydratedDataA) && Array.isArray(hydratedDataB)) { + for (let i = 0; i < hydratedDataA.length; i++) { + for (const name of queryResA.relationshipNames) { + // Check hydrated relationship + const includedA = hydratedDataA[i][name] + const includedB = hydratedDataB[i][name] + if (includedA && includedB) { + if (!revsAreEqual(includedA, includedB)) { + return false + } + } + } + } + } + } + return true +} + +const revsAreEqual = (docA, docB) => { + return docA?._rev === docB?._rev +} + +const arraysHaveSameLength = (arrayA, arrayB) => { + return ( + Array.isArray(arrayA) && + Array.isArray(arrayB) && + arrayA.length === arrayB.length + ) +} diff --git a/packages/cozy-client/src/hooks/utils.spec.js b/packages/cozy-client/src/hooks/utils.spec.js new file mode 100644 index 0000000000..023d48bebf --- /dev/null +++ b/packages/cozy-client/src/hooks/utils.spec.js @@ -0,0 +1,220 @@ +import { equalityCheckForQuery } from './utils' + +const mapIdsToDocuments = (state, doctype, ids) => { + return ids.map(id => state[doctype][id]) +} + +const state = { + documents: { + 'io.cozy.files': { + doc1: { + _id: 'doc1' + }, + doc2: { + _id: 'doc2' + }, + doc3: { + _id: 'doc3' + } + } + }, + queries: { + query1: { + id: 'query1', + data: ['doc1', 'doc2'] + }, + query2: { + id: 'query2', + data: ['doc2'] + } + } +} + +const defaultQueryResult = { + id: 1, + data: [], + fetchStatus: 'loaded', + relationshipNames: null +} + +describe('equalityCheckForQuery', () => { + const queryResultA1 = { + id: 1, + storeData: mapIdsToDocuments(state.documents, 'io.cozy.files', [ + 'doc1', + 'doc2' + ]), + ...defaultQueryResult + } + const queryResultA2 = { + id: 1, + storeData: mapIdsToDocuments(state.documents, 'io.cozy.files', [ + 'doc1', + 'doc2' + ]), + ...defaultQueryResult + } + const queryResultA3 = { + id: 1, + storeData: mapIdsToDocuments(state.documents, 'io.cozy.files', [ + 'doc1', + 'doc2', + 'doc3' + ]), + ...defaultQueryResult + } + const queryResultA4 = { + id: 1, + storeData: mapIdsToDocuments(state.documents, 'io.cozy.files', [ + 'doc2', + 'doc3' + ]), + ...defaultQueryResult + } + const queryResultB1 = { + id: 2, + storeData: mapIdsToDocuments(state.documents, 'io.cozy.files', ['doc2']), + ...defaultQueryResult + } + + const queryResultB2 = { + id: 2, + storeData: mapIdsToDocuments(state.documents, 'io.cozy.files', ['doc3']), + ...defaultQueryResult + } + + const queryResultC1 = { + id: 3, + storeData: state.documents['io.cozy.files'].doc1, + data: {}, + ...defaultQueryResult + } + + const queryResultC2 = { + id: 3, + storeData: state.documents['io.cozy.files'].doc1, + data: {}, + ...defaultQueryResult + } + + const queryResultC3 = { + id: 3, + storeData: state.documents['io.cozy.files'].doc2, + data: {}, + ...defaultQueryResult + } + + it('should return true for referential equality', () => { + expect(equalityCheckForQuery(queryResultA1, queryResultA1)).toBe(true) + expect(equalityCheckForQuery(null, null)).toBe(true) + }) + + it('should return false if one object is null', () => { + expect(equalityCheckForQuery(null, queryResultA1)).toBe(false) + expect(equalityCheckForQuery(queryResultA1, null)).toBe(false) + }) + + it('should return false if one or both objects are not objects', () => { + // @ts-ignore + expect(equalityCheckForQuery('notAnObject', queryResultA1)).toBe(false) + // @ts-ignore + expect(equalityCheckForQuery(queryResultA1, 'notAnObject')).toBe(false) + }) + + it('should return false if `id` properties are different', () => { + expect(equalityCheckForQuery(queryResultA1, queryResultB1)).toBe(false) + }) + + it('should return false if one or both objects lack `data`', () => { + // @ts-ignore + expect(equalityCheckForQuery({ id: 1 }, queryResultA1)).toBe(false) + // @ts-ignore + expect(equalityCheckForQuery(queryResultA1, { id: 1 })).toBe(false) + }) + + it('should return false if `data` lengths are different', () => { + expect(equalityCheckForQuery(queryResultA1, queryResultA3)).toBe(false) + }) + + it('should return false if elements in `data` are different', () => { + expect(equalityCheckForQuery(queryResultA1, queryResultA3)).toBe(false) + expect(equalityCheckForQuery(queryResultA3, queryResultA4)).toBe(false) + expect(equalityCheckForQuery(queryResultB1, queryResultB2)).toBe(false) + }) + + it('should return true for matching data array, with equal references ', () => { + expect(equalityCheckForQuery(queryResultA1, queryResultA2)).toBe(true) + }) + + it('should return false for matching data array, with different references ', () => { + const queryResShallowCopyA1 = { + ...queryResultA1, + storeData: JSON.parse(JSON.stringify(queryResultA1.storeData)) // Deep copy + } + expect(equalityCheckForQuery(queryResultA1, queryResShallowCopyA1)).toBe( + false + ) + }) + + it('should return true for matching object data', () => { + expect(equalityCheckForQuery(queryResultC1, queryResultC2)).toBe(true) + }) + it('should return false for different object data', () => { + expect(equalityCheckForQuery(queryResultC1, queryResultC3)).toBe(false) + }) +}) + +describe('equalityCheckForQuery with relationships', () => { + const queryResA = { + ...defaultQueryResult, + relationshipNames: ['relation1'], + storeData: mapIdsToDocuments(state.documents, 'io.cozy.files', [ + 'doc1', + 'doc2' + ]), + data: [{ relation1: { _rev: 'rev1' } }] + } + + const queryResB = { + ...defaultQueryResult, + relationshipNames: ['relation1'], + storeData: mapIdsToDocuments(state.documents, 'io.cozy.files', [ + 'doc1', + 'doc2' + ]), + data: [{ relation1: { _rev: 'rev2' } }] + } + + const queryResC = { + ...defaultQueryResult, + relationshipNames: ['relation1'], + storeData: mapIdsToDocuments(state.documents, 'io.cozy.files', [ + 'doc1', + 'doc2' + ]), + data: [{ relation1: { _rev: 'rev1' } }, { relation1: { _rev: 'rev2' } }] + } + + const queryResD = { + ...defaultQueryResult, + relationshipNames: ['relation1', 'relation2'], + storeData: mapIdsToDocuments(state.documents, 'io.cozy.files', [ + 'doc1', + 'doc2' + ]), + data: [{ relation1: { _rev: 'rev1' } }, { relation2: { _rev: 'rev2' } }] + } + + it('returns true when data and relationship revisions match', () => { + expect(equalityCheckForQuery(queryResA, queryResA)).toBe(true) + expect(equalityCheckForQuery(queryResD, queryResD)).toBe(true) + }) + + it('returns false when relationship revisions differ', () => { + expect(equalityCheckForQuery(queryResA, queryResB)).toBe(false) + }) + + it('returns false when data lengths differ', () => { + expect(equalityCheckForQuery(queryResA, queryResC)).toBe(false) + }) +}) diff --git a/packages/cozy-client/src/store/documents.js b/packages/cozy-client/src/store/documents.js index 410ee7fe3a..8992b0d998 100644 --- a/packages/cozy-client/src/store/documents.js +++ b/packages/cozy-client/src/store/documents.js @@ -173,7 +173,6 @@ export const extractAndMergeDocument = (data, updatedStateWithIncluded) => { let mergedData = Object.assign({}, updatedStateWithIncluded) mergedData[doctype] = Object.assign({}, updatedStateWithIncluded[doctype]) - Object.values(sortedData).map(data => { const id = properId(data) if (mergedData[doctype][id]) { diff --git a/packages/cozy-client/src/types.js b/packages/cozy-client/src/types.js index 37fa07fb5d..ced5121522 100644 --- a/packages/cozy-client/src/types.js +++ b/packages/cozy-client/src/types.js @@ -277,6 +277,15 @@ import { QueryDefinition } from './queries/dsl' * @property {object|Array} data */ +/** + * @typedef {object} QueryStateResult + * @property {object|Array} storeData - Collection of store's documents + * @property {object|Array} data - Collection of hydrated documents + * @property {Array} relationshipNames - The relationships names, used to check hydrated documents + * @property {string|number} id - The query id + * @property {string} fetchStatus - The query fetching status + */ + /** * @typedef {QueryStateWithoutData & QueryStateData} QueryState */ diff --git a/packages/cozy-client/types/CozyClient.d.ts b/packages/cozy-client/types/CozyClient.d.ts index fa9c8f5b9d..58182f57bd 100644 --- a/packages/cozy-client/types/CozyClient.d.ts +++ b/packages/cozy-client/types/CozyClient.d.ts @@ -76,6 +76,10 @@ export type ClientOptions = { * - 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. */ store?: boolean; + /** + * - If set to true, all documents will be hydrated w.r.t. the provided schema's relationships, even if the relationship does not exist on the doc. + */ + forceHydratation?: boolean; }; /** * @typedef {import("./types").CozyClientDocument} CozyClientDocument @@ -99,6 +103,7 @@ export type ClientOptions = { * @property {import("./types").AppMetadata} [appMetadata] - Metadata about the application that will be used in ensureCozyMetadata * @property {import("./types").ClientCapabilities} [capabilities] - Capabilities sent by the stack * @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. + * @property {boolean} [forceHydratation] - If set to true, all documents will be hydrated w.r.t. the provided schema's relationships, even if the relationship does not exist on the doc. */ /** * Responsible for @@ -212,6 +217,10 @@ declare class CozyClient { * - 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. */ store?: boolean; + /** + * - If set to true, all documents will be hydrated w.r.t. the provided schema's relationships, even if the relationship does not exist on the doc. + */ + forceHydratation?: boolean; }; queryIdGenerator: QueryIDGenerator; isLogged: boolean; diff --git a/packages/cozy-client/types/hooks/utils.d.ts b/packages/cozy-client/types/hooks/utils.d.ts new file mode 100644 index 0000000000..4cd1825eab --- /dev/null +++ b/packages/cozy-client/types/hooks/utils.d.ts @@ -0,0 +1 @@ +export function equalityCheckForQuery(queryResA: import("../types").QueryStateResult, queryResB: import("../types").QueryStateResult): boolean; diff --git a/packages/cozy-client/types/types.d.ts b/packages/cozy-client/types/types.d.ts index 672012c3b6..59086f1f84 100644 --- a/packages/cozy-client/types/types.d.ts +++ b/packages/cozy-client/types/types.d.ts @@ -508,6 +508,28 @@ export type QueryStateWithoutData = { export type QueryStateData = { data: object | any[]; }; +export type QueryStateResult = { + /** + * - Collection of store's documents + */ + storeData: object | any[]; + /** + * - Collection of hydrated documents + */ + data: object | any[]; + /** + * - The relationships names, used to check hydrated documents + */ + relationshipNames: Array; + /** + * - The query id + */ + id: string | number; + /** + * - The query fetching status + */ + fetchStatus: string; +}; export type QueryState = QueryStateWithoutData & QueryStateData; export type AutoUpdateOptions = any; export type QueryOptions = {