Skip to content

Commit

Permalink
feat: add support for reducers
Browse files Browse the repository at this point in the history
  • Loading branch information
mychidarko committed Nov 20, 2023
1 parent 0931b22 commit 0927bce
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 4 deletions.
10 changes: 9 additions & 1 deletion packages/store/src/core/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,15 @@ export function useStaticStore<StateType = any>(
export function useReducer<PayloadType = any>(
reducer: string | Reducer<State>
) {
//
const forceUpdate = useForceUpdate();

return Manager.useReducer<PayloadType>(reducer, forceUpdate);
}

export function useStaticReducer<PayloadType = any>(
reducer: string | Reducer<State>
) {
return Manager.useReducer<PayloadType>(reducer);
}

export function setStore<StateType extends State = State>(
Expand Down
40 changes: 39 additions & 1 deletion packages/store/src/core/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
}
Expand Down Expand Up @@ -144,6 +144,44 @@ export default class Manager {
return selectedState;
}

/**
* Call a reducer
* @param {string|Function} reducer The reducer to call
*/
public static useReducer<PayloadType = any>(
reducer: string | Reducer<State>,
forceUpdate?: VoidFunction
) {
const runner = <PayloadType = any>(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<PayloadType>(reducerFunction(reducer));
}

this._options.reducers[reducer.name] = reducer;
return runner<PayloadType>(reducerFunction(reducer.name));
}

protected static _pluginInit(plugins: Plugin[]) {
plugins.forEach((plugin: any) => {
/**
Expand Down
5 changes: 3 additions & 2 deletions packages/store/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ export * from './plugins/';

export {
createStore,
useStore,
useStaticStore,
setStore,
getStore,
useStore,
useStaticStore,
useReducer,
useStaticReducer,
} from './core/hooks';

0 comments on commit 0927bce

Please sign in to comment.