0.2.0-alpha.1 • Published 1 year ago

@xania/state v0.2.0-alpha.1

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

State beta

Is blazingly fast javascript library for managing reactive state.

benchmark results

Visit the docs website to learn more about how to use @xania/state in your project.

Getting started

npm install @xania/state
import { State } from "@xania/state"

const a = new State(1);
const b = a.map(x => x + 1);
const c = a.map(x => x * 2);
const d = a.bind(x => x % 2 === ? b : c);

Motivation

@xania/state is intended to be complementary to RxJS and is especially an alternative to BehaviorSubject and it's main goal to provide reactivity for the View library. RxJS is on the other hand better suited for handling events coming from view, e.g. for debounce, async, etc...

state flow;

  • Compatibility with RxJS, RxJS for events and scheduling, and xania for fine grained state.
  • Side effects are hidden
  • Side effects are idempotent
  • (eventual) consistency between source state and observer state

fine-grained state

In realworld, a state is practically never isolated from other parts of the state. e.g. firstName can be represented by a state object but it is also part of the Employee state and the two and all there observers needs to be in sync. Most used pattern for updating firstName in other libraries use a coarse grained approach where the whole person updates is updates. Biggest disadvantage is that the handling of firstName gets entangled with the structure of Person, which also means that this affected by any changes in structure.

@xania/state provides a different pattern using fine-grained approach. @xania/state provides a prop method to create an isolated state object and uses (internal) operators to keep the parent en it's property in sync.

const person = new State({
  firstName: 'Ibrahim',
});
const firstName = person.prop('firstName');
firstName.set('Ramy');

console.log(person.get().firstName); // prints 'Ramy'
  1. we can create rxjs observables from state objects
import * as Rx from 'rxjs';

const s = new State(1);
const x = Rx.from(s);
  1. And we can connect rxjs back to state objects
const x = Rx.timer(0, 1000);
const s = State.from(x);

Design and concepts

State objects encapsulate values and are responsible for synchronisation with derived state and derived state of derived state etc..

new State(1).set(2);
Derived state

The are three core methods of creating a derived state.

  • prop: property of a root object
  • map: monadic map
  • bind: monadic bind
State mutations

State mutation is done by calling set on root object. Derived states do not allow for direct mutations. Changes can only flow from root states with one exception, namely a property state mapped directly of a root state in which case we can guarantee consistency for all derived states.

Sync external mutations

Xania does not ignore the fact that we can mutate the state outside the formal set operation. That's where sync comes into play.

const data = {
  firstName: 'Ibrahim',
};
const person = new State(data);
const firstName = state.prop('firstName');
firstName.subscribe({
  next(x) {
    console.log('Hello, ', x);
  },
});
// console output: Hello, Ibrahim

// external mutation
data.firstName = 'Ramy';
sync(person);
// console output: Hello, Ramy

To maintain

Diamond problem

Xania ensures correct order in which the updates are propagated in a single roundtrip. This is especially important in case of the known diamond problem.

live demo

Features:

  • monadic state (map, bind)
  • topological sorting
  • asynchronuous data (in progress)
  • scheduling (in progress)
  • batching (in progress)
0.1.52

1 year ago

0.1.53

1 year ago

0.1.54

1 year ago

0.1.55

1 year ago

0.1.56

1 year ago

0.1.57

1 year ago

0.1.58

1 year ago

0.1.50

1 year ago

0.1.51

1 year ago

0.1.49

1 year ago

0.1.41

1 year ago

0.1.42

1 year ago

0.1.43

1 year ago

0.1.45

1 year ago

0.1.46

1 year ago

0.1.47

1 year ago

0.1.48

1 year ago

0.1.40

1 year ago

0.1.38

1 year ago

0.1.39

1 year ago

0.1.32

1 year ago

0.1.33

1 year ago

0.1.34

1 year ago

0.1.35

1 year ago

0.1.36

1 year ago

0.1.37

1 year ago

0.2.0-alpha.1

1 year ago

0.1.27

1 year ago

0.1.28

1 year ago

0.1.20

1 year ago

0.1.21

1 year ago

0.1.22

1 year ago

0.1.23

1 year ago

0.1.24

1 year ago

0.1.25

1 year ago

0.1.26

1 year ago

0.1.19

1 year ago

0.1.18

1 year ago

0.1.17

1 year ago

0.1.15

1 year ago

0.1.14

1 year ago

0.1.13

1 year ago

0.1.12

1 year ago

0.1.11

1 year ago

0.1.10

1 year ago

0.1.9

1 year ago

0.1.8

1 year ago

0.1.7

1 year ago

0.1.6

1 year ago

0.1.5

1 year ago

0.1.4

1 year ago

0.1.3

1 year ago

0.1.2

1 year ago

0.1.1

1 year ago

0.1.0

1 year ago