@graphql-box/cache-manager 5.0.2 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/cjs/index.cjs +1 -1
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/esm/index.mjs +1 -1
  4. package/dist/esm/index.mjs.map +1 -1
  5. package/dist/production.analysis.txt +125 -96
  6. package/dist/types/cjs/helpers/createEntityDataKey.d.cts +4 -0
  7. package/dist/types/cjs/helpers/createEntityDataKey.d.cts.map +1 -0
  8. package/dist/types/cjs/helpers/filterOutPropsWithEntityArgsOrDirectives.d.cts +5 -0
  9. package/dist/types/cjs/helpers/filterOutPropsWithEntityArgsOrDirectives.d.cts.map +1 -0
  10. package/dist/types/cjs/helpers/filterOutPropsWithEntityOrArgs.d.cts +6 -0
  11. package/dist/types/cjs/helpers/filterOutPropsWithEntityOrArgs.d.cts.map +1 -0
  12. package/dist/types/cjs/helpers/isFieldEntity.d.cts +3 -0
  13. package/dist/types/cjs/helpers/isFieldEntity.d.cts.map +1 -0
  14. package/dist/types/cjs/helpers/validTypeIdValue.d.cts +1 -1
  15. package/dist/types/cjs/helpers/validTypeIdValue.d.cts.map +1 -1
  16. package/dist/types/cjs/main.d.cts +3 -5
  17. package/dist/types/cjs/main.d.cts.map +1 -1
  18. package/dist/types/cjs/types.d.cts +5 -5
  19. package/dist/types/cjs/types.d.cts.map +1 -1
  20. package/dist/types/esm/helpers/createEntityDataKey.d.ts +4 -0
  21. package/dist/types/esm/helpers/createEntityDataKey.d.ts.map +1 -0
  22. package/dist/types/esm/helpers/filterOutPropsWithEntityArgsOrDirectives.d.ts +5 -0
  23. package/dist/types/esm/helpers/filterOutPropsWithEntityArgsOrDirectives.d.ts.map +1 -0
  24. package/dist/types/esm/helpers/filterOutPropsWithEntityOrArgs.d.ts +6 -0
  25. package/dist/types/esm/helpers/filterOutPropsWithEntityOrArgs.d.ts.map +1 -0
  26. package/dist/types/esm/helpers/isFieldEntity.d.ts +3 -0
  27. package/dist/types/esm/helpers/isFieldEntity.d.ts.map +1 -0
  28. package/dist/types/esm/helpers/validTypeIdValue.d.ts +1 -1
  29. package/dist/types/esm/helpers/validTypeIdValue.d.ts.map +1 -1
  30. package/dist/types/esm/main.d.ts +3 -5
  31. package/dist/types/esm/main.d.ts.map +1 -1
  32. package/dist/types/esm/types.d.ts +5 -5
  33. package/dist/types/esm/types.d.ts.map +1 -1
  34. package/dist/types/tsconfig.build.tsbuildinfo +1 -1
  35. package/package.json +5 -5
  36. package/src/__snapshots__/index.test.ts.snap +19450 -19450
  37. package/src/helpers/createEntityDataKey.ts +11 -0
  38. package/src/helpers/filterOutPropsWithEntityArgsOrDirectives.ts +45 -0
  39. package/src/helpers/filterOutPropsWithEntityOrArgs.ts +31 -0
  40. package/src/helpers/isFieldEntity.ts +24 -0
  41. package/src/helpers/validTypeIdValue.ts +3 -3
  42. package/src/index.test.ts +153 -127
  43. package/src/main.ts +122 -179
  44. package/src/types.ts +5 -5
  45. package/dist/types/cjs/helpers/filterOutPropsWithArgsOrDirectives.d.cts +0 -6
  46. package/dist/types/cjs/helpers/filterOutPropsWithArgsOrDirectives.d.cts.map +0 -1
  47. package/dist/types/esm/helpers/filterOutPropsWithArgsOrDirectives.d.ts +0 -6
  48. package/dist/types/esm/helpers/filterOutPropsWithArgsOrDirectives.d.ts.map +0 -1
  49. package/src/helpers/filterOutPropsWithArgsOrDirectives.ts +0 -29
package/src/main.ts CHANGED
@@ -36,16 +36,19 @@ import {
36
36
  } from '@graphql-box/helpers';
37
37
  import { Cacheability } from 'cacheability';
38
38
  import { type FieldNode, Kind, OperationTypeNode, print } from 'graphql';
39
- import { assign, cloneDeep, get, isEqual, isNumber, isUndefined, set, unset } from 'lodash-es';
39
+ import { assign, get, isEqual, isNumber, isUndefined, set, unset } from 'lodash-es';
40
40
  import { CACHE_CONTROL, HEADER_NO_CACHE, METADATA, NO_CACHE } from './constants.ts';
41
41
  import { logCacheEntry, logCacheQuery, logPartialCompiled } from './debug/index.ts';
42
42
  import { areOnlyPopulatedFieldsTypeIdKeys } from './helpers/areOnlyPopulatedFieldsTypeIdKeys.ts';
43
43
  import { combineDataSets } from './helpers/combineData.ts';
44
+ import { createEntityDataKey } from './helpers/createEntityDataKey.ts';
44
45
  import { deriveOpCacheability } from './helpers/deriveOpCacheability.ts';
45
- import { filterOutPropsWithArgsOrDirectives } from './helpers/filterOutPropsWithArgsOrDirectives.ts';
46
+ import { filterOutPropsWithEntityArgsOrDirectives } from './helpers/filterOutPropsWithEntityArgsOrDirectives.ts';
47
+ import { filterOutPropsWithEntityOrArgs } from './helpers/filterOutPropsWithEntityOrArgs.ts';
46
48
  import { filterQuery } from './helpers/filterQuery.ts';
47
49
  import { getDataValue } from './helpers/getDataValue.ts';
48
50
  import { hasTypename } from './helpers/hasTypename.ts';
51
+ import { isFieldEntity } from './helpers/isFieldEntity.ts';
49
52
  import { isLastResponseChunk } from './helpers/isLastResponseChunk.ts';
50
53
  import { isNotLastResponseChunk } from './helpers/isNotLastResponseChunk.ts';
51
54
  import { isNotResponseChunk } from './helpers/isNotResponseChunk.ts';
@@ -88,7 +91,7 @@ export class CacheManager implements CacheManagerDef {
88
91
 
89
92
  private static _getFieldDataFromAncestor<T>(ancestorFieldData: unknown, propNameOrIndex: string | number) {
90
93
  const dataValue = getDataValue<T>(ancestorFieldData, propNameOrIndex);
91
- return isObjectLike(dataValue) ? cloneDeep(dataValue) : dataValue;
94
+ return isObjectLike(dataValue) ? structuredClone(dataValue) : dataValue;
92
95
  }
93
96
 
94
97
  private static _getOperationCacheControl(cacheMetadata: CacheMetadata | undefined, operation: string): string {
@@ -276,12 +279,7 @@ export class CacheManager implements CacheManagerDef {
276
279
  }
277
280
 
278
281
  if (!fieldCount.missing) {
279
- const dataCaching = this._setQueryResponseCacheEntry(hash, { cacheMetadata, data }, options, cacheManagerContext);
280
-
281
- if (options.awaitDataCaching) {
282
- await dataCaching;
283
- }
284
-
282
+ this._setQueryResponseCacheEntry(hash, { cacheMetadata, data }, options, cacheManagerContext);
285
283
  return { response: { cacheMetadata, data } };
286
284
  }
287
285
 
@@ -300,13 +298,13 @@ export class CacheManager implements CacheManagerDef {
300
298
  return this._cache;
301
299
  }
302
300
 
303
- public async cacheQuery(
301
+ public cacheQuery(
304
302
  requestData: RequestData,
305
303
  updatedRequestData: RequestData | undefined,
306
304
  rawResponseData: RawResponseDataWithMaybeCacheMetadata,
307
305
  options: RequestOptions,
308
306
  context: RequestContext
309
- ): Promise<ResponseData> {
307
+ ): ResponseData {
310
308
  const cacheManagerContext: CacheManagerContext = {
311
309
  ...context,
312
310
  fragmentDefinitions: getFragmentDefinitions((updatedRequestData ?? requestData).ast),
@@ -316,12 +314,12 @@ export class CacheManager implements CacheManagerDef {
316
314
  return this._cacheResponse(requestData, updatedRequestData, rawResponseData, options, cacheManagerContext);
317
315
  }
318
316
 
319
- public async cacheResponse(
317
+ public cacheResponse(
320
318
  requestData: RequestData,
321
319
  rawResponseData: RawResponseDataWithMaybeCacheMetadata,
322
320
  options: RequestOptions,
323
321
  context: RequestContext
324
- ): Promise<ResponseData> {
322
+ ): ResponseData {
325
323
  const cacheManagerContext: CacheManagerContext = {
326
324
  ...context,
327
325
  fragmentDefinitions: getFragmentDefinitions(requestData.ast),
@@ -363,13 +361,13 @@ export class CacheManager implements CacheManagerDef {
363
361
  this._partialQueryResponses.delete(hash);
364
362
  }
365
363
 
366
- public async setQueryResponseCacheEntry(
364
+ public setQueryResponseCacheEntry(
367
365
  requestData: RequestData,
368
366
  responseData: ResponseData,
369
367
  options: RequestOptions,
370
368
  context: CacheManagerContext
371
- ): Promise<void> {
372
- return this._setQueryResponseCacheEntry(requestData.hash, responseData, options, context);
369
+ ): void {
370
+ this._setQueryResponseCacheEntry(requestData.hash, responseData, options, context);
373
371
  }
374
372
 
375
373
  private async _analyzeFieldNode(
@@ -450,7 +448,7 @@ export class CacheManager implements CacheManagerDef {
450
448
  ): Promise<void> {
451
449
  const keysAndPaths = buildFieldKeysAndPaths(fieldNode, cachedAncestorFieldData, context);
452
450
  const { propNameOrIndex, requestFieldCacheKey, requestFieldPath } = keysAndPaths;
453
- const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath)!;
451
+ const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
454
452
 
455
453
  const { cacheability, data, entityData, requestFieldPathData } = await this._retrieveCachedParentNodeData(
456
454
  cachedAncestorFieldData,
@@ -553,13 +551,13 @@ export class CacheManager implements CacheManagerDef {
553
551
  return cacheMetadata;
554
552
  }
555
553
 
556
- private async _cacheResponse(
554
+ private _cacheResponse(
557
555
  requestData: RequestData,
558
556
  updatedRequestData: RequestData | undefined,
559
557
  rawResponseData: RawResponseDataWithMaybeCacheMetadata,
560
558
  options: RequestOptions,
561
559
  context: CacheManagerContext
562
- ): Promise<ResponseData> {
560
+ ): ResponseData {
563
561
  const normalizedResponseData = normalizePatchResponseData(rawResponseData, context);
564
562
  let responseDataForCaching: RawResponseDataWithMaybeCacheMetadata | undefined = normalizedResponseData;
565
563
 
@@ -572,24 +570,22 @@ export class CacheManager implements CacheManagerDef {
572
570
  responseDataForCaching = this._retrieveResponseDataForCaching(normalizedResponseData, context);
573
571
  }
574
572
 
575
- const dataCaching: Promise<void>[] = [];
576
-
577
573
  if (responseDataForCaching) {
578
574
  const { data } = responseDataForCaching;
579
575
  const cacheMetadata = this._buildCacheMetadata(requestData, responseDataForCaching, options, context);
580
576
 
581
- dataCaching.push(
577
+ void new Promise(() => {
582
578
  this._setEntityAndRequestFieldPathCacheEntries(
583
579
  requestData,
584
580
  {
585
581
  cacheMetadata,
586
- entityData: cloneDeep(data),
587
- requestFieldPathData: cloneDeep(data),
582
+ entityData: structuredClone(data),
583
+ requestFieldPathData: structuredClone(data),
588
584
  },
589
585
  options,
590
586
  context
591
- )
592
- );
587
+ );
588
+ });
593
589
 
594
590
  let queryCacheMetadata: CacheMetadata | undefined;
595
591
  let queryData: PlainData | undefined;
@@ -598,30 +594,21 @@ export class CacheManager implements CacheManagerDef {
598
594
  let partialQueryResponse: PartialQueryResponse | undefined;
599
595
 
600
596
  if (context.queryFiltered && updatedRequestData) {
601
- dataCaching.push(
602
- this._setQueryResponseCacheEntry(updatedRequestData.hash, { cacheMetadata, data }, options, context)
603
- );
604
-
597
+ this._setQueryResponseCacheEntry(updatedRequestData.hash, { cacheMetadata, data }, options, context);
605
598
  partialQueryResponse = this._getPartialQueryResponse(requestData.hash);
606
599
  }
607
600
 
608
601
  queryCacheMetadata = CacheManager._mergeResponseCacheMetadata(cacheMetadata, partialQueryResponse);
609
602
  queryData = this._mergeResponseData(data, partialQueryResponse);
610
603
 
611
- dataCaching.push(
612
- this._setQueryResponseCacheEntry(
613
- requestData.hash,
614
- { cacheMetadata: queryCacheMetadata, data: queryData },
615
- options,
616
- context
617
- )
604
+ this._setQueryResponseCacheEntry(
605
+ requestData.hash,
606
+ { cacheMetadata: queryCacheMetadata, data: queryData },
607
+ options,
608
+ context
618
609
  );
619
610
  }
620
611
 
621
- if (options.awaitDataCaching) {
622
- await Promise.all(dataCaching);
623
- }
624
-
625
612
  if (isNotResponseChunk(normalizedResponseData, context) && queryCacheMetadata && queryData) {
626
613
  return {
627
614
  cacheMetadata: queryCacheMetadata,
@@ -710,22 +697,6 @@ export class CacheManager implements CacheManagerDef {
710
697
  }
711
698
  }
712
699
 
713
- private _isFieldEntity(fieldData: unknown, { isEntity, possibleTypes }: FieldTypeInfo): boolean {
714
- if (!isPlainObject(fieldData) || !(this._typeIDKey in fieldData)) {
715
- return false;
716
- }
717
-
718
- if (isEntity) {
719
- return true;
720
- }
721
-
722
- if (possibleTypes.length === 0) {
723
- return false;
724
- }
725
-
726
- return possibleTypes.some(type => type.typeName === fieldData.__typename);
727
- }
728
-
729
700
  private _mergeResponseData(responseData: PlainData, partialQueryResponse?: PartialQueryResponse): PlainData {
730
701
  if (!partialQueryResponse) {
731
702
  return responseData;
@@ -734,25 +705,24 @@ export class CacheManager implements CacheManagerDef {
734
705
  return mergeDataSets(partialQueryResponse.data, responseData, this._typeIDKey);
735
706
  }
736
707
 
737
- private async _parseEntityAndRequestFieldPathCacheEntryData(
708
+ private _parseEntityAndRequestFieldPathCacheEntryData(
738
709
  field: FieldNode,
739
710
  ancestorKeysAndPaths: AncestorKeysAndPaths,
740
711
  { cacheMetadata, entityData, requestFieldPathData }: ResponseDataForCaching,
741
712
  options: RequestOptions,
742
713
  context: CacheManagerContext
743
- ): Promise<void> {
714
+ ): void {
744
715
  const keysAndPaths = buildFieldKeysAndPaths(field, ancestorKeysAndPaths, context);
745
- const { requestFieldCacheKey, requestFieldPath, responseDataPath } = keysAndPaths;
716
+ const { hashedRequestFieldCacheKey, requestFieldCacheKey, requestFieldPath, responseDataPath } = keysAndPaths;
746
717
  const fieldData = get(requestFieldPathData, responseDataPath) as unknown;
747
718
  const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
719
+ const cacheability = cacheMetadata.get(requestFieldPath);
748
720
 
749
721
  if (!isObjectLike(fieldData) && !fieldTypeInfo?.hasDirectives) {
750
722
  return;
751
723
  }
752
724
 
753
725
  if (isObjectLike(fieldData)) {
754
- const promises: Promise<void>[] = [];
755
-
756
726
  iterateChildFields(
757
727
  field,
758
728
  fieldData,
@@ -764,41 +734,81 @@ export class CacheManager implements CacheManagerDef {
764
734
  _fragmentName: string | undefined,
765
735
  childIndex?: number
766
736
  ) => {
767
- promises.push(
768
- this._parseEntityAndRequestFieldPathCacheEntryData(
769
- childField,
770
- { index: childIndex, requestFieldCacheKey, requestFieldPath, responseDataPath },
771
- { cacheMetadata, entityData, requestFieldPathData },
772
- options,
773
- context
774
- )
737
+ this._parseEntityAndRequestFieldPathCacheEntryData(
738
+ childField,
739
+ { index: childIndex, requestFieldCacheKey, requestFieldPath, responseDataPath },
740
+ { cacheMetadata, entityData, requestFieldPathData },
741
+ options,
742
+ context
775
743
  );
776
744
  }
777
745
  );
746
+ }
778
747
 
779
- await Promise.all(promises);
748
+ if (isUndefined(fieldData) || !fieldTypeInfo || !cacheability) {
749
+ return;
780
750
  }
781
751
 
782
- await this._setEntityAndRequestFieldPathCacheEntry(
783
- field,
784
- keysAndPaths,
785
- { cacheMetadata, entityData, requestFieldPathData },
786
- options,
787
- context
788
- );
752
+ const isEntity = isFieldEntity(fieldData, fieldTypeInfo, this._typeIDKey);
753
+ const hasArgsOrDirectives = !!fieldTypeInfo.hasArguments || !!fieldTypeInfo.hasDirectives;
754
+
755
+ if (context.operation === OperationTypeNode.QUERY && (isEntity || hasArgsOrDirectives)) {
756
+ void this._setRequestFieldPathCacheEntry(
757
+ keysAndPaths,
758
+ {
759
+ cacheability,
760
+ fieldData: filterOutPropsWithEntityArgsOrDirectives(structuredClone(fieldData), field, keysAndPaths, context),
761
+ fieldTypeInfo,
762
+ },
763
+ options,
764
+ context
765
+ );
766
+
767
+ if (hasChildFields(field, { fragmentDefinitions: context.fragmentDefinitions })) {
768
+ if (isEntity) {
769
+ set(requestFieldPathData, responseDataPath, {
770
+ __cacheKey: `${REQUEST_FIELD_PATHS}::${hashedRequestFieldCacheKey}`,
771
+ });
772
+ } else {
773
+ unset(requestFieldPathData, responseDataPath);
774
+ }
775
+ }
776
+ }
777
+
778
+ if (isEntity) {
779
+ void this._setEntityCacheEntry(
780
+ {
781
+ cacheability,
782
+ fieldData: filterOutPropsWithEntityOrArgs(
783
+ structuredClone(get(entityData, responseDataPath)) as EntityData,
784
+ field,
785
+ keysAndPaths,
786
+ context
787
+ ),
788
+ fieldTypeInfo,
789
+ },
790
+ options,
791
+ context
792
+ );
793
+
794
+ set(entityData, responseDataPath, {
795
+ __cacheKey: `${DATA_ENTITIES}::${createEntityDataKey(fieldData, fieldTypeInfo, context)}`,
796
+ });
797
+ }
789
798
  }
790
799
 
791
800
  private async _retrieveCachedEntityData(
792
801
  validTypeIDValue: string | number,
793
- { possibleTypes, typeName }: FieldTypeInfo,
802
+ fieldTypeInfo: FieldTypeInfo | undefined,
794
803
  options: RequestOptions,
795
804
  context: CacheManagerContext
796
805
  ): Promise<Partial<CheckCacheEntryResult<EntityData>>> {
806
+ const { possibleTypes = [], typeName } = fieldTypeInfo ?? {};
797
807
  const typeNames = [...possibleTypes.map(type => type.typeName), typeName];
798
808
 
799
809
  const checkResults = await Promise.all(
800
810
  typeNames.map(name =>
801
- this._checkCacheEntry<EntityData>(DATA_ENTITIES, `${name}::${validTypeIDValue}`, options, context)
811
+ this._checkCacheEntry<EntityData>(DATA_ENTITIES, `${String(name)}::${validTypeIDValue}`, options, context)
802
812
  )
803
813
  );
804
814
 
@@ -825,7 +835,7 @@ export class CacheManager implements CacheManagerDef {
825
835
  private async _retrieveCachedParentNodeData(
826
836
  { entityData: ancestorEntityData, requestFieldPathData: ancestorRequestFieldPathData }: CachedAncestorFieldData,
827
837
  { hashedRequestFieldCacheKey, propNameOrIndex, requestFieldCacheKey }: KeysAndPaths,
828
- fieldTypeInfo: FieldTypeInfo,
838
+ fieldTypeInfo: FieldTypeInfo | undefined,
829
839
  options: RequestOptions,
830
840
  context: CacheManagerContext
831
841
  ) {
@@ -942,18 +952,18 @@ export class CacheManager implements CacheManagerDef {
942
952
  _context: CacheManagerContext & { requestFieldCacheKey?: string }
943
953
  ): Promise<void> {
944
954
  try {
945
- await this._cache.set(`${cacheType}::${hash}`, cloneDeep(value), cachemapOptions);
955
+ await this._cache.set(`${cacheType}::${hash}`, value, cachemapOptions);
946
956
  } catch {
947
957
  // no catch
948
958
  }
949
959
  }
950
960
 
951
- private async _setEntityAndRequestFieldPathCacheEntries(
961
+ private _setEntityAndRequestFieldPathCacheEntries(
952
962
  requestData: RequestData,
953
963
  responseData: ResponseDataForCaching,
954
964
  options: RequestOptions,
955
965
  context: CacheManagerContext
956
- ): Promise<void> {
966
+ ): void {
957
967
  const operationNode = getOperationDefinitions(requestData.ast, context.operation)[0];
958
968
 
959
969
  if (!operationNode) {
@@ -966,69 +976,22 @@ export class CacheManager implements CacheManagerDef {
966
976
  return;
967
977
  }
968
978
 
969
- await Promise.all(
970
- fieldsAndTypeNames.map(({ fieldNode }) => {
971
- return this._parseEntityAndRequestFieldPathCacheEntryData(
972
- fieldNode,
973
- { requestFieldPath: context.operation },
974
- responseData,
975
- options,
976
- context
977
- );
978
- })
979
- );
980
- }
981
-
982
- private async _setEntityAndRequestFieldPathCacheEntry(
983
- field: FieldNode,
984
- keysAndPaths: KeysAndPaths,
985
- { cacheMetadata, entityData, requestFieldPathData }: ResponseDataForCaching,
986
- options: RequestOptions,
987
- context: CacheManagerContext
988
- ) {
989
- const { requestFieldPath, responseDataPath } = keysAndPaths;
990
- const fieldData = get(entityData, responseDataPath) as unknown;
991
- const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
992
- const cacheability = cacheMetadata.get(requestFieldPath);
993
-
994
- if (isUndefined(fieldData) || !fieldTypeInfo || !cacheability) {
995
- return;
996
- }
997
-
998
- const promises: Promise<void>[] = [];
999
-
1000
- promises.push(
1001
- this._setRequestFieldPathCacheEntry(
1002
- field,
1003
- keysAndPaths,
1004
- { cacheability, data: requestFieldPathData, fieldTypeInfo },
979
+ fieldsAndTypeNames.map(({ fieldNode }) => {
980
+ this._parseEntityAndRequestFieldPathCacheEntryData(
981
+ fieldNode,
982
+ { requestFieldPath: context.operation },
983
+ responseData,
1005
984
  options,
1006
985
  context
1007
- )
1008
- );
1009
-
1010
- const isEntity = this._isFieldEntity(fieldData, fieldTypeInfo);
1011
-
1012
- if (!isEntity && fieldTypeInfo.hasArguments) {
1013
- unset(entityData, responseDataPath);
1014
- }
1015
-
1016
- if (isEntity) {
1017
- promises.push(
1018
- this._setEntityCacheEntry(keysAndPaths, { cacheability, data: entityData, fieldTypeInfo }, options, context)
1019
986
  );
1020
- }
1021
-
1022
- await Promise.all(promises);
987
+ });
1023
988
  }
1024
989
 
1025
990
  private async _setEntityCacheEntry(
1026
- { responseDataPath }: KeysAndPaths,
1027
- { cacheability, data, fieldTypeInfo }: DataForCachingEntry,
991
+ { cacheability, fieldData, fieldTypeInfo }: DataForCachingEntry<EntityData>,
1028
992
  options: RequestOptions,
1029
993
  context: CacheManagerContext
1030
994
  ) {
1031
- let fieldData = get(data, responseDataPath) as EntityData;
1032
995
  const fieldTypeName = fieldTypeInfo.isEntity ? fieldTypeInfo.typeName : fieldData.__typename;
1033
996
  const entityDataKey = `${fieldTypeName}::${String(fieldData[this._typeIDKey])}`;
1034
997
  const result = await this._checkCacheEntry<EntityData>(DATA_ENTITIES, entityDataKey, options, context);
@@ -1037,7 +1000,7 @@ export class CacheManager implements CacheManagerDef {
1037
1000
  fieldData = mergeDataSets(result.entry, fieldData, this._typeIDKey);
1038
1001
  }
1039
1002
 
1040
- await this._setCacheEntry(
1003
+ void this._setCacheEntry(
1041
1004
  DATA_ENTITIES,
1042
1005
  entityDataKey,
1043
1006
  fieldData,
@@ -1045,8 +1008,6 @@ export class CacheManager implements CacheManagerDef {
1045
1008
  options,
1046
1009
  context
1047
1010
  );
1048
-
1049
- set(data, responseDataPath, { __cacheKey: `${DATA_ENTITIES}::${entityDataKey}` });
1050
1011
  }
1051
1012
 
1052
1013
  private _setFieldCacheability(
@@ -1131,16 +1092,16 @@ export class CacheManager implements CacheManagerDef {
1131
1092
  this._partialQueryResponses.set(hash, partialQueryResponse);
1132
1093
  }
1133
1094
 
1134
- private async _setQueryResponseCacheEntry(
1095
+ private _setQueryResponseCacheEntry(
1135
1096
  hash: string,
1136
1097
  { cacheMetadata, data }: ResponseData,
1137
1098
  options: RequestOptions,
1138
1099
  context: CacheManagerContext
1139
- ): Promise<void> {
1100
+ ): void {
1140
1101
  const dehydratedCacheMetadata = dehydrateCacheMetadata(cacheMetadata);
1141
1102
  const cacheControl = CacheManager._getOperationCacheControl(cacheMetadata, context.operation);
1142
1103
 
1143
- await this._setCacheEntry(
1104
+ void this._setCacheEntry(
1144
1105
  QUERY_RESPONSES,
1145
1106
  hash,
1146
1107
  { cacheMetadata: dehydratedCacheMetadata, data },
@@ -1151,48 +1112,30 @@ export class CacheManager implements CacheManagerDef {
1151
1112
  }
1152
1113
 
1153
1114
  private async _setRequestFieldPathCacheEntry(
1154
- field: FieldNode,
1155
1115
  keysAndPaths: KeysAndPaths,
1156
- { cacheability, data, fieldTypeInfo }: DataForCachingEntry,
1116
+ { cacheability, fieldData }: DataForCachingEntry,
1157
1117
  options: RequestOptions,
1158
1118
  context: CacheManagerContext
1159
1119
  ): Promise<void> {
1160
- const { hashedRequestFieldCacheKey, requestFieldCacheKey, responseDataPath } = keysAndPaths;
1161
- let fieldData = get(data, responseDataPath) as unknown;
1162
- const isEntity = this._isFieldEntity(fieldData, fieldTypeInfo);
1163
- const hasArgsOrDirectives = fieldTypeInfo.hasArguments || fieldTypeInfo.hasDirectives;
1120
+ const { hashedRequestFieldCacheKey, requestFieldCacheKey } = keysAndPaths;
1164
1121
 
1165
- if (context.operation === OperationTypeNode.QUERY && (isEntity || hasArgsOrDirectives)) {
1166
- if (isPlainObject(fieldData) && field.selectionSet?.selections) {
1167
- fieldData = filterOutPropsWithArgsOrDirectives(fieldData, field.selectionSet.selections, keysAndPaths, context);
1168
- }
1169
-
1170
- const result = await this._checkCacheEntry(REQUEST_FIELD_PATHS, hashedRequestFieldCacheKey, options, {
1171
- ...context,
1172
- requestFieldCacheKey,
1173
- });
1174
-
1175
- if (result && isObjectLike(result.entry) && isObjectLike(fieldData)) {
1176
- fieldData = mergeDataSets(result.entry, fieldData, this._typeIDKey);
1177
- }
1178
-
1179
- await this._setCacheEntry(
1180
- REQUEST_FIELD_PATHS,
1181
- hashedRequestFieldCacheKey,
1182
- fieldData,
1183
- { cacheHeaders: { cacheControl: cacheability.printCacheControl() }, tag: options.tag },
1184
- options,
1185
- { ...context, requestFieldCacheKey }
1186
- );
1122
+ const result = await this._checkCacheEntry(REQUEST_FIELD_PATHS, hashedRequestFieldCacheKey, options, {
1123
+ ...context,
1124
+ requestFieldCacheKey,
1125
+ });
1187
1126
 
1188
- if (hasChildFields(field, { fragmentDefinitions: context.fragmentDefinitions })) {
1189
- if (isEntity) {
1190
- set(data, responseDataPath, { __cacheKey: `${REQUEST_FIELD_PATHS}::${hashedRequestFieldCacheKey}` });
1191
- } else {
1192
- unset(data, responseDataPath);
1193
- }
1194
- }
1127
+ if (result && isObjectLike(result.entry) && isObjectLike(fieldData)) {
1128
+ fieldData = mergeDataSets(result.entry, fieldData, this._typeIDKey);
1195
1129
  }
1130
+
1131
+ void this._setCacheEntry(
1132
+ REQUEST_FIELD_PATHS,
1133
+ hashedRequestFieldCacheKey,
1134
+ fieldData,
1135
+ { cacheHeaders: { cacheControl: cacheability.printCacheControl() }, tag: options.tag },
1136
+ options,
1137
+ { ...context, requestFieldCacheKey }
1138
+ );
1196
1139
  }
1197
1140
 
1198
1141
  private _setResponseChunksAwaitingCaching(
package/src/types.ts CHANGED
@@ -122,9 +122,9 @@ export interface ResponseDataForCaching {
122
122
  requestFieldPathData: PlainData;
123
123
  }
124
124
 
125
- export interface DataForCachingEntry {
125
+ export interface DataForCachingEntry<Data = unknown> {
126
126
  cacheability: Cacheability;
127
- data: PlainData;
127
+ fieldData: Data;
128
128
  fieldTypeInfo: FieldTypeInfo;
129
129
  }
130
130
 
@@ -157,13 +157,13 @@ export interface CacheManagerDef {
157
157
  responseData: RawResponseDataWithMaybeCacheMetadata,
158
158
  options: RequestOptions,
159
159
  context: RequestContext
160
- ): Promise<ResponseData>;
160
+ ): ResponseData;
161
161
  cacheResponse(
162
162
  requestData: RequestData,
163
163
  responseData: RawResponseDataWithMaybeCacheMetadata,
164
164
  options: RequestOptions,
165
165
  context: RequestContext
166
- ): Promise<ResponseData>;
166
+ ): ResponseData;
167
167
  checkCacheEntry(
168
168
  cacheType: CacheTypes,
169
169
  hash: string,
@@ -181,5 +181,5 @@ export interface CacheManagerDef {
181
181
  responseData: ResponseData,
182
182
  options: RequestOptions,
183
183
  context: CacheManagerContext
184
- ): Promise<void>;
184
+ ): void;
185
185
  }
@@ -1,6 +0,0 @@
1
- import { type PlainObject } from '@graphql-box/core';
2
- import { type KeysAndPaths } from '@graphql-box/helpers';
3
- import { type SelectionNode } from 'graphql';
4
- import { type CacheManagerContext } from '../types.cts';
5
- export declare const filterOutPropsWithArgsOrDirectives: (fieldData: PlainObject, selectionNodes: readonly SelectionNode[], ancestorKeysAndPaths: KeysAndPaths, context: CacheManagerContext) => PlainObject;
6
- //# sourceMappingURL=filterOutPropsWithArgsOrDirectives.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"filterOutPropsWithArgsOrDirectives.d.cts","sourceRoot":"","sources":["../../../../src/helpers/filterOutPropsWithArgsOrDirectives.cts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,KAAK,YAAY,EAAqD,MAAM,sBAAsB,CAAC;AAC5G,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,eAAO,MAAM,kCAAkC,cAClC,WAAW,kBACN,SAAS,aAAa,EAAE,wBAClB,YAAY,WACzB,mBAAmB,gBAkB7B,CAAC"}
@@ -1,6 +0,0 @@
1
- import { type PlainObject } from '@graphql-box/core';
2
- import { type KeysAndPaths } from '@graphql-box/helpers';
3
- import { type SelectionNode } from 'graphql';
4
- import { type CacheManagerContext } from '../types.ts';
5
- export declare const filterOutPropsWithArgsOrDirectives: (fieldData: PlainObject, selectionNodes: readonly SelectionNode[], ancestorKeysAndPaths: KeysAndPaths, context: CacheManagerContext) => PlainObject;
6
- //# sourceMappingURL=filterOutPropsWithArgsOrDirectives.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"filterOutPropsWithArgsOrDirectives.d.ts","sourceRoot":"","sources":["../../../../src/helpers/filterOutPropsWithArgsOrDirectives.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,KAAK,YAAY,EAAqD,MAAM,sBAAsB,CAAC;AAC5G,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,eAAO,MAAM,kCAAkC,cAClC,WAAW,kBACN,SAAS,aAAa,EAAE,wBAClB,YAAY,WACzB,mBAAmB,gBAkB7B,CAAC"}
@@ -1,29 +0,0 @@
1
- import { type PlainObject } from '@graphql-box/core';
2
- import { type KeysAndPaths, buildFieldKeysAndPaths, getName, resolveFragments } from '@graphql-box/helpers';
3
- import { type SelectionNode } from 'graphql';
4
- import { keys } from 'lodash-es';
5
- import { type CacheManagerContext } from '../types.ts';
6
-
7
- export const filterOutPropsWithArgsOrDirectives = (
8
- fieldData: PlainObject,
9
- selectionNodes: readonly SelectionNode[],
10
- ancestorKeysAndPaths: KeysAndPaths,
11
- context: CacheManagerContext
12
- ) => {
13
- const fieldAndTypeName = resolveFragments(selectionNodes, context.fragmentDefinitions);
14
-
15
- return keys(fieldData).reduce<PlainObject>((acc, key) => {
16
- const match = fieldAndTypeName.find(({ fieldNode }) => getName(fieldNode) === key);
17
-
18
- if (match) {
19
- const { requestFieldPath } = buildFieldKeysAndPaths(match.fieldNode, ancestorKeysAndPaths, context);
20
- const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
21
-
22
- if (!fieldTypeInfo?.hasArguments && !fieldTypeInfo?.hasDirectives) {
23
- acc[key] = fieldData[key];
24
- }
25
- }
26
-
27
- return acc;
28
- }, {});
29
- };