A small, fast state-management solution using observer pattern. This library allows you to create observables, subscribe to them, and publish changes to them. It also supports computed observables,
You can try a live demo here.
npm install @janghye0k/observable # or yarn add @janghye0k/observable or pnpm add @janghye0k/observable
- Create observable state
- Subscribe to the observable state
- Unsubscribe exist listener
- Modifying arrays and objects
- Computed value
import { observable } from '@janghye0k/observable';
const ov = observable('init');
const listener = function (state, prevState) {};
ov.subscribe(listener);
ov(); // 'init'
ov('init'); // 'init', no change
ov('changed'); // fn('changed', 'init')
ov.value = 'silent'; // silent update
ov.publish(); // fn('silent', 'init');
const ov = observable(1);
const listener = function (state, prevState) {};
ov.subscribe(listener);
ov(13); // listener(13, 1)
ov(0); // listener(0, 13)
const ov = observable('init');
Modifying arrays and objects will not publish, but replacing them will.
const ov = observable([]);
const listener = function (state, prevState) {};
ov.subscribe(listener);
ov([1]); // listener([1], [])
ov.value.push(2);
ov().push(3);
ov.pusblish(); // listener([1, 2, 3], [])
Passing a function caches the result as the value. Any extra arguments will be passed to the function. Any observables called within the function will be subscribed to, and updates to those observables will recompute the value. Child observables must be called, mere references are ignored. If the function returns a Promise, the value is assigned async after resolution.
const a = observable(1); // a() == 1
const b = observable(() => a() + 1); // b() == 2
const c = observable((arg) => a() + b() + arg, 3); // c() == 6
a(3);
console.log(a(), b(), c()); // 3, 4, 10
function sleep(timeout) {
new Promise((resolve) => setTimeout(resolve, timeout));
}
const ov = observable(async () => {
await sleep(1000);
return 1;
});
console.log(ov()); // null;
await sleep(1000);
console.log(ov()); // 1