@graphql-box/cache-manager 5.1.0 → 5.2.3
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.
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/production.analysis.txt +18 -47
- package/dist/types/cjs/helpers/filterOutPropsWithArgsOrDirectives.d.cts +6 -0
- package/dist/types/cjs/helpers/filterOutPropsWithArgsOrDirectives.d.cts.map +1 -0
- package/dist/types/cjs/helpers/validTypeIdValue.d.cts +1 -1
- package/dist/types/cjs/helpers/validTypeIdValue.d.cts.map +1 -1
- package/dist/types/cjs/main.d.cts +5 -3
- package/dist/types/cjs/main.d.cts.map +1 -1
- package/dist/types/cjs/types.d.cts +5 -5
- package/dist/types/cjs/types.d.cts.map +1 -1
- package/dist/types/esm/helpers/filterOutPropsWithArgsOrDirectives.d.ts +6 -0
- package/dist/types/esm/helpers/filterOutPropsWithArgsOrDirectives.d.ts.map +1 -0
- package/dist/types/esm/helpers/validTypeIdValue.d.ts +1 -1
- package/dist/types/esm/helpers/validTypeIdValue.d.ts.map +1 -1
- package/dist/types/esm/main.d.ts +5 -3
- package/dist/types/esm/main.d.ts.map +1 -1
- package/dist/types/esm/types.d.ts +5 -5
- package/dist/types/esm/types.d.ts.map +1 -1
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/__snapshots__/index.test.ts.snap +18519 -18519
- package/src/helpers/filterOutPropsWithArgsOrDirectives.ts +29 -0
- package/src/helpers/validTypeIdValue.ts +3 -3
- package/src/index.test.ts +127 -153
- package/src/main.ts +179 -122
- package/src/types.ts +5 -5
- package/dist/types/cjs/helpers/createEntityDataKey.d.cts +0 -4
- package/dist/types/cjs/helpers/createEntityDataKey.d.cts.map +0 -1
- package/dist/types/cjs/helpers/filterOutPropsWithEntityArgsOrDirectives.d.cts +0 -5
- package/dist/types/cjs/helpers/filterOutPropsWithEntityArgsOrDirectives.d.cts.map +0 -1
- package/dist/types/cjs/helpers/filterOutPropsWithEntityOrArgs.d.cts +0 -6
- package/dist/types/cjs/helpers/filterOutPropsWithEntityOrArgs.d.cts.map +0 -1
- package/dist/types/cjs/helpers/isFieldEntity.d.cts +0 -3
- package/dist/types/cjs/helpers/isFieldEntity.d.cts.map +0 -1
- package/dist/types/esm/helpers/createEntityDataKey.d.ts +0 -4
- package/dist/types/esm/helpers/createEntityDataKey.d.ts.map +0 -1
- package/dist/types/esm/helpers/filterOutPropsWithEntityArgsOrDirectives.d.ts +0 -5
- package/dist/types/esm/helpers/filterOutPropsWithEntityArgsOrDirectives.d.ts.map +0 -1
- package/dist/types/esm/helpers/filterOutPropsWithEntityOrArgs.d.ts +0 -6
- package/dist/types/esm/helpers/filterOutPropsWithEntityOrArgs.d.ts.map +0 -1
- package/dist/types/esm/helpers/isFieldEntity.d.ts +0 -3
- package/dist/types/esm/helpers/isFieldEntity.d.ts.map +0 -1
- package/src/helpers/createEntityDataKey.ts +0 -11
- package/src/helpers/filterOutPropsWithEntityArgsOrDirectives.ts +0 -45
- package/src/helpers/filterOutPropsWithEntityOrArgs.ts +0 -31
- package/src/helpers/isFieldEntity.ts +0 -24
package/src/main.ts
CHANGED
|
@@ -36,19 +36,16 @@ 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, get, isEqual, isNumber, isUndefined, set, unset } from 'lodash-es';
|
|
39
|
+
import { assign, cloneDeep, 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';
|
|
45
44
|
import { deriveOpCacheability } from './helpers/deriveOpCacheability.ts';
|
|
46
|
-
import {
|
|
47
|
-
import { filterOutPropsWithEntityOrArgs } from './helpers/filterOutPropsWithEntityOrArgs.ts';
|
|
45
|
+
import { filterOutPropsWithArgsOrDirectives } from './helpers/filterOutPropsWithArgsOrDirectives.ts';
|
|
48
46
|
import { filterQuery } from './helpers/filterQuery.ts';
|
|
49
47
|
import { getDataValue } from './helpers/getDataValue.ts';
|
|
50
48
|
import { hasTypename } from './helpers/hasTypename.ts';
|
|
51
|
-
import { isFieldEntity } from './helpers/isFieldEntity.ts';
|
|
52
49
|
import { isLastResponseChunk } from './helpers/isLastResponseChunk.ts';
|
|
53
50
|
import { isNotLastResponseChunk } from './helpers/isNotLastResponseChunk.ts';
|
|
54
51
|
import { isNotResponseChunk } from './helpers/isNotResponseChunk.ts';
|
|
@@ -91,7 +88,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
91
88
|
|
|
92
89
|
private static _getFieldDataFromAncestor<T>(ancestorFieldData: unknown, propNameOrIndex: string | number) {
|
|
93
90
|
const dataValue = getDataValue<T>(ancestorFieldData, propNameOrIndex);
|
|
94
|
-
return isObjectLike(dataValue) ?
|
|
91
|
+
return isObjectLike(dataValue) ? cloneDeep(dataValue) : dataValue;
|
|
95
92
|
}
|
|
96
93
|
|
|
97
94
|
private static _getOperationCacheControl(cacheMetadata: CacheMetadata | undefined, operation: string): string {
|
|
@@ -279,7 +276,12 @@ export class CacheManager implements CacheManagerDef {
|
|
|
279
276
|
}
|
|
280
277
|
|
|
281
278
|
if (!fieldCount.missing) {
|
|
282
|
-
this._setQueryResponseCacheEntry(hash, { cacheMetadata, data }, options, cacheManagerContext);
|
|
279
|
+
const dataCaching = this._setQueryResponseCacheEntry(hash, { cacheMetadata, data }, options, cacheManagerContext);
|
|
280
|
+
|
|
281
|
+
if (options.awaitDataCaching) {
|
|
282
|
+
await dataCaching;
|
|
283
|
+
}
|
|
284
|
+
|
|
283
285
|
return { response: { cacheMetadata, data } };
|
|
284
286
|
}
|
|
285
287
|
|
|
@@ -298,13 +300,13 @@ export class CacheManager implements CacheManagerDef {
|
|
|
298
300
|
return this._cache;
|
|
299
301
|
}
|
|
300
302
|
|
|
301
|
-
public cacheQuery(
|
|
303
|
+
public async cacheQuery(
|
|
302
304
|
requestData: RequestData,
|
|
303
305
|
updatedRequestData: RequestData | undefined,
|
|
304
306
|
rawResponseData: RawResponseDataWithMaybeCacheMetadata,
|
|
305
307
|
options: RequestOptions,
|
|
306
308
|
context: RequestContext
|
|
307
|
-
): ResponseData {
|
|
309
|
+
): Promise<ResponseData> {
|
|
308
310
|
const cacheManagerContext: CacheManagerContext = {
|
|
309
311
|
...context,
|
|
310
312
|
fragmentDefinitions: getFragmentDefinitions((updatedRequestData ?? requestData).ast),
|
|
@@ -314,12 +316,12 @@ export class CacheManager implements CacheManagerDef {
|
|
|
314
316
|
return this._cacheResponse(requestData, updatedRequestData, rawResponseData, options, cacheManagerContext);
|
|
315
317
|
}
|
|
316
318
|
|
|
317
|
-
public cacheResponse(
|
|
319
|
+
public async cacheResponse(
|
|
318
320
|
requestData: RequestData,
|
|
319
321
|
rawResponseData: RawResponseDataWithMaybeCacheMetadata,
|
|
320
322
|
options: RequestOptions,
|
|
321
323
|
context: RequestContext
|
|
322
|
-
): ResponseData {
|
|
324
|
+
): Promise<ResponseData> {
|
|
323
325
|
const cacheManagerContext: CacheManagerContext = {
|
|
324
326
|
...context,
|
|
325
327
|
fragmentDefinitions: getFragmentDefinitions(requestData.ast),
|
|
@@ -361,13 +363,13 @@ export class CacheManager implements CacheManagerDef {
|
|
|
361
363
|
this._partialQueryResponses.delete(hash);
|
|
362
364
|
}
|
|
363
365
|
|
|
364
|
-
public setQueryResponseCacheEntry(
|
|
366
|
+
public async setQueryResponseCacheEntry(
|
|
365
367
|
requestData: RequestData,
|
|
366
368
|
responseData: ResponseData,
|
|
367
369
|
options: RequestOptions,
|
|
368
370
|
context: CacheManagerContext
|
|
369
|
-
): void {
|
|
370
|
-
this._setQueryResponseCacheEntry(requestData.hash, responseData, options, context);
|
|
371
|
+
): Promise<void> {
|
|
372
|
+
return this._setQueryResponseCacheEntry(requestData.hash, responseData, options, context);
|
|
371
373
|
}
|
|
372
374
|
|
|
373
375
|
private async _analyzeFieldNode(
|
|
@@ -448,7 +450,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
448
450
|
): Promise<void> {
|
|
449
451
|
const keysAndPaths = buildFieldKeysAndPaths(fieldNode, cachedAncestorFieldData, context);
|
|
450
452
|
const { propNameOrIndex, requestFieldCacheKey, requestFieldPath } = keysAndPaths;
|
|
451
|
-
const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath)
|
|
453
|
+
const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath)!;
|
|
452
454
|
|
|
453
455
|
const { cacheability, data, entityData, requestFieldPathData } = await this._retrieveCachedParentNodeData(
|
|
454
456
|
cachedAncestorFieldData,
|
|
@@ -551,13 +553,13 @@ export class CacheManager implements CacheManagerDef {
|
|
|
551
553
|
return cacheMetadata;
|
|
552
554
|
}
|
|
553
555
|
|
|
554
|
-
private _cacheResponse(
|
|
556
|
+
private async _cacheResponse(
|
|
555
557
|
requestData: RequestData,
|
|
556
558
|
updatedRequestData: RequestData | undefined,
|
|
557
559
|
rawResponseData: RawResponseDataWithMaybeCacheMetadata,
|
|
558
560
|
options: RequestOptions,
|
|
559
561
|
context: CacheManagerContext
|
|
560
|
-
): ResponseData {
|
|
562
|
+
): Promise<ResponseData> {
|
|
561
563
|
const normalizedResponseData = normalizePatchResponseData(rawResponseData, context);
|
|
562
564
|
let responseDataForCaching: RawResponseDataWithMaybeCacheMetadata | undefined = normalizedResponseData;
|
|
563
565
|
|
|
@@ -570,22 +572,24 @@ export class CacheManager implements CacheManagerDef {
|
|
|
570
572
|
responseDataForCaching = this._retrieveResponseDataForCaching(normalizedResponseData, context);
|
|
571
573
|
}
|
|
572
574
|
|
|
575
|
+
const dataCaching: Promise<void>[] = [];
|
|
576
|
+
|
|
573
577
|
if (responseDataForCaching) {
|
|
574
578
|
const { data } = responseDataForCaching;
|
|
575
579
|
const cacheMetadata = this._buildCacheMetadata(requestData, responseDataForCaching, options, context);
|
|
576
580
|
|
|
577
|
-
|
|
581
|
+
dataCaching.push(
|
|
578
582
|
this._setEntityAndRequestFieldPathCacheEntries(
|
|
579
583
|
requestData,
|
|
580
584
|
{
|
|
581
585
|
cacheMetadata,
|
|
582
|
-
entityData:
|
|
583
|
-
requestFieldPathData:
|
|
586
|
+
entityData: cloneDeep(data),
|
|
587
|
+
requestFieldPathData: cloneDeep(data),
|
|
584
588
|
},
|
|
585
589
|
options,
|
|
586
590
|
context
|
|
587
|
-
)
|
|
588
|
-
|
|
591
|
+
)
|
|
592
|
+
);
|
|
589
593
|
|
|
590
594
|
let queryCacheMetadata: CacheMetadata | undefined;
|
|
591
595
|
let queryData: PlainData | undefined;
|
|
@@ -594,21 +598,30 @@ export class CacheManager implements CacheManagerDef {
|
|
|
594
598
|
let partialQueryResponse: PartialQueryResponse | undefined;
|
|
595
599
|
|
|
596
600
|
if (context.queryFiltered && updatedRequestData) {
|
|
597
|
-
|
|
601
|
+
dataCaching.push(
|
|
602
|
+
this._setQueryResponseCacheEntry(updatedRequestData.hash, { cacheMetadata, data }, options, context)
|
|
603
|
+
);
|
|
604
|
+
|
|
598
605
|
partialQueryResponse = this._getPartialQueryResponse(requestData.hash);
|
|
599
606
|
}
|
|
600
607
|
|
|
601
608
|
queryCacheMetadata = CacheManager._mergeResponseCacheMetadata(cacheMetadata, partialQueryResponse);
|
|
602
609
|
queryData = this._mergeResponseData(data, partialQueryResponse);
|
|
603
610
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
611
|
+
dataCaching.push(
|
|
612
|
+
this._setQueryResponseCacheEntry(
|
|
613
|
+
requestData.hash,
|
|
614
|
+
{ cacheMetadata: queryCacheMetadata, data: queryData },
|
|
615
|
+
options,
|
|
616
|
+
context
|
|
617
|
+
)
|
|
609
618
|
);
|
|
610
619
|
}
|
|
611
620
|
|
|
621
|
+
if (options.awaitDataCaching) {
|
|
622
|
+
await Promise.all(dataCaching);
|
|
623
|
+
}
|
|
624
|
+
|
|
612
625
|
if (isNotResponseChunk(normalizedResponseData, context) && queryCacheMetadata && queryData) {
|
|
613
626
|
return {
|
|
614
627
|
cacheMetadata: queryCacheMetadata,
|
|
@@ -697,6 +710,22 @@ export class CacheManager implements CacheManagerDef {
|
|
|
697
710
|
}
|
|
698
711
|
}
|
|
699
712
|
|
|
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
|
+
|
|
700
729
|
private _mergeResponseData(responseData: PlainData, partialQueryResponse?: PartialQueryResponse): PlainData {
|
|
701
730
|
if (!partialQueryResponse) {
|
|
702
731
|
return responseData;
|
|
@@ -705,24 +734,25 @@ export class CacheManager implements CacheManagerDef {
|
|
|
705
734
|
return mergeDataSets(partialQueryResponse.data, responseData, this._typeIDKey);
|
|
706
735
|
}
|
|
707
736
|
|
|
708
|
-
private _parseEntityAndRequestFieldPathCacheEntryData(
|
|
737
|
+
private async _parseEntityAndRequestFieldPathCacheEntryData(
|
|
709
738
|
field: FieldNode,
|
|
710
739
|
ancestorKeysAndPaths: AncestorKeysAndPaths,
|
|
711
740
|
{ cacheMetadata, entityData, requestFieldPathData }: ResponseDataForCaching,
|
|
712
741
|
options: RequestOptions,
|
|
713
742
|
context: CacheManagerContext
|
|
714
|
-
): void {
|
|
743
|
+
): Promise<void> {
|
|
715
744
|
const keysAndPaths = buildFieldKeysAndPaths(field, ancestorKeysAndPaths, context);
|
|
716
|
-
const {
|
|
745
|
+
const { requestFieldCacheKey, requestFieldPath, responseDataPath } = keysAndPaths;
|
|
717
746
|
const fieldData = get(requestFieldPathData, responseDataPath) as unknown;
|
|
718
747
|
const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
|
|
719
|
-
const cacheability = cacheMetadata.get(requestFieldPath);
|
|
720
748
|
|
|
721
749
|
if (!isObjectLike(fieldData) && !fieldTypeInfo?.hasDirectives) {
|
|
722
750
|
return;
|
|
723
751
|
}
|
|
724
752
|
|
|
725
753
|
if (isObjectLike(fieldData)) {
|
|
754
|
+
const promises: Promise<void>[] = [];
|
|
755
|
+
|
|
726
756
|
iterateChildFields(
|
|
727
757
|
field,
|
|
728
758
|
fieldData,
|
|
@@ -734,81 +764,41 @@ export class CacheManager implements CacheManagerDef {
|
|
|
734
764
|
_fragmentName: string | undefined,
|
|
735
765
|
childIndex?: number
|
|
736
766
|
) => {
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
767
|
+
promises.push(
|
|
768
|
+
this._parseEntityAndRequestFieldPathCacheEntryData(
|
|
769
|
+
childField,
|
|
770
|
+
{ index: childIndex, requestFieldCacheKey, requestFieldPath, responseDataPath },
|
|
771
|
+
{ cacheMetadata, entityData, requestFieldPathData },
|
|
772
|
+
options,
|
|
773
|
+
context
|
|
774
|
+
)
|
|
743
775
|
);
|
|
744
776
|
}
|
|
745
777
|
);
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
if (isUndefined(fieldData) || !fieldTypeInfo || !cacheability) {
|
|
749
|
-
return;
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
const isEntity = isFieldEntity(fieldData, fieldTypeInfo, this._typeIDKey);
|
|
753
|
-
const hasArgsOrDirectives = !!fieldTypeInfo.hasArguments || !!fieldTypeInfo.hasDirectives;
|
|
754
778
|
|
|
755
|
-
|
|
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
|
-
}
|
|
779
|
+
await Promise.all(promises);
|
|
776
780
|
}
|
|
777
781
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
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
|
-
}
|
|
782
|
+
await this._setEntityAndRequestFieldPathCacheEntry(
|
|
783
|
+
field,
|
|
784
|
+
keysAndPaths,
|
|
785
|
+
{ cacheMetadata, entityData, requestFieldPathData },
|
|
786
|
+
options,
|
|
787
|
+
context
|
|
788
|
+
);
|
|
798
789
|
}
|
|
799
790
|
|
|
800
791
|
private async _retrieveCachedEntityData(
|
|
801
792
|
validTypeIDValue: string | number,
|
|
802
|
-
|
|
793
|
+
{ possibleTypes, typeName }: FieldTypeInfo,
|
|
803
794
|
options: RequestOptions,
|
|
804
795
|
context: CacheManagerContext
|
|
805
796
|
): Promise<Partial<CheckCacheEntryResult<EntityData>>> {
|
|
806
|
-
const { possibleTypes = [], typeName } = fieldTypeInfo ?? {};
|
|
807
797
|
const typeNames = [...possibleTypes.map(type => type.typeName), typeName];
|
|
808
798
|
|
|
809
799
|
const checkResults = await Promise.all(
|
|
810
800
|
typeNames.map(name =>
|
|
811
|
-
this._checkCacheEntry<EntityData>(DATA_ENTITIES, `${
|
|
801
|
+
this._checkCacheEntry<EntityData>(DATA_ENTITIES, `${name}::${validTypeIDValue}`, options, context)
|
|
812
802
|
)
|
|
813
803
|
);
|
|
814
804
|
|
|
@@ -835,7 +825,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
835
825
|
private async _retrieveCachedParentNodeData(
|
|
836
826
|
{ entityData: ancestorEntityData, requestFieldPathData: ancestorRequestFieldPathData }: CachedAncestorFieldData,
|
|
837
827
|
{ hashedRequestFieldCacheKey, propNameOrIndex, requestFieldCacheKey }: KeysAndPaths,
|
|
838
|
-
fieldTypeInfo: FieldTypeInfo
|
|
828
|
+
fieldTypeInfo: FieldTypeInfo,
|
|
839
829
|
options: RequestOptions,
|
|
840
830
|
context: CacheManagerContext
|
|
841
831
|
) {
|
|
@@ -952,18 +942,18 @@ export class CacheManager implements CacheManagerDef {
|
|
|
952
942
|
_context: CacheManagerContext & { requestFieldCacheKey?: string }
|
|
953
943
|
): Promise<void> {
|
|
954
944
|
try {
|
|
955
|
-
await this._cache.set(`${cacheType}::${hash}`, value, cachemapOptions);
|
|
945
|
+
await this._cache.set(`${cacheType}::${hash}`, cloneDeep(value), cachemapOptions);
|
|
956
946
|
} catch {
|
|
957
947
|
// no catch
|
|
958
948
|
}
|
|
959
949
|
}
|
|
960
950
|
|
|
961
|
-
private _setEntityAndRequestFieldPathCacheEntries(
|
|
951
|
+
private async _setEntityAndRequestFieldPathCacheEntries(
|
|
962
952
|
requestData: RequestData,
|
|
963
953
|
responseData: ResponseDataForCaching,
|
|
964
954
|
options: RequestOptions,
|
|
965
955
|
context: CacheManagerContext
|
|
966
|
-
): void {
|
|
956
|
+
): Promise<void> {
|
|
967
957
|
const operationNode = getOperationDefinitions(requestData.ast, context.operation)[0];
|
|
968
958
|
|
|
969
959
|
if (!operationNode) {
|
|
@@ -976,22 +966,69 @@ export class CacheManager implements CacheManagerDef {
|
|
|
976
966
|
return;
|
|
977
967
|
}
|
|
978
968
|
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
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 },
|
|
984
1005
|
options,
|
|
985
1006
|
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)
|
|
986
1019
|
);
|
|
987
|
-
}
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
await Promise.all(promises);
|
|
988
1023
|
}
|
|
989
1024
|
|
|
990
1025
|
private async _setEntityCacheEntry(
|
|
991
|
-
{
|
|
1026
|
+
{ responseDataPath }: KeysAndPaths,
|
|
1027
|
+
{ cacheability, data, fieldTypeInfo }: DataForCachingEntry,
|
|
992
1028
|
options: RequestOptions,
|
|
993
1029
|
context: CacheManagerContext
|
|
994
1030
|
) {
|
|
1031
|
+
let fieldData = get(data, responseDataPath) as EntityData;
|
|
995
1032
|
const fieldTypeName = fieldTypeInfo.isEntity ? fieldTypeInfo.typeName : fieldData.__typename;
|
|
996
1033
|
const entityDataKey = `${fieldTypeName}::${String(fieldData[this._typeIDKey])}`;
|
|
997
1034
|
const result = await this._checkCacheEntry<EntityData>(DATA_ENTITIES, entityDataKey, options, context);
|
|
@@ -1000,7 +1037,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
1000
1037
|
fieldData = mergeDataSets(result.entry, fieldData, this._typeIDKey);
|
|
1001
1038
|
}
|
|
1002
1039
|
|
|
1003
|
-
|
|
1040
|
+
await this._setCacheEntry(
|
|
1004
1041
|
DATA_ENTITIES,
|
|
1005
1042
|
entityDataKey,
|
|
1006
1043
|
fieldData,
|
|
@@ -1008,6 +1045,8 @@ export class CacheManager implements CacheManagerDef {
|
|
|
1008
1045
|
options,
|
|
1009
1046
|
context
|
|
1010
1047
|
);
|
|
1048
|
+
|
|
1049
|
+
set(data, responseDataPath, { __cacheKey: `${DATA_ENTITIES}::${entityDataKey}` });
|
|
1011
1050
|
}
|
|
1012
1051
|
|
|
1013
1052
|
private _setFieldCacheability(
|
|
@@ -1092,16 +1131,16 @@ export class CacheManager implements CacheManagerDef {
|
|
|
1092
1131
|
this._partialQueryResponses.set(hash, partialQueryResponse);
|
|
1093
1132
|
}
|
|
1094
1133
|
|
|
1095
|
-
private _setQueryResponseCacheEntry(
|
|
1134
|
+
private async _setQueryResponseCacheEntry(
|
|
1096
1135
|
hash: string,
|
|
1097
1136
|
{ cacheMetadata, data }: ResponseData,
|
|
1098
1137
|
options: RequestOptions,
|
|
1099
1138
|
context: CacheManagerContext
|
|
1100
|
-
): void {
|
|
1139
|
+
): Promise<void> {
|
|
1101
1140
|
const dehydratedCacheMetadata = dehydrateCacheMetadata(cacheMetadata);
|
|
1102
1141
|
const cacheControl = CacheManager._getOperationCacheControl(cacheMetadata, context.operation);
|
|
1103
1142
|
|
|
1104
|
-
|
|
1143
|
+
await this._setCacheEntry(
|
|
1105
1144
|
QUERY_RESPONSES,
|
|
1106
1145
|
hash,
|
|
1107
1146
|
{ cacheMetadata: dehydratedCacheMetadata, data },
|
|
@@ -1112,30 +1151,48 @@ export class CacheManager implements CacheManagerDef {
|
|
|
1112
1151
|
}
|
|
1113
1152
|
|
|
1114
1153
|
private async _setRequestFieldPathCacheEntry(
|
|
1154
|
+
field: FieldNode,
|
|
1115
1155
|
keysAndPaths: KeysAndPaths,
|
|
1116
|
-
{ cacheability,
|
|
1156
|
+
{ cacheability, data, fieldTypeInfo }: DataForCachingEntry,
|
|
1117
1157
|
options: RequestOptions,
|
|
1118
1158
|
context: CacheManagerContext
|
|
1119
1159
|
): Promise<void> {
|
|
1120
|
-
const { hashedRequestFieldCacheKey, requestFieldCacheKey } = keysAndPaths;
|
|
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;
|
|
1121
1164
|
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
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
|
+
}
|
|
1126
1169
|
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1170
|
+
const result = await this._checkCacheEntry(REQUEST_FIELD_PATHS, hashedRequestFieldCacheKey, options, {
|
|
1171
|
+
...context,
|
|
1172
|
+
requestFieldCacheKey,
|
|
1173
|
+
});
|
|
1130
1174
|
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
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
|
+
);
|
|
1187
|
+
|
|
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
|
+
}
|
|
1195
|
+
}
|
|
1139
1196
|
}
|
|
1140
1197
|
|
|
1141
1198
|
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 {
|
|
126
126
|
cacheability: Cacheability;
|
|
127
|
-
|
|
127
|
+
data: PlainData;
|
|
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
|
-
): ResponseData
|
|
160
|
+
): Promise<ResponseData>;
|
|
161
161
|
cacheResponse(
|
|
162
162
|
requestData: RequestData,
|
|
163
163
|
responseData: RawResponseDataWithMaybeCacheMetadata,
|
|
164
164
|
options: RequestOptions,
|
|
165
165
|
context: RequestContext
|
|
166
|
-
): ResponseData
|
|
166
|
+
): Promise<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
|
-
): void
|
|
184
|
+
): Promise<void>;
|
|
185
185
|
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { EntityData, FieldTypeInfo } from '@graphql-box/core';
|
|
2
|
-
import type { CacheManagerContext } from '../types.cts';
|
|
3
|
-
export declare const createEntityDataKey: (fieldData: EntityData, fieldTypeInfo: FieldTypeInfo, context: CacheManagerContext) => string;
|
|
4
|
-
//# sourceMappingURL=createEntityDataKey.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createEntityDataKey.d.cts","sourceRoot":"","sources":["../../../../src/helpers/createEntityDataKey.cts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,eAAO,MAAM,mBAAmB,cACnB,UAAU,iBACN,aAAa,WACnB,mBAAmB,WAI7B,CAAC"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { type KeysAndPaths } from '@graphql-box/helpers';
|
|
2
|
-
import { type FieldNode } from 'graphql';
|
|
3
|
-
import { type CacheManagerContext } from '../types.cts';
|
|
4
|
-
export declare const filterOutPropsWithEntityArgsOrDirectives: (fieldData: unknown, field: FieldNode, ancestorKeysAndPaths: KeysAndPaths, context: CacheManagerContext) => unknown;
|
|
5
|
-
//# sourceMappingURL=filterOutPropsWithEntityArgsOrDirectives.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"filterOutPropsWithEntityArgsOrDirectives.d.cts","sourceRoot":"","sources":["../../../../src/helpers/filterOutPropsWithEntityArgsOrDirectives.cts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,YAAY,EAKlB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,eAAO,MAAM,wCAAwC,cACxC,OAAO,SACX,SAAS,wBACM,YAAY,WACzB,mBAAmB,YA2B7B,CAAC"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { type EntityData } from '@graphql-box/core';
|
|
2
|
-
import { type KeysAndPaths } from '@graphql-box/helpers';
|
|
3
|
-
import { type FieldNode } from 'graphql';
|
|
4
|
-
import { type CacheManagerContext } from '../types.cts';
|
|
5
|
-
export declare const filterOutPropsWithEntityOrArgs: (fieldData: EntityData, field: FieldNode, ancestorKeysAndPaths: KeysAndPaths, context: CacheManagerContext) => EntityData;
|
|
6
|
-
//# sourceMappingURL=filterOutPropsWithEntityOrArgs.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"filterOutPropsWithEntityOrArgs.d.cts","sourceRoot":"","sources":["../../../../src/helpers/filterOutPropsWithEntityOrArgs.cts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,KAAK,YAAY,EAAqD,MAAM,sBAAsB,CAAC;AAC5G,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,eAAO,MAAM,8BAA8B,cAC9B,UAAU,SACd,SAAS,wBACM,YAAY,WACzB,mBAAmB,eAmB7B,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isFieldEntity.d.cts","sourceRoot":"","sources":["../../../../src/helpers/isFieldEntity.cts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGnE,eAAO,MAAM,aAAa,cACb,OAAO,iBACH,aAAa,GAAG,SAAS,aAC7B,MAAM,4BAiBlB,CAAC"}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { EntityData, FieldTypeInfo } from '@graphql-box/core';
|
|
2
|
-
import type { CacheManagerContext } from '../types.ts';
|
|
3
|
-
export declare const createEntityDataKey: (fieldData: EntityData, fieldTypeInfo: FieldTypeInfo, context: CacheManagerContext) => string;
|
|
4
|
-
//# sourceMappingURL=createEntityDataKey.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createEntityDataKey.d.ts","sourceRoot":"","sources":["../../../../src/helpers/createEntityDataKey.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,eAAO,MAAM,mBAAmB,cACnB,UAAU,iBACN,aAAa,WACnB,mBAAmB,WAI7B,CAAC"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { type KeysAndPaths } from '@graphql-box/helpers';
|
|
2
|
-
import { type FieldNode } from 'graphql';
|
|
3
|
-
import { type CacheManagerContext } from '../types.ts';
|
|
4
|
-
export declare const filterOutPropsWithEntityArgsOrDirectives: (fieldData: unknown, field: FieldNode, ancestorKeysAndPaths: KeysAndPaths, context: CacheManagerContext) => unknown;
|
|
5
|
-
//# sourceMappingURL=filterOutPropsWithEntityArgsOrDirectives.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"filterOutPropsWithEntityArgsOrDirectives.d.ts","sourceRoot":"","sources":["../../../../src/helpers/filterOutPropsWithEntityArgsOrDirectives.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,YAAY,EAKlB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,eAAO,MAAM,wCAAwC,cACxC,OAAO,SACX,SAAS,wBACM,YAAY,WACzB,mBAAmB,YA2B7B,CAAC"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { type EntityData } from '@graphql-box/core';
|
|
2
|
-
import { type KeysAndPaths } from '@graphql-box/helpers';
|
|
3
|
-
import { type FieldNode } from 'graphql';
|
|
4
|
-
import { type CacheManagerContext } from '../types.ts';
|
|
5
|
-
export declare const filterOutPropsWithEntityOrArgs: (fieldData: EntityData, field: FieldNode, ancestorKeysAndPaths: KeysAndPaths, context: CacheManagerContext) => EntityData;
|
|
6
|
-
//# sourceMappingURL=filterOutPropsWithEntityOrArgs.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"filterOutPropsWithEntityOrArgs.d.ts","sourceRoot":"","sources":["../../../../src/helpers/filterOutPropsWithEntityOrArgs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,KAAK,YAAY,EAAqD,MAAM,sBAAsB,CAAC;AAC5G,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,eAAO,MAAM,8BAA8B,cAC9B,UAAU,SACd,SAAS,wBACM,YAAY,WACzB,mBAAmB,eAmB7B,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isFieldEntity.d.ts","sourceRoot":"","sources":["../../../../src/helpers/isFieldEntity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGnE,eAAO,MAAM,aAAa,cACb,OAAO,iBACH,aAAa,GAAG,SAAS,aAC7B,MAAM,4BAiBlB,CAAC"}
|