Skip to content

Commit

Permalink
Use redux toolkit (#25)
Browse files Browse the repository at this point in the history
This transitions superglue to use redux toolkit. Notable changes here include:

1. The `flash` is no longer managed by superglue. Instead, its a slice that
listens to dispatched superglue events. The slice is generated automatically
when you first install superglue. This is backward breaking, to add the flash
back you would have to add a flash slice:

```js
import { createSlice, createAction } from '@reduxjs/toolkit'
import { SAVE_RESPONSE, BEFORE_VISIT} from '@thoughtbot/superglue'

const saveResponse = createAction(SAVE_RESPONSE)
const beforeVisit = createAction(BEFORE_VISIT)

export const flashSlice = createSlice({
  name: 'flash',
  initialState: {},
  extraReducers: (builder) => {
    builder.addCase(beforeVisit, (state, action) => {
      return {}
    })
    builder.addCase(saveResponse, (state, action) => {
      const { page } = action.payload;

      return {
        ...state, ...page.slices.flash
      }
    })
  }
})

```

and select the state via

```js
const flash = useSelector((state) => state.flash)
```

2. Similarly, we created a `slices/pages` to more easily allow for developer
customizations. This replaces the `applicationPagesReducer` in the previous
`reducer.js` file.

3. We refactor the creation of the redux store into its own `store.js` file
to make it more obvious for developers to customize.
  • Loading branch information
jho406 committed Oct 7, 2023
1 parent cc63ef7 commit 4218841
Show file tree
Hide file tree
Showing 27 changed files with 131 additions and 222 deletions.
19 changes: 4 additions & 15 deletions superglue/lib/action_creators/requests.js
Expand Up @@ -8,7 +8,6 @@ import {
removePropsAt,
} from '../utils'
import {
CLEAR_FLASH,
BEFORE_FETCH,
BEFORE_VISIT,
BEFORE_REMOTE,
Expand Down Expand Up @@ -66,15 +65,6 @@ function buildMeta(pageKey, page, state) {
}
}

export function clearFlash({ pageKey }) {
return {
type: CLEAR_FLASH,
payload: {
pageKey,
},
}
}

export function remote(
path,
{
Expand All @@ -95,8 +85,9 @@ export function remote(
body,
})
pageKey = pageKey || getState().superglue.currentPageKey
const currentPageKey = getState().superglue.currentPageKey

dispatch(beforeRemote({ fetchArgs }))
dispatch(beforeRemote({ currentPageKey, fetchArgs }))
dispatch(beforeFetch({ fetchArgs }))

return fetch(...fetchArgs)
Expand Down Expand Up @@ -142,9 +133,6 @@ export function visit(
let pageKey = urlToPageKey(path)

return (dispatch, getState) => {
const currentKey = getState().superglue.currentPageKey
dispatch(clearFlash({ pageKey: currentKey }))

placeholderKey = placeholderKey && urlToPageKey(placeholderKey)
const hasPlaceholder = !!getState().pages[placeholderKey]

Expand Down Expand Up @@ -175,7 +163,8 @@ export function visit(
signal,
})

dispatch(beforeVisit({ fetchArgs }))
const currentPageKey = getState().superglue.currentPageKey
dispatch(beforeVisit({ currentPageKey, fetchArgs }))
dispatch(beforeFetch({ fetchArgs }))

lastVisitController.abort()
Expand Down
1 change: 0 additions & 1 deletion superglue/lib/actions.js
Expand Up @@ -4,7 +4,6 @@ export const BEFORE_REMOTE = '@@superglue/BEFORE_REMOTE'

export const SAVE_RESPONSE = '@@superglue/SAVE_RESPONSE'
export const HANDLE_GRAFT = '@@superglue/HANDLE_GRAFT'
export const CLEAR_FLASH = '@@superglue/CLEAR_FLASH'

export const SUPERGLUE_ERROR = '@@superglue/ERROR'
export const GRAFTING_ERROR = '@@superglue/GRAFTING_ERROR'
Expand Down
4 changes: 4 additions & 0 deletions superglue/lib/index.js
Expand Up @@ -27,6 +27,7 @@ export {
REMOVE_PAGE,
GRAFTING_ERROR,
GRAFTING_SUCCESS,
HISTORY_CHANGE,
} from './actions'

export {
Expand All @@ -46,8 +47,11 @@ export { getIn } from './utils/immutability'
export { urlToPageKey }

function pageToInitialState(key, page) {
const slices = page.slices || {}

return {
pages: { [key]: page },
...slices,
}
}

Expand Down
22 changes: 0 additions & 22 deletions superglue/lib/reducers/index.js
@@ -1,7 +1,6 @@
import { setIn, getIn, urlToPageKey } from '../utils'
import {
REMOVE_PAGE,
CLEAR_FLASH,
SAVE_RESPONSE,
HANDLE_GRAFT,
HISTORY_CHANGE,
Expand Down Expand Up @@ -96,15 +95,6 @@ export function appendReceivedFragmentsOntoPage(
return nextState
}

export function addFlash(state, pageKey, receivedFlash) {
const nextState = { ...state }
const nextPage = { ...state[pageKey] }
nextPage.flash = { ...nextPage.flash, ...receivedFlash }
nextState[pageKey] = nextPage

return nextState
}

export function graftNodeOntoPage(state, pageKey, node, pathToNode) {
if (!node) {
console.warn(
Expand Down Expand Up @@ -132,7 +122,6 @@ export function handleGraft(state, pageKey, page) {
data: receivedNode,
path: pathToNode,
fragments: receivedFragments = [],
flash: receivedFlash,
} = page

return [
Expand All @@ -144,7 +133,6 @@ export function handleGraft(state, pageKey, page) {
pageKey,
receivedFragments
),
(nextState) => addFlash(nextState, pageKey, receivedFlash),
].reduce((memo, fn) => fn(memo), state)
}

Expand Down Expand Up @@ -185,16 +173,6 @@ export function pageReducer(state = {}, action) {

return nextState
}
case CLEAR_FLASH: {
const { pageKey } = action.payload
const nextState = { ...state }
const nextPage = { ...state[pageKey] }

nextPage.flash = {}
nextState[pageKey] = nextPage

return nextState
}
case COPY_PAGE: {
const nextState = { ...state }
const { from, to } = action.payload
Expand Down
5 changes: 2 additions & 3 deletions superglue/lib/utils/react.js
Expand Up @@ -14,12 +14,11 @@ export function mapStateToProps(
let params = ownProps
const csrfToken = state.superglue.csrfToken
pageKey = urlToPageKey(pageKey)
const { data, flash, fragments } = state.pages[pageKey] || {
const { data, fragments } = state.pages[pageKey] || {
data: {},
flash: {},
fragments: [],
}
return { ...data, ...params, pageKey, csrfToken, flash, fragments }
return { ...data, ...params, pageKey, csrfToken, fragments }
}

export const mapDispatchToProps = {
Expand Down
14 changes: 0 additions & 14 deletions superglue/spec/features/navigation.spec.js
Expand Up @@ -71,7 +71,6 @@ describe('start', () => {
data: {
heading: 'this is page 1',
},
flash: {},
componentIdentifier: 'home',
assets: ['123.js', '123.css'],
fragments: [],
Expand Down Expand Up @@ -106,7 +105,6 @@ describe('start', () => {
data: {
heading: 'this is page 1',
},
flash: {},
componentIdentifier: 'home',
assets: ['123.js', '123.css'],
fragments: [],
Expand Down Expand Up @@ -137,7 +135,6 @@ describe('navigation', () => {
data: {
heading: 'this is page 1',
},
flash: {},
componentIdentifier: 'home',
assets: ['123.js', '123.css'],
fragments: [],
Expand Down Expand Up @@ -165,7 +162,6 @@ describe('navigation', () => {

const pageState = {
data: { heading: 'Some heading 2' },
flash: {},
csrfToken: 'token',
assets: ['application-123.js', 'application-123.js'],
componentIdentifier: 'about',
Expand Down Expand Up @@ -194,7 +190,6 @@ describe('navigation', () => {
data: {
heading: 'this is page 1',
},
flash: {},
componentIdentifier: 'home',
assets: ['123.js', '123.css'],
fragments: [],
Expand Down Expand Up @@ -230,7 +225,6 @@ describe('navigation', () => {

const pageState = {
data: { heading: 'Some heading 2' },
flash: {},
csrfToken: 'token',
assets: ['application-123.js', 'application-123.js'],
componentIdentifier: 'about',
Expand Down Expand Up @@ -272,7 +266,6 @@ describe('navigation', () => {
data: {
heading: 'this is page 1',
},
flash: {},
componentIdentifier: 'home',
assets: ['123.js', '123.css'],
fragments: [],
Expand Down Expand Up @@ -315,7 +308,6 @@ describe('navigation', () => {
data: {
heading: 'this is page 1',
},
flash: {},
componentIdentifier: 'home',
assets: ['123.js', '123.css'],
fragments: [],
Expand Down Expand Up @@ -369,7 +361,6 @@ describe('navigation', () => {
data: {
heading: 'this is page 1',
},
flash: {},
componentIdentifier: 'home',
assets: ['123.js', '123.css'],
fragments: [],
Expand Down Expand Up @@ -419,7 +410,6 @@ describe('navigation', () => {
data: {
heading: 'this is page 1',
},
flash: {},
componentIdentifier: 'home',
assets: ['123.js', '123.css'],
fragments: [],
Expand Down Expand Up @@ -496,7 +486,6 @@ describe('navigation', () => {
data: {
heading: 'this is page 1',
},
flash: {},
componentIdentifier: 'home',
assets: ['123.js', '123.css'],
fragments: [],
Expand Down Expand Up @@ -540,7 +529,6 @@ describe('navigation', () => {
data: {
heading: 'this is page 1',
},
flash: {},
componentIdentifier: 'home',
assets: ['123.js', '123.css'],
fragments: [],
Expand All @@ -561,7 +549,6 @@ describe('navigation', () => {

const pageState = {
data: { heading: 'Some heading 2' },
flash: {},
csrfToken: 'token',
assets: ['application-123.js', 'application-123.js'],
componentIdentifier: 'about',
Expand Down Expand Up @@ -591,7 +578,6 @@ describe('navigation', () => {
heading: 'this is page 1',
address: undefined,
},
flash: {},
fragments: [],
componentIdentifier: 'home',
}
Expand Down
2 changes: 0 additions & 2 deletions superglue/spec/fixtures.js
Expand Up @@ -5,7 +5,6 @@ export const visitSuccess = () => {
csrfToken: 'token',
assets: ['application-123.js', 'application-123.js'],
componentIdentifier: 'about',
flash: {},
fragments: [],
}),
headers: {
Expand All @@ -23,7 +22,6 @@ export const graftSuccessWithNewZip = () => {
path: 'data.address',
csrfToken: 'token',
assets: ['application-new123.js', 'application-new123.js'],
flash: {},
fragments: [],
}),
headers: {
Expand Down
17 changes: 7 additions & 10 deletions superglue/spec/lib/action_creators.spec.js
Expand Up @@ -272,6 +272,7 @@ describe('action creators', () => {
{
type: '@@superglue/BEFORE_REMOTE',
payload: {
currentPageKey: "/bar",
fetchArgs: [
'/foo?props_at=data.body&__=0',
{
Expand Down Expand Up @@ -327,6 +328,7 @@ describe('action creators', () => {
{
type: '@@superglue/BEFORE_REMOTE',
payload: {
currentPageKey: "/bar",
fetchArgs: [
'/foo?props_at=data.body.aside.top&__=0',
{
Expand Down Expand Up @@ -780,7 +782,7 @@ describe('action creators', () => {
const expectedActions = [
{
type: '@@superglue/BEFORE_REMOTE',
payload: { fetchArgs: ['/foo?__=0', expect.any(Object)] },
payload: { currentPageKey: "/bar", fetchArgs: ['/foo?__=0', expect.any(Object)] },
},
{
type: '@@superglue/BEFORE_FETCH',
Expand Down Expand Up @@ -856,7 +858,7 @@ describe('action creators', () => {
const expectedActions = [
{
type: '@@superglue/BEFORE_REMOTE',
payload: { fetchArgs: ['/foo?__=0', expect.any(Object)] },
payload: { currentPageKey: '/bar', fetchArgs: ['/foo?__=0', expect.any(Object)] },
},
{
type: '@@superglue/BEFORE_FETCH',
Expand Down Expand Up @@ -987,7 +989,7 @@ describe('action creators', () => {
const expectedActions = [
{
type: '@@superglue/BEFORE_REMOTE',
payload: { fetchArgs: ['/foo?__=0', expect.any(Object)] },
payload: { currentPageKey: "/bar", fetchArgs: ['/foo?__=0', expect.any(Object)] },
},
{
type: '@@superglue/BEFORE_FETCH',
Expand Down Expand Up @@ -1021,7 +1023,7 @@ describe('action creators', () => {
const expectedActions = [
{
type: '@@superglue/BEFORE_REMOTE',
payload: { fetchArgs: ['/foo?__=0', expect.any(Object)] },
payload: { currentPageKey: "/bar", fetchArgs: ['/foo?__=0', expect.any(Object)] },
},
{
type: '@@superglue/BEFORE_FETCH',
Expand Down Expand Up @@ -1060,7 +1062,7 @@ describe('action creators', () => {
const expectedActions = [
{
type: '@@superglue/BEFORE_REMOTE',
payload: { fetchArgs: ['/foo?__=0', expect.any(Object)] },
payload: { currentPageKey: "/bar", fetchArgs: ['/foo?__=0', expect.any(Object)] },
},
{
type: '@@superglue/BEFORE_FETCH',
Expand Down Expand Up @@ -1316,7 +1318,6 @@ describe('action creators', () => {
data: {
address: {},
},
flash: {},
csrfToken: 'token',
assets: [
'application-new123.js',
Expand All @@ -1333,10 +1334,6 @@ describe('action creators', () => {
fetchMock.mock('/details?props_at=data.address&__=0', mockResponse)

const expectedActions = [
{
type: '@@superglue/CLEAR_FLASH',
payload: { pageKey: '/current' },
},
{
type: '@@superglue/COPY_PAGE',
payload: { from: '/current', to: '/details' },
Expand Down

0 comments on commit 4218841

Please sign in to comment.