Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(gatsby): add a way to skip tracking inline objects #38805

Merged
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 @@ -738,12 +738,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 @@ -584,16 +610,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)
pieh marked this conversation as resolved.
Show resolved Hide resolved
if (!node) return null
const links = getRichTextEntityLinks(source.richTextData, nodeType)[
entityType
].map(({ id }) => id)

const res = await context.nodeModel.findAll({
query: {
Expand All @@ -602,7 +625,7 @@ export const createSchemaCustomization: GatsbyNode["createSchemaCustomization"]
id: {
in: links,
},
spaceId: { eq: node.sys.spaceId },
spaceId: { eq: source.spaceId },
},
},
},
Expand Down Expand Up @@ -678,8 +701,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`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be updated before the release once it's clear that Gatsby Version that will contain the addition.

For now it will mean that users will have to use gatsby@ctf-next (once new wave of canary is released that include this change) - so maybe temporarily we can use that version there whatever that will end up being?

},
})
}

// 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