<commit_before># cozy-client
A simple and declarative way of managing [cozy-stack](https://github.com/cozy/cozy-stack) API calls and resulting data.

## Introduction
`cozy-client` is a convenient yet powerful way to bind `cozy-stack` queries to your React components, and may also be used without React. It uses `redux` internally to centralize the statuses of the various fetches and replications triggered by the library, and to store locally the data in a normalized way.

`cozy-client` is made of 2 layers:

 - an inner layer, the client itself, that allows fetching data with a simple API and can be used with any framework or library:
```js
import { CozyClient } from 'cozy-client'

const client = new CozyClient({...})
client.fetchDocument('io.cozy.todos', 'e8354db7abfef08b7a14e43b2b106a9d')
  .then(document => { /* do something with the document */ })
```

 - an outer layer that exposes `redux` action creators and selectors. These selectors return informations regarding to the state of the fetches, so that you can use these informations in your UI (by displaying a spinner for instance). This layer requires your app to use React or preact for now, but we're investigating ways of making it work with other libraries.

### Collections

Collections are simply lists of documents of the same type: when you fetch a collection with `cozy-client`, you retrieve a paginated list of documents filtered by [Mango selectors](https://github.com/cloudant/mango#selector-syntax).

```js
import { CozyClient } from 'cozy-client'

const client = new CozyClient({...})
client.fetchCollection('timeline', 'io.cozy.files', {
  fields: ['name', 'size', 'updated_at', 'metadata'],
  selector: {
    class: 'image',
    trashed: false
  },
  sort: {
    'metadata.datetime': 'desc'
  }
}).then(photos => { /* do something with the photos */ })
```
## Install
`npm install --save cozy-client`
or 
`yarn add cozy-client`

## Usage
You first need to instantiate a client and for that [to retrieve the domain name of the cozy instance and a token](https://cozy.github.io/cozy-docs-v3/en/dev/app/#behind-the-magic):

```js
import { CozyClient } from 'cozy-client'
const root = document.querySelector('[role=application]')
const data = root.dataset

const client = new CozyClient({
  cozyURL: `${window.location.protocol}//${data.cozyDomain}`,
  token: data.cozyToken
})
```

### Redux integration

To integrate `cozy-client` with your existing Redux store, you need to add a reducer and a middleware:

```js
import { cozyMiddleware, reducer } from 'cozy-client'
import { combineReducers, createStore, applyMiddleware } from 'redux'
import myReducers from './myapp'

const store = createStore(
  combineReducers({...myReducers, reducer}),
  applyMiddleware(cozyMiddleware)
)
```

### React integration

To make it easier to integrate data fetching in your component, you can use a specific higher-order component called `cozyConnect`. Basic example of usage:

```jsx
import React from 'react'
import { cozyConnect, fetchCollection } from 'cozy-client'

const TodoList = ({ todos }) => {
  const { data, fetchStatus } = props
  if (fetchStatus !== 'loaded') {
    return <h1>Loading...</h1>
  }
  return (
    <ul>
      {data.map(todo => <li>{todo.label}</li>)}
    </ul>
  )
}

const mapDocumentsToProps = (ownProps) => ({
  todos: fetchCollection('todos', 'io.cozy.todos')
})

export default cozyConnect(mapDocumentsToProps)(TodoList)
```
When we use `cozyConnect` to wrap a component, three things happen:
 - The actions specified by the `mapDocumentsToProps` function (here the `fetchCollection` call) will be dispatched when the component mounts, resulting in the loading of data from the client-side store, or the server if the data is not in the store
 - Our component subscribes to the store, so that it is updated if the data changes<commit_msg>doc: fix typo in CozyClient README 📚<commit_after># cozy-client
A simple and declarative way of managing [cozy-stack](https://github.com/cozy/cozy-stack) API calls and resulting data.

## Introduction
`cozy-client` is a convenient yet powerful way to bind `cozy-stack` queries to your React components, and may also be used without React. It uses `redux` internally to centralize the statuses of the various fetches and replications triggered by the library, and to store locally the data in a normalized way.

`cozy-client` is made of 2 layers:

 - an inner layer, the client itself, that allows fetching data with a simple API and can be used with any framework or library:
```js
import { CozyClient } from 'cozy-client'

const client = new CozyClient({...})
client.fetchDocument('io.cozy.todos', 'e8354db7abfef08b7a14e43b2b106a9d')
  .then(document => { /* do something with the document */ })
```

 - an outer layer that exposes `redux` action creators and selectors. These selectors return informations regarding to the state of the fetches, so that you can use these informations in your UI (by displaying a spinner for instance). This layer requires your app to use React or preact for now, but we're investigating ways of making it work with other libraries.

### Collections

Collections are simply lists of documents of the same type: when you fetch a collection with `cozy-client`, you retrieve a paginated list of documents filtered by [Mango selectors](https://github.com/cloudant/mango#selector-syntax).

```js
import { CozyClient } from 'cozy-client'

const client = new CozyClient({...})
client.fetchCollection('timeline', 'io.cozy.files', {
  fields: ['name', 'size', 'updated_at', 'metadata'],
  selector: {
    class: 'image',
    trashed: false
  },
  sort: {
    'metadata.datetime': 'desc'
  }
}).then(photos => { /* do something with the photos */ })
```
## Install
`npm install --save cozy-client`
or 
`yarn add cozy-client`

## Usage
You first need to instantiate a client and for that [to retrieve the domain name of the cozy instance and a token](https://cozy.github.io/cozy-docs-v3/en/dev/app/#behind-the-magic):

```js
import { CozyClient } from 'cozy-client'
const root = document.querySelector('[role=application]')
const data = root.dataset

const client = new CozyClient({
  cozyURL: `${window.location.protocol}//${data.cozyDomain}`,
  token: data.cozyToken
})
```

### Redux integration

To integrate `cozy-client` with your existing Redux store, you need to add a reducer and a middleware:

```js
import { cozyMiddleware, reducer } from 'cozy-client'
import { combineReducers, createStore, applyMiddleware } from 'redux'
import myReducers from './myapp'

const store = createStore(
  combineReducers({...myReducers, reducer}),
  applyMiddleware(cozyMiddleware)
)
```

### React integration

To make it easier to integrate data fetching in your component, you can use a specific higher-order component called `cozyConnect`. Basic example of usage:

```jsx
import React from 'react'
import { cozyConnect, fetchCollection } from 'cozy-client'

const TodoList = ({ todos }) => {
  const { data, fetchStatus } = todos
  if (fetchStatus !== 'loaded') {
    return <h1>Loading...</h1>
  }
  return (
    <ul>
      {data.map(todo => <li>{todo.label}</li>)}
    </ul>
  )
}

const mapDocumentsToProps = (ownProps) => ({
  todos: fetchCollection('todos', 'io.cozy.todos')
})

export default cozyConnect(mapDocumentsToProps)(TodoList)
```
When we use `cozyConnect` to wrap a component, three things happen:
 - The actions specified by the `mapDocumentsToProps` function (here the `fetchCollection` call) will be dispatched when the component mounts, resulting in the loading of data from the client-side store, or the server if the data is not in the store
 - Our component subscribes to the store, so that it is updated if the data changes
{'fraction_non_alphanumeric': 0.10974186016344532, 'fraction_numerical': 0.0054481774549228175, 'mean_word_length': 4.448763250883392, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 25, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5299013', 'n_tokens_mistral': 2326, 'n_tokens_neox': 2251, 'n_words': 905}