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

[Issue] Prevent writing LAST_ACTION to localStorage unless predicate is true. #14

Closed
initFabian opened this issue Aug 27, 2018 · 3 comments

Comments

@initFabian
Copy link

On the codebase that I am working on, we are dealing with very large state objects that exceed the amount allowed by localStorage. We had to override actionStorageMiddleware with our own version that prevented localStorage.setItem('LAST_ACTION', .. from happening unless action.type was allowed. So my question is, does every action have to be stored even if you're only allowing a few of them? Let me know if this tweak falls within the purpose of redux-state-sync and we can continue this conversation.

@aohua
Copy link
Owner

aohua commented Aug 29, 2018

I think it's not necessary to store those actions which are not allowed. Do you want to send a pull request with the tweak that you did?

@initFabian
Copy link
Author

We have some syntactic sugar(wrapper) around the framework, so we made the change in our codebase. We overwrote the middleware portion of your framework. From what I'm seeing, it may require a few changes to the API, I could be mistaken though. Could you checkout my code snippet below and fiddle around with some ideas on how you would like to accomplish this?

// TabSyncMiddleware.js
import { createStorageListener, withReduxStateSync } from 'redux-state-sync';
import ActionWhiteList from './ActionWhiteList'; // actions we want to sync across tabs

function s4() {
  return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}

function guid() {
  return `${s4()}-${s4()}-${s4()}-${s4()}-${s4()}-${s4()}-${s4()}-${s4()}`;
}

export const reducerTabSync = withReduxStateSync;

export const tabSyncMiddleware = ({ getState }) => (next) => (action) => {
  if (action && !action.$uuid) {
    const stampedAction = {
      $uuid: guid(),
      ...action
    };

    try {
      if (action.type === '&_SEND_INIT_STATE') {
        if (getState()) {
          stampedAction.payload = getState();
          localStorage.setItem('LAST_ACTION', JSON.stringify(stampedAction));
        }
        return next(action);
      }

      if (ActionWhiteList.includes(action.type)) { // here's the part we needed
        localStorage.setItem('LAST_ACTION', JSON.stringify(stampedAction));
      }
    } catch (e) {
      console.error('Failed to store `LAST_ACTION` to localStorage.');
    }
  }
  return next(action);
};

export const TabSyncWrapper = (store) => {
  createStorageListener(store, {
    initiateWithState: true,
    predicate: (actionType) => {
      return ActionWhiteList.includes(actionType);
    }
  });

  return store;
};

Usage

//  index.js
import { tabSyncMiddleware, TabSyncWrapper, reducerTabSync } from './middleware/TabSyncMiddleware';

// ...


const enhancer = composeEnhancers(
  applyMiddleware( ..., ..., tabSyncMiddleware)
);

const store = TabSyncWrapper(createStore(
  reducerTabSync(reducers),
  enhancer
));

// ...

render(
  <Provider store={store}>
    <AppRouter />
  </Provider>,
  document.getElementById('root')
);

@aohua
Copy link
Owner

aohua commented Nov 28, 2018

Sorry for the long delay, I just released redux-state-sync 2.0, Your problem should be fixed in the new version.

@aohua aohua closed this as completed Nov 28, 2018
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

No branches or pull requests

2 participants