# tigress

> Typed Immutable Graph-like Reactive State

Latest version **0.0.34** (published 2017-12-19) · MIT license · 0 weekly downloads

## Install

```sh
npm install tigress
pnpm add tigress
yarn add tigress
bun add tigress
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.34 |
| Published | 2017-12-19 |
| First published | 2017-05-18 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 1 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | aaroncr, anthony-landis |

## Links

- npm: https://www.npmjs.com/package/tigress
- Repository: https://github.com/anywhere-com/tigress.js
- Homepage: https://github.com/anywhere-com/tigress.js#readme
- Issues: https://github.com/anywhere-com/tigress.js/issues
- npm.io page: https://npm.io/package/tigress

## Dependencies (1)

- [immutable](https://npm.io/package/immutable.md) ^3.8.1

## Recent versions

- 0.0.34 (latest) — 2017-12-19
- 0.0.33 — 2017-12-19
- 0.0.32 — 2017-12-19
- 0.0.31 — 2017-12-18
- 0.0.30 — 2017-12-18
- 0.0.29 — 2017-12-18
- 0.0.28 — 2017-12-15
- 0.0.26 — 2017-07-10
- 0.0.24 — 2017-06-16
- 0.0.23 — 2017-06-15
- 0.0.22 — 2017-06-15
- 0.0.21 — 2017-06-15
- 0.0.20 — 2017-06-13
- 0.0.17 — 2017-06-02
- 0.0.15 — 2017-05-31
- … 14 more at https://npm.io/package/tigress/versions

## README

# Tigress

## Overview

tigress is a state management library that takes advantage of the robust type information available in TypeScript. It maintains a root state store which should be some immutable data structure and allows for atomically reading and writing that state store and receiving reactive change notifications upon state changes. It facilitates the creation of reusable components by providing a robust machanisms for navigating tree-like data structures. 
 
tigress also provides constructs for reactive state computations along with React integration to allow for reactive view changes. In addition, there is advanced support for using state containers in data validation scenarios that allows for attaching validation metadata at any point in the state tree as well as accessing the current DB value of data being updated.

tigress's change notifications are compatible with RxJS and the proposed ECMAScript Observable specification.

## Ref's

State containers in tigress are called `Ref`s. `Ref`s come in read-only and read-write variants. All readonly variants take a simple `RO` suffix (i.e. `RefRO`). All `Ref`s take a single type parameter
representing the type of state managed by the `Ref`, ex: `Ref<number>`. When we refer to the types
of `Ref`'s in TypeScript, the interface form (`IRef` or `IRefRO`) is usually used as the return
value for functions in TypeScript.

### `rootRef`

To create a new `Ref` use the `rootRef` function passing in the initial state:

```ts
const myRef : IRef<number> = rootRef(0);
```

### `get`

The most basic operation for using `Ref`'s is to get the current state using the `get()` method.

```ts
console.log(myRef.get());
// 0
```

#### Dependency Tracking

Calling get in a reactive computation (either inside a `reaction` or `reactive` React component)
will automatically register the `Ref` as a dependency of the computation. This means that whenenver
the `Ref` updates the reactive computation will update. (To get the current state without
registering the `Ref` as a reactive dependency, use `getNonReactive`.)

#### Nullability

Because `Ref`s are meant to work with tree-like data structures, given a type `T` that is
non-null we can't know whether it is the child of some nullable parent. So `get` always
returns `T | null`. (There is a variant of `get` called `getResolved` for "resolved" Ref's
that returns a non-null value but this is an advanced topic).

### `swap` and `reset`

If we have a regular read-write `Ref`, `swap` and `reset` are used to modify the state. `swap` takes
an update function which takes the current state and returns the new state. `reset` simply takes a
value to set as the new state. Both `swap` and `reset` return the new value of the state after the
operation. Because `Ref`'s could point to values in nested tree data structures,
`swap` and `reset` are not guaranteed to succeed and thus the return value is the only reliable
way to know what the actual value of the state is after attempting to mutate it.

Ex:
```ts
myRef.swap(cur => cur != null ? cur + 1 : cur);
console.log(myRef.get());
// 1
myRef.reset(3);
console.log(myRef.get());
// 3
```

#### Nullability

Because of the complexities in working with tree-like data structures, the update function
passed to `swap` must take a nullable value and can return a nullable value regardless of what
the underlying type for the `Ref` is. `reset` will only take a type that corresponds to the
nullability of the underlying type. Both `swap` and `reset` may take a nullable value.

### `subscribe`

The `subscribe` method is used to listen to change notifications from any `Ref`-like containers.
`subscribe` takes an `IObserver` parameter and returns an `ISubscription` value. `IObserver`
and `ISubscription` in tigress correspond almost exactly to the `Observer` and `Subscription`
interfaces specified in https://github.com/tc39/proposal-observable, with the minor difference
that tigress's `IObserver` allows all fields to be optional. This allows for listening to
changes simply by providing the `next` parameters of `IObserver`:

```ts
myRef.subscribe({next: x => console.log(x)});
```

## Prop's and Child Ref's

`tigress` allows for easy interaction with nested state trees via Props which are
typed representations of the properties of objcets. There
are two basic Prop interfaces: `IProp` and `IPropRO` and read-write and read-only
properties respectively. All Prop's have a getter method and a string name and
read-write Prop's also have a setter method.

### Prop Basics

Anything conforming to the `IProp` or `IPropRO` can be used in Tigress. The
simplest way to create Prop's is to use the provider `Prop` and `PropRO` types.
Prop getters, setters and name's are described below.

#### getter

A Prop getter is a function taking a parent value and
returning a child value. To deal cleanly with nested 
trees, getters must always accept a possibly null parent
and can always return a nullable value regardless of
the underlying nullability of this Prop.

#### setter

A Prop setter is a function taking a parent value and
a new child value and return a new value for the parent.
To deal cleanly with nested trees, setters must always
accept a possibly null parent value and possibly null
new child value and can always return a nullable value.
Thus it is up to Prop implementations to properly handle
or reject null values.

#### name

The Prop's `name` is more than just a description
string name, it is used to navigate metadata trees and
thus must be carefully chosen. This is an advanced topic
which will be discussed later in more detail.

### Ref `child` and `childRO`

Prop's are used by Ref's in order to create "child" Ref's.
That is - Ref's that behave just like any other Ref, but point
to a child value in the state tree. Every `IRef` has `child`
function which takes an `IProp` and returns another read-write
`IRef` pointing to the child. Every `IRef` and `IRefRO` have
a `childRO` function which takes an `IPropRO` and returns
a read-only `IRefRO` pointing to the child.

### Creating Prop's via code-generation

Prop's are not intended to be created by hand except in the most basic cases.
Internally Anywhere generates Props for all of the types in its API backend using
Template Haskell. A similar code generator code be created for Typescript types
using the Typescript compiler API.

## Reactions

TODO

## Resolved Ref's

TODO

## Metadata

TODO

## Clean Copy Ref's

TODO

---
_Source: https://npm.io/package/tigress · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
