@muzikanto/observable
v5.0.1
Published
The state manager
Downloads
26
Maintainers
Readme
Observable
- Introduction
- Installation
- Examples
- API
- createStore
- createEvent
- createEffect
- createApi
- combine
- combineAsync
- forward
- timer
- useStore
- StoreConsumer
- connect
- isEvent
- isStore
- License
Linked projects
| name | version | downloads |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| observable-form
| | |
Introduction
- create store
- listen store changes
- listen store object part change
- create event and subscribe store to event
- create effect and subscribe events (done, fail, loading)
- create cacheable effect
- async store parts with combineAsync
- override Event, Effect, Store if you need
- and more..
Installation
npm i @muzikanto/observable
# or
yarn add @muzikanto/observable
Migrate 3.x.x > 4.x.x
remove to @muzikanto/observable-global
- createGlobalStore
- GlobalStoreCtx
- GlobalStoreProvider
- useGlobal
Examples
example createStore
const store = createStore<number>({ value: 1 });
function Component() {
const state = useStore(store); // {value: 1};
// const value = useStore(store, s => s.value);
return <span>{state.value}</span>;
}
example createEvent
const store = createStore<number>(1);
const append = createEvent<number>();
const change = createEvent<number>();
store.on(append, (state, payload) => state + payload);
store.on(change, (state, payload) => payload);
append(2); // 3
change(-2); // -2
store.reset(); // 1
example createEffect
type Request = { param: number };
// create cachable effect
const effect = createEffect<Request, Response, Error>(
async (params: Request) => {
try {
const response = await axios.get('https://example.com', { params });
return response;
} catch (e) {
throw e;
}
},
{ cache: true, cacheTime: 60000 },
);
// subscribe in store
storeDone.on(effect.done, (_, payload) => payload);
storeFail.on(effect.fail, (_, payload) => payload);
storeLoading.on(effect.loading, (_, payload) => payload);
// call
effect({ param: 1 })
.then((response) => console.log(response))
.catch((err) => console.log(err));
example combine
const one = createStore('Hello ');
const two = createStore('World');
const combinedObjStore = combine({ one, two });
combinedObjStore.get(); // { one: 'Hello ', two: 'World' }
const combinedStringStore = combine({ one, two }, ({ one, two }) => {
return one + ' ' + two;
});
combinedStringStore.get(); // Hello World
example combineAsync
const one = createStore(1);
const two = createStore(2);
const three = createStore(3);
const combinedStore = combineAsync({ one, two });
combinedStore.get(); // { one: 1, two: 2 }
combinedStore.injectStore('three', three);
combinedStringStore.get(); // { one: 1, two: 2, three: 3 }
example timer
// change on timeout
(async () => {
const store = createStore(1);
const ev = createEvent<number>();
store.on(ev, (state, payload) => state + payload);
const runTimer = timer(ev, 200);
runTimer(2);
await wait(200); // wait timeout change to 3
store.get(); // 3
})()(
// change on interval
async () => {
const store = createStore(1);
const ev = createEvent<number>();
store.on(ev, (state, payload) => state + payload);
const runTimer = timer(ev, 200, 100);
runTimer(2);
await wait(200); // wait timeout
await wait(100); // wait interval 1, change to 3
await wait(100); // wait interval 2, change to 5
store.get(); // 5
},
)();
Api
createStore
function createStore<T>(initialState: T): Store<T>
interface Store<T> {
get: () => T;
set: (v: T) => void;
subscribe: (listener: Listener<any>, selector?: (state: T) => any) =>() => void;
reset: () => void;
on: <P>(event: IEvent<P>, handler: (state: T, payload: P) => T) => () => void;
watch: (handler: (state: T, prev: T) => void): () => void;
}
createEvent
function createEvent<P = void>(): IEvent<P>;
type IEvent<P = void> = {
(payload: P): void;
watch: (watcher: Listener<P>) => () => void;
};
createEffect
function createEffect<Req, Res, Err = Error>(
handler: (params: Req) => Promise<Res>,
options?: {
done?: IEvent<Res>;
fail?: IEvent<Err>;
loading?: IEvent<boolean>;
cache?: boolean;
cacheTime?: number;
},
): IEffect<Req, Res, Err>;
type IEffect<Req, Res, Err = Error> = {
(request: Req): Promise<Res>;
done: IEvent<Res>;
fail: IEvent<Err>;
loading: IEvent<boolean>;
};
createApi
function createApi<S, A extends { [key: string]: (state: S, payload: any) => S }>(
state: S,
api: A,
): Api<S, A>;
type Api<S, A extends { [key: string]: (store: Store<S>, payload: any) => S }> = ApiEvents<S, A> & {
store: Store<S>;
};
type ApiEvents<S, A> = {
[K in keyof A]: A[K] extends (store: S, e: infer E) => S ? IEvent<E> : any;
};
combine
function combine<Map extends { [key: string]: any }, S = Map>(
map: { [k in keyof Map]: Store<Map[k]> },
func?: (map: Map) => S,
): CombineStore<S>;
combineAsync
function combineAsync<Map extends { [key: string]: any }, S = Map>(
map: { [k in keyof Map]: Store<Map[k]> },
func?: (map: Map) => S,
): CombineAsyncStore<S>;
forward
function forward<P>(
from: IEvent<P>,
to: IEvent<P> | Array<IEvent<P>>,
): (() => void) | Array<() => void>;
timer
export type Timer<R> = IEvent<R> & {
disable: () => void;
};
function timer<R>(event: IEvent<R>, timeout: number, interval?: number): Timer<R>;
useStore
function useStore<T, V>(observable: Store<T>, selector?: (state: T) => V): V;