From 1fff689c0802b9cca7e9f9a1cb20eec376997b66 Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Wed, 20 Feb 2019 03:16:30 -0800 Subject: [PATCH] fix: check for dirty pages when nodes are deleted (so queries are ru-run and data is removed from pages) (#11831) * fix: check for dirty pages when nodes are deleted (so queries are ru-run and data is removed from pages) * typo fix * Use fake API call as suggested by @pieh * better name * Fix comparision as page.updatedAt is a unix timestamp * Remove page when deleted from internal query running cache so it can be run again if page recreated * WIP * MORE WIP * Revert "MORE WIP" This reverts commit 890fb367eaae649bbe981edf4baf5cf071ce97bc. * Revert "WIP" This reverts commit 190625f6237553728675059822dda5736c515b43. * Document FAKE_API_CALL --- packages/gatsby/src/bootstrap/page-hot-reloader.js | 7 ++++++- .../internal-plugins/query-runner/page-query-runner.js | 9 +++++++++ packages/gatsby/src/utils/api-runner-node.js | 6 +++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/gatsby/src/bootstrap/page-hot-reloader.js b/packages/gatsby/src/bootstrap/page-hot-reloader.js index c83e335f1084f..6eab902e0ab97 100644 --- a/packages/gatsby/src/bootstrap/page-hot-reloader.js +++ b/packages/gatsby/src/bootstrap/page-hot-reloader.js @@ -16,6 +16,11 @@ emitter.on(`CREATE_NODE`, action => { emitter.on(`DELETE_NODE`, action => { if (action.payload.internal.type !== `SitePage`) { pagesDirty = true + // Make a fake API call to trigger `API_RUNNING_QUEUE_EMPTY` being called. + // We don't want to call runCreatePages here as there might be work in + // progress. So this is a safe way to make sure runCreatePages gets called + // at a safe time. + apiRunnerNode(`FAKE_API_CALL`) } }) @@ -45,7 +50,7 @@ const runCreatePages = async () => { }) .map(p => p.id) - const timestamp = new Date().toJSON() + const timestamp = Date.now() await apiRunnerNode(`createPages`, { graphql, diff --git a/packages/gatsby/src/internal-plugins/query-runner/page-query-runner.js b/packages/gatsby/src/internal-plugins/query-runner/page-query-runner.js index f273ccac1717a..40a9c781a0c55 100644 --- a/packages/gatsby/src/internal-plugins/query-runner/page-query-runner.js +++ b/packages/gatsby/src/internal-plugins/query-runner/page-query-runner.js @@ -93,6 +93,15 @@ exports.runQueuedActions = runQueuedActions emitter.on(`API_RUNNING_QUEUE_EMPTY`, runQueuedActions) let seenIdsWithoutDataDependencies = [] + +// Remove pages from seenIdsWithoutDataDependencies when they're deleted +// so their query will be run again if they're created again. +emitter.on(`DELETE_PAGE`, action => { + seenIdsWithoutDataDependencies = seenIdsWithoutDataDependencies.filter( + p => p !== action.payload.path + ) +}) + const findIdsWithoutDataDependencies = () => { const state = store.getState() const allTrackedIds = _.uniq( diff --git a/packages/gatsby/src/utils/api-runner-node.js b/packages/gatsby/src/utils/api-runner-node.js index f36ce40fa4e80..c9a8ae89b7b30 100644 --- a/packages/gatsby/src/utils/api-runner-node.js +++ b/packages/gatsby/src/utils/api-runner-node.js @@ -201,7 +201,11 @@ module.exports = async (api, args = {}, pluginSource) => }) // Check that the API is documented. - if (!apiList[api]) { + // "FAKE_API_CALL" is used when code needs to trigger something + // to happen once the the API queue is empty. Ideally of course + // we'd have an API (returning a promise) for that. But this + // works nicely in the meantime. + if (!apiList[api] && api !== `FAKE_API_CALL`) { reporter.panic(`api: "${api}" is not a valid Gatsby api`) }