Skip to content

Commit ad74957

Browse files
Andaristpieh
authored andcommitted
fix(gatsby-source-filesystem): Queue all operations which happ… (#17404)
1 parent fbb1cc8 commit ad74957

File tree

2 files changed

+42
-29
lines changed

2 files changed

+42
-29
lines changed

packages/gatsby-source-filesystem/src/__tests__/gatsby-node.js

+3-6
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ describe(`tests`, () => {
100100
expect(api.actions.createNode).toBeCalled()
101101
})
102102

103-
// change event doesn't queue currently - this need to be fixed
104-
it.skip(`queues node creation from changed files`, async () => {
103+
it(`queues node creation from changed files`, async () => {
105104
const api = createApi()
106105
const sourceNodesPromise = gatsbyNode.sourceNodes(api, { path: `` })
107106
// allow microtasks execution
@@ -138,8 +137,7 @@ describe(`tests`, () => {
138137
expect(api.actions.createNode).toBeCalled()
139138
})
140139

141-
// unlink event doesn't queue currently - this need to be fixed
142-
it.skip(`queues node deletion from deleted files`, async () => {
140+
it(`queues node deletion from deleted files`, async () => {
143141
const api = createApi()
144142
const sourceNodesPromise = gatsbyNode.sourceNodes(api, { path: `` })
145143
// allow microtasks execution
@@ -157,8 +155,7 @@ describe(`tests`, () => {
157155
expect(api.actions.deleteNode).toBeCalled()
158156
})
159157

160-
// unlinkDir event doesn't queue currently - this need to be fixed
161-
it.skip(`queues node deletion from deleted directories`, async () => {
158+
it(`queues node deletion from deleted directories`, async () => {
162159
const api = createApi()
163160
const sourceNodesPromise = gatsbyNode.sourceNodes(api, { path: `` })
164161
// allow microtasks execution

packages/gatsby-source-filesystem/src/gatsby-node.js

+39-23
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,6 @@ const createFSMachine = (
1212
{ actions: { createNode, deleteNode }, getNode, createNodeId, reporter },
1313
pluginOptions
1414
) => {
15-
// For every path that is reported before the 'ready' event, we throw them
16-
// into a queue and then flush the queue when 'ready' event arrives.
17-
// After 'ready', we handle the 'add' event without putting it into a queue.
18-
let pathQueue = []
19-
const flushPathQueue = () => {
20-
let queue = pathQueue.slice()
21-
pathQueue = null
22-
return Promise.all(queue.map(createAndProcessNode))
23-
}
24-
2515
const createAndProcessNode = path => {
2616
const fileNodePromise = createFileNode(
2717
path,
@@ -34,6 +24,35 @@ const createFSMachine = (
3424
return fileNodePromise
3525
}
3626

27+
const deletePathNode = path => {
28+
const node = getNode(createNodeId(path))
29+
// It's possible the node was never created as sometimes tools will
30+
// write and then immediately delete temporary files to the file system.
31+
if (node) {
32+
deleteNode({ node })
33+
}
34+
}
35+
36+
// For every path that is reported before the 'ready' event, we throw them
37+
// into a queue and then flush the queue when 'ready' event arrives.
38+
// After 'ready', we handle the 'add' event without putting it into a queue.
39+
let pathQueue = []
40+
const flushPathQueue = () => {
41+
let queue = pathQueue.slice()
42+
pathQueue = null
43+
return Promise.all(
44+
// eslint-disable-next-line consistent-return
45+
queue.map(({ op, path }) => {
46+
switch (op) {
47+
case `delete`:
48+
return deletePathNode(path)
49+
case `upsert`:
50+
return createAndProcessNode(path)
51+
}
52+
})
53+
)
54+
}
55+
3756
const fsMachine = Machine(
3857
{
3958
id: `fs`,
@@ -59,20 +78,19 @@ const createFSMachine = (
5978
on: {
6079
CHOKIDAR_READY: `READY`,
6180
CHOKIDAR_ADD: { actions: `queueNodeProcessing` },
81+
CHOKIDAR_CHANGE: { actions: `queueNodeProcessing` },
82+
CHOKIDAR_UNLINK: { actions: `queueNodeDeleting` },
6283
},
6384
exit: `flushPathQueue`,
6485
},
6586
READY: {
6687
on: {
6788
CHOKIDAR_ADD: { actions: `createAndProcessNode` },
89+
CHOKIDAR_CHANGE: { actions: `createAndProcessNode` },
90+
CHOKIDAR_UNLINK: { actions: `deletePathNode` },
6891
},
6992
},
7093
},
71-
// TODO: those two were not restricted to READY state, but maybe they should? or even maybe it should queue in NOT_READY?
72-
on: {
73-
CHOKIDAR_CHANGE: { actions: `createAndProcessNode` },
74-
CHOKIDAR_UNLINK: { actions: `deleteNode` },
75-
},
7694
},
7795
},
7896
},
@@ -84,22 +102,20 @@ const createFSMachine = (
84102
}
85103
createAndProcessNode(path).catch(err => reporter.error(err))
86104
},
87-
deleteNode(_, { pathType, path }, { state }) {
105+
deletePathNode(_, { pathType, path }, { state }) {
88106
if (state.matches(`BOOTSTRAP.BOOTSTRAPPED`)) {
89107
reporter.info(`${pathType} deleted at ${path}`)
90108
}
91-
const node = getNode(createNodeId(path))
92-
// It's possible the node was never created as sometimes tools will
93-
// write and then immediately delete temporary files to the file system.
94-
if (node) {
95-
deleteNode({ node })
96-
}
109+
deletePathNode(path)
97110
},
98111
flushPathQueue(_, { resolve, reject }) {
99112
flushPathQueue().then(resolve, reject)
100113
},
114+
queueNodeDeleting(_, { path }) {
115+
pathQueue.push({ op: `delete`, path })
116+
},
101117
queueNodeProcessing(_, { path }) {
102-
pathQueue.push(path)
118+
pathQueue.push({ op: `upsert`, path })
103119
},
104120
},
105121
}

0 commit comments

Comments
 (0)