Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type definitions #42

Closed
wants to merge 1 commit into from
Closed

Conversation

ambientlight
Copy link
Contributor

@ambientlight ambientlight commented Jan 17, 2019

Adds type definitions discussed in #24, however with difference in following definitions:

type storeCreator('action, 'origin, 'state) =
  (
    ~reducer: reducer('action, 'origin),
    ~preloadedState: 'state,
    ~enhancer: middleware('action, 'state)=?,
    unit
  ) =>
  store('action, 'state);

type storeEnhancer('action, 'origin, 'state) =
  storeCreator('action, 'origin, 'state) =>
  storeCreator('action, 'origin, 'state);

type applyMiddleware('action, 'origin, 'state) =
  middleware('action, 'state) => storeEnhancer('action, 'origin, 'state);

Additional type parameter 'origin accounts for the scenario when storeEnhancer applies composition (decorates original store with higher level state and reducer - hope my wording is correct here), where real-world example looks the following way:

Enhancer to wrap ReactReason router:

let enhancer = (storeCreator: storeCreator('action, 'origin, 'state)) => (~reducer, ~preloadedState, ~enhancer=?, ()) => {
  let routerReducer = (state, action) => 
    switch(action){
    | `RouterLocationChanged(route: ReasonReact.Router.url) => { ...state, route }
    | _ => {
      ...state,
      state: reducer(state.state, action)
    }};
  
  let interceptPushRoute = (store, next, action) => 
    switch(action, enhancer){
    | (`RouterPushRoute(path), _) => ReasonReact.Router.push(path);
    | (_, Some(enhancer)) => enhancer(store, next, action)
    | (_, None) => next(action)
    };
  
  let store = storeCreator(~reducer=routerReducer, ~preloadedState, ~enhancer=interceptPushRoute, ());
  let _watcherId = ReasonReact.Router.watchUrl(url => Reductive.Store.dispatch(store, `RouterLocationChanged(url)));
  store
};

which is used in store defined like:

let storeCreator = devToolsEnhancer @@ ReductiveRouter.enhancer @@ Reductive.Store.create;
let store = storeCreator(
  ~reducer=appReducer,
  ~preloadedState={
    route: {
      path: [],
      hash: "",
      search: ""
    },
    state: {
      counter: 0, 
      content: ""
    },
  },
  (),
);

storeCreator in this case is passed with an original reducer - sub-reducer in our resulting decorated store.

@MargaretKrutikova
Copy link
Collaborator

Was just planning to look into this, is the code in the PR no longer necessary?

@ambientlight
Copy link
Contributor Author

I no longer think that breakdown for 'action, 'origin, 'state is a good idea. Pull request was created when I got originally confused when my storeEnhancer composition was applied in an opposite to expected way, and type system as expected has complained on this. by that time I forgot about this pr, and basically just saw it.

@ambientlight ambientlight mentioned this pull request Dec 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants