Skip to content

janghye0k/observable

Repository files navigation

Build Size Version

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.

Installation

npm install @janghye0k/observable # or yarn add @janghye0k/observable or pnpm add @janghye0k/observable

Usage

Create observable state

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');

Subscribe to the observable state

const ov = observable(1);
const listener = function (state, prevState) {};
ov.subscribe(listener);

ov(13); // listener(13, 1)
ov(0); // listener(0, 13)

Unsubscribe exist listener

const ov = observable('init');

Modifying arrays and objects

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], [])

Computed value

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

License

MIT