diff --git a/packages/gatsby/src/redux/__tests__/__snapshots__/nodes.js.snap b/packages/gatsby/src/redux/__tests__/__snapshots__/nodes.ts.snap similarity index 100% rename from packages/gatsby/src/redux/__tests__/__snapshots__/nodes.js.snap rename to packages/gatsby/src/redux/__tests__/__snapshots__/nodes.ts.snap diff --git a/packages/gatsby/src/redux/__tests__/nodes.js b/packages/gatsby/src/redux/__tests__/nodes.ts similarity index 83% rename from packages/gatsby/src/redux/__tests__/nodes.js rename to packages/gatsby/src/redux/__tests__/nodes.ts index 44870361eac3a..80f73686f3044 100644 --- a/packages/gatsby/src/redux/__tests__/nodes.js +++ b/packages/gatsby/src/redux/__tests__/nodes.ts @@ -1,18 +1,29 @@ -const { actions } = require(`../actions`) -const nodeReducer = require(`../reducers/nodes`) -const nodeTouchedReducer = require(`../reducers/nodes-touched`) +import { actions } from "../actions" +import { nodeReducer } from "../reducers/nodes" +import nodeTouchedReducer from "../reducers/nodes-touched" +import { IGatsbyNode } from "../types" jest.mock(`../../db/nodes`) jest.mock(`../nodes`) const dispatch = jest.fn() -describe(`Create and update nodes`, () => { - beforeEach(() => { +type MapObject = Record + +const fromMapToObject = (map: Map): MapObject => { + const obj: MapObject = {} + Array.from(map.entries()).forEach(([key, value]) => { + obj[key] = value + }) + return obj +} + +describe(`Create and update nodes`, (): void => { + beforeEach((): void => { dispatch.mockClear() }) - it(`allows creating nodes`, () => { + it(`allows creating nodes`, (): void => { actions.createNode( { id: `hi`, @@ -37,7 +48,7 @@ describe(`Create and update nodes`, () => { }) }) - it(`allows updating nodes`, () => { + it(`allows updating nodes`, (): void => { actions.createNode( { id: `hi`, @@ -89,12 +100,13 @@ describe(`Create and update nodes`, () => { let state = nodeReducer(undefined, action) state = nodeReducer(state, updateAction) - expect(state.get(`hi`).pickle).toEqual(false) - expect(state.get(`hi`).deep.array[0]).toEqual(1) - expect(state.get(`hi`).deep2.boom).toEqual(`foo`) + + expect(state.get(`hi`)!.pickle).toEqual(false) + expect((state.get(`hi`)!.deep as any).array![0]).toEqual(1) + expect((state.get(`hi`)!.deep2 as any).boom).toEqual(`foo`) }) - it(`nodes that are added are also "touched"`, () => { + it(`nodes that are added are also "touched"`, (): void => { actions.createNode( { id: `hi`, @@ -112,14 +124,14 @@ describe(`Create and update nodes`, () => { )(dispatch) const action = dispatch.mock.calls[0][0] - let state = nodeTouchedReducer(undefined, action) + const state = nodeTouchedReducer(undefined, action) expect(state instanceof Set).toBe(true) expect(state.has(`hi`)).toBe(true) }) - it(`allows adding fields to nodes`, () => { + it(`allows adding fields to nodes`, (): void => { actions.createNode( { id: `hi`, @@ -155,7 +167,7 @@ describe(`Create and update nodes`, () => { }) }) - it(`throws error if a field is updated by a plugin not its owner`, () => { + it(`throws error if a field is updated by a plugin not its owner`, (): void => { actions.createNode( { id: `hi`, @@ -186,7 +198,7 @@ describe(`Create and update nodes`, () => { ) state = nodeReducer(state, addFieldAction) - function callActionCreator() { + function callActionCreator(): void { actions.createNodeField( { node: state.get(`hi`), @@ -203,7 +215,7 @@ describe(`Create and update nodes`, () => { ) }) - it(`throws error if a node is created by a plugin not its owner`, () => { + it(`throws error if a node is created by a plugin not its owner`, (): void => { actions.createNode( { id: `hi`, @@ -220,7 +232,7 @@ describe(`Create and update nodes`, () => { } )(dispatch) - function callActionCreator() { + function callActionCreator(): void { actions.createNode( { id: `hi2`, @@ -243,8 +255,8 @@ describe(`Create and update nodes`, () => { ) }) - it(`throws error if a node sets a value on "fields"`, () => { - function callActionCreator() { + it(`throws error if a node sets a value on "fields"`, (): void => { + function callActionCreator(): void { actions.createNode( { id: `hi`, @@ -271,11 +283,3 @@ describe(`Create and update nodes`, () => { ) }) }) - -const fromMapToObject = map => { - const obj = {} - Array.from(map.entries()).forEach(([key, value]) => { - obj[key] = value - }) - return obj -} diff --git a/packages/gatsby/src/redux/reducers/index.js b/packages/gatsby/src/redux/reducers/index.js index db80119a10f52..10223e20f2458 100644 --- a/packages/gatsby/src/redux/reducers/index.js +++ b/packages/gatsby/src/redux/reducers/index.js @@ -1,4 +1,4 @@ -const reduxNodes = require(`./nodes`) +import { nodeReducer } from "./nodes" const lokiNodes = require(`../../db/loki/nodes`).reducer import { pagesReducer } from "./pages" import { redirectsReducer } from "./redirects" @@ -10,6 +10,7 @@ import { pageDataReducer } from "./page-data" import { themesReducer } from "./themes" import { webpackCompilationHashReducer } from "./webpack-compilation-hash" import { reducer as logReducer } from "gatsby-cli/lib/reporter/redux/reducer" +import { lastAction } from "./last-action" // const backend = process.env.GATSBY_DB_NODES || `redux` const backend = `redux` @@ -18,7 +19,7 @@ function getNodesReducer() { let nodesReducer switch (backend) { case `redux`: - nodesReducer = reduxNodes + nodesReducer = nodeReducer break case `loki`: nodesReducer = lokiNodes @@ -57,7 +58,7 @@ module.exports = { nodesByType: getNodesByTypeReducer(), resolvedNodesCache: require(`./resolved-nodes`), nodesTouched: require(`./nodes-touched`), - lastAction: require(`./last-action`), + lastAction: lastAction, flattenedPlugins: require(`./flattened-plugins`), config: require(`./config`), schema: schemaReducer, diff --git a/packages/gatsby/src/redux/reducers/last-action.js b/packages/gatsby/src/redux/reducers/last-action.js deleted file mode 100644 index 7f6a486f36394..0000000000000 --- a/packages/gatsby/src/redux/reducers/last-action.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = (state = null, action) => action diff --git a/packages/gatsby/src/redux/reducers/last-action.ts b/packages/gatsby/src/redux/reducers/last-action.ts new file mode 100644 index 0000000000000..1b3b11c756cf0 --- /dev/null +++ b/packages/gatsby/src/redux/reducers/last-action.ts @@ -0,0 +1,6 @@ +import { IGatsbyState, ActionsUnion } from "../types" + +export const lastAction = ( + _state: IGatsbyState["lastAction"], + action: ActionsUnion +): IGatsbyState["lastAction"] => action diff --git a/packages/gatsby/src/redux/reducers/nodes.js b/packages/gatsby/src/redux/reducers/nodes.ts similarity index 76% rename from packages/gatsby/src/redux/reducers/nodes.js rename to packages/gatsby/src/redux/reducers/nodes.ts index 2e37dd3a16b56..d9ee830706a12 100644 --- a/packages/gatsby/src/redux/reducers/nodes.js +++ b/packages/gatsby/src/redux/reducers/nodes.ts @@ -1,7 +1,13 @@ -module.exports = (state = new Map(), action) => { +import { ActionsUnion, IGatsbyState } from "../types" + +export const nodeReducer = ( + state: IGatsbyState["nodes"] = new Map(), + action: ActionsUnion +): IGatsbyState["nodes"] => { switch (action.type) { case `DELETE_CACHE`: return new Map() + case `CREATE_NODE`: { state.set(action.payload.id, action.payload) return state diff --git a/packages/gatsby/src/redux/types.ts b/packages/gatsby/src/redux/types.ts index fc0ea0dfc7080..569ceea30e911 100644 --- a/packages/gatsby/src/redux/types.ts +++ b/packages/gatsby/src/redux/types.ts @@ -223,12 +223,17 @@ export interface ICachedReduxState { } export type ActionsUnion = + | IAddChildNodeToParentNodeAction + | IAddFieldToNodeAction | IAddThirdPartySchema | ICreateFieldExtension + | ICreateNodeAction | ICreatePageAction | ICreatePageDependencyAction | ICreateTypes | IDeleteCacheAction + | IDeleteNodeAction + | IDeleteNodesAction | IDeleteComponentDependenciesAction | IDeletePageAction | IPageQueryRunAction @@ -472,3 +477,30 @@ export interface ISetSiteConfig { type: `SET_SITE_CONFIG` payload: IGatsbyState["config"] } + +export interface ICreateNodeAction { + type: `CREATE_NODE` + payload: IGatsbyNode +} + +export interface IAddFieldToNodeAction { + type: `ADD_FIELD_TO_NODE` + payload: IGatsbyNode +} + +export interface IAddChildNodeToParentNodeAction { + type: `ADD_CHILD_NODE_TO_PARENT_NODE` + payload: IGatsbyNode +} + +export interface IDeleteNodeAction { + type: `DELETE_NODE` + payload: { + id: Identifier + } +} + +export interface IDeleteNodesAction { + type: `DELETE_NODES` + payload: Identifier[] +}