Repository: gatsbyjs/gatsby
File: packages/gatsby/src/redux/index.ts (TypeScript)

Code before:
} from "redux"
import _ from "lodash"

import { mett } from "../utils/mett"
import thunk, { ThunkMiddleware } from "redux-thunk"
import * as reducers from "./reducers"
import { writeToCache, readFromCache } from "./persist"
import { IGatsbyState, ActionsUnion } from "./types"

// Create event emitter for actions
export const emitter = mett()

// Read old node data from cache.
export const readState = (): IGatsbyState => {
  try {
    const state = readFromCache() as IGatsbyState
    if (state.nodes) {
      // re-create nodesByType
      state.nodesByType = new Map()
      state.nodes.forEach(node => {
        const { type } = node.internal
        if (!state.nodesByType.has(type)) {
          state.nodesByType.set(type, new Map())
        }
        // eslint-disable-next-line no-unused-expressions
        state.nodesByType.get(type)?.set(node.id, node)
      })
    }

    // jsonDataPaths was removed in the per-page-manifest
    // changes. Explicitly delete it here to cover case where user
    // runs gatsby the first time after upgrading.
    delete state[`jsonDataPaths`]
    return state
  } catch (e) {
    // ignore errors.
  }
  // BUG: Would this not cause downstream bugs? seems likely. Why wouldn't we just
  // throw and kill the program?
  return {} as IGatsbyState
}

export interface IMultiDispatch {
  <T extends ActionsUnion>(action: T[]): T[]
}

/**
 * Redux middleware handling array of actions
 */
const multi: Middleware<IMultiDispatch> = ({ dispatch }) => next => (
  action: ActionsUnion

Review comment (bug):
why this part was changed? also the change seems "wrong" - we should be guaranteed that `state.nodesByType.get(type)` exists, because of last 3 lines that create entry if it didn't exist before

Code after:
} from "redux"
import _ from "lodash"

import { mett } from "../utils/mett"
import thunk, { ThunkMiddleware } from "redux-thunk"
import * as reducers from "./reducers"
import { writeToCache, readFromCache } from "./persist"
import { IGatsbyState, ActionsUnion } from "./types"

// Create event emitter for actions
export const emitter = mett()

// Read old node data from cache.
export const readState = (): IGatsbyState => {
  try {
    const state = readFromCache() as IGatsbyState
    if (state.nodes) {
      // re-create nodesByType
      state.nodesByType = new Map()
      state.nodes.forEach(node => {
        const { type } = node.internal
        if (!state.nodesByType.has(type)) {
          state.nodesByType.set(type, new Map())
        }
        // The `.has` and `.set` calls above make this safe
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        state.nodesByType.get(type)!.set(node.id, node)
      })
    }

    // jsonDataPaths was removed in the per-page-manifest
    // changes. Explicitly delete it here to cover case where user
    // runs gatsby the first time after upgrading.
    delete state[`jsonDataPaths`]
    return state
  } catch (e) {
    // ignore errors.
  }
  // BUG: Would this not cause downstream bugs? seems likely. Why wouldn't we just
  // throw and kill the program?
  return {} as IGatsbyState
}

export interface IMultiDispatch {
  <T extends ActionsUnion>(action: T[]): T[]
}

/**
 * Redux middleware handling array of actions
 */
const multi: Middleware<IMultiDispatch> = ({ dispatch }) => next => (