perf: reduce document data deepCopying in field hooks (#10610)
A lot of this deepCopying was just not necessary. This removes the deepCopying from all field hook operations where I think it's 100% safe. It does not remove all deepCopying, especially in areas where the input data was deep copied, and that data pre-modification is then used after the field hooks have run. In these cases, further execution of the hook might be intentionally expecting the unmodified version of that input data
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import type { DeepPartial } from 'ts-essentials'
|
||||
|
||||
import type { Args } from '../../../fields/hooks/beforeChange/index.js'
|
||||
import type { AccessResult, CollectionSlug, FileToSave, SanitizedConfig } from '../../../index.js'
|
||||
import type {
|
||||
Payload,
|
||||
PayloadRequest,
|
||||
@@ -22,6 +21,13 @@ import { afterChange } from '../../../fields/hooks/afterChange/index.js'
|
||||
import { afterRead } from '../../../fields/hooks/afterRead/index.js'
|
||||
import { beforeChange } from '../../../fields/hooks/beforeChange/index.js'
|
||||
import { beforeValidate } from '../../../fields/hooks/beforeValidate/index.js'
|
||||
import {
|
||||
type AccessResult,
|
||||
type CollectionSlug,
|
||||
deepCopyObjectSimple,
|
||||
type FileToSave,
|
||||
type SanitizedConfig,
|
||||
} from '../../../index.js'
|
||||
import { deleteAssociatedFiles } from '../../../uploads/deleteAssociatedFiles.js'
|
||||
import { uploadFiles } from '../../../uploads/uploadFiles.js'
|
||||
import { checkDocumentLockStatus } from '../../../utilities/checkDocumentLockStatus.js'
|
||||
@@ -110,7 +116,7 @@ export const updateDocument = async <
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
depth: 0,
|
||||
doc: docWithLocales,
|
||||
doc: deepCopyObjectSimple(docWithLocales),
|
||||
draft: draftArg,
|
||||
fallbackLocale: id ? null : fallbackLocale,
|
||||
global: null,
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Forbidden } from '../errors/Forbidden.js'
|
||||
import { NotFound } from '../errors/NotFound.js'
|
||||
import { afterRead } from '../fields/hooks/afterRead/index.js'
|
||||
import { beforeDuplicate } from '../fields/hooks/beforeDuplicate/index.js'
|
||||
import { deepCopyObjectSimple } from '../utilities/deepCopyObject.js'
|
||||
import { getLatestCollectionVersion } from '../versions/getLatestCollectionVersion.js'
|
||||
|
||||
type GetDuplicateDocumentArgs = {
|
||||
@@ -92,7 +93,7 @@ export const getDuplicateDocumentData = async ({
|
||||
collection: collectionConfig,
|
||||
context: req.context,
|
||||
depth: 0,
|
||||
doc: duplicatedFromDocWithLocales,
|
||||
doc: deepCopyObjectSimple(duplicatedFromDocWithLocales),
|
||||
draft: draftArg,
|
||||
fallbackLocale: null,
|
||||
global: null,
|
||||
|
||||
@@ -3,7 +3,6 @@ import type { SanitizedGlobalConfig } from '../../../globals/config/types.js'
|
||||
import type { RequestContext } from '../../../index.js'
|
||||
import type { JsonObject, PayloadRequest } from '../../../types/index.js'
|
||||
|
||||
import { deepCopyObjectSimple } from '../../../utilities/deepCopyObject.js'
|
||||
import { traverseFields } from './traverseFields.js'
|
||||
|
||||
type Args<T extends JsonObject> = {
|
||||
@@ -37,13 +36,11 @@ export const afterChange = async <T extends JsonObject>({
|
||||
previousDoc,
|
||||
req,
|
||||
}: Args<T>): Promise<T> => {
|
||||
const doc = deepCopyObjectSimple(incomingDoc)
|
||||
|
||||
await traverseFields({
|
||||
collection,
|
||||
context,
|
||||
data,
|
||||
doc,
|
||||
doc: incomingDoc,
|
||||
fields: collection?.fields || global?.fields,
|
||||
global,
|
||||
operation,
|
||||
@@ -53,8 +50,8 @@ export const afterChange = async <T extends JsonObject>({
|
||||
req,
|
||||
schemaPath: [],
|
||||
siblingData: data,
|
||||
siblingDoc: doc,
|
||||
siblingDoc: incomingDoc,
|
||||
})
|
||||
|
||||
return doc
|
||||
return incomingDoc
|
||||
}
|
||||
|
||||
@@ -56,7 +56,6 @@ export async function afterRead<T extends JsonObject>(args: Args<T>): Promise<T>
|
||||
showHiddenFields,
|
||||
} = args
|
||||
|
||||
const doc = deepCopyObjectSimple(incomingDoc)
|
||||
const fieldPromises = []
|
||||
const populationPromises = []
|
||||
|
||||
@@ -75,7 +74,7 @@ export async function afterRead<T extends JsonObject>(args: Args<T>): Promise<T>
|
||||
context,
|
||||
currentDepth,
|
||||
depth,
|
||||
doc,
|
||||
doc: incomingDoc,
|
||||
draft,
|
||||
fallbackLocale,
|
||||
fieldPromises,
|
||||
@@ -93,11 +92,11 @@ export async function afterRead<T extends JsonObject>(args: Args<T>): Promise<T>
|
||||
select,
|
||||
selectMode: select ? getSelectMode(select) : undefined,
|
||||
showHiddenFields,
|
||||
siblingDoc: doc,
|
||||
siblingDoc: incomingDoc,
|
||||
})
|
||||
|
||||
await Promise.all(fieldPromises)
|
||||
await Promise.all(populationPromises)
|
||||
|
||||
return doc
|
||||
return incomingDoc
|
||||
}
|
||||
|
||||
@@ -28,20 +28,18 @@ export const beforeDuplicate = async <T extends JsonObject>({
|
||||
overrideAccess,
|
||||
req,
|
||||
}: Args<T>): Promise<T> => {
|
||||
const newDoc = deepCopyObjectSimple(doc)
|
||||
|
||||
await traverseFields({
|
||||
id,
|
||||
collection,
|
||||
context,
|
||||
doc: newDoc,
|
||||
doc,
|
||||
fields: collection?.fields,
|
||||
overrideAccess,
|
||||
path: [],
|
||||
req,
|
||||
schemaPath: [],
|
||||
siblingDoc: newDoc,
|
||||
siblingDoc: doc,
|
||||
})
|
||||
|
||||
return newDoc
|
||||
return doc
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ export const beforeValidate = async <T extends JsonObject>({
|
||||
req,
|
||||
}: Args<T>): Promise<T> => {
|
||||
const data = deepCopyObjectSimple(incomingData)
|
||||
|
||||
await traverseFields({
|
||||
id,
|
||||
collection,
|
||||
|
||||
@@ -127,7 +127,7 @@ export const updateOperation = async <
|
||||
collection: null,
|
||||
context: req.context,
|
||||
depth: 0,
|
||||
doc: globalJSON,
|
||||
doc: deepCopyObjectSimple(globalJSON),
|
||||
draft: draftArg,
|
||||
fallbackLocale,
|
||||
global: globalConfig,
|
||||
|
||||
@@ -98,7 +98,6 @@ const replaceWithDraftIfAvailable = async <T extends TypeWithID>({
|
||||
return doc
|
||||
}
|
||||
|
||||
draft = deepCopyObjectSimple(draft)
|
||||
draft = sanitizeInternalFields(draft)
|
||||
|
||||
// Patch globalType onto version doc
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import type { SanitizedGlobalConfig } from '../globals/config/types.js'
|
||||
import type { Document, Payload, PayloadRequest, Where } from '../types/index.js'
|
||||
|
||||
import { docHasTimestamps } from '../types/index.js'
|
||||
|
||||
type Args = {
|
||||
config: SanitizedGlobalConfig
|
||||
locale?: string
|
||||
|
||||
Reference in New Issue
Block a user