Open vhmth opened 6 years ago
@vhmth Agreed - this is a great idea!
I'm wondering what the best implementation structure would look like. Ideally we want this to be configured into a store so that we continue to same composability paradigm we've been using before (you can have multiple proxy or background stores without any complication).
Creating the alias action is easy, and the storage is easy (we can just store internally exactly how we are now). The question is how we attach to a store.
The middleware was nice because it was transparent in what it was doing and just used redux's store api.
I can see us doing it through the wrapStore
call or the middleware method, potentially...
So the middleware way being turning something like this:
// background.js
import { applyMiddleware, createStore } from 'redux';
import { alias, wrapStore } from 'react-chrome-redux';
const aliases = {
// this key is the name of the action to proxy, the value is the action
// creator that gets executed when the proxied action is received in the
// background
'user-clicked-alias': () => {
// this call can only be made in the background script
chrome.notifications.create(...);
};
};
const store = createStore(rootReducer,
applyMiddleware(
alias(aliases)
)
);
Into something like this:
// background.js
import { applyMiddleware, createStore } from 'redux';
import { aliases, wrapStore } from 'react-chrome-redux';
aliases.createAlias("user-clicked-alias", () => {
// this call can only be made in the background script
chrome.notifications.create(...);
});
const store = createStore(rootReducer,
applyMiddleware(
aliases
)
);
Somewhat. I was thinking we take it a step further and return an action creator that can be called either on the background or content script and will always execute in the background. Something like this:
// ===========
// background.js
// ===========
import { applyMiddleware, createStore } from 'redux';
import { aliases } from 'react-chrome-redux';
// effectively initializes all aliases/creators
import 'creators';
const store = createStore(rootReducer,
applyMiddleware(
aliases
)
);
// ============
// creators/index.js
// ============
import { aliases } from 'react-chrome-redux';
export const userClickedAlias = aliases.createAlias('user-clicked-alias', () => {
// do whatever
});
export const userExit = () => {
return { type: 'some_action' };
};
// ========
// content.js
// ========
import { wrapStore } from 'react-chrome-redux';
import { userClickedAlias } from 'creators';
const store; // a normal Redux store
const wrappedStore = wrapStore(store, {
portName: 'MY_APP',
serializer: payload => JSON.stringify(payload, dateReplacer),
deserializer: payload => JSON.parse(payload, dateReviver)
});
// actually ferries request to background
wrappedStore.dispatch(userClickedAlias());
Now you can use userClickedAlias
either on the content script or background page. When you use it in a content script, it will simply try to ferry the user-click-alias
message to the background and will call the function passed in (granted it was initialized in the background of course). You can now keep all action creators in the same file and it will make sense that no matter where you call the alias functions, they'll get executed in the background.
While this might not be as much of a problem in Chrome extensions, something worth considering is the potential issue of having action creators defined both in the background script and the content script(s). See https://github.com/hardchor/electron-redux/issues/92 for more detail. Essentially we need the ability to declare and define aliased actions separately somehow, but hopefully not with duplicated code.
https://www.useloom.com/share/d3e482bbc3354bd0b1c1b6fadb5f8fd6
https://github.com/tshaddix/react-chrome-redux/pull/131#issuecomment-381700100