Skip to content

Commit

Permalink
cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
pieh committed Dec 11, 2024
1 parent f611677 commit d0b1452
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,5 @@ emitter.on(`DELETE_PAGE`, action => {
: swapToStagedDelete(deleteNodeActions)
}

console.log(`deletePage stuff`, {
transactionId: action.transactionId,
deleteNodeActions,
})

store.dispatch(deleteNodeActions)
})
51 changes: 51 additions & 0 deletions packages/gatsby/src/redux/actions/commit-staging-nodes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { ActionsUnion } from "../types"
import { internalCreateNodeWithoutValidation } from "./internal"
import { actions as publicActions } from "./public"
import { getNode } from "../../datastore"

import { store } from "../index"

export const commitStagingNodes = (
transactionId: string
): Array<ActionsUnion> => {
const transaction = store
.getState()
.nodesStaging.transactions.get(transactionId)
if (!transaction) {
return []
}

const actions: Array<ActionsUnion> = [
{
type: `COMMIT_STAGING_NODES`,
payload: {
transactionId,
},
},
]

const nodesState = new Map()
for (const action of transaction) {
if (action.type === `CREATE_NODE_STAGING`) {
nodesState.set(action.payload.id, action)
} else if (action.type === `DELETE_NODE_STAGING` && action.payload?.id) {
nodesState.set(action.payload.id, undefined)
}
}
for (const [id, actionOrDelete] of nodesState.entries()) {
if (actionOrDelete) {
actions.push(
...internalCreateNodeWithoutValidation(
actionOrDelete.payload,
actionOrDelete.plugin,
actionOrDelete
)
)
} else {
// delete case
actions.push(publicActions.deleteNode(getNode(id)))
}
}

return actions
}
135 changes: 87 additions & 48 deletions packages/gatsby/src/redux/actions/internal.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import reporter from "gatsby-cli/lib/reporter"
import _ from "lodash"

import {
IGatsbyConfig,
Expand Down Expand Up @@ -28,8 +29,11 @@ import {
IDeleteNodeManifests,
IClearGatsbyImageSourceUrlAction,
ActionsUnion,
IGatsbyNode,
IDeleteNodeAction,
} from "../types"

import { store } from "../index"
import { gatsbyConfigSchema } from "../../joi-schemas/joi"
import { didYouMean } from "../../utils/did-you-mean"
import {
Expand All @@ -39,9 +43,8 @@ import {
getInProcessJobPromise,
} from "../../utils/jobs/manager"
import { getEngineContext } from "../../utils/engine-context"
import { store } from "../index"

import { getNode } from "../../datastore"
import { hasNodeChanged } from "../../utils/nodes"

/**
* Create a dependency between a page and data. Probably for
Expand Down Expand Up @@ -450,62 +453,98 @@ export const clearGatsbyImageSourceUrls =
}
}

let publicActions
export const setPublicActions = (actions): void => {
publicActions = actions
// We add a counter to node.internal for fast comparisons/intersections
// of various node slices. The counter must increase even across builds.
export function getNextNodeCounter(): number {
const lastNodeCounter = store.getState().status.LAST_NODE_COUNTER ?? 0
if (lastNodeCounter >= Number.MAX_SAFE_INTEGER) {
throw new Error(
`Could not create more nodes. Maximum node count is reached: ${lastNodeCounter}`
)
}
return lastNodeCounter + 1
}

export const commitStagingNodes = (
transactionId: string
): Array<ActionsUnion> => {
const transaction = store
.getState()
.nodesStaging.transactions.get(transactionId)
if (!transaction) {
return []
}
export const findChildren = (initialChildren: Array<string>): Array<string> => {
const children = [...initialChildren]
const queue = [...initialChildren]
const traversedNodes = new Set()

const actions: Array<ActionsUnion> = [
{
type: `COMMIT_STAGING_NODES`,
payload: {
transactionId,
},
},
]

const nodesState = new Map()
for (const action of transaction) {
if (action.type === `CREATE_NODE_STAGING`) {
nodesState.set(action.payload.id, action)
} else if (action.type === `DELETE_NODE_STAGING` && action.payload?.id) {
nodesState.set(action.payload.id, undefined)
while (queue.length > 0) {
const currentChild = getNode(queue.pop()!)
if (!currentChild || traversedNodes.has(currentChild.id)) {
continue
}
traversedNodes.add(currentChild.id)
const newChildren = currentChild.children
if (_.isArray(newChildren) && newChildren.length > 0) {
children.push(...newChildren)
queue.push(...newChildren)
}
}
return children
}

function sanitizeNode(node: any): any {
return {
...node,
internal: {
...node.internal,
owner: undefined,
},
function isNode(node: any): node is IGatsbyNode {
return Boolean(node)
}

export function internalCreateNodeWithoutValidation(
node: IGatsbyNode,
plugin?: IGatsbyPlugin,
actionOptions?: any
): Array<ActionsUnion> {
let deleteActions: Array<IDeleteNodeAction> | undefined
let updateNodeAction

const oldNode = getNode(node.id)

// marking internal-data-bridge as owner of SitePage instead of plugin that calls createPage
if (oldNode && !hasNodeChanged(node.id, node.internal.contentDigest)) {
updateNodeAction = {
...actionOptions,
plugin,
type: `TOUCH_NODE`,
typeName: node.internal.type,
payload: node.id,
}
} else {
// Remove any previously created descendant nodes as they're all due
// to be recreated.
if (oldNode) {
const createDeleteAction = (node: IGatsbyNode): IDeleteNodeAction => {
return {
...actionOptions,
type: `DELETE_NODE`,
plugin,
payload: node,
isRecursiveChildrenDelete: true,
}
}
deleteActions = findChildren(oldNode.children)
.map(getNode)
.filter(isNode)
.map(createDeleteAction)
}
}

for (const [id, actionOrDelete] of nodesState.entries()) {
if (actionOrDelete) {
actions.push(
publicActions.createNode(
sanitizeNode(actionOrDelete.payload),
actionOrDelete.plugin
)
)
} else {
// delete case
actions.push(publicActions.deleteNode(getNode(id), actionOrDelete.plugin))
node.internal.counter = getNextNodeCounter()

updateNodeAction = {
...actionOptions,
type: `CREATE_NODE`,
plugin,
oldNode,
payload: node,
}
}

const actions: Array<ActionsUnion> = []

if (deleteActions && deleteActions.length) {
actions.push(...deleteActions)
}

actions.push(updateNodeAction)

return actions
}
106 changes: 16 additions & 90 deletions packages/gatsby/src/redux/actions/public.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,16 @@ const apiRunnerNode = require(`../../utils/api-runner-node`)
const { getNonGatsbyCodeFrame } = require(`../../utils/stack-trace-utils`)
const { getPageMode } = require(`../../utils/page-mode`)
const normalizePath = require(`../../utils/normalize-path`).default
import { createJobV2FromInternalJob, setPublicActions } from "./internal"
import {
createJobV2FromInternalJob,
internalCreateNodeWithoutValidation,
getNextNodeCounter,
findChildren,
} from "./internal"
import { maybeSendJobToMainProcess } from "../../utils/jobs/worker-messaging"
import { reportOnce } from "../../utils/report-once"
import { wrapNode } from "../../utils/detect-node-mutations"
import { shouldRunOnCreatePage, shouldRunOnCreateNode } from "../plugin-runner"

const isNotTestEnv = process.env.NODE_ENV !== `test`
const isTestEnv = process.env.NODE_ENV === `test`
Expand All @@ -57,29 +63,6 @@ const ensureWindowsDriveIsUppercase = filePath => {
: filePath
}

const findChildren = initialChildren => {
const children = [...initialChildren]
const queue = [...initialChildren]
const traversedNodes = new Set()

while (queue.length > 0) {
const currentChild = getNode(queue.pop())
if (!currentChild || traversedNodes.has(currentChild.id)) {
continue
}
traversedNodes.add(currentChild.id)
const newChildren = currentChild.children
if (_.isArray(newChildren) && newChildren.length > 0) {
children.push(...newChildren)
queue.push(...newChildren)
}
}
return children
}

import type { Plugin } from "./types"
import { shouldRunOnCreateNode } from "../plugin-runner"

type Job = {
id: string,
}
Expand Down Expand Up @@ -482,14 +465,9 @@ ${reservedFields.map(f => ` * "${f}"`).join(`\n`)}
}
node.id = `SitePage ${internalPage.path}`

let deleteActions
let updateNodeAction
// const shouldCommitImmediately =
// // !shouldRunOnCreateNode() ||
// !page.path.includes("hello-world")
const transactionId =
actionOptions?.transactionId ??
(shouldRunOnCreateNode() ? node.internal.contentDigest : undefined)
(shouldRunOnCreatePage() ? node.internal.contentDigest : undefined)

// Sanitize page object so we don't attempt to serialize user-provided objects that are not serializable later
const sanitizedPayload = sanitizeNode(internalPage)
Expand Down Expand Up @@ -517,53 +495,13 @@ ${reservedFields.map(f => ` * "${f}"`).join(`\n`)}
return actions
}

const oldNode = getNode(node.id)

// marking internal-data-bridge as owner of SitePage instead of plugin that calls createPage
if (oldNode && !hasNodeChanged(node.id, node.internal.contentDigest)) {
updateNodeAction = {
...actionOptions,
plugin: { name: `internal-data-bridge` },
type: `TOUCH_NODE`,
typeName: node.internal.type,
payload: node.id,
}
} else {
// Remove any previously created descendant nodes as they're all due
// to be recreated.
if (oldNode) {
const createDeleteAction = node => {
return {
...actionOptions,
type: `DELETE_NODE`,
plugin: { name: `internal-data-bridge` },
payload: node,
isRecursiveChildrenDelete: true,
}
}
deleteActions = findChildren(oldNode.children)
.map(getNode)
.map(createDeleteAction)
}

node.internal.counter = getNextNodeCounter()

updateNodeAction = {
...actionOptions,
type: `CREATE_NODE`,
plugin: { name: `internal-data-bridge` },
oldNode,
payload: node,
}
}

if (deleteActions && deleteActions.length) {
actions.push(...deleteActions)
}

actions.push(updateNodeAction)
const upsertNodeActions = internalCreateNodeWithoutValidation(
node,
{ name: `internal-data-bridge` },
actionOptions
)

return actions
return [...actions, ...upsertNodeActions]
}

/**
Expand Down Expand Up @@ -605,18 +543,6 @@ actions.deleteNode = (node: any, plugin?: Plugin) => {
}
}

// We add a counter to node.internal for fast comparisons/intersections
// of various node slices. The counter must increase even across builds.
function getNextNodeCounter() {
const lastNodeCounter = store.getState().status.LAST_NODE_COUNTER ?? 0
if (lastNodeCounter >= Number.MAX_SAFE_INTEGER) {
throw new Error(
`Could not create more nodes. Maximum node count is reached: ${lastNodeCounter}`
)
}
return lastNodeCounter + 1
}

// memberof notation is added so this code can be referenced instead of the wrapper.
/**
* Create a new node.
Expand Down Expand Up @@ -861,7 +787,7 @@ actions.createNode =
Array.isArray(actions) ? actions : [actions]
).find(action => action.type === `CREATE_NODE`)

if (!createNodeAction) {
if (!createNodeAction || !shouldRunOnCreateNode()) {
return Promise.resolve(undefined)
}

Expand Down Expand Up @@ -1552,4 +1478,4 @@ actions.setRequestHeaders = ({ domain, headers }, plugin: Plugin) => {

module.exports = { actions }

setPublicActions(actions)
// setPublicActions(actions)
Loading

0 comments on commit d0b1452

Please sign in to comment.