I guess you start to see a pattern here.
Yes we are going to create different types of stores with increasing numbers of arguments, like mixins but without the Class fuss.
Our ComponentStore will take a component argument.
This will enable us mainly two things
- If the component has a render(newState, oldState) method then we subscribe this method to the store state$ with the right operators (distinctUntilChange, pairWise…)
- addObservedAttributesReducer(reducer_function) that will behave like the channelReducer, but the source will be the observedAttributes$ BehaviourSubject property of the component. The observedAttributes$ property has a value always equal to the observed attributes dictionnary of the component and pushes a next value when an attributeValue changes.
javascript// ComponentStore const createComponentStore = ( { render, observedAttributes$ }, channel$, init = null ) => { const store = createChannelStore(channel$, init); let renderSubscription; let observedAttributesReducer; if (render) { renderSubscription = store .getState$() .pipe( tap(render) ) .subscribe(); } const addObservedAttributeReducer = reducer => { observedAttributesReducer = store.addReducer(reducer)(observedAttributes$); return observedAttributesReducer; }; const removeObservedAttributeReducer = messageKey => { observedAttributesReducer?.unsubscribe(); }; return { ...store, addObservedAttributeReducer, removeObservedAttributeReducer }; };
Here are some usual reducers functions that we might use
javascriptidentity = (state, message) => message assign = propertyName => (state, message) => {...state, [propertyName] : message}