How to access redux state snapshot from Google Chrome content_scripts injected script?

Viewed 15

The problem

I'm developing an google chrome extension where i add buttons to the already existing 3rd party react app. All of the data that im accessing by UI workarounds are accessible in the Redux Store by DevTools. How can i make my script injected into the app read the store as well as the dispatched actions

Best attempt

I've created this piece of code to load the store, then state and inspect actions, but for some reason only works in devtools console. Does not work from content_scripts injection. It returns empty set.

To run the code paste it in console and type callMe(). Then do some action on an app with redux

const callMe = function () {
    function compose(...funcs) {
      if (funcs.length === 0) {
        // infer the argument type so it is usable in inference down the line
        return (arg) => arg
      }
  
      if (funcs.length === 1) {
        return funcs[0]
      }
  
      return funcs.reduce(
        (a, b) =>
          (...args) =>
            a(b(...args))
      )
    }
    // Find the root element for React
    const roots = Array.from(document.querySelectorAll("*[id]"))
      .filter((el:any) => el?._reactRootContainer?._internalRoot?.current)
      .map((reactRoot:any) => reactRoot._reactRootContainer._internalRoot.current);
  
  
    // Traverse a dom element
    const stores = new Set();
    const traverse = (element) => {
      let store =
        element?.memoizedState?.element?.props?.store
        || element?.pendingProps?.store
        || element?.stateNode?.store;
  
      if (store) {
        stores.add(store);
      }
  
      if (element.child) {
        traverse(element.child);
      }
    };
    // const internalRoot = reactRoot._reactRootContainer._internalRoot.current;
  
    // Traverse the root react element to find all Redux States in the app
    console.log(roots);
    roots.forEach(traverse);
  
    console.log(stores);
  
    // @ts-ignore
    let aStore= [...stores][0];
  
    const ourMiddleware = ({ dispatch, getState }) => next => (action) => {
      const result = typeof action === 'function' ? action(dispatch, getState) : next(action);
      console.log(result, action);
      return result;
    };
  
    const oldDispatch = aStore.dispatch;
    const oldStore = {
      ...aStore,
      dispatch: oldDispatch
    }
    allegroStore.dispatch = compose(ourMiddleware(oldStore))(oldDispatch);

  };
0 Answers
Related