<commit_before># avenger

[![](https://travis-ci.org/buildo/avenger.svg)](https://travis-ci.org/buildo/avenger)
[![](https://img.shields.io/npm/v/avenger.svg?sytle=flat-square)](https://www.npmjs.com/package/avenger)
[![npm downloads](https://img.shields.io/npm/dm/avenger.svg?style=flat-square)](https://www.npmjs.com/package/avenger)
[![](https://david-dm.org/buildo/avenger.svg)](https://david-dm.org/buildo/avenger#info=dependencies&view=list)
[![](https://david-dm.org/buildo/avenger/dev-status.svg)](https://david-dm.org/buildo/avenger#info=devDependencies&view=list)

### TLDR

A CQRS-flavoured data fetching and caching layer in JavaScript.

Batching, caching, data-dependecies and manual invalidations in a declarative fashion for node and the browser.

### API layers

Avenger provides 3+ levels of apis:

- **layer 0** `fetch`: provides an abstraction over asyncronous data retrieval (`fetch`) and operators to compose different fetches together (`composition` and `product`). Includes data-dependencies and promise pipelining, and a prescription for api categorization.
- **layer 1** `fcache`: caching layer on top of `fetch`. Caching and batching happens here. This layer can be considered similar to [DataLoader](https://github.com/facebook/dataloader), adding more powerful caching strategies. You'd use this layer directly in a stateless (server-side) environment, where no long-living cache is involved.
- **layer 2** `query`: extends `fcache` with observable queries. You'd use this layer in a stateful (client) environment, where the app interacts with a long-living cache of remote/async data.
- **layer** + [react-avenger](https://github.com/buildo/react-avenger): provides helpers to connect an avenger instance to React components in a declarative fashion. You'd use this layer in a generic React client


# Fetch

A `fetch` is a function with the following signature:

```
fetch: A -> Promise[P]
```

whenever we write `~>` instead of `->` we're implying `Promise[]`

ex: we can write `fetch: A ~> P` for short.

## Classification

Given a fetch `fetch: A ~> P`:

- an *index* for `fetch` is defined as `List[A] ~> List[P]`
  - ex: `getListOfThingsByIds`
- a *catalog* for `fetch` is defined as `S ~> List[P]`
  - ex: `searchThingsWithQuery`

## Operators

### Product

Let:

```
f1: A1 ~> P1
f2: A2 ~> P2
...
fn: An ~> Pn
```

then:

```
product([f1, ... , fn]): [A1, ... , An] ~> [P1, ... , Pn]
```

in short:

We use the operator *product* whenever we want (and we always do if we can) to run multiple fetches in **parallel**.

### Composition

Let:<commit_msg>fix/improve index and catalog definitions<commit_after># avenger

[![](https://travis-ci.org/buildo/avenger.svg)](https://travis-ci.org/buildo/avenger)
[![](https://img.shields.io/npm/v/avenger.svg?sytle=flat-square)](https://www.npmjs.com/package/avenger)
[![npm downloads](https://img.shields.io/npm/dm/avenger.svg?style=flat-square)](https://www.npmjs.com/package/avenger)
[![](https://david-dm.org/buildo/avenger.svg)](https://david-dm.org/buildo/avenger#info=dependencies&view=list)
[![](https://david-dm.org/buildo/avenger/dev-status.svg)](https://david-dm.org/buildo/avenger#info=devDependencies&view=list)

### TLDR

A CQRS-flavoured data fetching and caching layer in JavaScript.

Batching, caching, data-dependecies and manual invalidations in a declarative fashion for node and the browser.

### API layers

Avenger provides 3+ levels of apis:

- **layer 0** `fetch`: provides an abstraction over asyncronous data retrieval (`fetch`) and operators to compose different fetches together (`composition` and `product`). Includes data-dependencies and promise pipelining, and a prescription for api categorization.
- **layer 1** `fcache`: caching layer on top of `fetch`. Caching and batching happens here. This layer can be considered similar to [DataLoader](https://github.com/facebook/dataloader), adding more powerful caching strategies. You'd use this layer directly in a stateless (server-side) environment, where no long-living cache is involved.
- **layer 2** `query`: extends `fcache` with observable queries. You'd use this layer in a stateful (client) environment, where the app interacts with a long-living cache of remote/async data.
- **layer** + [react-avenger](https://github.com/buildo/react-avenger): provides helpers to connect an avenger instance to React components in a declarative fashion. You'd use this layer in a generic React client


# Fetch

A `fetch` is a function with the following signature:

```
fetch: A -> Promise[P]
```

whenever we write `~>` instead of `->` we're implying `Promise[]`

ex: we can write `fetch: A ~> P` for short.

## Classification

Given a fetch `fetch: A ~> P`:

- an *index* for `fetch` is defined as `A ~> List[Id]` where
  - `A` is a generic "filter" argument (e.g: `ageMin=25`)
  - `Id` is an identifier for the `P` (it returns a list of Ids)
  - ex: `getThingIdsBySearchQuery -> Promise[List[ThingId]]`
- a *catalog* for `fetch` is defined as `A ~> List[P]` where
  - `A` is again a generic "filter" argument
  - `P` is the type of each item returned (it returns a list of payloads)
  - ex: `getThingsBySearchQuery -> Promise[List[Thing]]`

## Operators

### Product

Let:

```
f1: A1 ~> P1
f2: A2 ~> P2
...
fn: An ~> Pn
```

then:

```
product([f1, ... , fn]): [A1, ... , An] ~> [P1, ... , Pn]
```

in short:

We use the operator *product* whenever we want (and we always do if we can) to run multiple fetches in **parallel**.

### Composition

Let:
{'fraction_non_alphanumeric': 0.1503267973856209, 'fraction_numerical': 0.005083514887436456, 'mean_word_length': 4.481592039800995, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 27, 'https://': 24, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7496706', 'n_tokens_mistral': 1888, 'n_tokens_neox': 1759, 'n_words': 593}