# NetworkManager

NetworkManager orchestrates asynchronous fetches. By keeping track of all in-flight requests
it is able to dedupe identical requests if they are made using the throttle flag.

> **Info: implements**
>
> `NetworkManager` implements [Manager](https://dataclient.io/vue/api/Manager.md)

## Lifecycle

### Success

```mermaid
flowchart LR
  subgraph Controller.fetch
    direction TB
    key("Endpoint.key(...args)")--->dispatch("dispatch(FETCH)")
  end
  subgraph managers
    NetworkManager-->endpoint("endpoint(...args)")
    endpoint--resolves-->Controller.resolve
    Controller.resolve("Controller.resolve(response)")-->dispatchR("dispatch(SET_RESPONSE)")
  end
  managers--FETCH-->reducer:FETCH
  Controller.fetch--FETCH-->managers
  subgraph reducer:FETCH
    optimistic("Endpoint.?getOptimisticResponse()")-->SET_RESPONSE
    subgraph SET_RESPONSE
      normalize(normalize)-->update("Endpoint.update()")
    end
  end
  subgraph reducer:SET_RESPONSE
    direction LR
    normalize2(normalize)-->update2("Endpoint.update()")
  end
  managers--SET_RESPONSE-->reducer:SET_RESPONSE
  click key "/rest/api/Endpoint#key"
  click NetworkManager "/docs/api/NetworkManager"
  click optimistic "/rest/api/Endpoint#getoptimisticresponse"
  click update "/rest/api/Endpoint#update"
  click update2 "/rest/api/Endpoint#update"
  click dispatch "/docs/api/Actions#fetch"
  click dispatchR "/docs/api/Actions#set_response"
```

### Error

```mermaid
flowchart LR
  subgraph Controller.fetch
    direction TB
    key("Endpoint.key(...args)")--->dispatch("dispatch(FETCH)")
  end
  subgraph managers
    NetworkManager-->endpoint("endpoint(...args)")
    endpoint--rejects-->Controller.resolve
    Controller.resolve("Controller.resolve(error)")-->dispatchR("dispatch(SET_RESPONSE)")
  end
  managers--FETCH-->reducer:FETCH
  Controller.fetch--FETCH-->managers
  subgraph reducer:FETCH
    optimistic("Endpoint.?getOptimisticResponse()")-->SET_RESPONSE
    subgraph SET_RESPONSE
      normalize(normalize)-->update("Endpoint.update()")
    end
  end
  subgraph reducer:reduceError
    direction LR
    filterOptimistic(filterOptimistic)-->errorPolicy("Endpoint.errorPolicy()")
  end
  managers--SET_RESPONSE:error-->reducer:reduceError
  click key "/rest/api/Endpoint#key"
  click optimistic "/rest/api/Endpoint#getoptimisticresponse"
  click update "/rest/api/Endpoint#update"
  click errorPolicy "/rest/api/Endpoint#errorpolicy"
  click NetworkManager "/docs/api/NetworkManager"
  click dispatch "/docs/api/Actions#fetch"
  click dispatchR "/docs/api/Actions#set_response"
```

## Members

### constructor({ dataExpiryLength = 60000, errorExpiryLength = 1000 }) {#constructor}

Arguments represent the default time (in milliseconds) before a resource is considered 'stale'.

### middleware

#### Consumed Actions

- [fetch](https://dataclient.io/vue/api/Controller.md#fetch)

Will initiate network request and then dispatch upon completion.

#### Processed Actions

- [fetch](https://dataclient.io/vue/api/Controller.md#fetch)
- [setResponse](https://dataclient.io/vue/api/Controller.md#setResponse)
- [resetEntireStore](https://dataclient.io/vue/api/Controller.md#resetEntireStore)

#### Dispatched Actions

- [resolve](https://dataclient.io/vue/api/Controller.md#resolve)

### allSettled(): Promise {#allSettled}

Resolves once all fetches inflight are complete. Conceptually [Promise.allSettled](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled)

### skipLogging(action) {#skipLogging}

Used by DevtoolsManager to determine whether to log an action

Default:

```ts
skipLogging(action: ActionTypes) {
  return action.type === FETCH && action.meta.key in this.fetched;
}
```

## Protected members

### handleFetch(fetchAction) {#handlefetch}

Called when middleware intercepts 'rdc/fetch' action.

Will then start a promise for a key and potentially start the network
fetch.

Uses throttle only when instructed by action meta. This is valuable
for ensures mutation requests always go through.

### handleSet(setAction) {#handleset}

Called when middleware intercepts a set action.

Will resolve the promise associated with set key.

### throttle(key, fetch) {#throttle}

Ensures only one request for a given key is in flight at any time

Uses key to either retrieve in-flight promise, or if not
create a new promise and call fetch.

### getLastReset(): number {#getlastreset}

Timestamp when entire store was last reset

### clear(key) {#clear}

Clear promise state for a given key

### clearAll() {#clearall}

Ensures all promises are completed by rejecting remaining
