Skip to content

Instantly share code, notes, and snippets.

@blacktaxi
Created September 1, 2017 17:34
Show Gist options
  • Save blacktaxi/2c55d77dab96c53055b22b96ddfbd9a7 to your computer and use it in GitHub Desktop.
Save blacktaxi/2c55d77dab96c53055b22b96ddfbd9a7 to your computer and use it in GitHub Desktop.
Time travel debugging with Focal! (use Redux dev tools browser extension)
import { Atom } from '@grammarly/focal'
import { createStore } from 'redux'
declare global {
interface Window {
__REDUX_DEVTOOLS_EXTENSION__?: () => undefined
}
}
/**
* Call this on your root state atom to enable Redux dev tools debugging.
*
* For example:
* const state = Atom.create(initialState)
* createAtomStore(state) // <- this line enables redux devtools
*/
export function createAtomStore<TState>(atom: Atom<TState>) {
const store = createStore(
(_: TState, action: { type: '@@ATOM_UPDATE', newState: TState }) => {
return action.newState
},
atom.get(),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
let dispatch = true
let setAtom = true
const atomSub = atom.subscribe(x => {
if (dispatch) {
setAtom = false
store.dispatch({ type: '@@ATOM_UPDATE', newState: x })
setAtom = true
}
})
const storeSub = store.subscribe(() => {
if (setAtom) {
dispatch = false
// @TODO why do we get an undefined state here if you click commit right after
// the store was initialized?
atom.modify(x => store.getState() !== undefined ? store.getState() : x)
dispatch = true
}
})
return {
store,
unsubscribe() {
atomSub.unsubscribe()
storeSub()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment