diff --git a/packages/gatsby-source-filesystem/src/__tests__/gatsby-node.js b/packages/gatsby-source-filesystem/src/__tests__/gatsby-node.js index 06d188888272d..8056f21ae5e43 100644 --- a/packages/gatsby-source-filesystem/src/__tests__/gatsby-node.js +++ b/packages/gatsby-source-filesystem/src/__tests__/gatsby-node.js @@ -100,8 +100,7 @@ describe(`tests`, () => { expect(api.actions.createNode).toBeCalled() }) - // change event doesn't queue currently - this need to be fixed - it.skip(`queues node creation from changed files`, async () => { + it(`queues node creation from changed files`, async () => { const api = createApi() const sourceNodesPromise = gatsbyNode.sourceNodes(api, { path: `` }) // allow microtasks execution @@ -138,8 +137,7 @@ describe(`tests`, () => { expect(api.actions.createNode).toBeCalled() }) - // unlink event doesn't queue currently - this need to be fixed - it.skip(`queues node deletion from deleted files`, async () => { + it(`queues node deletion from deleted files`, async () => { const api = createApi() const sourceNodesPromise = gatsbyNode.sourceNodes(api, { path: `` }) // allow microtasks execution @@ -157,8 +155,7 @@ describe(`tests`, () => { expect(api.actions.deleteNode).toBeCalled() }) - // unlinkDir event doesn't queue currently - this need to be fixed - it.skip(`queues node deletion from deleted directories`, async () => { + it(`queues node deletion from deleted directories`, async () => { const api = createApi() const sourceNodesPromise = gatsbyNode.sourceNodes(api, { path: `` }) // allow microtasks execution diff --git a/packages/gatsby-source-filesystem/src/gatsby-node.js b/packages/gatsby-source-filesystem/src/gatsby-node.js index bc143049c7667..edce8f5ec077f 100644 --- a/packages/gatsby-source-filesystem/src/gatsby-node.js +++ b/packages/gatsby-source-filesystem/src/gatsby-node.js @@ -12,16 +12,6 @@ const createFSMachine = ( { actions: { createNode, deleteNode }, getNode, createNodeId, reporter }, pluginOptions ) => { - // For every path that is reported before the 'ready' event, we throw them - // into a queue and then flush the queue when 'ready' event arrives. - // After 'ready', we handle the 'add' event without putting it into a queue. - let pathQueue = [] - const flushPathQueue = () => { - let queue = pathQueue.slice() - pathQueue = null - return Promise.all(queue.map(createAndProcessNode)) - } - const createAndProcessNode = path => { const fileNodePromise = createFileNode( path, @@ -34,6 +24,35 @@ const createFSMachine = ( return fileNodePromise } + const deletePathNode = path => { + const node = getNode(createNodeId(path)) + // It's possible the node was never created as sometimes tools will + // write and then immediately delete temporary files to the file system. + if (node) { + deleteNode({ node }) + } + } + + // For every path that is reported before the 'ready' event, we throw them + // into a queue and then flush the queue when 'ready' event arrives. + // After 'ready', we handle the 'add' event without putting it into a queue. + let pathQueue = [] + const flushPathQueue = () => { + let queue = pathQueue.slice() + pathQueue = null + return Promise.all( + // eslint-disable-next-line consistent-return + queue.map(({ op, path }) => { + switch (op) { + case `delete`: + return deletePathNode(path) + case `upsert`: + return createAndProcessNode(path) + } + }) + ) + } + const fsMachine = Machine( { id: `fs`, @@ -59,20 +78,19 @@ const createFSMachine = ( on: { CHOKIDAR_READY: `READY`, CHOKIDAR_ADD: { actions: `queueNodeProcessing` }, + CHOKIDAR_CHANGE: { actions: `queueNodeProcessing` }, + CHOKIDAR_UNLINK: { actions: `queueNodeDeleting` }, }, exit: `flushPathQueue`, }, READY: { on: { CHOKIDAR_ADD: { actions: `createAndProcessNode` }, + CHOKIDAR_CHANGE: { actions: `createAndProcessNode` }, + CHOKIDAR_UNLINK: { actions: `deletePathNode` }, }, }, }, - // TODO: those two were not restricted to READY state, but maybe they should? or even maybe it should queue in NOT_READY? - on: { - CHOKIDAR_CHANGE: { actions: `createAndProcessNode` }, - CHOKIDAR_UNLINK: { actions: `deleteNode` }, - }, }, }, }, @@ -84,22 +102,20 @@ const createFSMachine = ( } createAndProcessNode(path).catch(err => reporter.error(err)) }, - deleteNode(_, { pathType, path }, { state }) { + deletePathNode(_, { pathType, path }, { state }) { if (state.matches(`BOOTSTRAP.BOOTSTRAPPED`)) { reporter.info(`${pathType} deleted at ${path}`) } - const node = getNode(createNodeId(path)) - // It's possible the node was never created as sometimes tools will - // write and then immediately delete temporary files to the file system. - if (node) { - deleteNode({ node }) - } + deletePathNode(path) }, flushPathQueue(_, { resolve, reject }) { flushPathQueue().then(resolve, reject) }, + queueNodeDeleting(_, { path }) { + pathQueue.push({ op: `delete`, path }) + }, queueNodeProcessing(_, { path }) { - pathQueue.push(path) + pathQueue.push({ op: `upsert`, path }) }, }, }