0.0.34 • Published 6 years ago

tigress v0.0.34

Weekly downloads
2
License
MIT
Repository
github
Last release
6 years ago

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 Refs. Refs come in read-only and read-write variants. All readonly variants take a simple RO suffix (i.e. RefRO). All Refs 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:

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.

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 Refs 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:

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:

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

0.0.34

6 years ago

0.0.33

6 years ago

0.0.32

6 years ago

0.0.31

6 years ago

0.0.30

6 years ago

0.0.29

6 years ago

0.0.28

6 years ago

0.0.26

7 years ago

0.0.24

7 years ago

0.0.23

7 years ago

0.0.22

7 years ago

0.0.21

7 years ago

0.0.20

7 years ago

0.0.17

7 years ago

0.0.15

7 years ago

0.0.14

7 years ago

0.0.13

7 years ago

0.0.12

7 years ago

0.0.11

7 years ago

0.0.10

7 years ago

0.0.9

7 years ago

0.0.8

7 years ago

0.0.7

7 years ago

0.0.6

7 years ago

0.0.5

7 years ago

0.0.4

7 years ago

0.0.3

7 years ago

0.0.2

7 years ago

0.0.1

7 years ago