From 0927bce6fac783a0f18f01e590df5060b7d4f9c0 Mon Sep 17 00:00:00 2001 From: mychidarko Date: Mon, 20 Nov 2023 10:28:22 +0000 Subject: [PATCH] feat: add support for reducers --- packages/store/src/core/hooks.ts | 10 +++++++- packages/store/src/core/store.ts | 40 +++++++++++++++++++++++++++++++- packages/store/src/index.ts | 5 ++-- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/packages/store/src/core/hooks.ts b/packages/store/src/core/hooks.ts index 3cff2b6..4c82fc8 100644 --- a/packages/store/src/core/hooks.ts +++ b/packages/store/src/core/hooks.ts @@ -76,7 +76,15 @@ export function useStaticStore( export function useReducer( reducer: string | Reducer ) { - // + const forceUpdate = useForceUpdate(); + + return Manager.useReducer(reducer, forceUpdate); +} + +export function useStaticReducer( + reducer: string | Reducer +) { + return Manager.useReducer(reducer); } export function setStore( diff --git a/packages/store/src/core/store.ts b/packages/store/src/core/store.ts index 488e942..bf9c8af 100644 --- a/packages/store/src/core/store.ts +++ b/packages/store/src/core/store.ts @@ -80,7 +80,7 @@ export default class Manager { * @param {State} state Current state of the store */ public static applyPluginHook(hook: Hook, state: any) { - this._plugins.forEach(plugin => { + this._plugins.forEach((plugin) => { plugin[hook] && plugin[hook]!(state); }); } @@ -144,6 +144,44 @@ export default class Manager { return selectedState; } + /** + * Call a reducer + * @param {string|Function} reducer The reducer to call + */ + public static useReducer( + reducer: string | Reducer, + forceUpdate?: VoidFunction + ) { + const runner = (reducer: Reducer) => { + return async (payload?: PayloadType) => { + const state = reducer(Manager.get(), payload); + Manager.set(await state); + + if (typeof forceUpdate === 'function') { + forceUpdate(); + } + }; + }; + + const reducerFunction = (reducerName: string): Reducer => { + const parts = reducerName.split('.'); + let base: any = this._options.reducers[parts[0]]; + + if (parts.length > 1) { + base = base[parts[1]]; + } + + return base; + }; + + if (typeof reducer === 'string') { + return runner(reducerFunction(reducer)); + } + + this._options.reducers[reducer.name] = reducer; + return runner(reducerFunction(reducer.name)); + } + protected static _pluginInit(plugins: Plugin[]) { plugins.forEach((plugin: any) => { /** diff --git a/packages/store/src/index.ts b/packages/store/src/index.ts index 69301d6..77452b4 100644 --- a/packages/store/src/index.ts +++ b/packages/store/src/index.ts @@ -3,9 +3,10 @@ export * from './plugins/'; export { createStore, - useStore, - useStaticStore, setStore, getStore, + useStore, + useStaticStore, useReducer, + useStaticReducer, } from './core/hooks';