Skip to content

Commit

Permalink
perf(gatsby): add a way to skip tracking inline objects (#38805)
Browse files Browse the repository at this point in the history
add new flag for nodes from external sources to prevent unnecessary data loops

---------

Co-authored-by: Michal Piechowiak <misiek.piechowiak@gmail.com>
  • Loading branch information
axe312ger and pieh authored Feb 29, 2024
1 parent 2c364df commit 1ce2026
Show file tree
Hide file tree
Showing 14 changed files with 78 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ jobs:
nvm install 18.0.0
nvm alias default 18.0.0
nvm use 18.0.0
choco install yarn
choco install yarn -y
- run:
name: Rebuild packages for windows
command: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -744,12 +744,15 @@ Ignored if layout = FLUID.",
},
"linkedFrom": "ContentfulLinkedFrom",
"richText": Object {
"resolve": [Function],
"type": "ContentfulRichText",
},
"richTextLocalized": Object {
"resolve": [Function],
"type": "ContentfulRichText",
},
"richTextValidated": Object {
"resolve": [Function],
"type": "ContentfulRichText",
},
"sys": Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {
GatsbyNode,
NodePluginSchema,
CreateSchemaCustomizationArgs,
IGatsbyResolverContext,
} from "gatsby"
import {
GraphQLFieldConfig,
Expand Down Expand Up @@ -31,15 +32,29 @@ import type {
} from "./types/contentful"
import { detectMarkdownField, makeContentTypeIdMap } from "./utils"
import { restrictedNodeFields } from "./config"
import { Document } from "@contentful/rich-text-types"

type CreateTypes = CreateSchemaCustomizationArgs["actions"]["createTypes"]

interface IContentfulGraphQLField
extends Omit<Partial<GraphQLFieldConfig<unknown, unknown>>, "type"> {
extends Omit<
Partial<
GraphQLFieldConfig<
IContentfulEntry,
IGatsbyResolverContext<IContentfulEntry, unknown>
>
>,
"type"
> {
type: string | GraphQLType
id?: string
}

interface IRichTextFieldStructure {
richTextData: Document
spaceId: string
}

// Contentful content type schemas
const ContentfulDataTypes: Map<
string,
Expand Down Expand Up @@ -112,7 +127,18 @@ const ContentfulDataTypes: Map<
[
`RichText`,
(): IContentfulGraphQLField => {
return { type: `ContentfulRichText` }
return {
type: `ContentfulRichText`,
resolve: (source, args, context, info): IRichTextFieldStructure => {
const richTextData = context.defaultFieldResolver(
source,
args,
context,
info
)
return { richTextData, spaceId: source.sys.spaceId }
},
}
},
],
])
Expand Down Expand Up @@ -599,16 +625,13 @@ export const createSchemaCustomization: GatsbyNode["createSchemaCustomization"]
const makeRichTextLinksResolver =
(nodeType, entityType) =>
async (
source,
source: IRichTextFieldStructure,
_args,
context
): Promise<Array<IContentfulEntry> | null> => {
const links = getRichTextEntityLinks(source, nodeType)[entityType].map(
({ id }) => id
)

const node = context.nodeModel.findRootNodeAncestor(source)
if (!node) return null
const links = getRichTextEntityLinks(source.richTextData, nodeType)[
entityType
].map(({ id }) => id)

const res = await context.nodeModel.findAll({
query: {
Expand All @@ -617,7 +640,7 @@ export const createSchemaCustomization: GatsbyNode["createSchemaCustomization"]
id: {
in: links,
},
spaceId: { eq: node.sys.spaceId },
spaceId: { eq: source.spaceId },
},
},
},
Expand Down Expand Up @@ -693,8 +716,8 @@ export const createSchemaCustomization: GatsbyNode["createSchemaCustomization"]
fields: {
json: {
type: `JSON`,
resolve(source) {
return source
resolve(source: IRichTextFieldStructure) {
return source.richTextData
},
},
links: {
Expand Down
12 changes: 12 additions & 0 deletions packages/gatsby-source-contentful/src/gatsby-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { GatsbyNode } from "gatsby"
import origFetch from "node-fetch"
import fetchRetry from "@vercel/fetch-retry"
import { polyfillImageServiceDevRoutes } from "gatsby-plugin-utils/polyfill-remote-file"
import { hasFeature } from "gatsby-plugin-utils/has-feature"

import { CODES } from "./report"
import { maskText } from "./plugin-options"
Expand Down Expand Up @@ -47,6 +48,17 @@ export const onPreInit: GatsbyNode["onPreInit"] = async (
{ store, reporter, actions },
pluginOptions
) => {
// gatsby version is too old
if (!hasFeature(`track-inline-object-opt-out`)) {
reporter.panic({
id: CODES.GatsbyPluginMissing,
context: {
// TODO update message to reflect the actual version with track-inline-object-opt-out support
sourceMessage: `Used gatsby version is too old and doesn't support required features. Please update to gatsby@>=5.X.0`,
},
})
}

// if gatsby-plugin-image is not installed
try {
await import(`gatsby-plugin-image/graphql-utils.js`)
Expand Down
2 changes: 2 additions & 0 deletions packages/gatsby-source-contentful/src/normalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,7 @@ export const createNodesForContentType = ({
type: makeTypeName(contentTypeItemId, contentTypePrefix),
// The content of an entry is guaranteed to be updated if and only if the .sys.updatedAt field changed
contentDigest: entryItem.sys.updatedAt as string,
trackInlineObjects: false,
},
// https://www.contentful.com/developers/docs/references/content-delivery-api/#/introduction/common-resource-attributes
// https://www.contentful.com/developers/docs/references/graphql/#/reference/schema-generation/sys-field
Expand Down Expand Up @@ -944,6 +945,7 @@ export const createAssetNodes = async ({
type: `ContentfulAsset`,
// The content of an asset is guaranteed to be updated if and only if the .sys.updatedAt field changed
contentDigest: assetItem.sys.updatedAt,
trackInlineObjects: false,
},
// https://www.contentful.com/developers/docs/references/content-delivery-api/#/introduction/common-resource-attributes
// https://www.contentful.com/developers/docs/references/graphql/#/reference/schema-generation/sys-field
Expand Down
6 changes: 6 additions & 0 deletions packages/gatsby-source-contentful/src/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const CODES = {
ContentTypesMissing: `111006`,
FetchTags: `111007`,
GenericContentfulError: `111008`,
GatsbyTooOld: `111009`,
}

interface IErrorMap {
Expand Down Expand Up @@ -57,4 +58,9 @@ export const ERROR_MAP: IErrorMap = {
level: `ERROR`,
category: `THIRD_PARTY`,
},
[CODES.GatsbyTooOld]: {
text: context => context.sourceMessage,
level: `ERROR`,
category: `USER`,
},
}
4 changes: 4 additions & 0 deletions packages/gatsby/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export type AvailableFeatures =
| "content-file-path"
| "stateful-source-nodes"
| "adapters"
| "track-inline-object-opt-out"

export {
Link,
Expand All @@ -34,6 +35,8 @@ export {

export * from "gatsby-script"

export { IGatsbyResolverContext } from "./dist/schema/type-definitions"

export {
AdapterInit,
IAdapter,
Expand Down Expand Up @@ -1777,6 +1780,7 @@ export interface NodeInput {
contentDigest: string
description?: string
contentFilePath?: string
trackInlineObjects?: boolean
}
[key: string]: unknown
}
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby/scripts/__tests__/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ it("generates the expected api output", done => {
"slices",
"stateful-source-nodes",
"adapters",
"track-inline-object-opt-out",
],
"node": Object {
"createPages": Object {},
Expand Down
2 changes: 1 addition & 1 deletion packages/gatsby/scripts/output-api-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ async function outputFile() {
}, {})

/** @type {Array<import("../index").AvailableFeatures>} */
output.features = ["image-cdn", "graphql-typegen", "content-file-path", "slices", "stateful-source-nodes", "adapters"];
output.features = ["image-cdn", "graphql-typegen", "content-file-path", "slices", "stateful-source-nodes", "adapters", "track-inline-object-opt-out"];

return fs.writeFile(
path.resolve(OUTPUT_FILE_NAME),
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby/src/joi-schemas/joi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ export const nodeSchema: Joi.ObjectSchema<IGatsbyNode> = Joi.object()
ignoreType: Joi.boolean(),
counter: Joi.number(),
contentFilePath: Joi.string(),
trackInlineObjects: Joi.boolean(),
})
.unknown(false), // Don't allow non-standard fields
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2016,6 +2016,7 @@ type Internal {
owner: String!
type: String!
contentFilePath: String
trackInlineObjects: Boolean
}
\\"\\"\\"
Expand Down Expand Up @@ -2356,6 +2357,7 @@ input InternalFilterInput {
owner: StringQueryOperatorInput
type: StringQueryOperatorInput
contentFilePath: StringQueryOperatorInput
trackInlineObjects: BooleanQueryOperatorInput
}
input BooleanQueryOperatorInput {
Expand Down Expand Up @@ -2452,6 +2454,7 @@ input InternalFieldSelector {
owner: FieldSelectorEnum
type: FieldSelectorEnum
contentFilePath: FieldSelectorEnum
trackInlineObjects: FieldSelectorEnum
}
type FileGroupConnection {
Expand Down Expand Up @@ -2566,6 +2569,7 @@ input InternalSortInput {
owner: SortOrderEnum
type: SortOrderEnum
contentFilePath: SortOrderEnum
trackInlineObjects: SortOrderEnum
}
type DirectoryConnection {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ type Internal {
owner: String!
type: String!
contentFilePath: String
trackInlineObjects: Boolean
}
\\"\\"\\"
Expand Down Expand Up @@ -555,6 +556,7 @@ input InternalFilterInput {
owner: StringQueryOperatorInput
type: StringQueryOperatorInput
contentFilePath: StringQueryOperatorInput
trackInlineObjects: BooleanQueryOperatorInput
}
input BooleanQueryOperatorInput {
Expand Down Expand Up @@ -651,6 +653,7 @@ input InternalFieldSelector {
owner: FieldSelectorEnum
type: FieldSelectorEnum
contentFilePath: FieldSelectorEnum
trackInlineObjects: FieldSelectorEnum
}
type FileGroupConnection {
Expand Down Expand Up @@ -765,6 +768,7 @@ input InternalSortInput {
owner: SortOrderEnum
type: SortOrderEnum
contentFilePath: SortOrderEnum
trackInlineObjects: SortOrderEnum
}
type DirectoryConnection {
Expand Down
3 changes: 3 additions & 0 deletions packages/gatsby/src/schema/node-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,9 @@ class LocalNodeModel {
* @param {Node} node Root Node
*/
trackInlineObjectsInRootNode(node) {
if (node.internal.trackInlineObjects === false) {
return
}
if (!this._trackedRootNodes.has(node)) {
addRootNodeToInlineObject(
this._rootNodeMap,
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby/src/schema/types/node-interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const getOrCreateNodeInterface = <TSource, TArgs>(
owner: `String!`,
type: `String!`,
contentFilePath: `String`,
trackInlineObjects: `Boolean`,
})
// TODO: Can be removed with graphql-compose 5.11
tc.getInputTypeComposer()
Expand Down

0 comments on commit 1ce2026

Please sign in to comment.