Shopping cart demo: (https://yesil.github.io/picosm/examples/cart/index.html)
Canvas demo: (https://yesil.github.io/picosm/examples/stars/index.html)
In this demo, the ranking of stars with the most connection is updated using a debounced observer, and tracking connected stars.
Use the metakey to connect stars to each other.
Pico State Manager is an experimental, lightweight, zero-dependency state manager that replicates core MobX features without using Proxy objects.
It also provides a helper function to make Lit components observers and updates them on changes.
Currently, the non-minified bundle size is 6729 bytes and around 1794 bytes gzipped.
You can also import only the specific modules you need from the source to further reduce the size.
makeObservable: Instruments a class with observable capabilities.observe: Callback when the instance of an observable class changes.reaction: React to specific changes.track: Tracks other observables and notifies own observers on change.subscribe: Subscribe to arbitrary messages sent over an observable.notify: Notify all subscribers of an observable with arbitrary messages.makeLitObserver: Helper function to make Lit components observers and update them on changes.
Add the picosm dependency:
npm add https://github.com/yesil/picosm/releases/download/v1.1.0/picosm-1.1.0.tgzSee the unit test: https://github.com/yesil/picosm/blob/main/test/LitObserver.test.js
See the demo app source code: https://github.com/yesil/picosm/tree/main/examples for a more comprehensive example.
Makes a class observable by adding reactive capabilities. The class should define:
static observableActions: Array of method names that should notify observers when calledstatic computedProperties: Array of getter names that should be cached until invalidated by an observable action
import { makeObservable } from 'picosm';
class Counter {
static observableActions = ['increment'];
static computedProperties = ['total'];
value = 0;
otherValue = 0;
increment() {
this.value += 1;
}
incrementOther() {
this.otherValue += 1;
}
get total() {
return this.value + this.otherValue;
}
}
makeObservable(Counter);
const instance = new Counter();
instance.increment();
console.log(instance.value); // 1Creates an observer for a given observable.
Returns a disposer function.
import { observe } from 'picosm';
const disposer = observe(instance, () => {
console.log('Instance changed');
});
instance.increment(); // Logs: 'Instance changed'
disposer(); // Stops observingReact to specific changes.
Returns a disposer function.
import { reaction } from 'picosm';
const disposer = reaction(
instance,
({ value }) => [value],
(value) => {
console.log('Value changed to', value);
},
);
instance.increment(); // Logs: 'Value changed to 1'
instance.incrementOther(); // nothing happens
disposer(); // Stops reactingYou can watch multiple observables at once by passing an array of targets. The callback receives the targets as positional parameters in the same order, and execute is called with the returned props when any target change causes the returned array to differ.
import { reaction } from 'picosm';
const disposer = reaction(
[a, b],
(storeA, storeB) => {
const sum = storeA.counter + storeB.counter;
return [sum];
},
(sum) => {
console.log('Sum changed to', sum);
},
);Internally, one observer is registered per target, using the same callback, so any target change will trigger the same computation and comparison.
Tracks other observables and notifies own observers on change.
Returns a disposer function.
import { track, observe } from 'picosm';
const otherInstance = new Counter();
const disposer = track(instance, otherInstance); // notify instance when otherInstance changes
const disposer = observe(instance, () => {
console.log('tracked dependency has changed', otherInstance);
});
otherInstance.increment();
disposer();Subscribe to arbitrary messages sent over an observable.
Returns a disposer function.
Notify all subscribers of an observable with arbitrary messages.
import { subscribe, notify } from 'picosm';
const disposer = subscribe(instance, (message) => {
console.log('Message received', message);
});
notify(instance, 'hello world');
disposer(); // Stops subscribingPlease feel free to:
- Open a PR to contribute.
- Create an issue to request a feature.