Skip to content

Instantly share code, notes, and snippets.

@ezekielchentnik
Last active March 3, 2023 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ezekielchentnik/a722931cc92fa54c2b659ae9455687d3 to your computer and use it in GitHub Desktop.
Save ezekielchentnik/a722931cc92fa54c2b659ae9455687d3 to your computer and use it in GitHub Desktop.
export class Store {
private subscribers: Function[];
private reducers: { [key: string]: Function };
private state: { [key: string]: any };
constructor(reducers = {}, initialState = {}) {
this.subscribers = [];
this.reducers = reducers;
this.state = this.reduce(initialState, {});
}
get value() {
return this.state;
}
select(fn) {
return fn(this.state);
}
subscribe(fn) {
this.subscribers = [...this.subscribers, fn];
fn(this.value);
return () => {
this.subscribers = this.subscribers.filter(sub => sub !== fn);
};
}
dispatch(action) {
this.state = this.reduce(this.state, action);
this.subscribers.forEach(fn => fn(this.value));
}
private reduce(state, action) {
const newState = {};
for (const prop in this.reducers) {
newState[prop] = this.reducers[prop](state[prop], action);
}
return newState;
}
}
export function exampleReducer(
state = initialState,
action: { type: string, payload: any }
) {
// do stuff, return state
return state;
}
const reducers = {
example: exampleReducer,
};
const store = new Store(reducers);
const getProducts = state => state.products;
const getPizzas = state => state.pizzas;
const getEntities = state => state.entities;
const entities$ = store.select(state =>
getEntities(getPizzas(getProducts(state)))
);
export const initialState = {
data: [],
entities: {},
loaded: false,
loading: false,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment