# Actions

Actions are minimal descriptions of store updates.

They are [dispatched by Controller methods](https://dataclient.io/vue/api/Controller.md#action-dispatchers) ->
[read and consumed by Manager middleware](https://dataclient.io/vue/api/Manager.md#reading-and-consuming-actions) ->
processed by [reducers](https://react.dev/reference/react/useReducer) registered with [DataClientPlugin](https://dataclient.io/vue/api/DataClientPlugin.md)
to update the store's state.

Many actions use the same meta information:

```ts
interface ActionMeta {
  readonly fetchedAt: number;
  readonly date: number;
  readonly expiresAt: number;
}
```

## FETCH

```ts
interface FetchMeta {
  fetchedAt: number;
  resolve: (value?: any | PromiseLike<any>) => void;
  reject: (reason?: any) => void;
  promise: Promise<any>;
}

interface FetchAction {
  type: typeof actionTypes.FETCH;
  endpoint: Endpoint;
  args: readonly [...Parameters<Endpoint>];
  key: string;
  meta: FetchMeta;
}
```

```js
{
  type: 'rdc/fetch',
  key: 'GET https://jsonplaceholder.typicode.com/todos?userId=1',
  args: [
    {
      userId: 1
    }
  ],
  endpoint: Endpoint('User.getList'),
  meta: {
    fetchedAt: '5:09:41.975 PM',
    resolve: function (){},
    reject: function (){},
    promise: {}
  }
}
```

Sent by [Controller.fetch()](https://dataclient.io/vue/api/Controller.md#fetch), [Controller.fetchIfStale()](https://dataclient.io/vue/api/Controller.md#fetchIfStale),
[useSuspense()](https://dataclient.io/vue/api/useSuspense.md), [useDLE()](https://dataclient.io/vue/api/useDLE.md), [useLive()](https://dataclient.io/vue/api/useLive.md), [useFetch()](https://dataclient.io/vue/api/useFetch.md)

Read by [NetworkManager](https://dataclient.io/vue/api/NetworkManager.md)

## SET

```ts
interface SetAction {
  type: typeof actionTypes.SET;
  schema: Queryable;
  args: readonly any[];
  meta: ActionMeta;
  value: {} | ((previousValue: Denormalize<Queryable>) => {});
}
```

```js
{
  type: 'rdc/set',
  value: {
    userId: 1,
    id: 1,
    title: 'delectus aut autem',
    completed: true
  },
  args: [
    {
      id: 1
    }
  ],
  schema: Todo,
  meta: {
    fetchedAt: '5:18:26.394 PM',
    date: '5:18:26.636 PM',
    expiresAt: '6:18:26.636 PM'
  }
}
```

Sent by [Controller.set()](https://dataclient.io/vue/api/Controller.md#set)

## SET\_RESPONSE

```ts
interface SetResponseAction {
  type: typeof actionTypes.SET_RESPONSE;
  endpoint: Endpoint;
  args: readonly any[];
  key: string;
  meta: ActionMeta;
  response: ResolveType<Endpoint> | Error;
  error: boolean;
}
```

```js
{
  type: 'rdc/setresponse',
  key: 'PATCH https://jsonplaceholder.typicode.com/todos/1',
  response: {
    userId: 1,
    id: 1,
    title: 'delectus aut autem',
    completed: true
  },
  args: [
    {
      id: 1
    },
    {
      completed: true
    }
  ],
  endpoint: Endpoint('Todo.partialUpdate'),
  meta: {
    fetchedAt: '5:18:26.394 PM',
    date: '5:18:26.636 PM',
    expiresAt: '6:18:26.636 PM'
  },
  error: false
}
```

Sent by [Controller.setResponse()](https://dataclient.io/vue/api/Controller.md#setResponse), [NetworkManager](https://dataclient.io/vue/api/NetworkManager.md)

Read by [NetworkManager](https://dataclient.io/vue/api/NetworkManager.md), [LogoutManager](https://dataclient.io/vue/api/LogoutManager.md)

## RESET

```ts
interface ResetAction {
  type: typeof actionTypes.RESET;
  date: number;
}
```

```js
{
  type: 'rdc/reset',
  date: '5:09:41.975 PM',
}
```

Sent by [Controller.resetEntireStore()](https://dataclient.io/vue/api/Controller.md#resetEntireStore)

Read by [NetworkManager](https://dataclient.io/vue/api/NetworkManager.md)

## SUBSCRIBE

```ts
interface SubscribeAction {
  type: typeof actionTypes.SUBSCRIBE;
  endpoint: Endpoint;
  args: readonly any[];
  key: string;
}
```

```js
{
  type: 'rdc/subscribe',
  key: 'GET https://api.exchange.coinbase.com/products/BTC-USD/ticker',
  args: [
    {
      product_id: 'BTC-USD'
    }
  ],
  endpoint: Endpoint('https://api.exchange.coinbase.com/products/:product_id/ticker'),
}
```

Sent by [Controller.subscribe()](https://dataclient.io/vue/api/Controller.md#subscribe), [useSubscription()](https://dataclient.io/vue/api/useSubscription.md), [useLive()](https://dataclient.io/vue/api/useLive.md)

Read by [SubscriptionManager](https://dataclient.io/vue/api/SubscriptionManager.md)

## UNSUBSCRIBE

```ts
interface UnsubscribeAction {
  type: typeof actionTypes.UNSUBSCRIBE;
  endpoint: Endpoint;
  args: readonly any[];
  key: string;
}
```

```js
{
  type: 'rdc/unsubscribe',
  key: 'GET https://api.exchange.coinbase.com/products/BTC-USD/ticker',
  args: [
    {
      product_id: 'BTC-USD'
    }
  ],
  endpoint: Endpoint('https://api.exchange.coinbase.com/products/:product_id/ticker'),
}
```

Sent by [Controller.unsubscribe()](https://dataclient.io/vue/api/Controller.md#unsubscribe), [useSubscription()](https://dataclient.io/vue/api/useSubscription.md), [useLive()](https://dataclient.io/vue/api/useLive.md)

Read by [SubscriptionManager](https://dataclient.io/vue/api/SubscriptionManager.md)

## INVALIDATE

```ts
interface InvalidateAction {
  type: typeof actionTypes.INVALIDATE;
  key: string;
}
```

```js
{
  type: 'rdc/invalidate',
  key: 'GET https://jsonplaceholder.typicode.com/todos?userId=1',
}
```

Sent by [Controller.invalidate()](https://dataclient.io/vue/api/Controller.md#invalidate)

## INVALIDATEALL

```ts
interface InvalidateAllAction {
  type: typeof actionTypes.INVALIDATEALL;
  testKey: (key: string) => boolean;
}
```

```js
{
  type: 'rdc/invalidateall',
  testKey: Endpoint('User.getList'),
}
```

Sent by [Controller.invalidateAll()](https://dataclient.io/vue/api/Controller.md#invalidateAll)

## EXPIREALL

```ts
interface ExpireAllAction {
  type: typeof actionTypes.EXPIREALL;
  testKey: (key: string) => boolean;
}
```

```js
{
  type: 'rdc/expireall',
  testKey: Endpoint('User.getList'),
}
```

Sent by [Controller.expireAll()](https://dataclient.io/vue/api/Controller.md#expireAll)
