optimize buildFieldMapsFromFlatObjectMetadata usages (#16132)

This newly introduced util can be a bit expensive especially when done
recursively.
This PR improves that


File | Pattern Fixed | Impact
-- | -- | --
format-result.util.ts | Recursive array/object processing | N array
items → 1 call
format-data.util.ts | Recursive array processing | N array items → 1
call
process-nested-relations-v2.helper.ts | Duplicate call in call chain | 2
calls → 1 call
common-result-getters.service.ts | Per-record processing in array | N
records → 1 call
compute-relation-connect-query-configs.util.ts | Nested loop (entities ×
connect fields) | N×M calls → 1 call
This commit is contained in:
Weiko
2025-11-27 15:01:51 +01:00
committed by GitHub
parent 27547fd445
commit da626f70b7
6 changed files with 89 additions and 46 deletions
@@ -9,7 +9,10 @@ import { getFlatFieldsFromFlatObjectMetadata } from 'src/engine/api/graphql/work
import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util';
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util';
import {
buildFieldMapsFromFlatObjectMetadata,
type FieldMapsForObject,
} from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util';
import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { type ConnectObject } from 'src/engine/twenty-orm/entity-manager/types/query-deep-partial-entity-with-nested-relation-fields.type';
@@ -36,6 +39,11 @@ export const computeRelationConnectQueryConfigs = (
) => {
const allConnectQueryConfigs: Record<string, RelationConnectQueryConfig> = {};
const fieldMaps = buildFieldMapsFromFlatObjectMetadata(
flatFieldMetadataMaps,
flatObjectMetadata,
);
for (const [entityIndex, entity] of entities.entries()) {
const nestedRelationConnectFields =
relationConnectQueryFieldsByEntityIndex[entityIndex];
@@ -57,6 +65,7 @@ export const computeRelationConnectQueryConfigs = (
flatFieldMetadataMaps,
flatIndexMaps,
entity,
fieldMaps,
);
const connectQueryConfig = allConnectQueryConfigs[connectFieldName];
@@ -132,17 +141,14 @@ const computeRecordToConnectCondition = (
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>,
flatIndexMaps: FlatEntityMaps<FlatIndexMetadata>,
entity: Record<string, unknown>,
fieldMaps: FieldMapsForObject,
): {
recordToConnectCondition: UniqueConstraintCondition;
uniqueConstraintFields: FlatFieldMetadata<FieldMetadataType>[];
targetObjectNameSingular: string;
} => {
const { fieldIdByName } = buildFieldMapsFromFlatObjectMetadata(
flatFieldMetadataMaps,
flatObjectMetadata,
);
const field = flatFieldMetadataMaps.byId[fieldIdByName[connectFieldName]];
const field =
flatFieldMetadataMaps.byId[fieldMaps.fieldIdByName[connectFieldName]];
if (
!isDefined(field) ||
@@ -7,7 +7,10 @@ import { capitalize } from 'twenty-shared/utils';
import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util';
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util';
import {
buildFieldMapsFromFlatObjectMetadata,
type FieldMapsForObject,
} from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { type CompositeFieldMetadataType } from 'src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory';
@@ -15,23 +18,27 @@ export function formatData<T>(
data: T,
flatObjectMetadata: FlatObjectMetadata,
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>,
fieldMapsForObject?: FieldMapsForObject,
): T {
if (!data) {
return data;
}
if (Array.isArray(data)) {
return data.map((item) =>
formatData(item, flatObjectMetadata, flatFieldMetadataMaps),
) as T;
}
const { fieldIdByName, fieldIdByJoinColumnName } =
const fieldMaps =
fieldMapsForObject ??
buildFieldMapsFromFlatObjectMetadata(
flatFieldMetadataMaps,
flatObjectMetadata,
);
if (Array.isArray(data)) {
return data.map((item) =>
formatData(item, flatObjectMetadata, flatFieldMetadataMaps, fieldMaps),
) as T;
}
const { fieldIdByName, fieldIdByJoinColumnName } = fieldMaps;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const newData: Record<string, any> = {};
@@ -16,7 +16,10 @@ import { getFlatFieldsFromFlatObjectMetadata } from 'src/engine/api/graphql/work
import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { buildFieldMapsFromFlatObjectMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util';
import {
buildFieldMapsFromFlatObjectMetadata,
type FieldMapsForObject,
} from 'src/engine/metadata-modules/flat-field-metadata/utils/build-field-maps-from-flat-object-metadata.util';
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
import { getCompositeFieldMetadataCollection } from 'src/engine/twenty-orm/utils/get-composite-field-metadata-collection';
import { isFieldMetadataEntityOfType } from 'src/engine/utils/is-field-metadata-of-type.util';
@@ -27,23 +30,25 @@ export function formatResult<T>(
flatObjectMetadata: FlatObjectMetadata | undefined,
flatObjectMetadataMaps: FlatEntityMaps<FlatObjectMetadata>,
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>,
fieldMapsForObject?: FieldMapsForObject,
): T {
if (!isDefined(data)) {
return data;
}
if (Array.isArray(data)) {
return data.map((item) =>
formatResult(
item,
flatObjectMetadata,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
),
) as T;
}
if (!isPlainObject(data)) {
if (Array.isArray(data)) {
return data.map((item) =>
formatResult(
item,
flatObjectMetadata,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
fieldMapsForObject,
),
) as T;
}
return data;
}
@@ -51,10 +56,14 @@ export function formatResult<T>(
throw new Error('Object metadata is missing');
}
const { fieldIdByName } = buildFieldMapsFromFlatObjectMetadata(
flatFieldMetadataMaps,
flatObjectMetadata,
);
const fieldMaps =
fieldMapsForObject ??
buildFieldMapsFromFlatObjectMetadata(
flatFieldMetadataMaps,
flatObjectMetadata,
);
const { fieldIdByName } = fieldMaps;
const compositeFieldMetadataMap = getCompositeFieldMetadataMap(
flatObjectMetadata,
@@ -86,6 +95,7 @@ export function formatResult<T>(
flatObjectMetadata,
flatObjectMetadataMaps,
flatFieldMetadataMaps,
fieldMaps,
);
} else if (fieldMetadata) {
// @ts-expect-error legacy noImplicitAny