From 5d6c81aefc634ab6a5a28950ccd602a83a2778e5 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 18 Jan 2022 11:19:24 -0500 Subject: [PATCH] Remove React from page bundle --- extension/src/app/stores/enhancerStore.ts | 2 +- extension/src/app/stores/persistState.ts | 82 +++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 extension/src/app/stores/persistState.ts diff --git a/extension/src/app/stores/enhancerStore.ts b/extension/src/app/stores/enhancerStore.ts index 532cfccb..578f0f1c 100644 --- a/extension/src/app/stores/enhancerStore.ts +++ b/extension/src/app/stores/enhancerStore.ts @@ -1,6 +1,6 @@ import { Action, compose, Reducer, StoreEnhancerStoreCreator } from 'redux'; import { instrument } from '@redux-devtools/instrument'; -import { persistState } from '@redux-devtools/core'; +import persistState from './persistState'; import { ConfigWithExpandedMaxAge } from '../../browser/extension/inject/pageScript'; export function getUrlParam(key: string) { diff --git a/extension/src/app/stores/persistState.ts b/extension/src/app/stores/persistState.ts new file mode 100644 index 00000000..37f6075f --- /dev/null +++ b/extension/src/app/stores/persistState.ts @@ -0,0 +1,82 @@ +import _ from 'lodash'; +import { Action, PreloadedState, Reducer, StoreEnhancer } from 'redux'; +import { LiftedState } from '@redux-devtools/instrument'; + +export default function persistState< + S, + A extends Action, + MonitorState +>( + sessionId?: string | null, + deserializeState: (state: S) => S = _.identity, + deserializeAction: (action: A) => A = _.identity +): StoreEnhancer { + if (!sessionId) { + return (next) => + (...args) => + next(...args); + } + + function deserialize( + state: LiftedState + ): LiftedState { + return { + ...state, + actionsById: _.mapValues(state.actionsById, (liftedAction) => ({ + ...liftedAction, + action: deserializeAction(liftedAction.action), + })), + committedState: deserializeState(state.committedState), + computedStates: state.computedStates.map((computedState) => ({ + ...computedState, + state: deserializeState(computedState.state), + })), + }; + } + + return (next) => + >( + reducer: Reducer, + initialState?: PreloadedState + ) => { + const key = `redux-dev-session-${sessionId}`; + + let finalInitialState; + try { + const json = localStorage.getItem(key); + if (json) { + finalInitialState = + deserialize(JSON.parse(json) as LiftedState) || + initialState; + next(reducer, initialState); + } + } catch (e) { + console.warn('Could not read debug session from localStorage:', e); // eslint-disable-line no-console + try { + localStorage.removeItem(key); + } finally { + finalInitialState = undefined; + } + } + + const store = next( + reducer, + finalInitialState as PreloadedState | undefined + ); + + return { + ...store, + dispatch(action: T) { + store.dispatch(action); + + try { + localStorage.setItem(key, JSON.stringify(store.getState())); + } catch (e) { + console.warn('Could not write debug session to localStorage:', e); // eslint-disable-line no-console + } + + return action; + }, + }; + }; +}