From c51e0f69f7d601f908f97ec355c60c787fe15393 Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Fri, 31 May 2024 16:41:20 +0200 Subject: [PATCH 1/8] feat: Persist documents to local Pouch when they have no `rev` When a PouchLink is configured, the synchronization process would retrieve only documents that exists on the remote database Those documents would be served as usual when a `.query()` is made using the PouchLink Unfortunately, not all `.query()` correspond to a document that exists on the remote database. With the collection mechanism, some documents are retrieved using an alternative endpoint and then the cozy-stack generate the document on-demand For example this is the case for `io.cozy.settings.flags`, `io.cozy.settings.context` and `io.cozy.settings.disk-usage` Because those documents does not actually exist on the remote database, we cannot sync them using the PouchDB sync mechanism and so they won't be available when the device is offline To fix this, we chose to manually insert those document in the local PouchDB when we detect that a `.query()` call retrieve them from the cozy-stack The easiest way we found to detect them is to check for the existence of `meta.rev` object in the `.query()` result. If no `rev` is present, this means that the documents does not come from the remote database but has been dynamically generated by the cozy-stack Those documents are inserted into existing PouchBD with the `cozyLocalOnly` attributes, so we know that they should not be replicated to the remote database on next sync In order to make the persist mechanism possible, we implemented a new `persistData()` method to the CozyLink interface The impact is that every `Link` should now implement the `persistData()` interface that should persist the data if it is able to do it, or to forward the action otherwise If no `Link` process the action, then the final "default" method will do nothing (contrary to the default for `request()` that would throw an error) BREAKING CHANGE: CozyClient's links should now implement a `persistData()` method that should persist the given data if it is able to do it, or to forward the action to the next `Link` otherwise --- packages/cozy-client/src/CozyClient.js | 35 ++++++++++ packages/cozy-client/src/CozyClient.spec.js | 68 ++++++++++++++++++- packages/cozy-client/src/CozyLink.js | 34 ++++++++-- packages/cozy-client/src/StackLink.js | 4 ++ packages/cozy-client/src/types.js | 7 ++ packages/cozy-pouch-link/src/CozyPouchLink.js | 40 +++++++++++ 6 files changed, 183 insertions(+), 5 deletions(-) diff --git a/packages/cozy-client/src/CozyClient.js b/packages/cozy-client/src/CozyClient.js index e0fbf7c94c..5d7d812108 100644 --- a/packages/cozy-client/src/CozyClient.js +++ b/packages/cozy-client/src/CozyClient.js @@ -97,6 +97,8 @@ const DOC_CREATION = 'creation' const DOC_UPDATE = 'update' /** + * @typedef {import("./types").CozyClientDocument} CozyClientDocument + * * @typedef {object} ClientOptions * @property {object} [client] * @property {object} [link] @@ -1084,6 +1086,9 @@ client.query(Q('io.cozy.bills'))`) */ async requestQuery(definition) { const mainResponse = await this.chain.request(definition) + + this.persistVirtualDocuments(mainResponse.data) + if (!definition.includes) { return mainResponse } @@ -1094,6 +1099,36 @@ client.query(Q('io.cozy.bills'))`) return withIncluded } + /** + * Save the document or array of documents into the persisted storage (if any) + * + * @private + * @param {CozyClientDocument | Array} data - Document or array of documents to be saved + * @returns {Promise} + */ + async persistVirtualDocuments(data) { + if (!Array.isArray(data)) { + await this.persistVirtualDocument(data) + } else { + for (const document of data) { + await this.persistVirtualDocument(document) + } + } + } + + /** + * Save the document or array of documents into the persisted storage (if any) + * + * @private + * @param {CozyClientDocument} document - Document to be saved + * @returns {Promise} + */ + async persistVirtualDocument(document) { + if (document && !document.meta?.rev && !document.cozyLocalOnly) { + await this.chain.persistData(document) + } + } + /** * Fetch relationships for a response (can be several docs). * Fills the `relationships` attribute of each documents. diff --git a/packages/cozy-client/src/CozyClient.spec.js b/packages/cozy-client/src/CozyClient.spec.js index 33fbc7bd7a..503983abf6 100644 --- a/packages/cozy-client/src/CozyClient.spec.js +++ b/packages/cozy-client/src/CozyClient.spec.js @@ -691,7 +691,8 @@ describe('CozyClient login', () => { describe('CozyClient', () => { const requestHandler = jest.fn() - const link = new CozyLink(requestHandler) + const persistHandler = jest.fn() + const link = new CozyLink(requestHandler, persistHandler) const MOCKED_DATE = '2018-05-05T09:09:00.115Z' @@ -722,6 +723,7 @@ describe('CozyClient', () => { afterEach(() => { requestHandler.mockReset() + persistHandler.mockReset() }) describe('setAppMetadata', () => { it('should update the appMetadata', () => { @@ -1381,6 +1383,7 @@ describe('CozyClient', () => { it('should return the same result if the query is run while she is already in loading status whithout requesting the query twice', async () => { jest.spyOn(client, 'requestQuery') + requestHandler.mockResolvedValue({}) const [resp, resp2] = await Promise.all([ client.query(query, { as: 'allTodos' }), @@ -1390,6 +1393,69 @@ describe('CozyClient', () => { expect(client.requestQuery).toHaveBeenCalledTimes(1) }) + it('should persist virtual document when no meta.rev', async () => { + jest.spyOn(client, 'requestQuery') + requestHandler.mockResolvedValue({ + data: { + _id: 'some_id' + } + }) + + await client.query(query, { as: 'allTodos' }) + + expect(persistHandler).toHaveBeenCalledWith( + { + _id: 'some_id' + }, + expect.anything() + ) + }) + + it('should persist array of virtual documents when no meta.rev', async () => { + jest.spyOn(client, 'requestQuery') + requestHandler.mockResolvedValue({ + data: [ + { + _id: 'some_id' + }, + { + _id: 'some_id2' + } + ] + }) + + await client.query(query, { as: 'allTodos' }) + + expect(persistHandler).toHaveBeenCalledWith( + { + _id: 'some_id' + }, + expect.anything() + ) + expect(persistHandler).toHaveBeenCalledWith( + { + _id: 'some_id2' + }, + expect.anything() + ) + }) + + it('should not persist virtual documents if cozyLocalOnly', async () => { + jest.spyOn(client, 'requestQuery') + requestHandler.mockResolvedValue({ + data: [ + { + _id: 'some_id', + cozyLocalOnly: true + } + ] + }) + + await client.query(query, { as: 'allTodos' }) + + expect(persistHandler).not.toHaveBeenCalled() + }) + describe('relationship with query failure', () => { beforeEach(() => { jest.spyOn(HasManyFiles, 'query').mockImplementation(() => { diff --git a/packages/cozy-client/src/CozyLink.js b/packages/cozy-client/src/CozyLink.js index 8b4f5a13fe..baec94a6b6 100644 --- a/packages/cozy-client/src/CozyLink.js +++ b/packages/cozy-client/src/CozyLink.js @@ -1,19 +1,27 @@ export default class CozyLink { - constructor(requestHandler) { + constructor(requestHandler, persistHandler) { if (typeof requestHandler === 'function') { this.request = requestHandler } + + if (typeof persistHandler === 'function') { + this.persistData = persistHandler + } } request(operation, result, forward) { throw new Error('request is not implemented') } + + persistData(data, forward) { + throw new Error('persistData is not implemented') + } } const toLink = handler => typeof handler === 'function' ? new CozyLink(handler) : handler -const defaultLinkHandler = (operation, result) => { +const defaultLinkRequestHandler = (operation, result) => { if (result) return result else if (operation.execute) return operation.execute() else @@ -22,14 +30,32 @@ const defaultLinkHandler = (operation, result) => { ) } +const defaultLinkPersistHandler = (operation, result) => { + // Do nothing +} + +const defaultLinkHandler = new CozyLink( + defaultLinkRequestHandler, + defaultLinkPersistHandler +) + export const chain = links => [...links, defaultLinkHandler].map(toLink).reduce(concat) const concat = (firstLink, nextLink) => { - return new CozyLink((operation, result, forward) => { + const requestHandler = (operation, result, forward) => { const nextForward = (op, res) => { return nextLink.request(op, res, forward) } return firstLink.request(operation, result, nextForward) - }) + } + + const persistHandler = (data, forward) => { + const nextForward = d => { + return nextLink.persistData(d, forward) + } + return firstLink.persistData(data, nextForward) + } + + return new CozyLink(requestHandler, persistHandler) } diff --git a/packages/cozy-client/src/StackLink.js b/packages/cozy-client/src/StackLink.js index 97e9a2fb92..e414c2b88b 100644 --- a/packages/cozy-client/src/StackLink.js +++ b/packages/cozy-client/src/StackLink.js @@ -83,6 +83,10 @@ export default class StackLink extends CozyLink { } return this.executeQuery(operation) } + + async persistData(data, forward) { + return forward(data) + } /** * * @param {QueryDefinition} query - Query to execute diff --git a/packages/cozy-client/src/types.js b/packages/cozy-client/src/types.js index 16fc62f519..1b3d5ca747 100644 --- a/packages/cozy-client/src/types.js +++ b/packages/cozy-client/src/types.js @@ -407,6 +407,11 @@ import { QueryDefinition } from './queries/dsl' * @property {boolean} [favorite] - Whether the document is marked as favorite */ +/** + * @typedef {object} CozyClientDocumentMeta - Meta object as specified by JSON-API (https://jsonapi.org/format/#document-meta) + * @property {string} [rev] - Current revision of the document + */ + /** * @typedef {object} CozyClientDocument - A document * @property {string} [_id] - Id of the document @@ -417,6 +422,8 @@ import { QueryDefinition } from './queries/dsl' * @property {ReferencedByRelationship} [relationships] - Relationships of the document * @property {Reference[]} [referenced_by] - referenced by of another document * @property {CozyMetadata} [cozyMetadata] - Cozy Metadata + * @property {CozyClientDocumentMeta} [meta] - Pouch Metadata + * @property {boolean} [cozyLocalOnly] - When true the document should NOT be replicated to the remote database */ /** diff --git a/packages/cozy-pouch-link/src/CozyPouchLink.js b/packages/cozy-pouch-link/src/CozyPouchLink.js index 9b7f43da49..7637b25a43 100644 --- a/packages/cozy-pouch-link/src/CozyPouchLink.js +++ b/packages/cozy-pouch-link/src/CozyPouchLink.js @@ -59,6 +59,8 @@ const normalizeAll = (docs, doctype) => { } /** + * @typedef {import('cozy-client/src/types').CozyClientDocument} CozyClientDocument + * * @typedef {"idle"|"replicating"} SyncStatus */ @@ -384,6 +386,44 @@ class PouchLink extends CozyLink { return this.executeQuery(operation) } } + + async persistData(data, forward = doNothing) { + const docWithoutType = sanitized(data) + docWithoutType.cozyLocalOnly = true + + const oldDoc = await this.getExistingDocument(data._id, data._type) + if (oldDoc) { + docWithoutType._rev = oldDoc._rev + } + + const db = this.pouches.getPouch(data._type) + await db.put(docWithoutType) + } + + /** + * Retrieve the existing document from Pouch + * + * @private + * @param {*} id - ID of the document to retrieve + * @param {*} type - Doctype of the document to retrieve + * @param {*} throwIfNotFound - If true the method will throw when the document is not found. Otherwise it will return null + * @returns {Promise} + */ + async getExistingDocument(id, type, throwIfNotFound = false) { + try { + const db = this.pouches.getPouch(type) + const existingDoc = await db.get(id) + + return existingDoc + } catch (err) { + if (err.name === 'not_found' && !throwIfNotFound) { + return null + } else { + throw err + } + } + } + /** * * Check if there is warmup queries for this doctype From 1a3665716ce71b4763a828acacd4f522bcf1c1a3 Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Fri, 31 May 2024 11:59:14 +0200 Subject: [PATCH 2/8] feat(pouch-link): Prevent synchronizing `cozyLocalOnly` documents In previous commit we manually inserted virtual documents into the local PouchDB with the `cozyLocalOnly` attribute We don't want to replicate those document into the remote database so we want to filter them from the synchronization process This is done using a PouchDB `selector` on the synchronization options --- packages/cozy-pouch-link/src/startReplication.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/cozy-pouch-link/src/startReplication.js b/packages/cozy-pouch-link/src/startReplication.js index 7774f8b13d..f8db3ef048 100644 --- a/packages/cozy-pouch-link/src/startReplication.js +++ b/packages/cozy-pouch-link/src/startReplication.js @@ -62,7 +62,12 @@ export const startReplication = ( } = replicationOptions const options = { batch_size: BATCH_SIZE, - ...customReplicationOptions + ...customReplicationOptions, + selector: { + cozyLocalOnly: { + $exists: false + } + } } let replication if (initialReplication && strategy !== 'toRemote') { From 873a60b1d5f76b0c07325a5c349d0a9390b48e6f Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Mon, 15 Jul 2024 16:05:08 +0200 Subject: [PATCH 3/8] test: Fix `normalizeDoc` test to add doctype --- packages/cozy-pouch-link/src/jsonapi.spec.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/cozy-pouch-link/src/jsonapi.spec.js b/packages/cozy-pouch-link/src/jsonapi.spec.js index acfb280972..12cf422b2f 100644 --- a/packages/cozy-pouch-link/src/jsonapi.spec.js +++ b/packages/cozy-pouch-link/src/jsonapi.spec.js @@ -28,17 +28,21 @@ const DELETED_DOC_FIXTURE = { describe('doc normalization', () => { it('keeps the highest between rev and _rev and removes the rev attribute', () => { - const normalized = normalizeDoc({ - _id: 1234, - _rev: '3-deadbeef', - rev: '4-cffee', - firstName: 'Bobba', - lastName: 'Fett' - }) + const normalized = normalizeDoc( + { + _id: 1234, + _rev: '3-deadbeef', + rev: '4-cffee', + firstName: 'Bobba', + lastName: 'Fett' + }, + 'io.cozy.contacts' + ) expect(normalized).toEqual({ _id: 1234, id: 1234, _rev: '4-cffee', + _type: 'io.cozy.contacts', firstName: 'Bobba', lastName: 'Fett' }) From 4bda4e5eccc13454163148a3fd7596eec60f2290 Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Tue, 18 Jun 2024 17:37:55 +0200 Subject: [PATCH 4/8] fix: Do not persist virtual documents when served from CozyPouchLink When querying documents from CozyPouchLink, then the `meta.rev` attribute is not added to the document. This happens because this attributes does not exist in database but is added by the cozy-stack when serving JSON:API format We don't want to add the `meta.rev` attribute by ourself as it may have side effects on the synchronization process (i.e. adding `meta.rev` in the database documents) Instead we want to introduce a `cozyFromPouch` attribute that is added by CozyPouchLink when returning the result --- packages/cozy-client/src/CozyClient.js | 7 ++++++- packages/cozy-client/src/types.js | 1 + packages/cozy-pouch-link/src/CozyPouchLink.spec.js | 1 + packages/cozy-pouch-link/src/jsonapi.js | 3 ++- packages/cozy-pouch-link/src/jsonapi.spec.js | 1 + 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/cozy-client/src/CozyClient.js b/packages/cozy-client/src/CozyClient.js index 5d7d812108..3e59246bb2 100644 --- a/packages/cozy-client/src/CozyClient.js +++ b/packages/cozy-client/src/CozyClient.js @@ -1124,7 +1124,12 @@ client.query(Q('io.cozy.bills'))`) * @returns {Promise} */ async persistVirtualDocument(document) { - if (document && !document.meta?.rev && !document.cozyLocalOnly) { + if ( + document && + !document.meta?.rev && + !document.cozyLocalOnly && + !document.cozyFromPouch + ) { await this.chain.persistData(document) } } diff --git a/packages/cozy-client/src/types.js b/packages/cozy-client/src/types.js index 1b3d5ca747..a539709033 100644 --- a/packages/cozy-client/src/types.js +++ b/packages/cozy-client/src/types.js @@ -424,6 +424,7 @@ import { QueryDefinition } from './queries/dsl' * @property {CozyMetadata} [cozyMetadata] - Cozy Metadata * @property {CozyClientDocumentMeta} [meta] - Pouch Metadata * @property {boolean} [cozyLocalOnly] - When true the document should NOT be replicated to the remote database + * @property {boolean} [cozyFromPouch] - When true the document has been retrieved from a local PouchDB */ /** diff --git a/packages/cozy-pouch-link/src/CozyPouchLink.spec.js b/packages/cozy-pouch-link/src/CozyPouchLink.spec.js index 1ce0a82ec9..61489944c7 100644 --- a/packages/cozy-pouch-link/src/CozyPouchLink.spec.js +++ b/packages/cozy-pouch-link/src/CozyPouchLink.spec.js @@ -473,6 +473,7 @@ describe('CozyPouchLink', () => { _id: '1', _rev: '1-deadbeef', _type: 'io.cozy.todos', + cozyFromPouch: true, done: false, id: '1', label: 'Buy bread' diff --git a/packages/cozy-pouch-link/src/jsonapi.js b/packages/cozy-pouch-link/src/jsonapi.js index 84901340cc..159435bf73 100644 --- a/packages/cozy-pouch-link/src/jsonapi.js +++ b/packages/cozy-pouch-link/src/jsonapi.js @@ -10,7 +10,8 @@ export const normalizeDoc = (doc, doctype) => { id, _id: id, _rev, - _type: doctype + _type: doctype, + cozyFromPouch: true } if (normalizedDoc.rev) { delete normalizedDoc.rev diff --git a/packages/cozy-pouch-link/src/jsonapi.spec.js b/packages/cozy-pouch-link/src/jsonapi.spec.js index 12cf422b2f..86bfd067cc 100644 --- a/packages/cozy-pouch-link/src/jsonapi.spec.js +++ b/packages/cozy-pouch-link/src/jsonapi.spec.js @@ -43,6 +43,7 @@ describe('doc normalization', () => { id: 1234, _rev: '4-cffee', _type: 'io.cozy.contacts', + cozyFromPouch: true, firstName: 'Bobba', lastName: 'Fett' }) From f72623c245166f0375403324b17d40c96fe9dec1 Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Fri, 12 Jul 2024 17:17:38 +0200 Subject: [PATCH 5/8] feat: Handle io.cozy.apps_registry query On the StackLink side, the `io.cozy.apps_registry` is handled by the AppsRegistryCollection that queries a specific cozy-stack route when the `slug` parameter equals `maintenance` This is a shortcut to query all apps under maintenance This is problematic because the local Pouch is synchronized on this doctype and stores all apps with their respective IDs. There is no `maintenance` document, so we cannot process a query that selects this ID To make this possible, we want to persist the `maintenance` query's result as a single document with the `maintenance` id --- packages/cozy-client/src/CozyClient.js | 18 ++++++++++++++++-- packages/cozy-pouch-link/src/jsonapi.js | 14 ++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/cozy-client/src/CozyClient.js b/packages/cozy-client/src/CozyClient.js index 3e59246bb2..9efc27a872 100644 --- a/packages/cozy-client/src/CozyClient.js +++ b/packages/cozy-client/src/CozyClient.js @@ -1087,7 +1087,7 @@ client.query(Q('io.cozy.bills'))`) async requestQuery(definition) { const mainResponse = await this.chain.request(definition) - this.persistVirtualDocuments(mainResponse.data) + this.persistVirtualDocuments(definition, mainResponse.data) if (!definition.includes) { return mainResponse @@ -1106,7 +1106,21 @@ client.query(Q('io.cozy.bills'))`) * @param {CozyClientDocument | Array} data - Document or array of documents to be saved * @returns {Promise} */ - async persistVirtualDocuments(data) { + async persistVirtualDocuments(definition, data) { + if (definition.doctype === 'io.cozy.apps_registry') { + // io.cozy.apps_registry has a dedicated `maintenance` endpoint on cozy-stack that + // returns data different than the one stored in database + // As we want to have transparent queries, whether it uses the stack API or Pouch, + // we store the full response into a single doc, with a `maintenance` _id + // and a special `cozyPouchData` attribute, to highlight this special case + return await this.persistVirtualDocument({ + _type: 'io.cozy.apps_registry', + _id: 'maintenance', + // @ts-ignore + cozyPouchData: data + }) + } + if (!Array.isArray(data)) { await this.persistVirtualDocument(data) } else { diff --git a/packages/cozy-pouch-link/src/jsonapi.js b/packages/cozy-pouch-link/src/jsonapi.js index 159435bf73..5ff0a18f58 100644 --- a/packages/cozy-pouch-link/src/jsonapi.js +++ b/packages/cozy-pouch-link/src/jsonapi.js @@ -22,6 +22,20 @@ export const normalizeDoc = (doc, doctype) => { const filterDeletedDocumentsFromRows = doc => !!doc export const fromPouchResult = (res, withRows, doctype) => { + // Sometimes, queries are transformed by Collections and they call a dedicated + // cozy-stack route. When this is the case, we want to be able to replicate the same + // query from cozy-pouch-link. It is not possible as-is because the received data + // is not the same as the one stored in the Couch database + // To handle this, we store the received data in the Pouch with a dedicated id and + // we store the query result in a `cozyPouchData` attribute + // So when `cozyPouchData` attribute exists, we know that we want to return its content + // as the result of the query + if (res.cozyPouchData) { + return { + data: res.cozyPouchData + } + } + if (withRows) { const docs = res.rows ? res.rows.map(row => row.doc).filter(filterDeletedDocumentsFromRows) From 8ac08a95f36e3905d639b1e683b9cba29e9280ad Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Mon, 22 Jul 2024 17:21:15 +0200 Subject: [PATCH 6/8] fix: Persist `io.cozy.files.shortcuts` even if they have a `meta.rev` `io.cozy.files.shortcuts` doctype does not exist in Couch database This doctype is created by cozy-stack from `io.cozy.files` documents This has two impact: - First, we cannot call `PouchDB.replicate` on this doctype as it does not actually exist - Second, `io.cozy.files` documents have a `meta.rev` attributes that is included into the interpolated `io.cozy.files.shortcuts` one. So the virtual documents persistance mechanism is not triggered So with actual implementation we cannot persist `io.cozy.files.shortcuts` for offline usage To make it possible, we want to enforce virtual documents persistance for this doctype even if it has a `meta.rev` attribute --- packages/cozy-client/src/CozyClient.js | 29 +++++++++++++-------- packages/cozy-client/src/CozyClient.spec.js | 19 ++++++++++++++ 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/packages/cozy-client/src/CozyClient.js b/packages/cozy-client/src/CozyClient.js index 9efc27a872..323da62e0b 100644 --- a/packages/cozy-client/src/CozyClient.js +++ b/packages/cozy-client/src/CozyClient.js @@ -1107,25 +1107,32 @@ client.query(Q('io.cozy.bills'))`) * @returns {Promise} */ async persistVirtualDocuments(definition, data) { + const enforceList = ['io.cozy.files.shortcuts'] + + const enforce = enforceList.includes(definition.doctype) + if (definition.doctype === 'io.cozy.apps_registry') { // io.cozy.apps_registry has a dedicated `maintenance` endpoint on cozy-stack that // returns data different than the one stored in database // As we want to have transparent queries, whether it uses the stack API or Pouch, // we store the full response into a single doc, with a `maintenance` _id // and a special `cozyPouchData` attribute, to highlight this special case - return await this.persistVirtualDocument({ - _type: 'io.cozy.apps_registry', - _id: 'maintenance', - // @ts-ignore - cozyPouchData: data - }) + return await this.persistVirtualDocument( + { + _type: 'io.cozy.apps_registry', + _id: 'maintenance', + // @ts-ignore + cozyPouchData: data + }, + enforce + ) } if (!Array.isArray(data)) { - await this.persistVirtualDocument(data) + await this.persistVirtualDocument(data, enforce) } else { for (const document of data) { - await this.persistVirtualDocument(document) + await this.persistVirtualDocument(document, enforce) } } } @@ -1135,12 +1142,12 @@ client.query(Q('io.cozy.bills'))`) * * @private * @param {CozyClientDocument} document - Document to be saved + * @param {boolean} enforce - When true, save the document even if `meta.rev` exists * @returns {Promise} */ - async persistVirtualDocument(document) { + async persistVirtualDocument(document, enforce) { if ( - document && - !document.meta?.rev && + ((document && !document.meta?.rev) || enforce) && !document.cozyLocalOnly && !document.cozyFromPouch ) { diff --git a/packages/cozy-client/src/CozyClient.spec.js b/packages/cozy-client/src/CozyClient.spec.js index 503983abf6..22d8f8a37b 100644 --- a/packages/cozy-client/src/CozyClient.spec.js +++ b/packages/cozy-client/src/CozyClient.spec.js @@ -1456,6 +1456,25 @@ describe('CozyClient', () => { expect(persistHandler).not.toHaveBeenCalled() }) + it('should enforce persisting io.cozy.files.shortcuts as virtual documents even if meta.rev exists', async () => { + jest.spyOn(client, 'requestQuery') + requestHandler.mockResolvedValue({ + data: [ + { + _id: 'some_id', + meta: { + rev: 'SOME_REV' + } + } + ] + }) + const shortcutsQuery = Q('io.cozy.files.shortcuts') + + await client.query(shortcutsQuery, { as: 'allShortcuts' }) + + expect(persistHandler).toHaveBeenCalled() + }) + describe('relationship with query failure', () => { beforeEach(() => { jest.spyOn(HasManyFiles, 'query').mockImplementation(() => { From 8cf4478292710bf1878a14713001e7c7fee6c042 Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Tue, 13 Aug 2024 16:44:44 +0200 Subject: [PATCH 7/8] feat: Add check to `_rev` attribute when persisting virtual documents In previous commit we added a check to `meta.rev` attribute in order to discriminate documents that exist in remote CouchDB from the ones that don't This approach would work only for documents handled by the cozy-stack using JSON-API But some CouchDB documents are served directly through the `data` route and are not wrapped into JSON-API When this is the case, they have a `_rev` attribute instead of a `meta.rev` one So we want to check for both forms before persisting virtual documents --- packages/cozy-client/src/CozyClient.js | 12 ++++---- packages/cozy-client/src/CozyClient.spec.js | 34 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/packages/cozy-client/src/CozyClient.js b/packages/cozy-client/src/CozyClient.js index 323da62e0b..e29a7115ad 100644 --- a/packages/cozy-client/src/CozyClient.js +++ b/packages/cozy-client/src/CozyClient.js @@ -1142,15 +1142,15 @@ client.query(Q('io.cozy.bills'))`) * * @private * @param {CozyClientDocument} document - Document to be saved - * @param {boolean} enforce - When true, save the document even if `meta.rev` exists + * @param {boolean} enforce - When true, save the document even if `meta.rev` or `_rev` exist * @returns {Promise} */ async persistVirtualDocument(document, enforce) { - if ( - ((document && !document.meta?.rev) || enforce) && - !document.cozyLocalOnly && - !document.cozyFromPouch - ) { + if (!document || document.cozyLocalOnly || document.cozyFromPouch) { + return + } + + if ((!document.meta?.rev && !document._rev) || enforce) { await this.chain.persistData(document) } } diff --git a/packages/cozy-client/src/CozyClient.spec.js b/packages/cozy-client/src/CozyClient.spec.js index 22d8f8a37b..5307e98079 100644 --- a/packages/cozy-client/src/CozyClient.spec.js +++ b/packages/cozy-client/src/CozyClient.spec.js @@ -1393,7 +1393,7 @@ describe('CozyClient', () => { expect(client.requestQuery).toHaveBeenCalledTimes(1) }) - it('should persist virtual document when no meta.rev', async () => { + it('should persist virtual document when no meta.rev nor _rev', async () => { jest.spyOn(client, 'requestQuery') requestHandler.mockResolvedValue({ data: { @@ -1411,7 +1411,37 @@ describe('CozyClient', () => { ) }) - it('should persist array of virtual documents when no meta.rev', async () => { + it('should not persist virtual document when meta.rev', async () => { + jest.spyOn(client, 'requestQuery') + requestHandler.mockResolvedValue({ + data: { + _id: 'some_id', + meta: { + rev: 'SOME_REV' + } + } + }) + + await client.query(query, { as: 'allTodos' }) + + expect(persistHandler).not.toHaveBeenCalled() + }) + + it('should not persist virtual document when _rev', async () => { + jest.spyOn(client, 'requestQuery') + requestHandler.mockResolvedValue({ + data: { + _id: 'some_id', + _rev: 'SOME_REV' + } + }) + + await client.query(query, { as: 'allTodos' }) + + expect(persistHandler).not.toHaveBeenCalled() + }) + + it('should persist array of virtual documents when no meta.rev nor _rev', async () => { jest.spyOn(client, 'requestQuery') requestHandler.mockResolvedValue({ data: [ From 1ba2e2ac01b5ddf6bd8ed9c993062c050d0fb12f Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Tue, 16 Jul 2024 17:36:46 +0200 Subject: [PATCH 8/8] docs: Update types and documentation --- docs/api/cozy-client/classes/CozyClient.md | 184 +++++++++--------- docs/api/cozy-client/classes/CozyLink.md | 26 ++- docs/api/cozy-client/classes/StackLink.md | 29 ++- docs/api/cozy-pouch-link/classes/PouchLink.md | 105 ++++++---- packages/cozy-client/types/CozyClient.d.ts | 65 +++++++ packages/cozy-client/types/CozyLink.d.ts | 3 +- packages/cozy-client/types/types.d.ts | 21 ++ .../cozy-pouch-link/types/CozyPouchLink.d.ts | 23 ++- packages/cozy-pouch-link/types/jsonapi.d.ts | 10 +- 9 files changed, 319 insertions(+), 147 deletions(-) diff --git a/docs/api/cozy-client/classes/CozyClient.md b/docs/api/cozy-client/classes/CozyClient.md index 8e3b3ae284..c58990ff60 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:152](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L152) +[packages/cozy-client/src/CozyClient.js:154](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L154) ## 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:165](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L165) +[packages/cozy-client/src/CozyClient.js:167](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L167) *** @@ -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:193](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L193) +[packages/cozy-client/src/CozyClient.js:195](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L195) *** @@ -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:186](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L186) +[packages/cozy-client/src/CozyClient.js:188](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L188) *** @@ -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:1633](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1633) +[packages/cozy-client/src/CozyClient.js:1694](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1694) *** @@ -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:173](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L173) +[packages/cozy-client/src/CozyClient.js:175](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L175) *** @@ -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:172](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L172) +[packages/cozy-client/src/CozyClient.js:174](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L174) *** @@ -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:487](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L487) +[packages/cozy-client/src/CozyClient.js:489](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L489) *** @@ -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:183](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L183) +[packages/cozy-client/src/CozyClient.js:185](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L185) *** @@ -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:166](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L166) +[packages/cozy-client/src/CozyClient.js:168](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L168) *** @@ -159,7 +159,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:171](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L171) *** @@ -169,7 +169,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:196](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L196) +[packages/cozy-client/src/CozyClient.js:198](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L198) *** @@ -179,7 +179,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:171](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L171) +[packages/cozy-client/src/CozyClient.js:173](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L173) *** @@ -189,7 +189,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:188](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L188) +[packages/cozy-client/src/CozyClient.js:190](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L190) *** @@ -199,7 +199,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:1608](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1608) +[packages/cozy-client/src/CozyClient.js:1669](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1669) *** @@ -209,7 +209,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:1538](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1538) +[packages/cozy-client/src/CozyClient.js:1599](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1599) *** @@ -219,7 +219,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:221](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L221) +[packages/cozy-client/src/CozyClient.js:223](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L223) *** @@ -239,7 +239,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:1291](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1291) +[packages/cozy-client/src/CozyClient.js:1352](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1352) *** @@ -284,7 +284,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:466](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L466) +[packages/cozy-client/src/CozyClient.js:468](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L468) *** @@ -304,7 +304,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:422](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L422) +[packages/cozy-client/src/CozyClient.js:424](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L424) *** @@ -324,7 +324,7 @@ Cozy-Client will automatically call `this.login()` if provided with a token and *Defined in* -[packages/cozy-client/src/CozyClient.js:567](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L567) +[packages/cozy-client/src/CozyClient.js:569](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L569) *** @@ -353,7 +353,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:1454](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1454) +[packages/cozy-client/src/CozyClient.js:1515](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1515) *** @@ -371,7 +371,7 @@ This mechanism is described in https://github.com/cozy/cozy-client/blob/master/p *Defined in* -[packages/cozy-client/src/CozyClient.js:1435](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1435) +[packages/cozy-client/src/CozyClient.js:1496](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1496) *** @@ -387,7 +387,7 @@ Returns whether the client has been revoked on the server *Defined in* -[packages/cozy-client/src/CozyClient.js:1550](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1550) +[packages/cozy-client/src/CozyClient.js:1611](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1611) *** @@ -412,7 +412,7 @@ Collection corresponding to the doctype *Defined in* -[packages/cozy-client/src/CozyClient.js:559](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L559) +[packages/cozy-client/src/CozyClient.js:561](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L561) *** @@ -450,7 +450,7 @@ await client.create('io.cozy.todos', { *Defined in* -[packages/cozy-client/src/CozyClient.js:614](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L614) +[packages/cozy-client/src/CozyClient.js:616](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L616) *** @@ -471,7 +471,7 @@ If `oauth` options are passed, stackClient is an OAuthStackClient. *Defined in* -[packages/cozy-client/src/CozyClient.js:1588](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1588) +[packages/cozy-client/src/CozyClient.js:1649](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1649) *** @@ -496,7 +496,7 @@ The document that has been deleted *Defined in* -[packages/cozy-client/src/CozyClient.js:870](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L870) +[packages/cozy-client/src/CozyClient.js:872](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L872) *** @@ -516,7 +516,7 @@ The document that has been deleted *Defined in* -[packages/cozy-client/src/CozyClient.js:1659](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1659) +[packages/cozy-client/src/CozyClient.js:1720](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1720) *** @@ -542,7 +542,7 @@ a method from cozy-client *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:237](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L237) *** @@ -564,7 +564,7 @@ a method from cozy-client *Defined in* -[packages/cozy-client/src/CozyClient.js:684](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L684) +[packages/cozy-client/src/CozyClient.js:686](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L686) *** @@ -588,7 +588,7 @@ Makes sure that the query exists in the store *Defined in* -[packages/cozy-client/src/CozyClient.js:891](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L891) +[packages/cozy-client/src/CozyClient.js:893](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L893) *** @@ -602,7 +602,7 @@ Makes sure that the query exists in the store *Defined in* -[packages/cozy-client/src/CozyClient.js:1541](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1541) +[packages/cozy-client/src/CozyClient.js:1602](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1602) *** @@ -625,7 +625,7 @@ Makes sure that the query exists in the store *Defined in* -[packages/cozy-client/src/CozyClient.js:563](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L563) +[packages/cozy-client/src/CozyClient.js:565](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L565) *** @@ -654,7 +654,7 @@ Query state *Defined in* -[packages/cozy-client/src/CozyClient.js:1388](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1388) +[packages/cozy-client/src/CozyClient.js:1449](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1449) *** @@ -675,7 +675,7 @@ Query state *Defined in* -[packages/cozy-client/src/CozyClient.js:576](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L576) +[packages/cozy-client/src/CozyClient.js:578](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L578) *** @@ -689,7 +689,7 @@ Query state *Defined in* -[packages/cozy-client/src/CozyClient.js:1266](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1266) +[packages/cozy-client/src/CozyClient.js:1327](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1327) *** @@ -710,7 +710,7 @@ Query state *Defined in* -[packages/cozy-client/src/CozyClient.js:583](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L583) +[packages/cozy-client/src/CozyClient.js:585](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L585) *** @@ -733,7 +733,7 @@ Creates an association that is linked to the store. *Defined in* -[packages/cozy-client/src/CozyClient.js:1273](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1273) +[packages/cozy-client/src/CozyClient.js:1334](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1334) *** @@ -747,7 +747,7 @@ Creates an association that is linked to the store. *Defined in* -[packages/cozy-client/src/CozyClient.js:1641](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1641) +[packages/cozy-client/src/CozyClient.js:1702](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1702) *** @@ -771,7 +771,7 @@ Array of documents or null if the collection does not exist. *Defined in* -[packages/cozy-client/src/CozyClient.js:1309](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1309) +[packages/cozy-client/src/CozyClient.js:1370](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1370) *** @@ -796,7 +796,7 @@ Document or null if the object does not exist. *Defined in* -[packages/cozy-client/src/CozyClient.js:1326](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1326) +[packages/cozy-client/src/CozyClient.js:1387](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1387) *** @@ -831,7 +831,7 @@ One or more mutation to execute *Defined in* -[packages/cozy-client/src/CozyClient.js:783](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L783) +[packages/cozy-client/src/CozyClient.js:785](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L785) *** @@ -851,7 +851,7 @@ One or more mutation to execute *Defined in* -[packages/cozy-client/src/CozyClient.js:1193](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1193) +[packages/cozy-client/src/CozyClient.js:1254](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1254) *** @@ -867,7 +867,7 @@ getInstanceOptions - Returns current instance options, such as domain or app slu *Defined in* -[packages/cozy-client/src/CozyClient.js:1668](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1668) +[packages/cozy-client/src/CozyClient.js:1729](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1729) *** @@ -894,7 +894,7 @@ Get a query from the internal store. *Defined in* -[packages/cozy-client/src/CozyClient.js:1347](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1347) +[packages/cozy-client/src/CozyClient.js:1408](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1408) *** @@ -923,7 +923,7 @@ the store up, which in turn will update the ``s and re-render the data. *Defined in* -[packages/cozy-client/src/CozyClient.js:1289](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1289) +[packages/cozy-client/src/CozyClient.js:1350](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1350) *** @@ -955,7 +955,7 @@ extract the value corresponding to the given `key` *Defined in* -[packages/cozy-client/src/CozyClient.js:1769](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1769) +[packages/cozy-client/src/CozyClient.js:1830](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1830) *** @@ -969,7 +969,7 @@ extract the value corresponding to the given `key` *Defined in* -[packages/cozy-client/src/CozyClient.js:1648](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1648) +[packages/cozy-client/src/CozyClient.js:1709](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1709) *** @@ -991,7 +991,7 @@ Sets public attribute and emits event related to revocation *Defined in* -[packages/cozy-client/src/CozyClient.js:1559](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1559) +[packages/cozy-client/src/CozyClient.js:1620](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1620) *** @@ -1013,7 +1013,7 @@ Emits event when token is refreshed *Defined in* -[packages/cozy-client/src/CozyClient.js:1570](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1570) +[packages/cozy-client/src/CozyClient.js:1631](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1631) *** @@ -1039,7 +1039,7 @@ the relationship *Defined in* -[packages/cozy-client/src/CozyClient.js:1236](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1236) +[packages/cozy-client/src/CozyClient.js:1297](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1297) *** @@ -1064,7 +1064,7 @@ Instead, the relationships will have null documents. *Defined in* -[packages/cozy-client/src/CozyClient.js:1213](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1213) +[packages/cozy-client/src/CozyClient.js:1274](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1274) *** @@ -1085,7 +1085,7 @@ Instead, the relationships will have null documents. *Defined in* -[packages/cozy-client/src/CozyClient.js:1247](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1247) +[packages/cozy-client/src/CozyClient.js:1308](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1308) *** @@ -1099,7 +1099,7 @@ Instead, the relationships will have null documents. *Defined in* -[packages/cozy-client/src/CozyClient.js:1411](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1411) +[packages/cozy-client/src/CozyClient.js:1472](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1472) *** @@ -1121,7 +1121,7 @@ loadInstanceOptionsFromDOM - Loads the dataset injected by the Stack in web page *Defined in* -[packages/cozy-client/src/CozyClient.js:1679](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1679) +[packages/cozy-client/src/CozyClient.js:1740](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1740) *** @@ -1139,7 +1139,7 @@ This method is not iso with loadInstanceOptionsFromDOM for now. *Defined in* -[packages/cozy-client/src/CozyClient.js:1700](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1700) +[packages/cozy-client/src/CozyClient.js:1761](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1761) *** @@ -1173,7 +1173,7 @@ Emits *Defined in* -[packages/cozy-client/src/CozyClient.js:455](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L455) +[packages/cozy-client/src/CozyClient.js:457](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L457) *** @@ -1196,7 +1196,7 @@ Emits *Defined in* -[packages/cozy-client/src/CozyClient.js:506](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L506) +[packages/cozy-client/src/CozyClient.js:508](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L508) *** @@ -1220,7 +1220,7 @@ and working. *Defined in* -[packages/cozy-client/src/CozyClient.js:1259](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1259) +[packages/cozy-client/src/CozyClient.js:1320](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1320) *** @@ -1241,7 +1241,7 @@ and working. *Defined in* -[packages/cozy-client/src/CozyClient.js:1035](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1035) +[packages/cozy-client/src/CozyClient.js:1037](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1037) *** @@ -1267,7 +1267,7 @@ Mutate a document *Defined in* -[packages/cozy-client/src/CozyClient.js:1053](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1053) +[packages/cozy-client/src/CozyClient.js:1055](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1055) *** @@ -1287,7 +1287,7 @@ Mutate a document *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:238](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L238) *** @@ -1309,7 +1309,7 @@ Dehydrates and adds metadata before saving a document *Defined in* -[packages/cozy-client/src/CozyClient.js:754](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L754) +[packages/cozy-client/src/CozyClient.js:756](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L756) *** @@ -1340,7 +1340,7 @@ please use `fetchQueryAndGetFromState` instead *Defined in* -[packages/cozy-client/src/CozyClient.js:918](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L918) +[packages/cozy-client/src/CozyClient.js:920](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L920) *** @@ -1367,7 +1367,7 @@ All documents matching the query *Defined in* -[packages/cozy-client/src/CozyClient.js:995](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L995) +[packages/cozy-client/src/CozyClient.js:997](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L997) *** @@ -1401,7 +1401,7 @@ All documents matching the query *Defined in* -[packages/cozy-client/src/CozyClient.js:1655](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1655) +[packages/cozy-client/src/CozyClient.js:1716](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1716) *** @@ -1427,7 +1427,7 @@ Contains the fetched token and the client information. *Defined in* -[packages/cozy-client/src/CozyClient.js:1405](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1405) +[packages/cozy-client/src/CozyClient.js:1466](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1466) *** @@ -1441,7 +1441,7 @@ Contains the fetched token and the client information. *Defined in* -[packages/cozy-client/src/CozyClient.js:426](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L426) +[packages/cozy-client/src/CozyClient.js:428](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L428) *** @@ -1509,7 +1509,7 @@ client.plugins.alerts *Defined in* -[packages/cozy-client/src/CozyClient.js:286](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L286) +[packages/cozy-client/src/CozyClient.js:288](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L288) *** @@ -1529,7 +1529,7 @@ client.plugins.alerts *Defined in* -[packages/cozy-client/src/CozyClient.js:237](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L237) +[packages/cozy-client/src/CozyClient.js:239](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L239) *** @@ -1548,7 +1548,7 @@ Contains the fetched token and the client information. *Defined in* -[packages/cozy-client/src/CozyClient.js:1500](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1500) +[packages/cozy-client/src/CozyClient.js:1561](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1561) *** @@ -1568,7 +1568,7 @@ Contains the fetched token and the client information. *Defined in* -[packages/cozy-client/src/CozyClient.js:1177](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1177) +[packages/cozy-client/src/CozyClient.js:1238](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1238) *** @@ -1594,7 +1594,7 @@ This method will reset the query state to its initial state and refetch it. *Defined in* -[packages/cozy-client/src/CozyClient.js:1798](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1798) +[packages/cozy-client/src/CozyClient.js:1859](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1859) *** @@ -1617,7 +1617,7 @@ Create or update a document on the server *Defined in* -[packages/cozy-client/src/CozyClient.js:636](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L636) +[packages/cozy-client/src/CozyClient.js:638](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L638) *** @@ -1652,7 +1652,7 @@ save the new resulting settings into database *Defined in* -[packages/cozy-client/src/CozyClient.js:1786](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1786) +[packages/cozy-client/src/CozyClient.js:1847](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1847) *** @@ -1681,7 +1681,7 @@ Saves multiple documents in one batch *Defined in* -[packages/cozy-client/src/CozyClient.js:657](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L657) +[packages/cozy-client/src/CozyClient.js:659](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L659) *** @@ -1701,7 +1701,7 @@ Saves multiple documents in one batch *Defined in* -[packages/cozy-client/src/CozyClient.js:1752](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1752) +[packages/cozy-client/src/CozyClient.js:1813](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1813) *** @@ -1725,7 +1725,7 @@ set some data in the store. *Defined in* -[packages/cozy-client/src/CozyClient.js:1725](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1725) +[packages/cozy-client/src/CozyClient.js:1786](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1786) *** @@ -1749,7 +1749,7 @@ At any time put an error function *Defined in* -[packages/cozy-client/src/CozyClient.js:1738](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1738) +[packages/cozy-client/src/CozyClient.js:1799](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1799) *** @@ -1787,7 +1787,7 @@ use options.force = true. *Defined in* -[packages/cozy-client/src/CozyClient.js:1526](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1526) +[packages/cozy-client/src/CozyClient.js:1587](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1587) *** @@ -1811,7 +1811,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:1421](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1421) +[packages/cozy-client/src/CozyClient.js:1482](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1482) *** @@ -1825,7 +1825,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:1745](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1745) +[packages/cozy-client/src/CozyClient.js:1806](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1806) *** @@ -1846,7 +1846,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:855](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L855) +[packages/cozy-client/src/CozyClient.js:857](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L857) *** @@ -1868,7 +1868,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:880](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L880) +[packages/cozy-client/src/CozyClient.js:882](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L882) *** @@ -1888,7 +1888,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:625](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L625) +[packages/cozy-client/src/CozyClient.js:627](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L627) *** @@ -1908,7 +1908,7 @@ Contains the fetched token and the client information. These should be stored an *Defined in* -[packages/cozy-client/src/CozyClient.js:1028](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1028) +[packages/cozy-client/src/CozyClient.js:1030](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1030) *** @@ -1934,7 +1934,7 @@ the DOM. *Defined in* -[packages/cozy-client/src/CozyClient.js:389](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L389) +[packages/cozy-client/src/CozyClient.js:391](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L391) *** @@ -1958,7 +1958,7 @@ environment variables *Defined in* -[packages/cozy-client/src/CozyClient.js:360](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L360) +[packages/cozy-client/src/CozyClient.js:362](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L362) *** @@ -1982,7 +1982,7 @@ a client with a cookie-based instance of cozy-client-js. *Defined in* -[packages/cozy-client/src/CozyClient.js:310](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L310) +[packages/cozy-client/src/CozyClient.js:312](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L312) *** @@ -2010,7 +2010,7 @@ An instance of a client, configured from the old client *Defined in* -[packages/cozy-client/src/CozyClient.js:328](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L328) +[packages/cozy-client/src/CozyClient.js:330](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L330) *** @@ -2044,4 +2044,4 @@ There are at the moment only 2 hooks available. *Defined in* -[packages/cozy-client/src/CozyClient.js:849](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L849) +[packages/cozy-client/src/CozyClient.js:851](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L851) diff --git a/docs/api/cozy-client/classes/CozyLink.md b/docs/api/cozy-client/classes/CozyLink.md index 2cefac7a5b..911ff17705 100644 --- a/docs/api/cozy-client/classes/CozyLink.md +++ b/docs/api/cozy-client/classes/CozyLink.md @@ -12,13 +12,14 @@ ### constructor -• **new CozyLink**(`requestHandler`) +• **new CozyLink**(`requestHandler`, `persistHandler`) *Parameters* | Name | Type | | :------ | :------ | | `requestHandler` | `any` | +| `persistHandler` | `any` | *Defined in* @@ -26,6 +27,27 @@ ## Methods +### persistData + +▸ **persistData**(`data`, `forward`): `void` + +*Parameters* + +| Name | Type | +| :------ | :------ | +| `data` | `any` | +| `forward` | `any` | + +*Returns* + +`void` + +*Defined in* + +[packages/cozy-client/src/CozyLink.js:16](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyLink.js#L16) + +*** + ### request ▸ **request**(`operation`, `result`, `forward`): `void` @@ -44,4 +66,4 @@ *Defined in* -[packages/cozy-client/src/CozyLink.js:8](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyLink.js#L8) +[packages/cozy-client/src/CozyLink.js:12](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyLink.js#L12) diff --git a/docs/api/cozy-client/classes/StackLink.md b/docs/api/cozy-client/classes/StackLink.md index 7a8fb81bf5..28869785a3 100644 --- a/docs/api/cozy-client/classes/StackLink.md +++ b/docs/api/cozy-client/classes/StackLink.md @@ -62,7 +62,7 @@ Transfers queries and mutations to a remote stack *Defined in* -[packages/cozy-client/src/StackLink.js:114](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L114) +[packages/cozy-client/src/StackLink.js:118](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L118) *** @@ -82,7 +82,32 @@ Transfers queries and mutations to a remote stack *Defined in* -[packages/cozy-client/src/StackLink.js:91](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L91) +[packages/cozy-client/src/StackLink.js:95](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L95) + +*** + +### persistData + +▸ **persistData**(`data`, `forward`): `Promise`<`any`> + +*Parameters* + +| Name | Type | +| :------ | :------ | +| `data` | `any` | +| `forward` | `any` | + +*Returns* + +`Promise`<`any`> + +*Overrides* + +[CozyLink](CozyLink.md).[persistData](CozyLink.md#persistdata) + +*Defined in* + +[packages/cozy-client/src/StackLink.js:87](https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/StackLink.js#L87) *** diff --git a/docs/api/cozy-pouch-link/classes/PouchLink.md b/docs/api/cozy-pouch-link/classes/PouchLink.md index a396a9c90e..2a559b56e1 100644 --- a/docs/api/cozy-pouch-link/classes/PouchLink.md +++ b/docs/api/cozy-pouch-link/classes/PouchLink.md @@ -36,7 +36,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:81](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L81) +[CozyPouchLink.js:83](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L83) ## Properties @@ -46,7 +46,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:134](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L134) +[CozyPouchLink.js:136](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L136) *** @@ -56,7 +56,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:91](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L91) +[CozyPouchLink.js:93](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L93) *** @@ -66,7 +66,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:92](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L92) +[CozyPouchLink.js:94](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L94) *** @@ -76,7 +76,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:93](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L93) +[CozyPouchLink.js:95](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L95) *** @@ -86,7 +86,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:85](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L85) +[CozyPouchLink.js:87](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L87) *** @@ -96,7 +96,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:204](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L204) +[CozyPouchLink.js:206](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L206) *** @@ -106,7 +106,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:99](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L99) +[CozyPouchLink.js:101](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L101) *** @@ -116,7 +116,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:94](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L94) +[CozyPouchLink.js:96](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L96) ## Methods @@ -136,7 +136,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:567](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L567) +[CozyPouchLink.js:607](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L607) *** @@ -156,7 +156,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:528](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L528) +[CozyPouchLink.js:568](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L568) *** @@ -177,7 +177,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:571](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L571) +[CozyPouchLink.js:611](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L611) *** @@ -197,7 +197,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:556](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L556) +[CozyPouchLink.js:596](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L596) *** @@ -218,7 +218,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:427](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L427) +[CozyPouchLink.js:467](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L467) *** @@ -240,13 +240,13 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:499](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L499) +[CozyPouchLink.js:539](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L539) *** ### executeQuery -▸ **executeQuery**(`__namedParameters`): `Promise`<{ `data`: `any` ; `meta`: { `count`: `any` = docs.length } ; `next`: `boolean` ; `skip`: `any` = offset } | { `data`: `any` ; `meta`: `undefined` ; `next`: `undefined` ; `skip`: `undefined` = offset }> +▸ **executeQuery**(`__namedParameters`): `Promise`<{ `data`: `any` = res.cozyPouchData; `meta`: `undefined` ; `next`: `undefined` ; `skip`: `undefined` = offset } | { `data`: `any` ; `meta`: { `count`: `any` = docs.length } ; `next`: `boolean` ; `skip`: `any` = offset }> *Parameters* @@ -256,11 +256,11 @@ CozyLink.constructor *Returns* -`Promise`<{ `data`: `any` ; `meta`: { `count`: `any` = docs.length } ; `next`: `boolean` ; `skip`: `any` = offset } | { `data`: `any` ; `meta`: `undefined` ; `next`: `undefined` ; `skip`: `undefined` = offset }> +`Promise`<{ `data`: `any` = res.cozyPouchData; `meta`: `undefined` ; `next`: `undefined` ; `skip`: `undefined` = offset } | { `data`: `any` ; `meta`: { `count`: `any` = docs.length } ; `next`: `boolean` ; `skip`: `any` = offset }> *Defined in* -[CozyPouchLink.js:445](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L445) +[CozyPouchLink.js:485](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L485) *** @@ -280,7 +280,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:321](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L321) +[CozyPouchLink.js:323](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L323) *** @@ -300,7 +300,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:114](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L114) +[CozyPouchLink.js:116](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L116) *** @@ -320,7 +320,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:317](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L317) +[CozyPouchLink.js:319](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L319) *** @@ -340,7 +340,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:258](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L258) +[CozyPouchLink.js:260](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L260) *** @@ -360,7 +360,7 @@ CozyLink.constructor *Defined in* -[CozyPouchLink.js:253](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L253) +[CozyPouchLink.js:255](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L255) *** @@ -386,7 +386,7 @@ Emits an event (pouchlink:sync:end) when the sync (all doctypes) is done *Defined in* -[CozyPouchLink.js:239](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L239) +[CozyPouchLink.js:241](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L241) *** @@ -406,7 +406,7 @@ Emits an event (pouchlink:sync:end) when the sync (all doctypes) is done *Defined in* -[CozyPouchLink.js:409](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L409) +[CozyPouchLink.js:449](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L449) *** @@ -427,7 +427,7 @@ Emits an event (pouchlink:sync:end) when the sync (all doctypes) is done *Defined in* -[CozyPouchLink.js:414](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L414) +[CozyPouchLink.js:454](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L454) *** @@ -457,7 +457,7 @@ Migrate the current adapter *Defined in* -[CozyPouchLink.js:148](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L148) +[CozyPouchLink.js:150](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L150) *** @@ -482,7 +482,7 @@ the need to wait for the warmup *Defined in* -[CozyPouchLink.js:395](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L395) +[CozyPouchLink.js:435](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L435) *** @@ -496,7 +496,7 @@ the need to wait for the warmup *Defined in* -[CozyPouchLink.js:167](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L167) +[CozyPouchLink.js:169](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L169) *** @@ -516,7 +516,32 @@ the need to wait for the warmup *Defined in* -[CozyPouchLink.js:297](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L297) +[CozyPouchLink.js:299](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L299) + +*** + +### persistData + +▸ **persistData**(`data`, `forward?`): `Promise`<`void`> + +*Parameters* + +| Name | Type | Default value | +| :------ | :------ | :------ | +| `data` | `any` | `undefined` | +| `forward` | (`operation`: `any`, `result`: `any`) => `void` | `doNothing` | + +*Returns* + +`Promise`<`void`> + +*Overrides* + +CozyLink.persistData + +*Defined in* + +[CozyPouchLink.js:390](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L390) *** @@ -536,7 +561,7 @@ the need to wait for the warmup *Defined in* -[CozyPouchLink.js:133](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L133) +[CozyPouchLink.js:135](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L135) *** @@ -562,7 +587,7 @@ CozyLink.request *Defined in* -[CozyPouchLink.js:340](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L340) +[CozyPouchLink.js:342](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L342) *** @@ -576,7 +601,7 @@ CozyLink.request *Defined in* -[CozyPouchLink.js:223](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L223) +[CozyPouchLink.js:225](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L225) *** @@ -595,7 +620,7 @@ Emits pouchlink:sync:start event when the replication begins *Defined in* -[CozyPouchLink.js:272](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L272) +[CozyPouchLink.js:274](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L274) *** @@ -614,7 +639,7 @@ Emits pouchlink:sync:stop event *Defined in* -[CozyPouchLink.js:289](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L289) +[CozyPouchLink.js:291](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L291) *** @@ -634,7 +659,7 @@ Emits pouchlink:sync:stop event *Defined in* -[CozyPouchLink.js:325](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L325) +[CozyPouchLink.js:327](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L327) *** @@ -648,7 +673,7 @@ Emits pouchlink:sync:stop event *Defined in* -[CozyPouchLink.js:593](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L593) +[CozyPouchLink.js:633](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L633) *** @@ -668,7 +693,7 @@ Emits pouchlink:sync:stop event *Defined in* -[CozyPouchLink.js:533](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L533) +[CozyPouchLink.js:573](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L573) *** @@ -688,7 +713,7 @@ Emits pouchlink:sync:stop event *Defined in* -[CozyPouchLink.js:538](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L538) +[CozyPouchLink.js:578](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L578) *** @@ -713,4 +738,4 @@ The adapter name *Defined in* -[CozyPouchLink.js:109](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L109) +[CozyPouchLink.js:111](https://github.com/cozy/cozy-client/blob/master/packages/cozy-pouch-link/src/CozyPouchLink.js#L111) diff --git a/packages/cozy-client/types/CozyClient.d.ts b/packages/cozy-client/types/CozyClient.d.ts index 04f4826f7a..a5b7934277 100644 --- a/packages/cozy-client/types/CozyClient.d.ts +++ b/packages/cozy-client/types/CozyClient.d.ts @@ -1,4 +1,50 @@ export default CozyClient; +export type CozyClientDocument = { + /** + * - Id of the document + */ + _id?: string; + /** + * - Id of the document + */ + id?: string; + /** + * - Type of the document + */ + _type?: string; + /** + * - Current revision of the document + */ + _rev?: string; + /** + * - When the document has been deleted + */ + _deleted?: boolean; + /** + * - Relationships of the document + */ + relationships?: import("./types").ReferencedByRelationship; + /** + * - referenced by of another document + */ + referenced_by?: import("./types").Reference[]; + /** + * - Cozy Metadata + */ + cozyMetadata?: import("./types").CozyMetadata; + /** + * - Pouch Metadata + */ + meta?: import("./types").CozyClientDocumentMeta; + /** + * - When true the document should NOT be replicated to the remote database + */ + cozyLocalOnly?: boolean; + /** + * - When true the document has been retrieved from a local PouchDB + */ + cozyFromPouch?: boolean; +}; export type ClientOptions = { client?: object; link?: object; @@ -36,6 +82,8 @@ export type ClientOptions = { store?: boolean; }; /** + * @typedef {import("./types").CozyClientDocument} CozyClientDocument + * * @typedef {object} ClientOptions * @property {object} [client] * @property {object} [link] @@ -458,6 +506,23 @@ declare class CozyClient { * @returns {Promise} */ private requestQuery; + /** + * Save the document or array of documents into the persisted storage (if any) + * + * @private + * @param {CozyClientDocument | Array} data - Document or array of documents to be saved + * @returns {Promise} + */ + private persistVirtualDocuments; + /** + * Save the document or array of documents into the persisted storage (if any) + * + * @private + * @param {CozyClientDocument} document - Document to be saved + * @param {boolean} enforce - When true, save the document even if `meta.rev` or `_rev` exist + * @returns {Promise} + */ + private persistVirtualDocument; /** * Fetch relationships for a response (can be several docs). * Fills the `relationships` attribute of each documents. diff --git a/packages/cozy-client/types/CozyLink.d.ts b/packages/cozy-client/types/CozyLink.d.ts index fb2974b285..bf6173d9c0 100644 --- a/packages/cozy-client/types/CozyLink.d.ts +++ b/packages/cozy-client/types/CozyLink.d.ts @@ -1,5 +1,6 @@ export default class CozyLink { - constructor(requestHandler: any); + constructor(requestHandler: any, persistHandler: any); request(operation: any, result: any, forward: any): void; + persistData(data: any, forward: any): void; } export function chain(links: any): any; diff --git a/packages/cozy-client/types/types.d.ts b/packages/cozy-client/types/types.d.ts index 51b219aeb3..f0bcba281c 100644 --- a/packages/cozy-client/types/types.d.ts +++ b/packages/cozy-client/types/types.d.ts @@ -694,6 +694,15 @@ export type CozyMetadata = { */ favorite?: boolean; }; +/** + * - Meta object as specified by JSON-API (https://jsonapi.org/format/#document-meta) + */ +export type CozyClientDocumentMeta = { + /** + * - Current revision of the document + */ + rev?: string; +}; /** * - A document */ @@ -730,6 +739,18 @@ export type CozyClientDocument = { * - Cozy Metadata */ cozyMetadata?: CozyMetadata; + /** + * - Pouch Metadata + */ + meta?: CozyClientDocumentMeta; + /** + * - When true the document should NOT be replicated to the remote database + */ + cozyLocalOnly?: boolean; + /** + * - When true the document has been retrieved from a local PouchDB + */ + cozyFromPouch?: boolean; }; /** * - A io.cozy.files document's metadata diff --git a/packages/cozy-pouch-link/types/CozyPouchLink.d.ts b/packages/cozy-pouch-link/types/CozyPouchLink.d.ts index 127c172b69..2023a26533 100644 --- a/packages/cozy-pouch-link/types/CozyPouchLink.d.ts +++ b/packages/cozy-pouch-link/types/CozyPouchLink.d.ts @@ -1,8 +1,11 @@ export function getReplicationURL(uri: any, token: any, doctype: any): string; export function isExpiredTokenError(pouchError: any): boolean; export default PouchLink; +export type CozyClientDocument = any; export type SyncStatus = "idle" | "replicating"; /** + * @typedef {import('cozy-client/src/types').CozyClientDocument} CozyClientDocument + * * @typedef {"idle"|"replicating"} SyncStatus */ /** @@ -117,6 +120,16 @@ declare class PouchLink extends CozyLink { getSyncInfo(doctype: any): any; getPouch(doctype: any): any; supportsOperation(operation: any): boolean; + /** + * Retrieve the existing document from Pouch + * + * @private + * @param {*} id - ID of the document to retrieve + * @param {*} type - Doctype of the document to retrieve + * @param {*} throwIfNotFound - If true the method will throw when the document is not found. Otherwise it will return null + * @returns {Promise} + */ + private getExistingDocument; /** * * Check if there is warmup queries for this doctype @@ -141,17 +154,17 @@ declare class PouchLink extends CozyLink { indexedFields: any; partialFilter: any; }): Promise<{ + data: any; + meta?: undefined; + skip?: undefined; + next?: undefined; + } | { data: any; meta: { count: any; }; skip: any; next: boolean; - } | { - data: any; - meta?: undefined; - skip?: undefined; - next?: undefined; }>; executeMutation(mutation: any, result: any, forward: any): Promise; createDocument(mutation: any): Promise; diff --git a/packages/cozy-pouch-link/types/jsonapi.d.ts b/packages/cozy-pouch-link/types/jsonapi.d.ts index defaa60591..bdd3d3ed37 100644 --- a/packages/cozy-pouch-link/types/jsonapi.d.ts +++ b/packages/cozy-pouch-link/types/jsonapi.d.ts @@ -1,14 +1,14 @@ export function normalizeDoc(doc: any, doctype: any): any; export function fromPouchResult(res: any, withRows: any, doctype: any): { + data: any; + meta?: undefined; + skip?: undefined; + next?: undefined; +} | { data: any; meta: { count: any; }; skip: any; next: boolean; -} | { - data: any; - meta?: undefined; - skip?: undefined; - next?: undefined; };