Skip to content

Instantly share code, notes, and snippets.

@weeksie
Created July 31, 2023 19:15
Show Gist options
  • Save weeksie/aa72f162e3feaf6cf0e5a6abeb3551a2 to your computer and use it in GitHub Desktop.
Save weeksie/aa72f162e3feaf6cf0e5a6abeb3551a2 to your computer and use it in GitHub Desktop.
Example background script with hand-rolled redux for chrome extensions
import reloadOnUpdate from "virtual:reload-on-update-in-background-script";
reloadOnUpdate("pages/background");
import {
type Store,
type StoreApi,
type Dispatch,
type Listener,
} from '@lib/store';
import { auth, productImport } from '@lib/middleware';
import { reducer, type InitialState } from '@lib/reducer';
const middlewares = [
auth,
productImport,
];
const dispatch: Dispatch = (action) => {
console.log(`[root dispatch]: ${action.type}`);
Store.state = reducer(Store.state, action);
notify();
};
const Store: Store = {
state: InitialState,
dispatch,
getState: () => Store.state,
}
let middlewareDispatch: Dispatch = () => {
throw new Error(`Can't dispatch while constructing middleware`);
};
const middlewareApi: StoreApi = {
getState: Store.getState,
dispatch: (action) => middlewareDispatch(action),
};
const chained = middlewares.map(middleware => middleware(middlewareApi));
middlewareDispatch = chained.reduce((a, b) => (next) => a(b(next)))(Store.dispatch);
Store.dispatch = middlewareDispatch;
const listeners = new Set<Listener>();
const subscribe = (listener: Listener) => {
listeners.add(listener);
listener(Store.getState());
}
const unsubscribe = (listener: Listener) => {
listeners.delete(listener);
}
const notify = () => {
for (const listener of listeners) {
listener(Store.getState());
}
}
chrome.runtime.onConnect.addListener((port) => {
if (port.name === 'stateSubscription') {
const listener: Listener = (state) => {
port.postMessage({ state });
}
subscribe(listener);
port.onDisconnect.addListener(() => {
unsubscribe(listener);
});
}
})
chrome.runtime.onMessage.addListener((request) => {
if (request.dispatch) {
Store.dispatch(request.action);
return;
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment