diff --git a/integration-tests/cache-resilience/utils/load-state.js b/integration-tests/cache-resilience/utils/load-state.js index 286b10c6564a4..7a8693f179e59 100644 --- a/integration-tests/cache-resilience/utils/load-state.js +++ b/integration-tests/cache-resilience/utils/load-state.js @@ -45,9 +45,6 @@ const sanitiseNode = value => { // we don't care about order of node creation at this point delete value.internal.counter - // loki adds $loki metadata into nodes - delete value.$loki - return value } diff --git a/packages/gatsby-recipes/src/providers/npm/__snapshots__/package.test.js.snap b/packages/gatsby-recipes/src/providers/npm/__snapshots__/package.test.js.snap index 6d07fa4c173ce..ab045a82d3f0c 100644 --- a/packages/gatsby-recipes/src/providers/npm/__snapshots__/package.test.js.snap +++ b/packages/gatsby-recipes/src/providers/npm/__snapshots__/package.test.js.snap @@ -17,24 +17,6 @@ Object { } `; -exports[`npm package resource e2e npm package resource test: NPMPackage destroy 1`] = ` -Object { - "_message": "Installed NPM package is-sorted@1.0.2", - "id": "is-sorted", - "name": "is-sorted", - "version": "1.0.2", -} -`; - -exports[`npm package resource e2e npm package resource test: NPMPackage update 1`] = ` -Object { - "_message": "Installed NPM package is-sorted@1.0.2", - "id": "is-sorted", - "name": "is-sorted", - "version": "1.0.2", -} -`; - exports[`npm package resource e2e npm package resource test: NPMPackage update plan 1`] = ` Object { "currentState": "is-sorted@1.0.0", diff --git a/packages/gatsby-telemetry/src/telemetry.js b/packages/gatsby-telemetry/src/telemetry.js index 630406e0a3c1d..d88461d7ff2d7 100644 --- a/packages/gatsby-telemetry/src/telemetry.js +++ b/packages/gatsby-telemetry/src/telemetry.js @@ -196,11 +196,7 @@ module.exports = class AnalyticsTracker { } getDbEngine() { - // if (process.env.GATSBY_DB_NODES === `loki`) { - // return `loki` - // } else { return `redux` - // } } getMachineId() { diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 40865fcdbd080..f627affce2004 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -94,7 +94,6 @@ "json-stringify-safe": "^5.0.1", "latest-version": "5.1.0", "lodash": "^4.17.15", - "lokijs": "^1.5.8", "md5": "^2.2.1", "md5-file": "^3.2.3", "micromatch": "^3.1.10", diff --git a/packages/gatsby/src/bootstrap/index.js b/packages/gatsby/src/bootstrap/index.js index cd377e286a18b..a3c69d0624b95 100644 --- a/packages/gatsby/src/bootstrap/index.js +++ b/packages/gatsby/src/bootstrap/index.js @@ -282,28 +282,6 @@ module.exports = async (args: BootstrapArgs) => { activity.end() - // if (process.env.GATSBY_DB_NODES === `loki`) { - // const loki = require(`../db/loki`) - // // Start the nodes database (in memory loki js with interval disk - // // saves). If data was saved from a previous build, it will be - // // loaded here - // activity = report.activityTimer(`start nodes db`, { - // parentSpan: bootstrapSpan, - // }) - // activity.start() - // const dbSaveFile = `${cacheDirectory}/loki/loki.db` - // try { - // await loki.start({ - // saveFile: dbSaveFile, - // }) - // } catch (e) { - // report.error( - // `Error starting DB. Perhaps try deleting ${path.dirname(dbSaveFile)}` - // ) - // } - // activity.end() - // } - activity = report.activityTimer(`copy gatsby files`, { parentSpan: bootstrapSpan, }) diff --git a/packages/gatsby/src/db/__tests__/fixtures/ensure-loki.js b/packages/gatsby/src/db/__tests__/fixtures/ensure-loki.js deleted file mode 100644 index 6f242c1cbbcb0..0000000000000 --- a/packages/gatsby/src/db/__tests__/fixtures/ensure-loki.js +++ /dev/null @@ -1,11 +0,0 @@ -const { backend } = require(`../../nodes`) - -module.exports = () => { - if (backend === `loki`) { - const lokiDb = require(`../../loki`) - beforeAll(lokiDb.start) - return true - } - - return false -} diff --git a/packages/gatsby/src/db/__tests__/nodes.js b/packages/gatsby/src/db/__tests__/nodes.js index 194d7962bbb99..71f453aa2ac57 100644 --- a/packages/gatsby/src/db/__tests__/nodes.js +++ b/packages/gatsby/src/db/__tests__/nodes.js @@ -1,7 +1,6 @@ const { actions } = require(`../../redux/actions`) const { getNode, getNodes } = require(`../nodes`) const { store } = require(`../../redux`) -require(`./fixtures/ensure-loki`)() const report = require(`gatsby-cli/lib/reporter`) jest.mock(`gatsby-cli/lib/reporter`) diff --git a/packages/gatsby/src/db/common/query.ts b/packages/gatsby/src/db/common/query.ts index a789e5cb25da9..b1e8ea9f7841e 100644 --- a/packages/gatsby/src/db/common/query.ts +++ b/packages/gatsby/src/db/common/query.ts @@ -122,8 +122,6 @@ export function dbQueryToSiftQuery(query: DbQuery): object { return result } -// Most of the below can be gone after we decide to remove loki - // Converts a nested mongo args object into a dotted notation. acc // (accumulator) must be a reference to an empty object. The converted // fields will be added to it. E.g @@ -155,24 +153,6 @@ export function dbQueryToSiftQuery(query: DbQuery): object { // $regex: // as above // } // } -export function toDottedFields( - filter: object, - acc: object = {}, - path: Array = [] -): object { - Object.keys(filter).forEach(key => { - const value = filter[key] - const nextValue = _.isPlainObject(value) && value[Object.keys(value)[0]] - if (key === `$elemMatch`) { - acc[path.join(`.`)] = { [`$elemMatch`]: toDottedFields(value) } - } else if (_.isPlainObject(nextValue)) { - toDottedFields(value, acc, path.concat(key)) - } else { - acc[path.concat(key).join(`.`)] = value - } - }) - return acc -} // Like above, but doesn't handle $elemMatch export function objectToDottedField( @@ -194,28 +174,3 @@ export function objectToDottedField( }) return result } - -export function liftResolvedFields( - args: object, - resolvedFields: object -): object { - const dottedFields = objectToDottedField(resolvedFields) - const dottedFieldKeys = Object.keys(dottedFields) - const finalArgs = {} - Object.keys(args).forEach(key => { - const value = args[key] - if (dottedFields[key]) { - finalArgs[`__gatsby_resolved.${key}`] = value - } else if ( - dottedFieldKeys.some(dottedKey => dottedKey.startsWith(key)) && - value.$elemMatch - ) { - finalArgs[`__gatsby_resolved.${key}`] = value - } else if (dottedFieldKeys.some(dottedKey => key.startsWith(dottedKey))) { - finalArgs[`__gatsby_resolved.${key}`] = value - } else { - finalArgs[key] = value - } - }) - return finalArgs -} diff --git a/packages/gatsby/src/db/index.js b/packages/gatsby/src/db/index.js index 77eb88973ce32..ffd41265d2e34 100644 --- a/packages/gatsby/src/db/index.js +++ b/packages/gatsby/src/db/index.js @@ -3,21 +3,13 @@ const report = require(`gatsby-cli/lib/reporter`) 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 let saveInProgress = false async function saveState() { if (saveInProgress) return saveInProgress = true try { - await Promise.all(dbs.map(db => db.saveState())) + await redux.saveState() } catch (err) { report.warn(`Error persisting state: ${(err && err.message) || err}`) } diff --git a/packages/gatsby/src/db/loki/__tests__/index.js b/packages/gatsby/src/db/loki/__tests__/index.js deleted file mode 100644 index 45e0988c4f064..0000000000000 --- a/packages/gatsby/src/db/loki/__tests__/index.js +++ /dev/null @@ -1,12 +0,0 @@ -const { colls, getDb, start } = require(`../index`) - -describe(`db`, () => { - start() - it(`should create system collections`, () => { - const db = getDb() - const nodeMetaColl = db.getCollection(colls.nodeMeta.name) - const nodeTypesColl = db.getCollection(colls.nodeTypes.name) - expect(nodeMetaColl).toBeDefined() - expect(nodeTypesColl).toBeDefined() - }) -}) diff --git a/packages/gatsby/src/db/loki/__tests__/nodes-query-test.js b/packages/gatsby/src/db/loki/__tests__/nodes-query-test.js deleted file mode 100644 index 862d407580a59..0000000000000 --- a/packages/gatsby/src/db/loki/__tests__/nodes-query-test.js +++ /dev/null @@ -1,56 +0,0 @@ -// if (process.env.GATSBY_DB_NODES === `loki`) { -// const _ = require(`lodash`) -// const { GraphQLObjectType } = require(`graphql`) -// const { store } = require(`../../../redux`) -// const runQuery = require(`../nodes-query`) -// const { getNodeTypeCollection } = require(`../nodes`) -// const lokiDb = require(`../index`) -// -// function makeNodes() { -// return [ -// { -// id: `1`, -// internal: { type: `Test` }, -// children: [], -// foo: `bar`, -// }, -// ] -// } -// -// async function runQueries(nodes, n) { -// for (const node of nodes) { -// store.dispatch({ type: `CREATE_NODE`, payload: node }) -// } -// const gqlType = new GraphQLObjectType({ -// name: `Test`, -// fields: { -// foo: { type: `String` }, -// }, -// }) -// const queryArgs = { filter: { foo: { eq: `bar` } } } -// const args = { gqlType, queryArgs, nodeTypeNames: [gqlType.name] } -// return await Promise.all(_.map(new Array(n), () => runQuery(args))) -// } -// -// describe(`query indexing`, () => { -// beforeEach(async () => { -// await lokiDb.start() -// store.dispatch({ type: `DELETE_CACHE` }) -// }) -// it(`does not create index when query run 1 time`, async () => { -// await runQueries(makeNodes(), 1) -// const coll = getNodeTypeCollection(`Test`) -// expect(coll.binaryIndices.hasOwnProperty(`foo`)).toEqual(false) -// }) -// -// it(`creates index when query run 5 times`, async () => { -// await runQueries(makeNodes(), 5) -// const coll = getNodeTypeCollection(`Test`) -// expect(coll.binaryIndices.hasOwnProperty(`foo`)).toEqual(true) -// }) -// }) -// } else { -it(`skipping loki nodes-query-test`, () => { - expect(true).toEqual(true) -}) -// } diff --git a/packages/gatsby/src/db/loki/__tests__/nodes.js b/packages/gatsby/src/db/loki/__tests__/nodes.js deleted file mode 100644 index b520d666a05ac..0000000000000 --- a/packages/gatsby/src/db/loki/__tests__/nodes.js +++ /dev/null @@ -1,30 +0,0 @@ -const { start, getDb, colls } = require(`../index`) -const { createNode, deleteNode } = require(`../nodes`) - -const type = `Test` -const node = { - id: `1`, - foo: `bar`, - internal: { type: type }, -} - -beforeAll(start) - -describe(`node`, () => { - it(`should create node ID index`, () => { - createNode(node) - const nodeMetaColl = getDb().getCollection(colls.nodeMeta.name) - expect(nodeMetaColl).toBeDefined() - const nodeMeta = nodeMetaColl.by(`id`, node.id) - const nodeTypeColl = getDb().getCollection(nodeMeta.typeCollName) - expect(nodeTypeColl).toBeDefined() - expect(nodeTypeColl.name).toEqual(`gatsby:nodeType:${type}`) - }) - - it(`should delete node ID index`, () => { - deleteNode(node) - const nodeMetaColl = getDb().getCollection(colls.nodeMeta.name) - const nodeMeta = nodeMetaColl.by(`id`, node.id) - expect(nodeMeta).toBeUndefined() - }) -}) diff --git a/packages/gatsby/src/db/loki/custom-comparators.js b/packages/gatsby/src/db/loki/custom-comparators.js deleted file mode 100644 index 3610a994a7365..0000000000000 --- a/packages/gatsby/src/db/loki/custom-comparators.js +++ /dev/null @@ -1,293 +0,0 @@ -// Gatsby has very specific sorting requirements. Specifically, -// undefined > null > everything else. So, if an orderby `desc` is -// specified, then nulls and undefined values are of higher rank. This -// is due to the use of lodash's `orderBy` function in -// `run-sift`. -// -// The below functions are alternate versions of the comparators used -// by loki that match lodash's behavior -// -// Note: This is quite hacky and not officially supported by Loki, but -// works quite well. -// -// The below implementation is a direct copy of Loki, except that -// undefined's rank is 11, and null's rank is 10. Whereas in loki, -// they are both of rank 1 -// -// Another change is that strings aren't coerced to numbers -function ltHelper(prop1, prop2, equal) { - var cv1, cv2, t1, t2 - - // if one of the params is falsy or strictly true or not equal to itself - // 0, 0.0, "", NaN, null, undefined, not defined, false, true - if ( - !prop1 || - !prop2 || - prop1 === true || - prop2 === true || - prop1 !== prop1 || - prop2 !== prop2 - ) { - switch (prop1) { - case undefined: - t1 = 11 - break - case null: - t1 = 10 - break - case false: - t1 = 3 - break - case true: - t1 = 4 - break - case ``: - t1 = 5 - break - // if strict equal probably 0 so sort higher, otherwise - // probably NaN so sort lower than even null - default: - t1 = prop1 === prop1 ? 9 : 0 - break - } - - switch (prop2) { - case undefined: - t2 = 11 - break - case null: - t2 = 10 - break - case false: - t2 = 3 - break - case true: - t2 = 4 - break - case ``: - t2 = 5 - break - default: - t2 = prop2 === prop2 ? 9 : 0 - break - } - - // one or both is edge case - if (t1 !== 9 || t2 !== 9) { - return t1 === t2 ? equal : t1 < t2 - } - } - - // if both are numbers, compare as numbers. - // NB: Changed from loki - strings compared as strings - cv1 = Number(prop1) - cv2 = Number(prop2) - - if (cv1 === prop1 && cv2 === prop2) { - if (cv1 < cv2) return true - if (cv1 > cv2) return false - return equal - } - - if (cv1 === cv1 && cv2 !== cv2) { - return true - } - - if (cv2 === cv2 && cv1 !== cv1) { - return false - } - - if (prop1 < prop2) return true - if (prop1 > prop2) return false - if (prop1 == prop2) return equal - - // not strict equal nor less than nor gt so must be mixed types, convert to string and use that to compare - cv1 = prop1.toString() - cv2 = prop2.toString() - - if (cv1 < cv2) { - return true - } - - if (cv1 == cv2) { - return equal - } - - return false -} - -function gtHelper(prop1, prop2, equal) { - var cv1, cv2, t1, t2 - - // 'falsy' and Boolean handling - if ( - !prop1 || - !prop2 || - prop1 === true || - prop2 === true || - prop1 !== prop1 || - prop2 !== prop2 - ) { - switch (prop1) { - case undefined: - t1 = 11 - break - case null: - t1 = 10 - break - case false: - t1 = 3 - break - case true: - t1 = 4 - break - case ``: - t1 = 5 - break - // NaN 0 - default: - t1 = prop1 === prop1 ? 9 : 0 - break - } - - switch (prop2) { - case undefined: - t2 = 11 - break - case null: - t2 = 10 - break - case false: - t2 = 3 - break - case true: - t2 = 4 - break - case ``: - t2 = 5 - break - default: - t2 = prop2 === prop2 ? 9 : 0 - break - } - - // one or both is edge case - if (t1 !== 9 || t2 !== 9) { - return t1 === t2 ? equal : t1 > t2 - } - } - - // if both are numbers (string encoded or not), compare as numbers - // NB: Changed from loki - strings compared as strings - cv1 = Number(prop1) - cv2 = Number(prop2) - if (cv1 === prop1 && cv2 === prop2) { - if (cv1 > cv2) return true - if (cv1 < cv2) return false - return equal - } - - if (cv1 === cv1 && cv2 !== cv2) { - return false - } - - if (cv2 === cv2 && cv1 !== cv1) { - return true - } - - if (prop1 > prop2) return true - if (prop1 < prop2) return false - if (prop1 == prop2) return equal - - // not strict equal nor less than nor gt so must be dates or mixed types - // convert to string and use that to compare - cv1 = prop1.toString() - cv2 = prop2.toString() - - if (cv1 > cv2) { - return true - } - - if (cv1 == cv2) { - return equal - } - - return false -} - -function aeqHelper(prop1, prop2) { - var cv1, cv2, t1, t2 - if (prop1 === prop2) return true - // 'falsy' and Boolean handling - if ( - !prop1 || - !prop2 || - prop1 === true || - prop2 === true || - prop1 !== prop1 || - prop2 !== prop2 - ) { - // dates and NaN conditions (typed dates before serialization) - switch (prop1) { - case undefined: - t1 = 1 - break - case null: - t1 = 2 - break - case false: - t1 = 3 - break - case true: - t1 = 4 - break - case ``: - t1 = 5 - break - default: - t1 = prop1 === prop1 ? 9 : 0 - break - } - switch (prop2) { - case undefined: - t2 = 1 - break - case null: - t2 = 2 - break - case false: - t2 = 3 - break - case true: - t2 = 4 - break - case ``: - t2 = 5 - break - default: - t2 = prop2 === prop2 ? 9 : 0 - break - } - // one or both is edge case - if (t1 !== 9 || t2 !== 9) { - return t1 === t2 - } - } - // Handle 'Number-like' comparisons - cv1 = Number(prop1) - cv2 = Number(prop2) - // if one or both are 'number-like'... - if (cv1 === cv1 || cv2 === cv2) { - return cv1 === cv2 - } - // not strict equal nor less than nor gt so must be mixed types, convert to string and use that to compare - cv1 = prop1.toString() - cv2 = prop2.toString() - return cv1 == cv2 -} - -module.exports = { - ltHelper, - gtHelper, - aeqHelper, -} diff --git a/packages/gatsby/src/db/loki/index.js b/packages/gatsby/src/db/loki/index.js deleted file mode 100644 index 46963183b663a..0000000000000 --- a/packages/gatsby/src/db/loki/index.js +++ /dev/null @@ -1,145 +0,0 @@ -const _ = require(`lodash`) -const fs = require(`fs-extra`) -const path = require(`path`) -const loki = require(`lokijs`) -const uuidv4 = require(`uuid/v4`) -const customComparators = require(`./custom-comparators`) - -// Ensure sorting behavior matches old lodash `orderBy` -// implementation. See `custom-comparators.js` for why. -loki.Comparators.lt = customComparators.ltHelper -loki.Comparators.gt = customComparators.gtHelper -loki.Comparators.aeq = customComparators.aeqHelper - -// Loki is a document store with the same semantics as mongo. This -// means there are no tables or relationships. Just a bunch of -// collections, each with objects. -// -// Gatsby stores nodes in collections by splitting them up by their -// `node.internal.type`. All nodes of a particular type go in 1 -// collection. The below `colls` object contains the metadata for -// these collections, and the "meta collections" used to track them. -// -// You won't use these directly. They are used by the collection -// functions in `./nodes.js`. E.g. `getTypeCollName()` and -// `getNodeTypeCollection` -const colls = { - // Each object has keys `id` and `typeCollName`. It's a way of - // quickly looking up the collection that a node is contained in. - // E.g. { id: `someNodeId`, typeCollName: `gatsby:nodeType:myType` } - nodeMeta: { - name: `gatsby:nodeMeta`, - options: { - unique: [`id`], - indices: [`id`], - }, - }, - // The list of all node type collections. Each object has keys - // `type` and `collName` so you can quickly look up the collection - // name for a node type. - // e.g. { type: `myType`, collName: `gatsby:nodeType:myType` } - nodeTypes: { - name: `gatsby:nodeTypes`, - options: { - unique: [`type`, `collName`], - indices: [`type`], - }, - }, -} - -// Must be set using `start()` -let db - -/** - * Ensures that the collections that support nodes have been - * created. See `colls` var in this file - */ -function ensureNodeCollections(db) { - _.forEach(colls, collInfo => { - const { name, options } = collInfo - db.addCollection(name, options) - }) -} - -function startFileDb({ saveFile, lokiDBOptions = {} }) { - return new Promise((resolve, reject) => { - const dbOptions = { - autoload: true, - autoloadCallback: err => { - if (err) { - reject(err) - } else { - resolve() - } - }, - ...lokiDBOptions, - } - db = new loki(saveFile, dbOptions) - }) -} - -async function startInMemory() { - // Use uuid purely for a random name - db = new loki(uuidv4()) -} - -/** - * Starts a loki database. If the file already exists, it will be - * loaded as the database state. If not, a new database will be - * created. If `saveFile` is omitted, an in-memory DB will be created. - * - * @param {string} saveFile on disk file that the database will be - * saved and loaded from. If this is omitted, an in-memory database - * will be created instead - * @returns {Promise} promise that is resolved once the database and - * the existing state has been loaded (if there was an existing - * saveFile) - */ -async function start({ saveFile, lokiDBOptions } = {}) { - if (saveFile && !_.isString(saveFile)) { - throw new Error(`saveFile must be a path`) - } - if (saveFile) { - const saveDir = path.dirname(saveFile) - await fs.ensureDir(saveDir) - await startFileDb({ saveFile, lokiDBOptions }) - } else { - await startInMemory() - } - 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) { - reject(err) - } else { - resolve() - } - }) - } else { - reject(`No database found.`) - } - }) -} - -/** - * Returns a reference to the database. If undefined, the db has not been - * initialized yet. Call `start()` - * - * @returns {Object} database, or undefined - */ -function getDb() { - return db -} - -module.exports = { - start, - getDb, - colls, - saveState, -} diff --git a/packages/gatsby/src/db/loki/nodes-query.js b/packages/gatsby/src/db/loki/nodes-query.js deleted file mode 100644 index 380727f9900b3..0000000000000 --- a/packages/gatsby/src/db/loki/nodes-query.js +++ /dev/null @@ -1,280 +0,0 @@ -const _ = require(`lodash`) -const { - GraphQLList, - getNullableType, - getNamedType, - isCompositeType, -} = require(`graphql`) -const { prepareRegex } = require(`../../utils/prepare-regex`) -const { - getNodeTypeCollection, - ensureFieldIndexes, - getNode, - getNodesByType, -} = require(`./nodes`) -const { - toDottedFields, - objectToDottedField, - liftResolvedFields, -} = require(`../common/query`) -import { getValueAt } from "../../utils/get-value-at" -const { runSiftOnNodes } = require(`../../redux/run-sift`) - -// Takes a raw graphql filter and converts it into a mongo-like args -// object that can be understood by loki. E.g. `eq` becomes -// `$eq`. gqlFilter should be the raw graphql filter returned from -// graphql-js. e.g. gqlFilter: -// -// { -// internal: { -// type: { -// eq: "TestNode" -// }, -// content: { -// glob: "et" -// } -// }, -// id: { -// glob: "12*" -// } -// } -// -// would return -// -// { -// internal: { -// type: { -// $eq: "TestNode" // append $ to eq -// }, -// content: { -// $regex: new MiniMatch(v) // convert glob to regex -// } -// }, -// id: { -// $regex: // as above -// } -// } -function toMongoArgs(gqlFilter, lastFieldType) { - lastFieldType = getNullableType(lastFieldType) - const mongoArgs = {} - _.each(gqlFilter, (v, k) => { - if (_.isPlainObject(v)) { - if (k === `elemMatch`) { - mongoArgs[`$elemMatch`] = toMongoArgs(v, getNamedType(lastFieldType)) - } else if (lastFieldType instanceof GraphQLList) { - mongoArgs[`$elemMatch`] = { - [k]: toMongoArgs(v, getNamedType(lastFieldType)), - } - } else { - const gqlFieldType = lastFieldType.getFields()[k].type - mongoArgs[k] = toMongoArgs(v, gqlFieldType) - } - } else { - if (k === `regex`) { - const re = prepareRegex(v) - // To ensure that false is returned if a field doesn't - // exist. E.g. `{nested.field: {$regex: /.*/}}` - mongoArgs[`$where`] = obj => !_.isUndefined(obj) && re.test(obj) - } else if (k === `glob`) { - const Minimatch = require(`minimatch`).Minimatch - const mm = new Minimatch(v) - mongoArgs[`$regex`] = mm.makeRe() - } else if (k === `eq` && v === null) { - mongoArgs[`$in`] = [null, undefined] - } else if ( - k === `eq` && - lastFieldType && - lastFieldType instanceof GraphQLList - ) { - mongoArgs[`$contains`] = v - } else if ( - k === `ne` && - lastFieldType && - lastFieldType instanceof GraphQLList - ) { - mongoArgs[`$containsNone`] = v - } else if ( - k === `in` && - lastFieldType && - lastFieldType instanceof GraphQLList - ) { - mongoArgs[`$containsAny`] = v - } else if ( - k === `nin` && - lastFieldType && - lastFieldType instanceof GraphQLList - ) { - mongoArgs[`$containsNone`] = v - } else if (k === `ne` && v === null) { - mongoArgs[`$ne`] = undefined - } else if (k === `nin` && lastFieldType.name === `Boolean`) { - mongoArgs[`$nin`] = v.concat([undefined]) - } else { - mongoArgs[`$${k}`] = v - } - } - }) - return mongoArgs -} - -// The query language that Gatsby has used since day 1 is `sift`. Both -// sift and loki are mongo-like query languages, but they have some -// subtle differences. One is that in sift, a nested filter such as -// `{foo: {bar: {ne: true} } }` will return true if the foo field -// doesn't exist, is null, or bar is null. Whereas loki will return -// false if the foo field doesn't exist or is null. This ensures that -// loki queries behave like sift -const isNeTrue = (obj, path) => { - if (path.length) { - const [first, ...rest] = path - return obj == null || obj[first] == null || isNeTrue(obj[first], rest) - } else { - return obj !== true - } -} - -const fixNeTrue = filter => - Object.keys(filter).reduce((acc, key) => { - const value = filter[key] - if (value[`$ne`] === true) { - const [first, ...path] = key.split(`.`) - acc[first] = { [`$where`]: obj => isNeTrue(obj, path) } - } else { - acc[key] = value - } - return acc - }, {}) - -// Converts graphQL args to a loki filter -const convertArgs = (gqlArgs, gqlType, resolvedFields) => - liftResolvedFields( - fixNeTrue(toDottedFields(toMongoArgs(gqlArgs.filter, gqlType))), - resolvedFields - ) - -// Converts graphql Sort args into the form expected by loki, which is -// a vector where the first value is a field name, and the second is a -// boolean `isDesc`. E.g -// -// { -// fields: [ `frontmatter___date`, `id` ], -// order: [`desc`] -// } -// -// would return -// -// [ [ `frontmatter.date`, true ], [ `id`, false ] ] -// -function toSortFields(sortArgs) { - const { fields, order } = sortArgs - const lokiSortFields = [] - for (let i = 0; i < fields.length; i++) { - const dottedField = fields[i] - const isDesc = order[i] && order[i].toLowerCase() === `desc` - lokiSortFields.push([dottedField, isDesc]) - } - return lokiSortFields -} - -function doesSortFieldsHaveArray(type, sortArgs) { - return sortArgs.some(([fields, _]) => { - const [field, ...rest] = fields.split(`.`) - const gqlField = type.getFields()[field] - if (gqlField) { - const type = getNullableType(gqlField.type) - if (type instanceof GraphQLList) { - return true - } else { - const namedType = getNamedType(type) - if (isCompositeType(namedType) && rest.length > 0) { - return doesSortFieldsHaveArray(namedType, [[rest.join(`.`), false]]) - } - } - } - return false - }) -} - -/** - * Runs the graphql query over the loki nodes db. - * - * @param {Object} args. Object with: - * - * {Object} gqlType: A GraphQL type - * - * {Object} queryArgs: The raw graphql query as a js object. E.g. `{ - * filter: { fields { slug: { eq: "/somepath" } } } }` - * - * {Object} context: The context from the QueryJob - * - * {boolean} firstOnly: Whether to return the first found match, or - * all matching results - * - * @returns {promise} A promise that will eventually be resolved with - * a collection of matching objects (even if `firstOnly` is true) - */ -async function runQuery(args) { - if (args.nodeTypeNames.length > 1) { - const nodes = args.nodeTypeNames.reduce((acc, typeName) => { - acc.push(...getNodesByType(typeName)) - return acc - }, []) - return runSiftOnNodes(nodes, args, getNode) - } - - const { - gqlType, - queryArgs, - firstOnly, - resolvedFields = {}, - nodeTypeNames, - } = args - const lokiArgs = convertArgs(queryArgs, gqlType, resolvedFields) - - let sortFields - if (queryArgs.sort) { - sortFields = toSortFields(queryArgs.sort) - } - const table = getNodeTypeCollection(nodeTypeNames[0]) - if (!table) { - return [] - } - const chain = table.chain() - chain.simplesort(`internal.counter`) - ensureFieldIndexes(nodeTypeNames[0], lokiArgs, sortFields || []) - - chain.find(lokiArgs, firstOnly) - - if (sortFields) { - // Loki is unable to sort arrays, so we fall back to lodash for that - const sortFieldsHaveArray = doesSortFieldsHaveArray(gqlType, sortFields) - const dottedFields = objectToDottedField(resolvedFields) - const dottedFieldKeys = Object.keys(dottedFields) - sortFields = sortFields.map(([field, order]) => { - if ( - dottedFields[field] || - dottedFieldKeys.some(key => field.startsWith(key)) - ) { - return [`__gatsby_resolved.${field}`, order] - } else { - return [field, order] - } - }) - - if (sortFieldsHaveArray) { - const sortFieldAccessors = sortFields.map(([field, _]) => v => - getValueAt(v, field) - ) - const sortFieldOrder = sortFields.map(([_, order]) => - order ? `desc` : `asc` - ) - return _.orderBy(chain.data(), sortFieldAccessors, sortFieldOrder) - } else { - return chain.compoundsort(sortFields).data() - } - } else { - return chain.data() - } -} - -module.exports = runQuery diff --git a/packages/gatsby/src/db/loki/nodes.js b/packages/gatsby/src/db/loki/nodes.js deleted file mode 100644 index 46d519ceeb737..0000000000000 --- a/packages/gatsby/src/db/loki/nodes.js +++ /dev/null @@ -1,410 +0,0 @@ -const _ = require(`lodash`) -const invariant = require(`invariant`) -const { getDb, colls } = require(`./index`) -import { createPageDependency } from "../../redux/actions/add-page-dependency" - -// /////////////////////////////////////////////////////////////////// -// Node collection metadata -// /////////////////////////////////////////////////////////////////// - -function makeTypeCollName(type) { - return `gatsby:nodeType:${type}` -} - -/** - * Creates a collection that will contain nodes of a certain type. The - * name of the collection for type `MyType` will be something like - * `gatsby:nodeType:MyType` (see `makeTypeCollName`) - */ -function createNodeTypeCollection(type) { - const collName = makeTypeCollName(type) - const nodeTypesColl = getDb().getCollection(colls.nodeTypes.name) - invariant(nodeTypesColl, `Collection ${colls.nodeTypes.name} should exist`) - nodeTypesColl.insert({ type, collName }) - // TODO what if `addCollection` fails? We will have inserted into - // nodeTypesColl but no collection will exist. Need to make this - // into a transaction - const options = { - unique: [`id`], - indices: [`id`, `internal.counter`], - disableMeta: true, - } - const coll = getDb().addCollection(collName, options) - return coll -} - -/** - * Returns the name of the collection that contains nodes of the - * specified type, where type is the node's `node.internal.type` - */ -function getTypeCollName(type) { - const nodeTypesColl = getDb().getCollection(colls.nodeTypes.name) - invariant(nodeTypesColl, `Collection ${colls.nodeTypes.name} should exist`) - const nodeTypeInfo = nodeTypesColl.by(`type`, type) - return nodeTypeInfo ? nodeTypeInfo.collName : undefined -} - -/** - * Returns a reference to the collection that contains nodes of the - * specified type, where type is the node's `node.internal.type` - */ -function getNodeTypeCollection(type) { - const typeCollName = getTypeCollName(type) - let coll - if (typeCollName) { - coll = getDb().getCollection(typeCollName) - invariant( - coll, - `Type [${type}] Collection doesn't exist for nodeTypeInfo: [${typeCollName}]` - ) - return coll - } else { - return undefined - } -} - -/** - * Deletes all empty node type collections, unless `force` is true, in - * which case it deletes the collections even if they have nodes in - * them - */ -function deleteNodeTypeCollections(force = false) { - const nodeTypesColl = getDb().getCollection(colls.nodeTypes.name) - // find() returns all objects in collection - const nodeTypes = nodeTypesColl.find() - for (const nodeType of nodeTypes) { - const coll = getDb().getCollection(nodeType.collName) - if (coll.count() === 0 || force) { - getDb().removeCollection(coll.name) - nodeTypesColl.remove(nodeType) - } - } -} - -/** - * Deletes all nodes from all the node type collections, including the - * id -> type metadata. There will be no nodes related data in loki - * after this is called - */ -function deleteAll() { - const db = getDb() - if (db) { - deleteNodeTypeCollections(true) - db.getCollection(colls.nodeMeta.name).clear() - } -} - -// /////////////////////////////////////////////////////////////////// -// Queries -// /////////////////////////////////////////////////////////////////// - -/** - * Returns the node with `id` == id, or null if not found - */ -function getNode(id) { - if (!id) { - return null - } - // First, find out which collection the node is in - const nodeMetaColl = getDb().getCollection(colls.nodeMeta.name) - invariant(nodeMetaColl, `nodeMeta collection should exist`) - const nodeMeta = nodeMetaColl.by(`id`, id) - if (nodeMeta) { - // Now get the collection and query it by the `id` field, which - // has an index on it - const { typeCollName } = nodeMeta - const typeColl = getDb().getCollection(typeCollName) - invariant( - typeColl, - `type collection ${typeCollName} referenced by nodeMeta but doesn't exist` - ) - return typeColl.by(`id`, id) - } else { - return undefined - } -} - -/** - * Returns all nodes of a type (where `typeName == - * node.internal.type`). This is an O(1) operation since nodes are - * already stored in separate collections by type - */ -function getNodesByType(typeName) { - invariant(typeName, `typeName is null`) - const collName = getTypeCollName(typeName) - const coll = getDb().getCollection(collName) - if (!coll) return [] - return coll.chain().simplesort(`internal.counter`).data() -} - -/** - * Returns the collection of all nodes. This should be deprecated and - * `getNodesByType` should be used instead. Or at least where possible - */ -function getNodes() { - const nodeTypes = getTypes() - return _.flatMap(nodeTypes, nodeType => getNodesByType(nodeType)) -} - -/** - * Returns the unique collection of all node types - */ -function getTypes() { - const nodeTypes = getDb().getCollection(colls.nodeTypes.name).data - return nodeTypes.map(nodeType => nodeType.type) -} - -/** - * Looks up the node by id, records a dependency between the node and - * the path, and then returns the node - * - * @param {string} id node id to lookup - * @param {string} path the page path to record a node dependency - * against - * @returns {Object} node or undefined if not found - */ -function getNodeAndSavePathDependency(id, path) { - invariant(id, `id is null`) - invariant(id, `path is null`) - const node = getNode(id) - createPageDependency({ path, nodeId: id }) - return node -} - -/** - * Determine if node has changed (by comparing its - * `internal.contentDigest` - * - * @param {string} id - * @param {string} digest - * @returns {boolean} - */ -function hasNodeChanged(id, digest) { - const node = getNode(id) - if (!node) { - return true - } else { - return node.internal.contentDigest !== digest - } -} - -// ///////////////////////////////////////////////////////////////// -// Create/Update/Delete -// /////////////////////////////////////////////////////////////////// - -/** - * Creates a node in the DB. Will create a collection for the node - * type if one hasn't been created yet - * - * @param {Object} node The node to add. Must have an `id` and - * `internal.type` - */ -function createNode(node, oldNode) { - invariant(node.internal, `node has no "internal" field`) - invariant(node.internal.type, `node has no "internal.type" field`) - invariant(node.id, `node has no "id" field`) - - const type = node.internal.type - - // Loki doesn't provide "upsert", so if the node already exists, we - // delete and then create it - if (oldNode) { - deleteNode(oldNode) - } - - let nodeTypeColl = getNodeTypeCollection(type) - if (!nodeTypeColl) { - nodeTypeColl = createNodeTypeCollection(type) - } - - const nodeMetaColl = getDb().getCollection(colls.nodeMeta.name) - invariant(nodeMetaColl, `Collection ${colls.nodeMeta.name} should exist`) - nodeMetaColl.insert({ id: node.id, typeCollName: nodeTypeColl.name }) - // TODO what if this insert fails? We will have inserted the id -> - // collName mapping, but there won't be any nodes in the type - // collection. Need to create a transaction around this - return nodeTypeColl.insert(node) -} - -/** - * Updates a node in the DB. The contents of `node` will completely - * overwrite value in the DB. Note, `node` must be a loki node. i.e it - * has `$loki` and `meta` fields. - * - * @param {Object} node The new node information. This should be all - * the node information. Not just changes - */ -function updateNode(node) { - invariant(node.internal, `node has no "internal" field`) - invariant(node.internal.type, `node has no "internal.type" field`) - invariant(node.id, `node has no "id" field`) - - const oldNode = getNode(node.id) - return createNode(node, oldNode) -} - -/** - * Deletes a node from its type collection and removes its id -> - * collName mapping. Function is idempotent. If the node has already - * been deleted, this is a noop. - * - * @param {Object} the node to delete. Must have an `id` and - * `internal.type` - */ -function deleteNode(node) { - invariant(node.internal, `node has no "internal" field`) - invariant(node.internal.type, `node has no "internal.type" field`) - invariant(node.id, `node has no "id" field`) - - const type = node.internal.type - - const nodeTypeColl = getNodeTypeCollection(type) - if (!nodeTypeColl) { - invariant( - nodeTypeColl, - `${type} collection doesn't exist. When trying to delete` - ) - } - - const obj = nodeTypeColl.by(`id`, node.id) - if (obj) { - const nodeMetaColl = getDb().getCollection(colls.nodeMeta.name) - invariant(nodeMetaColl, `Collection ${colls.nodeMeta.name} should exist`) - nodeMetaColl.findAndRemove({ id: node.id }) - // TODO What if this `remove()` fails? We will have removed the id - // -> collName mapping, but not the actual node in the - // collection. Need to make this into a transaction - nodeTypeColl.remove(obj) - } - // idempotent. Do nothing if node wasn't already in DB -} - -/** - * deprecated - */ -function deleteNodes(nodes) { - for (const node of nodes) { - deleteNode(node) - } -} - -const saveResolvedNodes = async (nodeTypeNames, resolver) => { - for (const typeName of nodeTypeNames) { - const nodes = getNodesByType(typeName) - const resolved = await Promise.all( - nodes.map(async node => { - node.__gatsby_resolved = await resolver(node) - return node - }) - ) - const nodeColl = getNodeTypeCollection(typeName) - if (nodeColl) { - nodeColl.update(resolved) - } - } -} - -// Cleared on DELETE_CACHE -let fieldUsages = null -const FIELD_INDEX_THRESHOLD = 5 - -// Every time we run a query, we increment a counter for each of its -// fields, so that we can determine which fields are used the -// most. Any time a field is seen more than `FIELD_INDEX_THRESHOLD` -// times, we create a loki index so that future queries with that -// field will execute faster. -// times, we create a loki index so that future queries with that -// field will execute faster. -function ensureFieldIndexes(typeName, lokiArgs, sortArgs) { - if (fieldUsages == null) { - fieldUsages = {} - const { emitter } = require(`../../redux`) - - emitter.on(`DELETE_CACHE`, () => { - for (const field in fieldUsages) { - delete fieldUsages[field] - } - }) - } - - const nodeColl = getNodeTypeCollection(typeName) - - if (!fieldUsages[typeName]) { - fieldUsages[typeName] = {} - } - - _.forEach(lokiArgs, (v, fieldName) => { - // Increment the usages of the field - _.update(fieldUsages[typeName], fieldName, n => (n ? n + 1 : 1)) - // If we have crossed the threshold, then create the index - if (_.get(fieldUsages[typeName], fieldName) >= FIELD_INDEX_THRESHOLD) { - // Loki ensures that this is a noop if index already exists. E.g - // if it was previously added via a sort field - nodeColl.ensureIndex(fieldName) - } - }) -} - -// /////////////////////////////////////////////////////////////////// -// Reducer -// /////////////////////////////////////////////////////////////////// - -function reducer(state = new Map(), action) { - switch (action.type) { - case `DELETE_CACHE`: - deleteAll() - return null - - case `CREATE_NODE`: { - createNode(action.payload, action.oldNode) - return null - } - - case `ADD_FIELD_TO_NODE`: - case `ADD_CHILD_NODE_TO_PARENT_NODE`: - updateNode(action.payload) - return null - - case `DELETE_NODE`: { - if (action.payload) { - deleteNode(action.payload) - } - return null - } - - case `DELETE_NODES`: { - deleteNodes(action.fullNodes) - return null - } - - default: - return null - } -} - -// /////////////////////////////////////////////////////////////////// -// Exports -// /////////////////////////////////////////////////////////////////// - -module.exports = { - getNodeTypeCollection, - - getNodes, - getNode, - getNodesByType, - getTypes, - hasNodeChanged, - getNodeAndSavePathDependency, - - createNode, - updateNode, - deleteNode, - - deleteNodeTypeCollections, - deleteAll, - - reducer, - - saveResolvedNodes, - ensureFieldIndexes, -} diff --git a/packages/gatsby/src/db/nodes.js b/packages/gatsby/src/db/nodes.js index b178e138ddd4d..633fd5cd4734e 100644 --- a/packages/gatsby/src/db/nodes.js +++ b/packages/gatsby/src/db/nodes.js @@ -1,6 +1,8 @@ /* @flow */ const _ = require(`lodash`) const { store } = require(`../redux`) +const nodesDb: NodeStore = require(`../redux/nodes`) +const runQuery = require(`../redux/run-sift`).runSift interface NodeStore { getNodes: () => Array; @@ -18,32 +20,7 @@ interface NodeStore { }) => any | undefined; } -if (process.env.GATSBY_DB_NODES === `loki`) { - console.info( - `The experimental Loki backend for Gatsby has been removed. Falling back to redux. If this causes problems for you, please file an issue on GitHub and tag @pvdz.` - ) -} - -// const backend = process.env.GATSBY_DB_NODES || `redux` -const backend = `redux` -let nodesDb: NodeStore -let runQuery -switch (backend) { - case `redux`: - nodesDb = require(`../redux/nodes`) - runQuery = require(`../redux/run-sift`).runSift - break - case `loki`: - nodesDb = require(`./loki/nodes`) - runQuery = require(`./loki/nodes-query`) - break - default: - throw new Error( - `Unsupported DB nodes backend (value of env var GATSBY_DB_NODES)` - ) -} - -module.exports = { ...nodesDb, runQuery, backend } +module.exports = { ...nodesDb, runQuery } /** * Get content for a node from the plugin that created it. diff --git a/packages/gatsby/src/query/__tests__/data-tracking.js b/packages/gatsby/src/query/__tests__/data-tracking.js index a5caf9c56bb5c..972223d0a0f0a 100644 --- a/packages/gatsby/src/query/__tests__/data-tracking.js +++ b/packages/gatsby/src/query/__tests__/data-tracking.js @@ -58,7 +58,6 @@ jest.mock(`gatsby-cli/lib/reporter`, () => { }) let mockPersistedState = {} -let lokiStorage = {} jest.mock(`../../redux/persist`, () => { return { readFromCache: () => mockPersistedState, @@ -68,17 +67,6 @@ jest.mock(`../../redux/persist`, () => { } }) -const mockedLokiFsAdapter = { - loadDatabase: (dbname, callback) => { - callback(lokiStorage[dbname]) - }, - - saveDatabase: (dbname, dbstring, callback) => { - lokiStorage[dbname] = dbstring - callback(null) - }, -} - const pluginOptions = {} let mockAPIs = {} @@ -117,7 +105,6 @@ const setup = async ({ restart = isFirstRun, clearCache = false } = {}) => { jest.resetModules() if (clearCache) { mockPersistedState = {} - lokiStorage = {} } } else if (clearCache) { console.error(`Can't clear cache without restarting`) @@ -161,20 +148,6 @@ const setup = async ({ restart = isFirstRun, clearCache = false } = {}) => { ) const apiRunner = require(`../../utils/api-runner-node`) - if (restart) { - const { backend } = require(`../../db/nodes`) - if (backend === `loki`) { - const loki = require(`../../db/loki`) - const dbSaveFile = `${__dirname}/fixtures/loki.db` - await loki.start({ - saveFile: dbSaveFile, - lokiDBOptions: { - adapter: mockedLokiFsAdapter, - }, - }) - } - } - queryRunner.mockClear() store.dispatch({ diff --git a/packages/gatsby/src/redux/__tests__/__snapshots__/index.js.snap b/packages/gatsby/src/redux/__tests__/__snapshots__/index.js.snap index c12a3d0399d3c..d6b55a51cd44e 100644 --- a/packages/gatsby/src/redux/__tests__/__snapshots__/index.js.snap +++ b/packages/gatsby/src/redux/__tests__/__snapshots__/index.js.snap @@ -1,36 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`redux db should write loki cache to disk 1`] = ` -Object { - "componentDataDependencies": Object { - "connections": Map {}, - "nodes": Map {}, - }, - "components": Map { - "/Users/username/dev/site/src/templates/my-sweet-new-page.js" => Object { - "componentPath": "/Users/username/dev/site/src/templates/my-sweet-new-page.js", - "isInBootstrap": true, - "pages": Set { - "/my-sweet-new-page/", - }, - "query": "", - }, - }, - "jobsV2": Object { - "complete": Map {}, - "incomplete": Map {}, - }, - "pageData": Map {}, - "pageDataStats": Map {}, - "staticQueryComponents": Map {}, - "status": Object { - "PLUGINS_HASH": "", - "plugins": Object {}, - }, - "webpackCompilationHash": "", -} -`; - exports[`redux db should write redux cache to disk 1`] = ` Object { "componentDataDependencies": Object { diff --git a/packages/gatsby/src/redux/__tests__/index.js b/packages/gatsby/src/redux/__tests__/index.js index 8eb7c193b3735..b8327549acf1b 100644 --- a/packages/gatsby/src/redux/__tests__/index.js +++ b/packages/gatsby/src/redux/__tests__/index.js @@ -111,36 +111,6 @@ describe(`redux db`, () => { mockWrittenContent.clear() }) - // yuck - loki and redux will have different shape of redux state (nodes and nodesByType) - // Note: branched skips will keep snapshots with and without loki env var - // if (process.env.GATSBY_DB_NODES === `loki`) { - // it.skip(`should write redux cache to disk`, async () => {}) - // it(`should write loki cache to disk`, async () => { - // expect(initialComponentsState).toEqual(new Map()) - // - // store.getState().nodes = getFakeNodes() - // - // await saveState() - // - // expect(writeToCache).toBeCalled() - // - // // reset state in memory - // store.dispatch({ - // type: `DELETE_CACHE`, - // }) - // // make sure store in memory is empty - // expect(store.getState().components).toEqual(initialComponentsState) - // - // // read data that was previously cached - // const data = readState() - // - // // make sure data was read and is not the same as our clean redux state - // expect(data.components).not.toEqual(initialComponentsState) - // - // expect(_.omit(data, [`nodes`, `nodesByType`])).toMatchSnapshot() - // }) - // } else { - it.skip(`should write loki cache to disk`, async () => {}) it(`should write redux cache to disk`, async () => { expect(initialComponentsState).toEqual(new Map()) @@ -165,7 +135,6 @@ describe(`redux db`, () => { expect(data).toMatchSnapshot() }) - // } it(`should drop legacy file if exists`, async () => { expect(initialComponentsState).toEqual(new Map()) diff --git a/packages/gatsby/src/redux/__tests__/run-sift.js b/packages/gatsby/src/redux/__tests__/run-sift.js index bd4ff8a82658f..36561a79ec8bf 100644 --- a/packages/gatsby/src/redux/__tests__/run-sift.js +++ b/packages/gatsby/src/redux/__tests__/run-sift.js @@ -1,470 +1,464 @@ -if (!process.env.GATSBY_DB_NODES || process.env.GATSBY_DB_NODES === `redux`) { - const { runSift, filterWithoutSift } = require(`../run-sift`) - const { store } = require(`../index`) - const { createDbQueriesFromObject } = require(`../../db/common/query`) - const { actions } = require(`../actions`) - const { - GraphQLObjectType, - GraphQLNonNull, - GraphQLID, - GraphQLString, - GraphQLList, - } = require(`graphql`) - - const mockNodes = () => [ - { - id: `id_1`, - string: `foo`, - slog: `abc`, - deep: { flat: { search: { chain: 123 } } }, - elemList: [ - { - foo: `bar`, - }, - ], - internal: { - type: `notTest`, - contentDigest: `0`, +const { runSift, filterWithoutSift } = require(`../run-sift`) +const { store } = require(`../index`) +const { createDbQueriesFromObject } = require(`../../db/common/query`) +const { actions } = require(`../actions`) +const { + GraphQLObjectType, + GraphQLNonNull, + GraphQLID, + GraphQLString, + GraphQLList, +} = require(`graphql`) + +const mockNodes = () => [ + { + id: `id_1`, + string: `foo`, + slog: `abc`, + deep: { flat: { search: { chain: 123 } } }, + elemList: [ + { + foo: `bar`, }, + ], + internal: { + type: `notTest`, + contentDigest: `0`, }, - { - id: `id_2`, - string: `bar`, - slog: `def`, - elemList: [ - { - foo: `baz`, - }, - ], - deep: { flat: { search: { chain: 500 } } }, - internal: { - type: `test`, - contentDigest: `0`, + }, + { + id: `id_2`, + string: `bar`, + slog: `def`, + elemList: [ + { + foo: `baz`, }, + ], + deep: { flat: { search: { chain: 500 } } }, + internal: { + type: `test`, + contentDigest: `0`, }, - { - id: `id_3`, - slog: `abc`, - string: `baz`, - elemList: [ - { - foo: `bar`, - }, + }, + { + id: `id_3`, + slog: `abc`, + string: `baz`, + elemList: [ + { + foo: `bar`, + }, + { + foo: `baz`, + }, + ], + deep: { flat: { search: { chain: 300 } } }, + internal: { + type: `test`, + contentDigest: `0`, + }, + }, + { + id: `id_4`, + string: `qux`, + slog: `def`, + deep: { flat: { search: { chain: 300 } } }, + internal: { + type: `test`, + contentDigest: `0`, + }, + first: { + willBeResolved: `willBeResolved`, + second: [ { - foo: `baz`, + willBeResolved: `willBeResolved`, + third: { + foo: `foo`, + }, }, ], - deep: { flat: { search: { chain: 300 } } }, - internal: { - type: `test`, - contentDigest: `0`, - }, }, - { - id: `id_4`, - string: `qux`, - slog: `def`, - deep: { flat: { search: { chain: 300 } } }, - internal: { - type: `test`, - contentDigest: `0`, - }, + }, +] + +const typeName = `test` +const gqlType = new GraphQLObjectType({ + name: typeName, + fields: () => { + return { + id: { type: new GraphQLNonNull(GraphQLID) }, + string: { type: GraphQLString }, first: { - willBeResolved: `willBeResolved`, - second: [ - { - willBeResolved: `willBeResolved`, - third: { - foo: `foo`, + type: new GraphQLObjectType({ + name: `First`, + fields: { + willBeResolved: { + type: GraphQLString, + resolve: () => `resolvedValue`, }, - }, - ], - }, - }, - ] - - const typeName = `test` - const gqlType = new GraphQLObjectType({ - name: typeName, - fields: () => { - return { - id: { type: new GraphQLNonNull(GraphQLID) }, - string: { type: GraphQLString }, - first: { - type: new GraphQLObjectType({ - name: `First`, - fields: { - willBeResolved: { - type: GraphQLString, - resolve: () => `resolvedValue`, - }, - second: { - type: new GraphQLList( - new GraphQLObjectType({ - name: `Second`, - fields: { - willBeResolved: { - type: GraphQLString, - resolve: () => `resolvedValue`, - }, - third: new GraphQLObjectType({ - name: `Third`, - fields: { - foo: GraphQLString, - }, - }), + second: { + type: new GraphQLList( + new GraphQLObjectType({ + name: `Second`, + fields: { + willBeResolved: { + type: GraphQLString, + resolve: () => `resolvedValue`, }, - }) - ), - }, + third: new GraphQLObjectType({ + name: `Third`, + fields: { + foo: GraphQLString, + }, + }), + }, + }) + ), }, - }), - }, - } - }, + }, + }), + }, + } + }, +}) + +describe(`run-sift tests`, () => { + beforeEach(() => { + store.dispatch({ type: `DELETE_CACHE` }) + mockNodes().forEach(node => + actions.createNode(node, { name: `test` })(store.dispatch) + ) }) + ;[ + { desc: `with cache`, cb: () /*:FiltersCache*/ => new Map() }, // Avoids sift for flat filters + { desc: `no cache`, cb: () => null }, // Always goes through sift + ].forEach(({ desc, cb: createFiltersCache }) => { + describe(desc, () => { + describe(`filters by just id correctly`, () => { + it(`eq operator`, async () => { + const queryArgs = { + filter: { + id: { eq: `id_2` }, + }, + } + + const resultSingular = await runSift({ + gqlType, + queryArgs, + firstOnly: true, + nodeTypeNames: [gqlType.name], + filtersCache: createFiltersCache(), + }) - describe(`run-sift tests`, () => { - beforeEach(() => { - store.dispatch({ type: `DELETE_CACHE` }) - mockNodes().forEach(node => - actions.createNode(node, { name: `test` })(store.dispatch) - ) - }) - ;[ - { desc: `with cache`, cb: () /*:FiltersCache*/ => new Map() }, // Avoids sift for flat filters - { desc: `no cache`, cb: () => null }, // Always goes through sift - ].forEach(({ desc, cb: createFiltersCache }) => { - describe(desc, () => { - describe(`filters by just id correctly`, () => { - it(`eq operator`, async () => { - const queryArgs = { - filter: { - id: { eq: `id_2` }, - }, - } - - const resultSingular = await runSift({ - gqlType, - queryArgs, - firstOnly: true, - nodeTypeNames: [gqlType.name], - filtersCache: createFiltersCache(), - }) - - const resultMany = await runSift({ - gqlType, - queryArgs, - firstOnly: false, - nodeTypeNames: [gqlType.name], - filtersCache: createFiltersCache(), - }) - - expect(resultSingular.map(o => o.id)).toEqual([mockNodes()[1].id]) - expect(resultMany.map(o => o.id)).toEqual([mockNodes()[1].id]) + const resultMany = await runSift({ + gqlType, + queryArgs, + firstOnly: false, + nodeTypeNames: [gqlType.name], + filtersCache: createFiltersCache(), }) - it(`eq operator honors type`, async () => { - const queryArgs = { - filter: { - id: { eq: `id_1` }, - }, - } - - const resultSingular = await runSift({ - gqlType, - queryArgs, - firstOnly: true, - nodeTypeNames: [gqlType.name], - filtersCache: createFiltersCache(), - }) - - const resultMany = await runSift({ - gqlType, - queryArgs, - firstOnly: false, - nodeTypeNames: [gqlType.name], - filtersCache: createFiltersCache(), - }) - - // `id-1` node is not of queried type, so results should be empty - expect(resultSingular).toEqual([]) - expect(resultMany).toEqual(null) + expect(resultSingular.map(o => o.id)).toEqual([mockNodes()[1].id]) + expect(resultMany.map(o => o.id)).toEqual([mockNodes()[1].id]) + }) + + it(`eq operator honors type`, async () => { + const queryArgs = { + filter: { + id: { eq: `id_1` }, + }, + } + + const resultSingular = await runSift({ + gqlType, + queryArgs, + firstOnly: true, + nodeTypeNames: [gqlType.name], + filtersCache: createFiltersCache(), }) - it(`non-eq operator`, async () => { - const queryArgs = { - filter: { - id: { ne: `id_2` }, - }, - } - - const resultSingular = await runSift({ - gqlType, - queryArgs, - firstOnly: true, - nodeTypeNames: [gqlType.name], - filtersCache: createFiltersCache(), - }) - - const resultMany = await runSift({ - gqlType, - queryArgs, - firstOnly: false, - nodeTypeNames: [gqlType.name], - filtersCache: createFiltersCache(), - }) - - expect(resultSingular.map(o => o.id)).toEqual([mockNodes()[2].id]) - expect(resultMany.map(o => o.id)).toEqual([ - mockNodes()[2].id, - mockNodes()[3].id, - ]) + const resultMany = await runSift({ + gqlType, + queryArgs, + firstOnly: false, + nodeTypeNames: [gqlType.name], + filtersCache: createFiltersCache(), }) - it(`return empty array in case of empty nodes`, async () => { - const queryArgs = { filter: {}, sort: {} } - const resultSingular = await runSift({ - gqlType, - queryArgs, - firstOnly: true, - nodeTypeNames: [`NonExistentNodeType`], - filtersCache: createFiltersCache(), - }) - expect(resultSingular).toEqual([]) + + // `id-1` node is not of queried type, so results should be empty + expect(resultSingular).toEqual([]) + expect(resultMany).toEqual(null) + }) + + it(`non-eq operator`, async () => { + const queryArgs = { + filter: { + id: { ne: `id_2` }, + }, + } + + const resultSingular = await runSift({ + gqlType, + queryArgs, + firstOnly: true, + nodeTypeNames: [gqlType.name], + filtersCache: createFiltersCache(), }) + + const resultMany = await runSift({ + gqlType, + queryArgs, + firstOnly: false, + nodeTypeNames: [gqlType.name], + filtersCache: createFiltersCache(), + }) + + expect(resultSingular.map(o => o.id)).toEqual([mockNodes()[2].id]) + expect(resultMany.map(o => o.id)).toEqual([ + mockNodes()[2].id, + mockNodes()[3].id, + ]) }) - describe(`filters by arbitrary property correctly`, () => { - it(`eq operator flat single`, async () => { - const queryArgs = { - filter: { - slog: { eq: `def` }, - }, - } - - const resultSingular = await runSift({ - gqlType, - queryArgs, - firstOnly: true, - nodeTypeNames: [gqlType.name], - filtersCache: createFiltersCache(), - }) - - expect(Array.isArray(resultSingular)).toBe(true) - expect(resultSingular.length).toEqual(1) - - resultSingular.map(node => { - expect(node.slog).toEqual(`def`) - }) + it(`return empty array in case of empty nodes`, async () => { + const queryArgs = { filter: {}, sort: {} } + const resultSingular = await runSift({ + gqlType, + queryArgs, + firstOnly: true, + nodeTypeNames: [`NonExistentNodeType`], + filtersCache: createFiltersCache(), }) - it(`eq operator flat many`, async () => { - const queryArgs = { - filter: { - slog: { eq: `def` }, - }, - } - - const resultMany = await runSift({ - gqlType, - queryArgs, - firstOnly: false, - nodeTypeNames: [gqlType.name], - filtersCache: createFiltersCache(), - }) - - expect(Array.isArray(resultMany)).toBe(true) - expect(resultMany.length).toEqual(2) - - resultMany.map(node => { - expect(node.slog).toEqual(`def`) - }) + expect(resultSingular).toEqual([]) + }) + }) + describe(`filters by arbitrary property correctly`, () => { + it(`eq operator flat single`, async () => { + const queryArgs = { + filter: { + slog: { eq: `def` }, + }, + } + + const resultSingular = await runSift({ + gqlType, + queryArgs, + firstOnly: true, + nodeTypeNames: [gqlType.name], + filtersCache: createFiltersCache(), }) - it(`eq operator deep single`, async () => { - const queryArgs = { - filter: { - deep: { flat: { search: { chain: { eq: 300 } } } }, - }, - } - - const resultSingular = await runSift({ - gqlType, - queryArgs, - firstOnly: true, - nodeTypeNames: [gqlType.name], - filtersCache: createFiltersCache(), - }) - - expect(Array.isArray(resultSingular)).toBe(true) - expect(resultSingular.length).toEqual(1) - - resultSingular.map(node => { - expect(node.deep.flat.search.chain).toEqual(300) - }) + + expect(Array.isArray(resultSingular)).toBe(true) + expect(resultSingular.length).toEqual(1) + + resultSingular.map(node => { + expect(node.slog).toEqual(`def`) }) - it(`eq operator deep many`, async () => { - const queryArgs = { - filter: { - deep: { flat: { search: { chain: { eq: 300 } } } }, - }, - } - - const resultMany = await runSift({ - gqlType, - queryArgs, - firstOnly: false, - nodeTypeNames: [gqlType.name], - filtersCache: createFiltersCache(), - }) - - expect(Array.isArray(resultMany)).toBe(true) - expect(resultMany.length).toEqual(2) - - resultMany.map(node => { - expect(node.deep.flat.search.chain).toEqual(300) - }) + }) + it(`eq operator flat many`, async () => { + const queryArgs = { + filter: { + slog: { eq: `def` }, + }, + } + + const resultMany = await runSift({ + gqlType, + queryArgs, + firstOnly: false, + nodeTypeNames: [gqlType.name], + filtersCache: createFiltersCache(), }) - it(`eq operator deep miss single`, async () => { - const queryArgs = { - filter: { - deep: { flat: { search: { chain: { eq: 999 } } } }, - }, - } - - const resultSingular = await runSift({ - gqlType, - queryArgs, - firstOnly: true, - nodeTypeNames: [gqlType.name], - filtersCache: createFiltersCache(), - }) - - expect(Array.isArray(resultSingular)).toBe(true) - expect(resultSingular.length).toEqual(0) + + expect(Array.isArray(resultMany)).toBe(true) + expect(resultMany.length).toEqual(2) + + resultMany.map(node => { + expect(node.slog).toEqual(`def`) + }) + }) + it(`eq operator deep single`, async () => { + const queryArgs = { + filter: { + deep: { flat: { search: { chain: { eq: 300 } } } }, + }, + } + + const resultSingular = await runSift({ + gqlType, + queryArgs, + firstOnly: true, + nodeTypeNames: [gqlType.name], + filtersCache: createFiltersCache(), }) - it(`eq operator deep miss many`, async () => { - const queryArgs = { - filter: { - deep: { flat: { search: { chain: { eq: 999 } } } }, - }, - } - const resultMany = await runSift({ - gqlType, - queryArgs, - firstOnly: false, - nodeTypeNames: [gqlType.name], - filtersCache: createFiltersCache(), - }) + expect(Array.isArray(resultSingular)).toBe(true) + expect(resultSingular.length).toEqual(1) - expect(resultMany).toBe(null) + resultSingular.map(node => { + expect(node.deep.flat.search.chain).toEqual(300) + }) + }) + it(`eq operator deep many`, async () => { + const queryArgs = { + filter: { + deep: { flat: { search: { chain: { eq: 300 } } } }, + }, + } + + const resultMany = await runSift({ + gqlType, + queryArgs, + firstOnly: false, + nodeTypeNames: [gqlType.name], + filtersCache: createFiltersCache(), }) - it(`elemMatch on array of objects`, async () => { - const queryArgs = { - filter: { - elemList: { - elemMatch: { foo: { eq: `baz` } }, - }, + expect(Array.isArray(resultMany)).toBe(true) + expect(resultMany.length).toEqual(2) + + resultMany.map(node => { + expect(node.deep.flat.search.chain).toEqual(300) + }) + }) + it(`eq operator deep miss single`, async () => { + const queryArgs = { + filter: { + deep: { flat: { search: { chain: { eq: 999 } } } }, + }, + } + + const resultSingular = await runSift({ + gqlType, + queryArgs, + firstOnly: true, + nodeTypeNames: [gqlType.name], + filtersCache: createFiltersCache(), + }) + + expect(Array.isArray(resultSingular)).toBe(true) + expect(resultSingular.length).toEqual(0) + }) + it(`eq operator deep miss many`, async () => { + const queryArgs = { + filter: { + deep: { flat: { search: { chain: { eq: 999 } } } }, + }, + } + + const resultMany = await runSift({ + gqlType, + queryArgs, + firstOnly: false, + nodeTypeNames: [gqlType.name], + filtersCache: createFiltersCache(), + }) + + expect(resultMany).toBe(null) + }) + + it(`elemMatch on array of objects`, async () => { + const queryArgs = { + filter: { + elemList: { + elemMatch: { foo: { eq: `baz` } }, }, - } - - const resultMany = await runSift({ - gqlType, - queryArgs, - firstOnly: false, - nodeTypeNames: [gqlType.name], - filtersCache: createFiltersCache(), - }) - - expect(Array.isArray(resultMany)).toBe(true) - expect(resultMany.map(({ id }) => id)).toEqual([`id_2`, `id_3`]) + }, + } + + const resultMany = await runSift({ + gqlType, + queryArgs, + firstOnly: false, + nodeTypeNames: [gqlType.name], + filtersCache: createFiltersCache(), }) + + expect(Array.isArray(resultMany)).toBe(true) + expect(resultMany.map(({ id }) => id)).toEqual([`id_2`, `id_3`]) }) }) }) }) +}) + +describe(`filterWithoutSift`, () => { + beforeAll(() => { + store.dispatch({ type: `DELETE_CACHE` }) + mockNodes().forEach(node => + actions.createNode(node, { name: `test` })(store.dispatch) + ) + }) - describe(`filterWithoutSift`, () => { - beforeAll(() => { - store.dispatch({ type: `DELETE_CACHE` }) - mockNodes().forEach(node => - actions.createNode(node, { name: `test` })(store.dispatch) - ) - }) - - it(`gets stuff from cache for simple query`, () => { - const filter = { - slog: { $eq: `def` }, - } - - const result = filterWithoutSift( - createDbQueriesFromObject(filter), - [typeName], - new Map() - ) - expect(Array.isArray(result)).toBe(true) - expect(result.length).toEqual(2) - - result.map(node => { - expect(node.slog).toEqual(`def`) - }) + it(`gets stuff from cache for simple query`, () => { + const filter = { + slog: { $eq: `def` }, + } + + const result = filterWithoutSift( + createDbQueriesFromObject(filter), + [typeName], + new Map() + ) + expect(Array.isArray(result)).toBe(true) + expect(result.length).toEqual(2) + + result.map(node => { + expect(node.slog).toEqual(`def`) }) + }) - it(`gets stuff from cache for deep query`, () => { - const filter = { - deep: { flat: { search: { chain: { $eq: 300 } } } }, - } - - const result = filterWithoutSift( - createDbQueriesFromObject(filter), - [typeName], - new Map() - ) - expect(Array.isArray(result)).toBe(true) - expect(result.length).toEqual(2) - - result.map(node => { - expect(node.deep.flat.search.chain).toEqual(300) - }) + it(`gets stuff from cache for deep query`, () => { + const filter = { + deep: { flat: { search: { chain: { $eq: 300 } } } }, + } + + const result = filterWithoutSift( + createDbQueriesFromObject(filter), + [typeName], + new Map() + ) + expect(Array.isArray(result)).toBe(true) + expect(result.length).toEqual(2) + + result.map(node => { + expect(node.deep.flat.search.chain).toEqual(300) }) + }) - it(`supports multi-query`, () => { - const filter = { - slog: { $eq: `def` }, - deep: { flat: { search: { chain: { $eq: 300 } } } }, - } - - const results = filterWithoutSift( - createDbQueriesFromObject(filter), - [typeName], - new Map() - ) - - // Count is irrelevant as long as it is non-zero and they all match filter - expect(Array.isArray(results)).toBe(true) - expect(results.length).toEqual(1) - expect(results[0].slog).toEqual(`def`) - expect(results[0].deep.flat.search.chain).toEqual(300) - }) + it(`supports multi-query`, () => { + const filter = { + slog: { $eq: `def` }, + deep: { flat: { search: { chain: { $eq: 300 } } } }, + } + + const results = filterWithoutSift( + createDbQueriesFromObject(filter), + [typeName], + new Map() + ) + + // Count is irrelevant as long as it is non-zero and they all match filter + expect(Array.isArray(results)).toBe(true) + expect(results.length).toEqual(1) + expect(results[0].slog).toEqual(`def`) + expect(results[0].deep.flat.search.chain).toEqual(300) + }) - it(`supports elemMatch`, () => { - const filter = { - elemList: { - $elemMatch: { foo: { $eq: `baz` } }, - }, - } + it(`supports elemMatch`, () => { + const filter = { + elemList: { + $elemMatch: { foo: { $eq: `baz` } }, + }, + } - const result = filterWithoutSift( - createDbQueriesFromObject(filter), - [typeName], - new Map() - ) + const result = filterWithoutSift( + createDbQueriesFromObject(filter), + [typeName], + new Map() + ) - expect(result).not.toBe(undefined) - expect(result.length).toBe(2) - }) - }) -} else { - it(`Loki skipping redux run-sift`, () => { - expect(true).toEqual(true) + expect(result).not.toBe(undefined) + expect(result.length).toBe(2) }) -} +}) diff --git a/packages/gatsby/src/redux/actions/public.js b/packages/gatsby/src/redux/actions/public.js index b73f86e25ba44..5f672202abc28 100644 --- a/packages/gatsby/src/redux/actions/public.js +++ b/packages/gatsby/src/redux/actions/public.js @@ -599,8 +599,7 @@ actions.deleteNodes = (nodes: any[], plugin: Plugin) => { const deleteNodesAction = { type: `DELETE_NODES`, plugin, - // Payload contains node IDs but inference-metadata and loki reducers require - // full node instances + // Payload contains node IDs but inference-metadata requires full node instances payload: nodeIds, fullNodes: nodeIds.map(getNode), } diff --git a/packages/gatsby/src/redux/persist.ts b/packages/gatsby/src/redux/persist.ts index e2ce8abafa59a..400010484b12d 100644 --- a/packages/gatsby/src/redux/persist.ts +++ b/packages/gatsby/src/redux/persist.ts @@ -57,7 +57,6 @@ export function readFromCache(): ICachedReduxState { const nodes: [string, IGatsbyNode][] = [].concat(...chunks) - // if (!chunks.length && process.env.GATSBY_DB_NODES !== `loki`) { if (!chunks.length) { report.info( `Cache exists but contains no nodes. There should be at least some nodes available so it seems the cache was corrupted. Disregarding the cache and proceeding as if there was none.` diff --git a/packages/gatsby/src/redux/reducers/index.js b/packages/gatsby/src/redux/reducers/index.js index db80119a10f52..b241c067038e5 100644 --- a/packages/gatsby/src/redux/reducers/index.js +++ b/packages/gatsby/src/redux/reducers/index.js @@ -1,5 +1,5 @@ const reduxNodes = require(`./nodes`) -const lokiNodes = require(`../../db/loki/nodes`).reducer +const nodesReducer = require(`./nodes-by-type`) import { pagesReducer } from "./pages" import { redirectsReducer } from "./redirects" import { schemaReducer } from "./schema" @@ -11,50 +11,13 @@ import { themesReducer } from "./themes" import { webpackCompilationHashReducer } from "./webpack-compilation-hash" import { reducer as logReducer } from "gatsby-cli/lib/reporter/redux/reducer" -// const backend = process.env.GATSBY_DB_NODES || `redux` -const backend = `redux` - -function getNodesReducer() { - let nodesReducer - switch (backend) { - case `redux`: - nodesReducer = reduxNodes - break - case `loki`: - nodesReducer = lokiNodes - break - default: - throw new Error( - `Unsupported DB nodes backend (value of env var GATSBY_DB_NODES)` - ) - } - return nodesReducer -} - -function getNodesByTypeReducer() { - let nodesReducer - switch (backend) { - case `redux`: - nodesReducer = require(`./nodes-by-type`) - break - case `loki`: - nodesReducer = (state = null) => null - break - default: - throw new Error( - `Unsupported DB nodes backend (value of env var GATSBY_DB_NODES)` - ) - } - return nodesReducer -} - /** * @property exports.nodesTouched Set */ module.exports = { program: require(`./program`), - nodes: getNodesReducer(), - nodesByType: getNodesByTypeReducer(), + nodes: reduxNodes, + nodesByType: nodesReducer, resolvedNodesCache: require(`./resolved-nodes`), nodesTouched: require(`./nodes-touched`), lastAction: require(`./last-action`), diff --git a/packages/gatsby/src/redux/reducers/inference-metadata.js b/packages/gatsby/src/redux/reducers/inference-metadata.js index 0b9261a82df29..c3cc49e52afd8 100644 --- a/packages/gatsby/src/redux/reducers/inference-metadata.js +++ b/packages/gatsby/src/redux/reducers/inference-metadata.js @@ -60,11 +60,7 @@ module.exports = (state = initialState(), action) => { } } -const ignoredFields = new Set([ - ...NodeInterfaceFields, - `$loki`, - `__gatsby_resolved`, -]) +const ignoredFields = new Set([...NodeInterfaceFields, `__gatsby_resolved`]) const initialTypeMetadata = () => { return { ignoredFields } diff --git a/packages/gatsby/src/redux/run-sift.js b/packages/gatsby/src/redux/run-sift.js index b1a8233e7a7f2..3e37940eeca63 100644 --- a/packages/gatsby/src/redux/run-sift.js +++ b/packages/gatsby/src/redux/run-sift.js @@ -6,9 +6,7 @@ const { makeRe } = require(`micromatch`) import { getValueAt } from "../utils/get-value-at" import _ from "lodash" const { - toDottedFields, objectToDottedField, - liftResolvedFields, createDbQueriesFromObject, prefixResolvedFields, dbQueryToSiftQuery, @@ -85,11 +83,6 @@ const prepareQueryArgs = (filterFields = {}) => return acc }, {}) -const getFilters = filters => - Object.keys(filters).map(key => { - return { [key]: filters[key] } - }) - ///////////////////////////////////////////////////////////////////// // Run Sift ///////////////////////////////////////////////////////////////////// @@ -540,7 +533,7 @@ const filterWithSift = (filters, firstOnly, nodeTypeNames, resolvedFields) => { let nodes /*: IGatsbyNode[]*/ = [] nodeTypeNames.forEach(typeName => addResolvedNodes(typeName, nodes)) - return _runSiftOnNodes( + return runSiftOnNodes( nodes, filters.map(f => dbQueryToSiftQuery(f)), firstOnly, @@ -550,40 +543,6 @@ const filterWithSift = (filters, firstOnly, nodeTypeNames, resolvedFields) => { ) } -/** - * Given a list of filtered nodes and sorting parameters, sort the nodes - * Note: this entry point is used by GATSBY_DB_NODES=loki - * - * @param {Array} nodes Should be all nodes of given type(s) - * @param args Legacy api arg, see _runSiftOnNodes - * @param {?function(id: string): IGatsbyNode | undefined} getNode - * @returns {Array | undefined | null} Collection of results. - * Collection will be limited to 1 if `firstOnly` is true - */ -const runSiftOnNodes = (nodes, args, getNode = siftGetNode) => { - const { - queryArgs: { filter } = { filter: {} }, - firstOnly = false, - resolvedFields = {}, - nodeTypeNames, - } = args - - let siftFilter = getFilters( - liftResolvedFields(toDottedFields(prepareQueryArgs(filter)), resolvedFields) - ) - - return _runSiftOnNodes( - nodes, - siftFilter, - firstOnly, - nodeTypeNames, - resolvedFields, - getNode - ) -} - -exports.runSiftOnNodes = runSiftOnNodes - /** * Given a list of filtered nodes and sorting parameters, sort the nodes * @@ -597,7 +556,7 @@ exports.runSiftOnNodes = runSiftOnNodes * @returns {Array | undefined | null} Collection of results. * Collection will be limited to 1 if `firstOnly` is true */ -const _runSiftOnNodes = ( +const runSiftOnNodes = ( nodes, filters, firstOnly, diff --git a/packages/gatsby/src/schema/__tests__/build-node-connections.js b/packages/gatsby/src/schema/__tests__/build-node-connections.js index 6b2bc14b3bf3c..21360e7d95ef6 100644 --- a/packages/gatsby/src/schema/__tests__/build-node-connections.js +++ b/packages/gatsby/src/schema/__tests__/build-node-connections.js @@ -9,8 +9,6 @@ const { actions } = require(`../../redux/actions`) jest.mock(`../../redux/actions/add-page-dependency`) import { createPageDependency } from "../../redux/actions/add-page-dependency" -require(`../../db/__tests__/fixtures/ensure-loki`)() - jest.mock(`gatsby-cli/lib/reporter`, () => { return { log: jest.fn(), diff --git a/packages/gatsby/src/schema/__tests__/build-node-types.js b/packages/gatsby/src/schema/__tests__/build-node-types.js index 6c71e76e38a9d..4080245397655 100644 --- a/packages/gatsby/src/schema/__tests__/build-node-types.js +++ b/packages/gatsby/src/schema/__tests__/build-node-types.js @@ -1,5 +1,4 @@ const { graphql, GraphQLString } = require(`graphql`) -require(`../../db/__tests__/fixtures/ensure-loki`)() const { createSchemaComposer } = require(`../schema-composer`) const { buildSchema } = require(`../schema`) diff --git a/packages/gatsby/src/schema/__tests__/build-schema.js b/packages/gatsby/src/schema/__tests__/build-schema.js index 7db2ce9e66eee..1ba72f7607fe6 100644 --- a/packages/gatsby/src/schema/__tests__/build-schema.js +++ b/packages/gatsby/src/schema/__tests__/build-schema.js @@ -19,7 +19,6 @@ const { buildInterfaceType, } = require(`../types/type-builders`) const withResolverContext = require(`../context`) -require(`../../db/__tests__/fixtures/ensure-loki`)() const nodes = require(`./fixtures/node-model`) diff --git a/packages/gatsby/src/schema/__tests__/connection-filter-on-linked-nodes.js b/packages/gatsby/src/schema/__tests__/connection-filter-on-linked-nodes.js index 585d73dd9619e..accc8edfc2da3 100644 --- a/packages/gatsby/src/schema/__tests__/connection-filter-on-linked-nodes.js +++ b/packages/gatsby/src/schema/__tests__/connection-filter-on-linked-nodes.js @@ -3,7 +3,6 @@ const { build } = require(`..`) const withResolverContext = require(`../context`) const { store } = require(`../../redux`) const { actions } = require(`../../redux/actions`) -require(`../../db/__tests__/fixtures/ensure-loki`)() function makeNodes() { return [ diff --git a/packages/gatsby/src/schema/__tests__/connection-input-fields.js b/packages/gatsby/src/schema/__tests__/connection-input-fields.js index b02187e61b0c5..68f0015ce765b 100644 --- a/packages/gatsby/src/schema/__tests__/connection-input-fields.js +++ b/packages/gatsby/src/schema/__tests__/connection-input-fields.js @@ -5,7 +5,6 @@ const { LocalNodeModel } = require(`../node-model`) const nodeStore = require(`../../db/nodes`) const { store } = require(`../../redux`) const { actions } = require(`../../redux/actions`) -require(`../../db/__tests__/fixtures/ensure-loki`)() function makeNodes() { return [ diff --git a/packages/gatsby/src/schema/__tests__/context.js b/packages/gatsby/src/schema/__tests__/context.js index d7533f5e92f65..244c83f11a040 100644 --- a/packages/gatsby/src/schema/__tests__/context.js +++ b/packages/gatsby/src/schema/__tests__/context.js @@ -6,7 +6,6 @@ const { store } = require(`../../redux`) const { dispatch } = store const { actions } = require(`../../redux/actions/restricted`) const { createTypes, createFieldExtension, createResolverContext } = actions -require(`../../db/__tests__/fixtures/ensure-loki`)() jest.mock(`gatsby-cli/lib/reporter`, () => { return { diff --git a/packages/gatsby/src/schema/__tests__/kitchen-sink.js b/packages/gatsby/src/schema/__tests__/kitchen-sink.js index 42cbf47cac364..cd439a79d6e53 100644 --- a/packages/gatsby/src/schema/__tests__/kitchen-sink.js +++ b/packages/gatsby/src/schema/__tests__/kitchen-sink.js @@ -16,7 +16,6 @@ const fs = require(`fs-extra`) const path = require(`path`) const { slash } = require(`gatsby-core-utils`) const withResolverContext = require(`../context`) -require(`../../db/__tests__/fixtures/ensure-loki`)() jest.mock(`../../utils/api-runner-node`) const apiRunnerNode = require(`../../utils/api-runner-node`) diff --git a/packages/gatsby/src/schema/__tests__/node-model.js b/packages/gatsby/src/schema/__tests__/node-model.js index 21222402b5bd3..7182e552e7bbd 100644 --- a/packages/gatsby/src/schema/__tests__/node-model.js +++ b/packages/gatsby/src/schema/__tests__/node-model.js @@ -1,7 +1,6 @@ const { store } = require(`../../redux`) const { actions } = require(`../../redux/actions`) const nodeStore = require(`../../db/nodes`) -require(`../../db/__tests__/fixtures/ensure-loki`)() const { LocalNodeModel } = require(`../node-model`) const { build } = require(`..`) const typeBuilders = require(`../types/type-builders`) diff --git a/packages/gatsby/src/schema/__tests__/print.js b/packages/gatsby/src/schema/__tests__/print.js index 6289242f9c6e5..bcfc573f6a64e 100644 --- a/packages/gatsby/src/schema/__tests__/print.js +++ b/packages/gatsby/src/schema/__tests__/print.js @@ -3,7 +3,6 @@ const { buildObjectType } = require(`../types/type-builders`) const { store } = require(`../../redux`) const { actions } = require(`../../redux/actions/restricted`) const { printTypeDefinitions } = actions -require(`../../db/__tests__/fixtures/ensure-loki`)() jest.mock(`fs-extra`) const fs = require(`fs-extra`) diff --git a/packages/gatsby/src/schema/__tests__/queries-file.js b/packages/gatsby/src/schema/__tests__/queries-file.js index 53a7474d01048..51c250e4d6857 100644 --- a/packages/gatsby/src/schema/__tests__/queries-file.js +++ b/packages/gatsby/src/schema/__tests__/queries-file.js @@ -3,7 +3,6 @@ const { store } = require(`../../redux`) const { actions } = require(`../../redux/actions`) const { build } = require(`..`) const withResolverContext = require(`../context`) -require(`../../db/__tests__/fixtures/ensure-loki`)() const path = require(`path`) const { slash } = require(`gatsby-core-utils`) diff --git a/packages/gatsby/src/schema/__tests__/queries.js b/packages/gatsby/src/schema/__tests__/queries.js index e39cfe0fe4b71..125da22330b98 100644 --- a/packages/gatsby/src/schema/__tests__/queries.js +++ b/packages/gatsby/src/schema/__tests__/queries.js @@ -3,7 +3,6 @@ const { store } = require(`../../redux`) const { actions } = require(`../../redux/actions`) const { build } = require(`..`) const withResolverContext = require(`../context`) -require(`../../db/__tests__/fixtures/ensure-loki`)() jest.mock(`../../utils/api-runner-node`) const apiRunnerNode = require(`../../utils/api-runner-node`) diff --git a/packages/gatsby/src/schema/__tests__/rebuild-schema.js b/packages/gatsby/src/schema/__tests__/rebuild-schema.js index c9a0900ca993f..8a21f49c91627 100644 --- a/packages/gatsby/src/schema/__tests__/rebuild-schema.js +++ b/packages/gatsby/src/schema/__tests__/rebuild-schema.js @@ -11,7 +11,6 @@ const { store } = require(`../../redux`) const { actions } = require(`../../redux/actions`) const { build, rebuild } = require(`..`) const { buildObjectType } = require(`../types/type-builders`) -require(`../../db/__tests__/fixtures/ensure-loki`)() jest.mock(`../../utils/api-runner-node`) diff --git a/packages/gatsby/src/schema/__tests__/rebuild-sitepage-type.js b/packages/gatsby/src/schema/__tests__/rebuild-sitepage-type.js index bfee55d5eff93..aaf3e86355777 100644 --- a/packages/gatsby/src/schema/__tests__/rebuild-sitepage-type.js +++ b/packages/gatsby/src/schema/__tests__/rebuild-sitepage-type.js @@ -1,6 +1,5 @@ const { store } = require(`../../redux`) const { build, rebuildWithSitePage } = require(`..`) -require(`../../db/__tests__/fixtures/ensure-loki`)() jest.mock(`gatsby-cli/lib/reporter`, () => { return { diff --git a/packages/gatsby/src/schema/__tests__/run-query.js b/packages/gatsby/src/schema/__tests__/run-query.js index ddbcf2ca86d27..34205982bef6a 100644 --- a/packages/gatsby/src/schema/__tests__/run-query.js +++ b/packages/gatsby/src/schema/__tests__/run-query.js @@ -2,9 +2,6 @@ const { runQuery: nodesQuery } = require(`../../db/nodes`) const { store } = require(`../../redux`) const { actions } = require(`../../redux/actions`) -// Note: loki does not match redux in certain node cases in this file -const IS_LOKI = require(`../../db/__tests__/fixtures/ensure-loki`)() - const makeNodesUneven = () => [ // Note: This is assumed to be an uneven node count { @@ -282,9 +279,6 @@ async function runFilterOnCache(filter, filtersCache) { } it(`should use the cache argument`, async () => { - // Loki does not use this system at all - if (IS_LOKI) return - const filtersCache = new Map() const [result] = await runFilterOnCache({ hair: { eq: 2 } }, filtersCache) @@ -421,8 +415,6 @@ it(`should use the cache argument`, async () => { }) it(`does not coerce numbers against single-element arrays`, async () => { - if (IS_LOKI) return - const needle = `8` // note: `('8' == [8]) === true` const [result] = await runFilter({ singleArray: { eq: needle }, @@ -435,8 +427,6 @@ it(`should use the cache argument`, async () => { describe(`$ne`, () => { it(`handles ne operator`, async () => { - if (IS_LOKI) return - const needle = 2 const [result, allNodes] = await runFilter({ hair: { ne: needle } }) @@ -448,8 +438,6 @@ it(`should use the cache argument`, async () => { }) it(`coerces number to string`, async () => { - if (IS_LOKI) return - const needle = 2 // Note: `id` is a numstr const [result, allNodes] = await runFilter({ id: { ne: needle } }) @@ -462,8 +450,6 @@ it(`should use the cache argument`, async () => { // This test causes a stack overflow right now it.skip(`dpes not coerce string to number`, async () => { - if (IS_LOKI) return - const needle = `2` // Note: `id` is a numstr const [result] = await runFilter({ id: { hair: needle } }) @@ -506,8 +492,6 @@ it(`should use the cache argument`, async () => { }) it(`handles ne operator with null`, async () => { - if (IS_LOKI) return - const needle = 0 const [result, allNodes] = await runFilter({ nil: { ne: needle } }) @@ -573,8 +557,6 @@ it(`should use the cache argument`, async () => { }) async function confirmPosition(allNodes, needle) { - if (IS_LOKI) return - const result = await runQuery( { filter: { exh: { lt: needle } } }, createFiltersCache(), @@ -642,8 +624,6 @@ it(`should use the cache argument`, async () => { }) it(`handles lt operator with null`, async () => { - if (IS_LOKI) return - const needle = null const [result, allNodes] = await runFilter({ nil: { lt: needle } }) @@ -669,8 +649,6 @@ it(`should use the cache argument`, async () => { }) async function confirmPosition(allNodes, needle) { - if (IS_LOKI) return - const result = await runQuery( { filter: { exh: { lte: needle } } }, createFiltersCache(), @@ -738,8 +716,6 @@ it(`should use the cache argument`, async () => { }) it(`handles lte operator with null`, async () => { - if (IS_LOKI) return - const needle = null const [result, allNodes] = await runFilter({ nil: { lte: needle } }) @@ -765,8 +741,6 @@ it(`should use the cache argument`, async () => { }) async function confirmPosition(allNodes, needle) { - if (IS_LOKI) return - const result = await runQuery( { filter: { exh: { gt: needle } } }, createFiltersCache(), @@ -834,8 +808,6 @@ it(`should use the cache argument`, async () => { }) it(`handles gt operator with null`, async () => { - if (IS_LOKI) return - const needle = null const [result, allNodes] = await runFilter({ nil: { gt: needle } }) @@ -861,8 +833,6 @@ it(`should use the cache argument`, async () => { }) async function confirmPosition(allNodes, needle) { - if (IS_LOKI) return - const result = await runQuery( { filter: { exh: { gte: needle } } }, createFiltersCache(), @@ -930,8 +900,6 @@ it(`should use the cache argument`, async () => { }) it(`handles gte operator with null`, async () => { - if (IS_LOKI) return - const needle = null const [result, allNodes] = await runFilter({ nil: { gte: needle } }) @@ -999,8 +967,6 @@ it(`should use the cache argument`, async () => { }) it(`does not match double quote for string without it`, async () => { - if (IS_LOKI) return - const [result, allNodes] = await runFilter({ name: { regex: `/"/` } }) expect(result).toEqual(null) @@ -1053,8 +1019,6 @@ it(`should use the cache argument`, async () => { }) it(`handles the in operator for just null`, async () => { - if (IS_LOKI) return - const [result, allNodes] = await runFilter({ nil: { in: [null] } }) // Do not include the nodes without a `nil` property @@ -1070,8 +1034,6 @@ it(`should use the cache argument`, async () => { }) it(`handles the in operator for double null`, async () => { - if (IS_LOKI) return - const [result, allNodes] = await runFilter({ nil: { in: [null, null] }, }) @@ -1089,8 +1051,6 @@ it(`should use the cache argument`, async () => { }) it(`handles the in operator for null in int and null`, async () => { - if (IS_LOKI) return - const [result, allNodes] = await runFilter({ nil: { in: [5, null] } }) // Include the nodes without a `nil` property @@ -1264,8 +1224,6 @@ it(`should use the cache argument`, async () => { }) it(`ignores the elemMatch operator on a partial sub tree`, async () => { - if (IS_LOKI) return - const [result] = await runFilter({ singleElem: { things: { @@ -1326,8 +1284,6 @@ it(`should use the cache argument`, async () => { }) it(`works for elemMatch on boolean field`, async () => { - if (IS_LOKI) return - const [result] = await runFilter({ boolean: { elemMatch: { @@ -1342,8 +1298,6 @@ it(`should use the cache argument`, async () => { }) it(`skips nodes without the field for elemMatch on boolean`, async () => { - if (IS_LOKI) return - const [result] = await runFilter({ boolSecondOnly: { elemMatch: { @@ -1358,8 +1312,6 @@ it(`should use the cache argument`, async () => { }) it(`works for elemMatch on string field`, async () => { - if (IS_LOKI) return - const [result] = await runFilter({ string: { elemMatch: { @@ -1374,8 +1326,6 @@ it(`should use the cache argument`, async () => { }) it(`should return all nodes for elemMatch on non-arrays too`, async () => { - if (IS_LOKI) return - const [result] = await runFilter({ name: { elemMatch: { @@ -1392,8 +1342,6 @@ it(`should use the cache argument`, async () => { }) it(`skips nodes without the field for elemMatch on string`, async () => { - if (IS_LOKI) return - const [result] = await runFilter({ strSecondOnly: { elemMatch: { @@ -1408,8 +1356,6 @@ it(`should use the cache argument`, async () => { }) it(`works for elemMatch on number field`, async () => { - if (IS_LOKI) return - const [result] = await runFilter({ float: { elemMatch: { @@ -1443,8 +1389,6 @@ it(`should use the cache argument`, async () => { }) it(`handles the nin operator for array [null]`, async () => { - if (IS_LOKI) return - const [result] = await runFilter({ nullArray: { nin: [null] }, }) @@ -1503,8 +1447,6 @@ it(`should use the cache argument`, async () => { }) it(`handles the nin operator for double null`, async () => { - if (IS_LOKI) return - const [result] = await runFilter({ nil: { nin: [null, null] }, }) @@ -1519,8 +1461,6 @@ it(`should use the cache argument`, async () => { }) it(`handles the nin operator for null in int+null`, async () => { - if (IS_LOKI) return - const [result] = await runFilter({ nil: { nin: [5, null] }, }) diff --git a/packages/gatsby/src/schema/extensions/__tests__/child-relations.js b/packages/gatsby/src/schema/extensions/__tests__/child-relations.js index 36e2ae55c38a6..2c02e441ff717 100644 --- a/packages/gatsby/src/schema/extensions/__tests__/child-relations.js +++ b/packages/gatsby/src/schema/extensions/__tests__/child-relations.js @@ -6,7 +6,6 @@ const { store } = require(`../../../redux`) const { dispatch } = store const { actions } = require(`../../../redux/actions`) const { createTypes } = actions -require(`../../../db/__tests__/fixtures/ensure-loki`)() const report = require(`gatsby-cli/lib/reporter`) report.error = jest.fn() diff --git a/packages/gatsby/src/schema/extensions/__tests__/field-extensions.js b/packages/gatsby/src/schema/extensions/__tests__/field-extensions.js index bf3cc4f9ed727..3e20eebb9cd6f 100644 --- a/packages/gatsby/src/schema/extensions/__tests__/field-extensions.js +++ b/packages/gatsby/src/schema/extensions/__tests__/field-extensions.js @@ -6,7 +6,6 @@ const { store } = require(`../../../redux`) const { actions } = require(`../../../redux/actions`) const { dispatch } = store const { createFieldExtension, createTypes } = actions -require(`../../../db/__tests__/fixtures/ensure-loki`)() const report = require(`gatsby-cli/lib/reporter`) report.error = jest.fn() diff --git a/packages/gatsby/src/schema/extensions/__tests__/interfaces.js b/packages/gatsby/src/schema/extensions/__tests__/interfaces.js index c9bb8dc1589f9..962024d6f5292 100644 --- a/packages/gatsby/src/schema/extensions/__tests__/interfaces.js +++ b/packages/gatsby/src/schema/extensions/__tests__/interfaces.js @@ -9,7 +9,6 @@ const { store } = require(`../../../redux`) const { dispatch } = store const { actions } = require(`../../../redux/actions`) const { createTypes, createFieldExtension } = actions -require(`../../../db/__tests__/fixtures/ensure-loki`)() const report = require(`gatsby-cli/lib/reporter`) report.panic = jest.fn() diff --git a/packages/gatsby/src/schema/infer/__tests__/infer-input.js b/packages/gatsby/src/schema/infer/__tests__/infer-input.js index 6ef4a83442bdb..10ab274167c45 100644 --- a/packages/gatsby/src/schema/infer/__tests__/infer-input.js +++ b/packages/gatsby/src/schema/infer/__tests__/infer-input.js @@ -8,7 +8,6 @@ const nodeStore = require(`../../../db/nodes`) const { store } = require(`../../../redux`) const { actions } = require(`../../../redux/actions`) import { createPageDependency } from "../../../redux/actions/add-page-dependency" -require(`../../../db/__tests__/fixtures/ensure-loki`)() jest.mock(`gatsby-cli/lib/reporter`, () => { return { diff --git a/packages/gatsby/src/schema/infer/__tests__/infer.js b/packages/gatsby/src/schema/infer/__tests__/infer.js index 5bf536f620f66..c53bd55cf347a 100644 --- a/packages/gatsby/src/schema/infer/__tests__/infer.js +++ b/packages/gatsby/src/schema/infer/__tests__/infer.js @@ -12,7 +12,6 @@ const { buildObjectType } = require(`../../types/type-builders`) const { hasNodes } = require(`../inference-metadata`) const { TypeConflictReporter } = require(`../type-conflict-reporter`) const withResolverContext = require(`../../context`) -require(`../../../db/__tests__/fixtures/ensure-loki`)() jest.mock(`gatsby-cli/lib/reporter`, () => { return { diff --git a/packages/gatsby/src/schema/infer/__tests__/merge-types.js b/packages/gatsby/src/schema/infer/__tests__/merge-types.js index 1859c65f52a95..b39f583672a4e 100644 --- a/packages/gatsby/src/schema/infer/__tests__/merge-types.js +++ b/packages/gatsby/src/schema/infer/__tests__/merge-types.js @@ -2,7 +2,6 @@ const { buildObjectType } = require(`../../types/type-builders`) const { store } = require(`../../../redux`) const { build } = require(`../..`) const { actions } = require(`../../../redux/actions`) -require(`../../../db/__tests__/fixtures/ensure-loki`)() jest.mock(`gatsby-cli/lib/reporter`, () => { return { diff --git a/packages/gatsby/src/schema/types/__tests__/date.js b/packages/gatsby/src/schema/types/__tests__/date.js index 7afe95b5802df..391a26f230c00 100644 --- a/packages/gatsby/src/schema/types/__tests__/date.js +++ b/packages/gatsby/src/schema/types/__tests__/date.js @@ -3,7 +3,6 @@ const { actions } = require(`../../../redux/actions`) const { build } = require(`../..`) const withResolverContext = require(`../../context`) const { isDate, looksLikeADate } = require(`../date`) -require(`../../../db/__tests__/fixtures/ensure-loki`)() jest.mock(`gatsby-cli/lib/reporter`, () => { return { diff --git a/packages/gatsby/src/schema/types/__tests__/filter-input.js b/packages/gatsby/src/schema/types/__tests__/filter-input.js index 5157ed0c059c3..62631b79fa013 100644 --- a/packages/gatsby/src/schema/types/__tests__/filter-input.js +++ b/packages/gatsby/src/schema/types/__tests__/filter-input.js @@ -1,7 +1,6 @@ const { build } = require(`../..`) const { store } = require(`../../../redux`) const { actions } = require(`../../../redux/actions`) -require(`../../../db/__tests__/fixtures/ensure-loki`)() jest.mock(`gatsby-cli/lib/reporter`, () => { return { diff --git a/starters/blog/package-lock.json b/starters/blog/package-lock.json index bab0509268b96..8a42faf90a47f 100644 --- a/starters/blog/package-lock.json +++ b/starters/blog/package-lock.json @@ -8449,7 +8449,6 @@ "json-stringify-safe": "^5.0.1", "latest-version": "5.1.0", "lodash": "^4.17.15", - "lokijs": "^1.5.8", "md5": "^2.2.1", "md5-file": "^3.2.3", "micromatch": "^3.1.10", @@ -12550,11 +12549,6 @@ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==" }, - "lokijs": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.8.tgz", - "integrity": "sha512-D8E3TBrY35o1ELnonp2MF8b3wKu2tVNl2TqRjvS+95oPMMe7OoIAxNY1qr+5BEZwnWn2V4ErAjVt000DonM+FA==" - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", diff --git a/starters/default/package-lock.json b/starters/default/package-lock.json index 29fc97880ef8b..76cba7cc7120a 100644 --- a/starters/default/package-lock.json +++ b/starters/default/package-lock.json @@ -8372,7 +8372,6 @@ "json-stringify-safe": "^5.0.1", "latest-version": "5.1.0", "lodash": "^4.17.15", - "lokijs": "^1.5.8", "md5": "^2.2.1", "md5-file": "^3.2.3", "micromatch": "^3.1.10", @@ -11836,11 +11835,6 @@ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==" }, - "lokijs": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.8.tgz", - "integrity": "sha512-D8E3TBrY35o1ELnonp2MF8b3wKu2tVNl2TqRjvS+95oPMMe7OoIAxNY1qr+5BEZwnWn2V4ErAjVt000DonM+FA==" - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", diff --git a/starters/gatsby-starter-blog-theme-core/package-lock.json b/starters/gatsby-starter-blog-theme-core/package-lock.json index 819bdfec931db..98a2d31c0bdb9 100644 --- a/starters/gatsby-starter-blog-theme-core/package-lock.json +++ b/starters/gatsby-starter-blog-theme-core/package-lock.json @@ -8394,7 +8394,6 @@ "json-stringify-safe": "^5.0.1", "latest-version": "5.1.0", "lodash": "^4.17.15", - "lokijs": "^1.5.8", "md5": "^2.2.1", "md5-file": "^3.2.3", "micromatch": "^3.1.10", @@ -12200,11 +12199,6 @@ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==" }, - "lokijs": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.8.tgz", - "integrity": "sha512-D8E3TBrY35o1ELnonp2MF8b3wKu2tVNl2TqRjvS+95oPMMe7OoIAxNY1qr+5BEZwnWn2V4ErAjVt000DonM+FA==" - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", diff --git a/starters/gatsby-starter-blog-theme/package-lock.json b/starters/gatsby-starter-blog-theme/package-lock.json index 1317d8d5aa0a3..f9acd15d3c504 100644 --- a/starters/gatsby-starter-blog-theme/package-lock.json +++ b/starters/gatsby-starter-blog-theme/package-lock.json @@ -8576,7 +8576,6 @@ "json-stringify-safe": "^5.0.1", "latest-version": "5.1.0", "lodash": "^4.17.15", - "lokijs": "^1.5.8", "md5": "^2.2.1", "md5-file": "^3.2.3", "micromatch": "^3.1.10", @@ -12470,11 +12469,6 @@ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==" }, - "lokijs": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.8.tgz", - "integrity": "sha512-D8E3TBrY35o1ELnonp2MF8b3wKu2tVNl2TqRjvS+95oPMMe7OoIAxNY1qr+5BEZwnWn2V4ErAjVt000DonM+FA==" - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", diff --git a/starters/gatsby-starter-notes-theme/package-lock.json b/starters/gatsby-starter-notes-theme/package-lock.json index 032967d4cd15c..de43edb86487e 100644 --- a/starters/gatsby-starter-notes-theme/package-lock.json +++ b/starters/gatsby-starter-notes-theme/package-lock.json @@ -7196,7 +7196,6 @@ "json-stringify-safe": "^5.0.1", "latest-version": "5.1.0", "lodash": "^4.17.15", - "lokijs": "^1.5.8", "md5": "^2.2.1", "md5-file": "^3.2.3", "micromatch": "^3.1.10", @@ -10520,11 +10519,6 @@ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==" }, - "lokijs": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.8.tgz", - "integrity": "sha512-D8E3TBrY35o1ELnonp2MF8b3wKu2tVNl2TqRjvS+95oPMMe7OoIAxNY1qr+5BEZwnWn2V4ErAjVt000DonM+FA==" - }, "longest-streak": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", diff --git a/starters/gatsby-starter-theme/package-lock.json b/starters/gatsby-starter-theme/package-lock.json index 16fe2c6fc0274..5e5cc860d3f42 100644 --- a/starters/gatsby-starter-theme/package-lock.json +++ b/starters/gatsby-starter-theme/package-lock.json @@ -8576,7 +8576,6 @@ "json-stringify-safe": "^5.0.1", "latest-version": "5.1.0", "lodash": "^4.17.15", - "lokijs": "^1.5.8", "md5": "^2.2.1", "md5-file": "^3.2.3", "micromatch": "^3.1.10", @@ -12558,11 +12557,6 @@ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==" }, - "lokijs": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.8.tgz", - "integrity": "sha512-D8E3TBrY35o1ELnonp2MF8b3wKu2tVNl2TqRjvS+95oPMMe7OoIAxNY1qr+5BEZwnWn2V4ErAjVt000DonM+FA==" - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", diff --git a/starters/hello-world/package-lock.json b/starters/hello-world/package-lock.json index 84b22119a61ed..5d3c7de6f8316 100644 --- a/starters/hello-world/package-lock.json +++ b/starters/hello-world/package-lock.json @@ -6878,7 +6878,6 @@ "json-stringify-safe": "^5.0.1", "latest-version": "5.1.0", "lodash": "^4.17.15", - "lokijs": "^1.5.8", "md5": "^2.2.1", "md5-file": "^3.2.3", "micromatch": "^3.1.10", @@ -9834,11 +9833,6 @@ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==" }, - "lokijs": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.8.tgz", - "integrity": "sha512-D8E3TBrY35o1ELnonp2MF8b3wKu2tVNl2TqRjvS+95oPMMe7OoIAxNY1qr+5BEZwnWn2V4ErAjVt000DonM+FA==" - }, "longest-streak": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", diff --git a/yarn.lock b/yarn.lock index ebe21279be120..abdcdf61ba486 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16109,11 +16109,6 @@ loglevel@^1.6.6: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.7.tgz#b3e034233188c68b889f5b862415306f565e2c56" integrity sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A== -lokijs@^1.5.8: - version "1.5.8" - resolved "https://registry.yarnpkg.com/lokijs/-/lokijs-1.5.8.tgz#9296f288edb2147389ec692fc972c428c59179d1" - integrity sha512-D8E3TBrY35o1ELnonp2MF8b3wKu2tVNl2TqRjvS+95oPMMe7OoIAxNY1qr+5BEZwnWn2V4ErAjVt000DonM+FA== - longest-streak@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-1.0.0.tgz#d06597c4d4c31b52ccb1f5d8f8fe7148eafd6965"