diff --git a/packages/gatsby/src/bootstrap/index.js b/packages/gatsby/src/bootstrap/index.js index fdd5ec63c8beb..295168602d2c5 100644 --- a/packages/gatsby/src/bootstrap/index.js +++ b/packages/gatsby/src/bootstrap/index.js @@ -21,6 +21,7 @@ const getConfigFile = require(`./get-config-file`) const tracer = require(`opentracing`).globalTracer() const preferDefault = require(`./prefer-default`) const nodeTracking = require(`../db/node-tracking`) +require(`../db`).startAutosave() // Show stack trace on unhandled promises. process.on(`unhandledRejection`, (reason, p) => { diff --git a/packages/gatsby/src/db/index.js b/packages/gatsby/src/db/index.js new file mode 100644 index 0000000000000..a50663a8859fa --- /dev/null +++ b/packages/gatsby/src/db/index.js @@ -0,0 +1,50 @@ +const _ = require(`lodash`) +const redux = require(`../redux`) +const { emitter } = redux + +// Even if we are using loki, we still include redux in the list of +// dbs since it still has pages, config, etc. +const dbs = [redux] +if (process.env.GATSBY_DB_NODES === `loki`) { + dbs.push(require(`./loki`)) +} + +// calls `saveState()` on all DBs +function saveState() { + for (const db of dbs) { + db.saveState() + } +} +const saveStateDebounced = _.debounce(saveState, 1000) + +/** + * Sets up listeners so that once bootstrap has finished, all + * databases save their state to disk. If we're in `develop` mode, + * then any new event triggers a debounced save as well. + */ +function startAutosave() { + // During development, once bootstrap is finished, persist state on changes. + let bootstrapFinished = false + if (process.env.gatsby_executing_command === `develop`) { + emitter.on(`BOOTSTRAP_FINISHED`, () => { + bootstrapFinished = true + saveState() + }) + emitter.on(`*`, () => { + if (bootstrapFinished) { + saveStateDebounced() + } + }) + } + + // During builds, persist state once bootstrap has finished. + if (process.env.gatsby_executing_command === `build`) { + emitter.on(`BOOTSTRAP_FINISHED`, () => { + saveState() + }) + } +} + +module.exports = { + startAutosave, +} diff --git a/packages/gatsby/src/db/loki/index.js b/packages/gatsby/src/db/loki/index.js index 09ab744376788..69e03095b3c5e 100644 --- a/packages/gatsby/src/db/loki/index.js +++ b/packages/gatsby/src/db/loki/index.js @@ -71,8 +71,6 @@ function startFileDb(saveFile) { resolve() } }, - autosave: true, - autosaveInterval: 1000, } db = new loki(saveFile, dbOptions) }) @@ -109,6 +107,24 @@ async function start({ saveFile } = {}) { ensureNodeCollections(db) } +// Saves the database to disk and returns a promise that will be +// resolved once the save has finished +function saveState() { + return new Promise((resolve, reject) => { + if (db) { + db.saveDatabase(err => { + if (err) { + console.log(`error saving loki DB`) + console.log(err) + reject(err) + } else { + resolve() + } + }) + } + }) +} + /** * Returns a reference to the database. If undefined, the db has not been * initalized yet. Call `start()` @@ -123,4 +139,5 @@ module.exports = { start, getDb, colls, + saveState, } diff --git a/packages/gatsby/src/redux/index.js b/packages/gatsby/src/redux/index.js index 103afb0fb62bb..b503211d55a4b 100644 --- a/packages/gatsby/src/redux/index.js +++ b/packages/gatsby/src/redux/index.js @@ -63,7 +63,8 @@ const store = Redux.createStore( ) // Persist state. -const saveState = state => { +function saveState() { + const state = store.getState() const pickedState = _.pick(state, [ `nodes`, `status`, @@ -85,34 +86,14 @@ const saveState = state => { () => {} ) } -const saveStateDebounced = _.debounce(saveState, 1000) + +exports.saveState = saveState store.subscribe(() => { const lastAction = store.getState().lastAction emitter.emit(lastAction.type, lastAction) }) -// During development, once bootstrap is finished, persist state on changes. -let bootstrapFinished = false -if (process.env.gatsby_executing_command === `develop`) { - emitter.on(`BOOTSTRAP_FINISHED`, () => { - bootstrapFinished = true - saveState(store.getState()) - }) - emitter.on(`*`, () => { - if (bootstrapFinished) { - saveStateDebounced(store.getState()) - } - }) -} - -// During builds, persist state once bootstrap has finished. -if (process.env.gatsby_executing_command === `build`) { - emitter.on(`BOOTSTRAP_FINISHED`, () => { - saveState(store.getState()) - }) -} - /** Event emitter */ exports.emitter = emitter