@muzikanto/observable
TypeScript icon, indicating that this package has built-in type declarations

5.0.1 • Public • Published

Observable

npm version downloads dependencies Status size Code style

Linked projects

name version downloads
observable-form npm version downloads

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

More 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

Run in CodeBox

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;

License

MIT

Package Sidebar

Install

npm i @muzikanto/observable

Weekly Downloads

13

Version

5.0.1

License

MIT

Unpacked Size

34.6 kB

Total Files

45

Last publish

Collaborators

  • muzikanto