Skip to content

Commit

Permalink
feat: Expose real time dispatch changes function
Browse files Browse the repository at this point in the history
When in a React environment, we use the RealTimeQueries component to
subscribe to a doctype changes and keep the internal store updated.

To be able to do the same thing manually for non React environment,
we expose the underlaying functions : dispatchCreate, dispatchCreate,
dispatchDelete.
  • Loading branch information
zatteo committed Sep 18, 2024
1 parent 30d2ca1 commit 6026040
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 70 deletions.
72 changes: 72 additions & 0 deletions docs/api/cozy-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,78 @@ Deconstructed link

***

### dispatchCreate

**dispatchCreate**(`client`, `doctype`, `couchDBDoc`): `void`

Dispatches a create action for a document to update CozyClient store from realtime callbacks.

*Parameters*

| Name | Type | Description |
| :------ | :------ | :------ |
| `client` | [`CozyClient`](classes/CozyClient.md) | CozyClient instance |
| `doctype` | `string` | Doctype of the document to create |
| `couchDBDoc` | `CouchDBDocument` | Document to create |

*Returns*

`void`

*Defined in*

packages/cozy-client/src/store/realtimes.js:59

***

### dispatchDelete

**dispatchDelete**(`client`, `doctype`, `couchDBDoc`): `void`

Dispatches a delete action for a document to update CozyClient store from realtime callbacks.

*Parameters*

| Name | Type | Description |
| :------ | :------ | :------ |
| `client` | [`CozyClient`](classes/CozyClient.md) | CozyClient instance |
| `doctype` | `string` | Doctype of the document to create |
| `couchDBDoc` | `CouchDBDocument` | Document to create |

*Returns*

`void`

*Defined in*

packages/cozy-client/src/store/realtimes.js:81

***

### dispatchUpdate

**dispatchUpdate**(`client`, `doctype`, `couchDBDoc`): `void`

Dispatches a update action for a document to update CozyClient store from realtime callbacks.

*Parameters*

| Name | Type | Description |
| :------ | :------ | :------ |
| `client` | [`CozyClient`](classes/CozyClient.md) | CozyClient instance |
| `doctype` | `string` | Doctype of the document to create |
| `couchDBDoc` | `CouchDBDocument` | Document to create |

*Returns*

`void`

*Defined in*

packages/cozy-client/src/store/realtimes.js:70

***

### ensureFirstSlash

**ensureFirstSlash**(`path`): `any`
Expand Down
82 changes: 14 additions & 68 deletions packages/cozy-client/src/RealTimeQueries.jsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,10 @@
import { memo, useEffect } from 'react'
import useClient from './hooks/useClient'
import { Mutations } from './queries/dsl'
import { receiveMutationResult } from './store'
import CozyClient from './CozyClient'

/**
* Normalizes an object representing a CouchDB document
*
* Ensures existence of `_type`
*
* @public
* @param {import("./types").CouchDBDocument} couchDBDoc - object representing the document
* @returns {import("./types").CozyClientDocument} full normalized document
*/
const normalizeDoc = (couchDBDoc, doctype) => {
return {
id: couchDBDoc._id,
_type: doctype,
...couchDBDoc
}
}

/**
* DispatchChange
*
* @param {CozyClient} client CozyClient instane
* @param {import("./types").Doctype} doctype Doctype of the document to update
* @param {import("./types").CouchDBDocument} couchDBDoc Document to update
* @param {import("./types").Mutation} mutationDefinitionCreator Mutation to apply
*/
const dispatchChange = (
client,
doctype,
couchDBDoc,
mutationDefinitionCreator
) => {
const data = normalizeDoc(couchDBDoc, doctype)
const response = {
data
}

const options = {}
client.dispatch(
receiveMutationResult(
client.generateRandomId(),
response,
options,
mutationDefinitionCreator(data)
)
)
}
import {
dispatchCreate,
dispatchDelete,
dispatchUpdate
} from './store/realtimes'

/**
* Component that subscribes to a doctype changes and keep the
Expand All @@ -71,25 +26,16 @@ const RealTimeQueries = ({ doctype }) => {
)
}

const dispatchCreate = couchDBDoc => {
dispatchChange(client, doctype, couchDBDoc, Mutations.createDocument)
}
const dispatchUpdate = couchDBDoc => {
dispatchChange(client, doctype, couchDBDoc, Mutations.updateDocument)
}
const dispatchDelete = couchDBDoc => {
dispatchChange(
client,
doctype,
{ ...couchDBDoc, _deleted: true },
Mutations.deleteDocument
)
}

const subscribe = async () => {
await realtime.subscribe('created', doctype, dispatchCreate)
await realtime.subscribe('updated', doctype, dispatchUpdate)
await realtime.subscribe('deleted', doctype, dispatchDelete)
await realtime.subscribe('created', doctype, data =>
dispatchCreate(client, doctype, data)
)
await realtime.subscribe('updated', doctype, data =>
dispatchUpdate(client, doctype, data)
)
await realtime.subscribe('deleted', doctype, data =>
dispatchDelete(client, doctype, data)
)
}
subscribe()

Expand Down
7 changes: 6 additions & 1 deletion packages/cozy-client/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ export {
isQueriesLoading,
hasQueriesBeenLoaded
} from './utils'
export { getQueryFromState } from './store'
export {
getQueryFromState,
dispatchCreate,
dispatchUpdate,
dispatchDelete
} from './store'
export { default as Registry } from './registry'
export { default as RealTimeQueries } from './RealTimeQueries'

Expand Down
2 changes: 2 additions & 0 deletions packages/cozy-client/src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,5 @@ export {
receiveMutationResult,
receiveMutationError
} from './mutations'

export { dispatchCreate, dispatchUpdate, dispatchDelete } from './realtimes'
88 changes: 88 additions & 0 deletions packages/cozy-client/src/store/realtimes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { Mutations } from '../queries/dsl'
import { receiveMutationResult } from './mutations'
import CozyClient from '../CozyClient'

/**
* Normalizes an object representing a CouchDB document
*
* Ensures existence of `_type`
*
* @public
* @param {import("../types").CouchDBDocument} couchDBDoc - object representing the document
* @returns {import("../types").CozyClientDocument} full normalized document
*/
const normalizeDoc = (couchDBDoc, doctype) => {
return {
id: couchDBDoc._id,
_type: doctype,
...couchDBDoc
}
}

/**
* DispatchChange
*
* @param {CozyClient} client CozyClient instane
* @param {import("../types").Doctype} doctype Doctype of the document to update
* @param {import("../types").CouchDBDocument} couchDBDoc Document to update
* @param {import("../types").Mutation} mutationDefinitionCreator Mutation to apply
*/
const dispatchChange = (
client,
doctype,
couchDBDoc,
mutationDefinitionCreator
) => {
const data = normalizeDoc(couchDBDoc, doctype)
const response = {
data
}

const options = {}
client.dispatch(
receiveMutationResult(
client.generateRandomId(),
response,
options,
mutationDefinitionCreator(data)
)
)
}

/**
* Dispatches a create action for a document to update CozyClient store from realtime callbacks.
*
* @param {CozyClient} client - CozyClient instance
* @param {import("../types").Doctype} doctype - Doctype of the document to create
* @param {import("../types").CouchDBDocument} couchDBDoc - Document to create
*/
export const dispatchCreate = (client, doctype, couchDBDoc) => {
dispatchChange(client, doctype, couchDBDoc, Mutations.createDocument)
}

/**
* Dispatches a update action for a document to update CozyClient store from realtime callbacks.
*
* @param {CozyClient} client - CozyClient instance
* @param {import("../types").Doctype} doctype - Doctype of the document to create
* @param {import("../types").CouchDBDocument} couchDBDoc - Document to create
*/
export const dispatchUpdate = (client, doctype, couchDBDoc) => {
dispatchChange(client, doctype, couchDBDoc, Mutations.updateDocument)
}

/**
* Dispatches a delete action for a document to update CozyClient store from realtime callbacks.
*
* @param {CozyClient} client - CozyClient instance
* @param {import("../types").Doctype} doctype - Doctype of the document to create
* @param {import("../types").CouchDBDocument} couchDBDoc - Document to create
*/
export const dispatchDelete = (client, doctype, couchDBDoc) => {
dispatchChange(
client,
doctype,
{ ...couchDBDoc, _deleted: true },
Mutations.deleteDocument
)
}
2 changes: 1 addition & 1 deletion packages/cozy-client/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ export { default } from "./CozyClient";
export { default as CozyLink } from "./CozyLink";
export { default as StackLink } from "./StackLink";
export { default as compose } from "lodash/flow";
export { getQueryFromState } from "./store";
export { default as Registry } from "./registry";
export { default as RealTimeQueries } from "./RealTimeQueries";
export { default as CozyProvider } from "./Provider";
Expand All @@ -21,4 +20,5 @@ export { Association, HasMany, HasOne, HasOneInPlace, HasManyInPlace, HasManyTri
export { isReferencedBy, isReferencedById, getReferencedBy, getReferencedById } from "./associations/helpers";
export { deconstructCozyWebLinkWithSlug, deconstructRedirectLink, dehydrate, generateWebLink, ensureFirstSlash, rootCozyUrl, InvalidRedirectLinkError, InvalidCozyUrlError, InvalidProtocolError, BlockedCozyError } from "./helpers";
export { cancelable, isQueryLoading, hasQueryBeenLoaded, isQueriesLoading, hasQueriesBeenLoaded } from "./utils";
export { getQueryFromState, dispatchCreate, dispatchUpdate, dispatchDelete } from "./store";
export { queryConnect, queryConnectFlat, withClient } from "./hoc";
1 change: 1 addition & 0 deletions packages/cozy-client/types/store/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ export function resetState(): {
export { getStateRoot, getCollectionFromState, getDocumentFromState, getQueryFromStore, getQueryFromState, getRawQueryFromState, isQueryExisting } from "./stateHelpers";
export { initQuery, loadQuery, resetQuery, receiveQueryResult, receiveQueryError, executeQueryFromState } from "./queries";
export { initMutation, receiveMutationResult, receiveMutationError } from "./mutations";
export { dispatchCreate, dispatchUpdate, dispatchDelete } from "./realtimes";
4 changes: 4 additions & 0 deletions packages/cozy-client/types/store/realtimes.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export function dispatchCreate(client: CozyClient, doctype: import("../types").Doctype, couchDBDoc: import("../types").CouchDBDocument): void;
export function dispatchUpdate(client: CozyClient, doctype: import("../types").Doctype, couchDBDoc: import("../types").CouchDBDocument): void;
export function dispatchDelete(client: CozyClient, doctype: import("../types").Doctype, couchDBDoc: import("../types").CouchDBDocument): void;
import CozyClient from "../CozyClient";

0 comments on commit 6026040

Please sign in to comment.