callbag-state

Callbag-based State Management

Usage no npm install needed!

<script type="module">
  import callbagState from 'https://cdn.skypack.dev/callbag-state';
</script>

README

callbag-state

tests coverage version

Callbag-based state management.

npm i callbag-state
import state from 'callbag-state';
import subscribe from 'callbag-subscribe';

const s = state(42);
subscribe(v => console.log('GOT: ' + v))(s);
console.log(s.get());
s.set(43);
console.log(s.get());

// > GOT: 42
// > 42
// > GOT: 43
// > 43

► TRY IT!



Usage

👉 Track the state and mutate it via .set() and .get():

import state from 'callbag-state';
import subscribe from 'callbag-subscribe';

const s = state(42);
subscribe(console.log)(s);

s.set(43);
s.set(s.get() + 1);

// > 42
// > 43
// > 44

► TRY IT!


👉 Track sub-states:

import state from 'callbag-state';
import subscribe from 'callbag-subscribe';

const s = state({x : 42});
const x = s.sub('x');
subscribe(console.log)(s);

x.set(43);
x.set(x.get() + 1);

// > {x: 42}
// > {x: 43}
// > {x: 44}

► TRY IT!


👉 Changes propagate properly wherever you make them on state-tree:

import state from 'callbag-state';
import subscribe from 'callbag-subscribe';

const s = state([{x : 42}, {x: 21}]);

subscribe(console.log)(s.sub(0).sub('x'));

s.set([{x: 44}]);
s.sub(0).set({x: 43});
s.sub(0).sub('x').set(45);

// > 42
// > 43
// > 44
// > 45

► TRY IT!


👉 Track changes:

import state from 'callbag-state';
import subscribe from 'callbag-subscribe';

const s = state([1, 2, 3, 4]);
subscribe(console.log)(s.downstream());

s.set([5, 2, 3, 4, 1]);

// > {
// >   value: [5, 2, 3, 4, 1],
// >   trace: {
// >     subs: {
// >       0: { from: 1, to: 5 },
// >       4: { from: undefined, to: 1}
// >     }
// >  }

► TRY IT!



Gotchas

⚠️⚠️ Don't change an object without changing its reference:

// WRONG:
const s = state([1, 2, 3, 4])
s.get().push(5);              // --> no updates
// CORRECT:
const s = state([1, 2, 3, 4])
s.set([...s.get(), 5]);
// FUN & CORRECT:
const s = state([1, 2, 3, 4])
s.sub(s.get().length).set(5)

► TRY IT!


⚠️⚠️ Only pass plain objects! Specifically, passing objects with circular references might result in stack-overflow!



Contribution

Be nice and respectful, more importantly super open and welcoming to all.

👉 Useful commands for working on this repo:

git clone https://github.com/loreanvictor/callbag-state.git
npm i              # --> install dependencies
npm start          # --> run `samples/index.ts`
npm test           # --> run all tests
npm run cov:view   # --> view code coverage