npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

tigress

v0.0.34

Published

Typed Immutable Graph-like Reactive State

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