UNPKG

@jupri-lab/store-core

Version:

A lightweight, easy-to-integrate, and type-safe state management library

81 lines (77 loc) 2.4 kB
class CombineStores { constructor(stores) { this.stores = stores; } getStore(selector) { return selector(this.stores); } } class MiddlewareManager { constructor(middlewares) { this.middlewareFns = new Set(middlewares); } apply(params) { const middlewareArray = Array.from(this.middlewareFns); if (middlewareArray.length === 0) return true; const middlewareResults = middlewareArray.map((middleware) => { const next = () => true; const result = middleware(params, next); return !result ? false : true; }); return middlewareResults.every((x) => x); } } class Store { constructor(configs) { this.subscribers = new Set(); this.states = configs.initialState; this.actions = configs.actions; this.middleware = new MiddlewareManager(configs.middlewares || []); } get() { return this.states; } dispatch(actionName, ...payload) { const action = this.actions[actionName]; if (action) { const middlewareChainSuccessful = this.middleware.apply({ action, actionName: action.name, payload, state: this.states, }); if (middlewareChainSuccessful) { const result = action(this.states, payload[0]); if (result instanceof Promise) { result .then((newState) => { this.states = newState; this.notify(); }) .catch(() => { throw new Error(`Error in async action ${String(actionName)}:`); }); } else { this.states = result; this.notify(); } } } else { throw new Error(`Action ${String(actionName)} is not defined`); } } subscribe(callback) { this.subscribers.add(callback); return () => this.unsubscribe(callback); } unsubscribe(callback) { this.subscribers.delete(callback); } notify() { this.subscribers.forEach((callback) => callback(this.states)); } } export { CombineStores, Store };