<commit_before># Providers

Providers are an abstraction specific to this framework with the goal of reducing the boilerplate needed to 
manage the global store.

They are built around *static classes*, in which properties are parts of the store and methods are either reducers or sagas.  
They are built this way because matching the redux concepts to already existing OOP concepts make them easier to reason about.  

However, using Providers is in no way a requirement.
If this abstraction doesn't suit you, you can still manage the store without it.  
See [vanilla-redux](./vanilla-redux.md) for more information.

These classes require heavy transformations to be fully usable by redux. The details of which are explored further in this article.  
`@providers` are best used with `@containers`, although they are fully compatible with other property mapping systems.

## Concepts

As they are merely an abstraction over redux, providers do not introduce any new concept. Everything you know about
reducers, sagas, selectors, actions, and stores still apply.

Just in case though, here is a quick reminder:

- Store: The store contains the state of the application. It is the same as a redux store.
- Reducers: Functions able to read and write to a fragment of the store at will. They are called whenever 
  actions are dispatched.
- Sagas: Generator Functions called whenever actions are dispatched. They exist to handle store-related asynchronous operations. 
  (see the redux-saga documentation for more details).
- Selectors: Functions that will retrieve a part of the store.
- Actions: Commands dispatched to reducers to tell them what to do.

Providers are designed to only handle a fragment of the store at a time in order to promote separation of concerns.
 
## Usage

Creating a new Provider is straightforward, simply create a new file and export a class decorated with `@provider`.

```javascript
import { provider } from 'reworkjs/decorators';

@provider
export default class PreferenceProvider {
  
}
```

Boom, we just created a new provider dedicated to handling the state of the user preferences / app settings.

Now let's fill it with useful data.

### State

Adding state to a provider isn't very complicated. Simply add a static property to it and voilà:
As soon as the provider loads, the property will be added to the fragment of the store this provider handles.

```javascript
import { provider } from 'reworkjs/decorators';

@provider
export default class PreferenceProvider {
  
  static maySendNotifications = false;
}
```

**IMPORTANT**: The property still resides inside the store of the application. Therefore, it is impossible to read nor
write it unless you already have access to the store.

In order to achieve this, the `@provider` decorator transforms the class to make getting a property return a selector, and
setting them fail.

```javascript
// Getting a property returns a selector. You will need to call the selector with the store instance to access it.
const selector = PreferenceProvider.maySendNotifications;
// selector: [function select_maySendNotifications(store)]

// Setting a property.
PreferenceProvider.maySendNotifications = true;
// Error: Cannot access @provider state outside of @reducer annotated methods. If you are trying to r/w the state from a @saga, you will need to use "yield put(this.<reducerMethodName>())"
```

An important note about providers is that everything inside then must be `static`.  
Any static property that is not decorated with neither `@reducer` nor `@saga` will be considered part of the state.

*Getting/Setting non-declared state has an undefined behavior on older browsers and will fail on evergreen browsers.*

### Updating the state (reducers)<commit_msg>Getter Documentation<commit_after># Providers

Providers are an abstraction specific to this framework with the goal of reducing the boilerplate needed to 
manage the global store.

They are built around *static classes*, in which properties are parts of the store and methods are either reducers or sagas.  
They are built this way because matching the redux concepts to already existing OOP concepts make them easier to reason about.  

However, using Providers is in no way a requirement.
If this abstraction doesn't suit you, you can still manage the store without it.  
See [vanilla-redux](./vanilla-redux.md) for more information.

These classes require heavy transformations to be fully usable by redux. The details of which are explored further in this article.  
`@providers` are best used with `@containers`, although they are fully compatible with other property mapping systems.

## Concepts

As they are merely an abstraction over redux, providers do not introduce any new concept. Everything you know about
reducers, sagas, selectors, actions, and stores still apply.

Just in case though, here is a quick reminder:

- Store: The store contains the state of the application. It is the same as a redux store.
- Reducers: Functions able to read and write to a fragment of the store at will. They are called whenever 
  actions are dispatched.
- Sagas: Generator Functions called whenever actions are dispatched. They exist to handle store-related asynchronous operations. 
  (see the redux-saga documentation for more details).
- Selectors: Functions that will retrieve a part of the store.
- Actions: Commands dispatched to reducers to tell them what to do.

Providers are designed to only handle a fragment of the store at a time in order to promote separation of concerns.
 
## Usage

Creating a new Provider is straightforward, simply create a new file and export a class decorated with `@provider`.

```javascript
import { provider } from 'reworkjs/decorators';

@provider
export default class PreferenceProvider {
  
}
```

Boom, we just created a new provider dedicated to handling the state of the user preferences / app settings.

Now let's fill it with useful data.

### State

Adding state to a provider isn't very complicated. Simply add a static property to it and voilà:
As soon as the provider loads, the property will be added to the fragment of the store this provider handles.

```javascript
import { provider } from 'reworkjs/decorators';

@provider
export default class PreferenceProvider {
  
  static maySendNotifications = false;
}
```

**IMPORTANT**: The property still resides inside the store of the application. Therefore, it is impossible to read nor
write it unless you already have access to the store.

In order to achieve this, the `@provider` decorator transforms the class to make getting a property return a selector, and
setting them fail.

```javascript
// Getting a property returns a selector. You will need to call the selector with the store instance to access it.
const selector = PreferenceProvider.maySendNotifications;
// selector: [function select_maySendNotifications(store)]

// Setting a property.
PreferenceProvider.maySendNotifications = true;
// Error: Cannot access @provider state outside of @reducer annotated methods. If you are trying to r/w the state from a @saga, you will need to use "yield put(this.<reducerMethodName>())"
```

An important note about providers is that everything inside then must be `static`.  
Any static property that is not decorated with neither `@reducer` nor `@saga` will be considered part of the state.

*Getting/Setting non-declared state has an undefined behavior on older browsers and will fail on evergreen browsers.*

### Getters

State getters are supported by Providers and will work like regular state with the difference that you cannot set them.   
Their value are computed based on other state properties.

```javascript
import { provider } from 'reworkjs/decorators';

@provider
export default class UserProvider {

  static user = null;
  static get loggedIn() {
    return this.user != null;
  }
}

UserProvider.user;     // selector
UserProvider.loggedIn; // selector
UserProvider.loggedIn(store.getState()); // false
```

### Setters

Setters are currently unsupported by Providers due to technical limitations. Trying to define one will result in an error. 

### Updating the state (reducers)
{'fraction_non_alphanumeric': 0.055419323197645906, 'fraction_numerical': 0.0, 'mean_word_length': 4.448897795591182, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, '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': '6520407', 'n_tokens_mistral': 2061, 'n_tokens_neox': 1951, 'n_words': 1154}