@graphql-box/cache-manager 5.1.0 → 5.2.4
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 +98 -127
- package/dist/types/cjs/debug/logCacheEntry.d.cts +1 -1
- package/dist/types/cjs/debug/logCacheEntry.d.cts.map +1 -1
- package/dist/types/cjs/debug/logCacheQuery.d.cts +1 -1
- package/dist/types/cjs/debug/logCacheQuery.d.cts.map +1 -1
- package/dist/types/cjs/debug/logPartialCompiled.d.cts +1 -1
- package/dist/types/cjs/debug/logPartialCompiled.d.cts.map +1 -1
- package/dist/types/cjs/helpers/areOnlyPopulatedFieldsTypeIdKeys.d.cts +1 -1
- package/dist/types/cjs/helpers/areOnlyPopulatedFieldsTypeIdKeys.d.cts.map +1 -1
- 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/debug/logCacheEntry.d.ts +1 -1
- package/dist/types/esm/debug/logCacheEntry.d.ts.map +1 -1
- package/dist/types/esm/debug/logCacheQuery.d.ts +1 -1
- package/dist/types/esm/debug/logCacheQuery.d.ts.map +1 -1
- package/dist/types/esm/debug/logPartialCompiled.d.ts +1 -1
- package/dist/types/esm/debug/logPartialCompiled.d.ts.map +1 -1
- package/dist/types/esm/helpers/areOnlyPopulatedFieldsTypeIdKeys.d.ts +1 -1
- package/dist/types/esm/helpers/areOnlyPopulatedFieldsTypeIdKeys.d.ts.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/debug/logCacheEntry.ts +1 -1
- package/src/debug/logCacheQuery.ts +1 -1
- package/src/debug/logPartialCompiled.ts +1 -1
- package/src/helpers/areOnlyPopulatedFieldsTypeIdKeys.ts +1 -1
- package/src/helpers/filterOutPropsWithArgsOrDirectives.ts +29 -0
- package/src/helpers/validTypeIdValue.ts +3 -3
- package/src/index.test.ts +137 -153
- package/src/main.ts +180 -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,12 +276,18 @@ 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
|
|
|
286
288
|
const filteredAST = filterQuery(requestData, cachedResponseData, cacheManagerContext);
|
|
287
289
|
const filteredRequest = print(filteredAST);
|
|
290
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
288
291
|
const { fragmentDefinitions, typeIDKey, ...rest } = cacheManagerContext;
|
|
289
292
|
assign(context, { ...rest, filteredRequest });
|
|
290
293
|
this._setPartialQueryResponse(hash, { cacheMetadata, data }, options, context);
|
|
@@ -298,13 +301,13 @@ export class CacheManager implements CacheManagerDef {
|
|
|
298
301
|
return this._cache;
|
|
299
302
|
}
|
|
300
303
|
|
|
301
|
-
public cacheQuery(
|
|
304
|
+
public async cacheQuery(
|
|
302
305
|
requestData: RequestData,
|
|
303
306
|
updatedRequestData: RequestData | undefined,
|
|
304
307
|
rawResponseData: RawResponseDataWithMaybeCacheMetadata,
|
|
305
308
|
options: RequestOptions,
|
|
306
309
|
context: RequestContext
|
|
307
|
-
): ResponseData {
|
|
310
|
+
): Promise<ResponseData> {
|
|
308
311
|
const cacheManagerContext: CacheManagerContext = {
|
|
309
312
|
...context,
|
|
310
313
|
fragmentDefinitions: getFragmentDefinitions((updatedRequestData ?? requestData).ast),
|
|
@@ -314,12 +317,12 @@ export class CacheManager implements CacheManagerDef {
|
|
|
314
317
|
return this._cacheResponse(requestData, updatedRequestData, rawResponseData, options, cacheManagerContext);
|
|
315
318
|
}
|
|
316
319
|
|
|
317
|
-
public cacheResponse(
|
|
320
|
+
public async cacheResponse(
|
|
318
321
|
requestData: RequestData,
|
|
319
322
|
rawResponseData: RawResponseDataWithMaybeCacheMetadata,
|
|
320
323
|
options: RequestOptions,
|
|
321
324
|
context: RequestContext
|
|
322
|
-
): ResponseData {
|
|
325
|
+
): Promise<ResponseData> {
|
|
323
326
|
const cacheManagerContext: CacheManagerContext = {
|
|
324
327
|
...context,
|
|
325
328
|
fragmentDefinitions: getFragmentDefinitions(requestData.ast),
|
|
@@ -361,13 +364,13 @@ export class CacheManager implements CacheManagerDef {
|
|
|
361
364
|
this._partialQueryResponses.delete(hash);
|
|
362
365
|
}
|
|
363
366
|
|
|
364
|
-
public setQueryResponseCacheEntry(
|
|
367
|
+
public async setQueryResponseCacheEntry(
|
|
365
368
|
requestData: RequestData,
|
|
366
369
|
responseData: ResponseData,
|
|
367
370
|
options: RequestOptions,
|
|
368
371
|
context: CacheManagerContext
|
|
369
|
-
): void {
|
|
370
|
-
this._setQueryResponseCacheEntry(requestData.hash, responseData, options, context);
|
|
372
|
+
): Promise<void> {
|
|
373
|
+
return this._setQueryResponseCacheEntry(requestData.hash, responseData, options, context);
|
|
371
374
|
}
|
|
372
375
|
|
|
373
376
|
private async _analyzeFieldNode(
|
|
@@ -448,7 +451,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
448
451
|
): Promise<void> {
|
|
449
452
|
const keysAndPaths = buildFieldKeysAndPaths(fieldNode, cachedAncestorFieldData, context);
|
|
450
453
|
const { propNameOrIndex, requestFieldCacheKey, requestFieldPath } = keysAndPaths;
|
|
451
|
-
const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath)
|
|
454
|
+
const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath)!;
|
|
452
455
|
|
|
453
456
|
const { cacheability, data, entityData, requestFieldPathData } = await this._retrieveCachedParentNodeData(
|
|
454
457
|
cachedAncestorFieldData,
|
|
@@ -551,13 +554,13 @@ export class CacheManager implements CacheManagerDef {
|
|
|
551
554
|
return cacheMetadata;
|
|
552
555
|
}
|
|
553
556
|
|
|
554
|
-
private _cacheResponse(
|
|
557
|
+
private async _cacheResponse(
|
|
555
558
|
requestData: RequestData,
|
|
556
559
|
updatedRequestData: RequestData | undefined,
|
|
557
560
|
rawResponseData: RawResponseDataWithMaybeCacheMetadata,
|
|
558
561
|
options: RequestOptions,
|
|
559
562
|
context: CacheManagerContext
|
|
560
|
-
): ResponseData {
|
|
563
|
+
): Promise<ResponseData> {
|
|
561
564
|
const normalizedResponseData = normalizePatchResponseData(rawResponseData, context);
|
|
562
565
|
let responseDataForCaching: RawResponseDataWithMaybeCacheMetadata | undefined = normalizedResponseData;
|
|
563
566
|
|
|
@@ -570,22 +573,24 @@ export class CacheManager implements CacheManagerDef {
|
|
|
570
573
|
responseDataForCaching = this._retrieveResponseDataForCaching(normalizedResponseData, context);
|
|
571
574
|
}
|
|
572
575
|
|
|
576
|
+
const dataCaching: Promise<void>[] = [];
|
|
577
|
+
|
|
573
578
|
if (responseDataForCaching) {
|
|
574
579
|
const { data } = responseDataForCaching;
|
|
575
580
|
const cacheMetadata = this._buildCacheMetadata(requestData, responseDataForCaching, options, context);
|
|
576
581
|
|
|
577
|
-
|
|
582
|
+
dataCaching.push(
|
|
578
583
|
this._setEntityAndRequestFieldPathCacheEntries(
|
|
579
584
|
requestData,
|
|
580
585
|
{
|
|
581
586
|
cacheMetadata,
|
|
582
|
-
entityData:
|
|
583
|
-
requestFieldPathData:
|
|
587
|
+
entityData: cloneDeep(data),
|
|
588
|
+
requestFieldPathData: cloneDeep(data),
|
|
584
589
|
},
|
|
585
590
|
options,
|
|
586
591
|
context
|
|
587
|
-
)
|
|
588
|
-
|
|
592
|
+
)
|
|
593
|
+
);
|
|
589
594
|
|
|
590
595
|
let queryCacheMetadata: CacheMetadata | undefined;
|
|
591
596
|
let queryData: PlainData | undefined;
|
|
@@ -594,21 +599,30 @@ export class CacheManager implements CacheManagerDef {
|
|
|
594
599
|
let partialQueryResponse: PartialQueryResponse | undefined;
|
|
595
600
|
|
|
596
601
|
if (context.queryFiltered && updatedRequestData) {
|
|
597
|
-
|
|
602
|
+
dataCaching.push(
|
|
603
|
+
this._setQueryResponseCacheEntry(updatedRequestData.hash, { cacheMetadata, data }, options, context)
|
|
604
|
+
);
|
|
605
|
+
|
|
598
606
|
partialQueryResponse = this._getPartialQueryResponse(requestData.hash);
|
|
599
607
|
}
|
|
600
608
|
|
|
601
609
|
queryCacheMetadata = CacheManager._mergeResponseCacheMetadata(cacheMetadata, partialQueryResponse);
|
|
602
610
|
queryData = this._mergeResponseData(data, partialQueryResponse);
|
|
603
611
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
612
|
+
dataCaching.push(
|
|
613
|
+
this._setQueryResponseCacheEntry(
|
|
614
|
+
requestData.hash,
|
|
615
|
+
{ cacheMetadata: queryCacheMetadata, data: queryData },
|
|
616
|
+
options,
|
|
617
|
+
context
|
|
618
|
+
)
|
|
609
619
|
);
|
|
610
620
|
}
|
|
611
621
|
|
|
622
|
+
if (options.awaitDataCaching) {
|
|
623
|
+
await Promise.all(dataCaching);
|
|
624
|
+
}
|
|
625
|
+
|
|
612
626
|
if (isNotResponseChunk(normalizedResponseData, context) && queryCacheMetadata && queryData) {
|
|
613
627
|
return {
|
|
614
628
|
cacheMetadata: queryCacheMetadata,
|
|
@@ -697,6 +711,22 @@ export class CacheManager implements CacheManagerDef {
|
|
|
697
711
|
}
|
|
698
712
|
}
|
|
699
713
|
|
|
714
|
+
private _isFieldEntity(fieldData: unknown, { isEntity, possibleTypes }: FieldTypeInfo): boolean {
|
|
715
|
+
if (!isPlainObject(fieldData) || !(this._typeIDKey in fieldData)) {
|
|
716
|
+
return false;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
if (isEntity) {
|
|
720
|
+
return true;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
if (possibleTypes.length === 0) {
|
|
724
|
+
return false;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
return possibleTypes.some(type => type.typeName === fieldData.__typename);
|
|
728
|
+
}
|
|
729
|
+
|
|
700
730
|
private _mergeResponseData(responseData: PlainData, partialQueryResponse?: PartialQueryResponse): PlainData {
|
|
701
731
|
if (!partialQueryResponse) {
|
|
702
732
|
return responseData;
|
|
@@ -705,24 +735,25 @@ export class CacheManager implements CacheManagerDef {
|
|
|
705
735
|
return mergeDataSets(partialQueryResponse.data, responseData, this._typeIDKey);
|
|
706
736
|
}
|
|
707
737
|
|
|
708
|
-
private _parseEntityAndRequestFieldPathCacheEntryData(
|
|
738
|
+
private async _parseEntityAndRequestFieldPathCacheEntryData(
|
|
709
739
|
field: FieldNode,
|
|
710
740
|
ancestorKeysAndPaths: AncestorKeysAndPaths,
|
|
711
741
|
{ cacheMetadata, entityData, requestFieldPathData }: ResponseDataForCaching,
|
|
712
742
|
options: RequestOptions,
|
|
713
743
|
context: CacheManagerContext
|
|
714
|
-
): void {
|
|
744
|
+
): Promise<void> {
|
|
715
745
|
const keysAndPaths = buildFieldKeysAndPaths(field, ancestorKeysAndPaths, context);
|
|
716
|
-
const {
|
|
746
|
+
const { requestFieldCacheKey, requestFieldPath, responseDataPath } = keysAndPaths;
|
|
717
747
|
const fieldData = get(requestFieldPathData, responseDataPath) as unknown;
|
|
718
748
|
const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
|
|
719
|
-
const cacheability = cacheMetadata.get(requestFieldPath);
|
|
720
749
|
|
|
721
750
|
if (!isObjectLike(fieldData) && !fieldTypeInfo?.hasDirectives) {
|
|
722
751
|
return;
|
|
723
752
|
}
|
|
724
753
|
|
|
725
754
|
if (isObjectLike(fieldData)) {
|
|
755
|
+
const promises: Promise<void>[] = [];
|
|
756
|
+
|
|
726
757
|
iterateChildFields(
|
|
727
758
|
field,
|
|
728
759
|
fieldData,
|
|
@@ -734,81 +765,41 @@ export class CacheManager implements CacheManagerDef {
|
|
|
734
765
|
_fragmentName: string | undefined,
|
|
735
766
|
childIndex?: number
|
|
736
767
|
) => {
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
768
|
+
promises.push(
|
|
769
|
+
this._parseEntityAndRequestFieldPathCacheEntryData(
|
|
770
|
+
childField,
|
|
771
|
+
{ index: childIndex, requestFieldCacheKey, requestFieldPath, responseDataPath },
|
|
772
|
+
{ cacheMetadata, entityData, requestFieldPathData },
|
|
773
|
+
options,
|
|
774
|
+
context
|
|
775
|
+
)
|
|
743
776
|
);
|
|
744
777
|
}
|
|
745
778
|
);
|
|
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
779
|
|
|
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
|
-
}
|
|
780
|
+
await Promise.all(promises);
|
|
776
781
|
}
|
|
777
782
|
|
|
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
|
-
}
|
|
783
|
+
await this._setEntityAndRequestFieldPathCacheEntry(
|
|
784
|
+
field,
|
|
785
|
+
keysAndPaths,
|
|
786
|
+
{ cacheMetadata, entityData, requestFieldPathData },
|
|
787
|
+
options,
|
|
788
|
+
context
|
|
789
|
+
);
|
|
798
790
|
}
|
|
799
791
|
|
|
800
792
|
private async _retrieveCachedEntityData(
|
|
801
793
|
validTypeIDValue: string | number,
|
|
802
|
-
|
|
794
|
+
{ possibleTypes, typeName }: FieldTypeInfo,
|
|
803
795
|
options: RequestOptions,
|
|
804
796
|
context: CacheManagerContext
|
|
805
797
|
): Promise<Partial<CheckCacheEntryResult<EntityData>>> {
|
|
806
|
-
const { possibleTypes = [], typeName } = fieldTypeInfo ?? {};
|
|
807
798
|
const typeNames = [...possibleTypes.map(type => type.typeName), typeName];
|
|
808
799
|
|
|
809
800
|
const checkResults = await Promise.all(
|
|
810
801
|
typeNames.map(name =>
|
|
811
|
-
this._checkCacheEntry<EntityData>(DATA_ENTITIES, `${
|
|
802
|
+
this._checkCacheEntry<EntityData>(DATA_ENTITIES, `${name}::${validTypeIDValue}`, options, context)
|
|
812
803
|
)
|
|
813
804
|
);
|
|
814
805
|
|
|
@@ -835,7 +826,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
835
826
|
private async _retrieveCachedParentNodeData(
|
|
836
827
|
{ entityData: ancestorEntityData, requestFieldPathData: ancestorRequestFieldPathData }: CachedAncestorFieldData,
|
|
837
828
|
{ hashedRequestFieldCacheKey, propNameOrIndex, requestFieldCacheKey }: KeysAndPaths,
|
|
838
|
-
fieldTypeInfo: FieldTypeInfo
|
|
829
|
+
fieldTypeInfo: FieldTypeInfo,
|
|
839
830
|
options: RequestOptions,
|
|
840
831
|
context: CacheManagerContext
|
|
841
832
|
) {
|
|
@@ -952,18 +943,18 @@ export class CacheManager implements CacheManagerDef {
|
|
|
952
943
|
_context: CacheManagerContext & { requestFieldCacheKey?: string }
|
|
953
944
|
): Promise<void> {
|
|
954
945
|
try {
|
|
955
|
-
await this._cache.set(`${cacheType}::${hash}`, value, cachemapOptions);
|
|
946
|
+
await this._cache.set(`${cacheType}::${hash}`, cloneDeep(value), cachemapOptions);
|
|
956
947
|
} catch {
|
|
957
948
|
// no catch
|
|
958
949
|
}
|
|
959
950
|
}
|
|
960
951
|
|
|
961
|
-
private _setEntityAndRequestFieldPathCacheEntries(
|
|
952
|
+
private async _setEntityAndRequestFieldPathCacheEntries(
|
|
962
953
|
requestData: RequestData,
|
|
963
954
|
responseData: ResponseDataForCaching,
|
|
964
955
|
options: RequestOptions,
|
|
965
956
|
context: CacheManagerContext
|
|
966
|
-
): void {
|
|
957
|
+
): Promise<void> {
|
|
967
958
|
const operationNode = getOperationDefinitions(requestData.ast, context.operation)[0];
|
|
968
959
|
|
|
969
960
|
if (!operationNode) {
|
|
@@ -976,22 +967,69 @@ export class CacheManager implements CacheManagerDef {
|
|
|
976
967
|
return;
|
|
977
968
|
}
|
|
978
969
|
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
970
|
+
await Promise.all(
|
|
971
|
+
fieldsAndTypeNames.map(({ fieldNode }) => {
|
|
972
|
+
return this._parseEntityAndRequestFieldPathCacheEntryData(
|
|
973
|
+
fieldNode,
|
|
974
|
+
{ requestFieldPath: context.operation },
|
|
975
|
+
responseData,
|
|
976
|
+
options,
|
|
977
|
+
context
|
|
978
|
+
);
|
|
979
|
+
})
|
|
980
|
+
);
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
private async _setEntityAndRequestFieldPathCacheEntry(
|
|
984
|
+
field: FieldNode,
|
|
985
|
+
keysAndPaths: KeysAndPaths,
|
|
986
|
+
{ cacheMetadata, entityData, requestFieldPathData }: ResponseDataForCaching,
|
|
987
|
+
options: RequestOptions,
|
|
988
|
+
context: CacheManagerContext
|
|
989
|
+
) {
|
|
990
|
+
const { requestFieldPath, responseDataPath } = keysAndPaths;
|
|
991
|
+
const fieldData = get(entityData, responseDataPath) as unknown;
|
|
992
|
+
const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
|
|
993
|
+
const cacheability = cacheMetadata.get(requestFieldPath);
|
|
994
|
+
|
|
995
|
+
if (isUndefined(fieldData) || !fieldTypeInfo || !cacheability) {
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
const promises: Promise<void>[] = [];
|
|
1000
|
+
|
|
1001
|
+
promises.push(
|
|
1002
|
+
this._setRequestFieldPathCacheEntry(
|
|
1003
|
+
field,
|
|
1004
|
+
keysAndPaths,
|
|
1005
|
+
{ cacheability, data: requestFieldPathData, fieldTypeInfo },
|
|
984
1006
|
options,
|
|
985
1007
|
context
|
|
1008
|
+
)
|
|
1009
|
+
);
|
|
1010
|
+
|
|
1011
|
+
const isEntity = this._isFieldEntity(fieldData, fieldTypeInfo);
|
|
1012
|
+
|
|
1013
|
+
if (!isEntity && fieldTypeInfo.hasArguments) {
|
|
1014
|
+
unset(entityData, responseDataPath);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
if (isEntity) {
|
|
1018
|
+
promises.push(
|
|
1019
|
+
this._setEntityCacheEntry(keysAndPaths, { cacheability, data: entityData, fieldTypeInfo }, options, context)
|
|
986
1020
|
);
|
|
987
|
-
}
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
await Promise.all(promises);
|
|
988
1024
|
}
|
|
989
1025
|
|
|
990
1026
|
private async _setEntityCacheEntry(
|
|
991
|
-
{
|
|
1027
|
+
{ responseDataPath }: KeysAndPaths,
|
|
1028
|
+
{ cacheability, data, fieldTypeInfo }: DataForCachingEntry,
|
|
992
1029
|
options: RequestOptions,
|
|
993
1030
|
context: CacheManagerContext
|
|
994
1031
|
) {
|
|
1032
|
+
let fieldData = get(data, responseDataPath) as EntityData;
|
|
995
1033
|
const fieldTypeName = fieldTypeInfo.isEntity ? fieldTypeInfo.typeName : fieldData.__typename;
|
|
996
1034
|
const entityDataKey = `${fieldTypeName}::${String(fieldData[this._typeIDKey])}`;
|
|
997
1035
|
const result = await this._checkCacheEntry<EntityData>(DATA_ENTITIES, entityDataKey, options, context);
|
|
@@ -1000,7 +1038,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
1000
1038
|
fieldData = mergeDataSets(result.entry, fieldData, this._typeIDKey);
|
|
1001
1039
|
}
|
|
1002
1040
|
|
|
1003
|
-
|
|
1041
|
+
await this._setCacheEntry(
|
|
1004
1042
|
DATA_ENTITIES,
|
|
1005
1043
|
entityDataKey,
|
|
1006
1044
|
fieldData,
|
|
@@ -1008,6 +1046,8 @@ export class CacheManager implements CacheManagerDef {
|
|
|
1008
1046
|
options,
|
|
1009
1047
|
context
|
|
1010
1048
|
);
|
|
1049
|
+
|
|
1050
|
+
set(data, responseDataPath, { __cacheKey: `${DATA_ENTITIES}::${entityDataKey}` });
|
|
1011
1051
|
}
|
|
1012
1052
|
|
|
1013
1053
|
private _setFieldCacheability(
|
|
@@ -1092,16 +1132,16 @@ export class CacheManager implements CacheManagerDef {
|
|
|
1092
1132
|
this._partialQueryResponses.set(hash, partialQueryResponse);
|
|
1093
1133
|
}
|
|
1094
1134
|
|
|
1095
|
-
private _setQueryResponseCacheEntry(
|
|
1135
|
+
private async _setQueryResponseCacheEntry(
|
|
1096
1136
|
hash: string,
|
|
1097
1137
|
{ cacheMetadata, data }: ResponseData,
|
|
1098
1138
|
options: RequestOptions,
|
|
1099
1139
|
context: CacheManagerContext
|
|
1100
|
-
): void {
|
|
1140
|
+
): Promise<void> {
|
|
1101
1141
|
const dehydratedCacheMetadata = dehydrateCacheMetadata(cacheMetadata);
|
|
1102
1142
|
const cacheControl = CacheManager._getOperationCacheControl(cacheMetadata, context.operation);
|
|
1103
1143
|
|
|
1104
|
-
|
|
1144
|
+
await this._setCacheEntry(
|
|
1105
1145
|
QUERY_RESPONSES,
|
|
1106
1146
|
hash,
|
|
1107
1147
|
{ cacheMetadata: dehydratedCacheMetadata, data },
|
|
@@ -1112,30 +1152,48 @@ export class CacheManager implements CacheManagerDef {
|
|
|
1112
1152
|
}
|
|
1113
1153
|
|
|
1114
1154
|
private async _setRequestFieldPathCacheEntry(
|
|
1155
|
+
field: FieldNode,
|
|
1115
1156
|
keysAndPaths: KeysAndPaths,
|
|
1116
|
-
{ cacheability,
|
|
1157
|
+
{ cacheability, data, fieldTypeInfo }: DataForCachingEntry,
|
|
1117
1158
|
options: RequestOptions,
|
|
1118
1159
|
context: CacheManagerContext
|
|
1119
1160
|
): Promise<void> {
|
|
1120
|
-
const { hashedRequestFieldCacheKey, requestFieldCacheKey } = keysAndPaths;
|
|
1161
|
+
const { hashedRequestFieldCacheKey, requestFieldCacheKey, responseDataPath } = keysAndPaths;
|
|
1162
|
+
let fieldData = get(data, responseDataPath) as unknown;
|
|
1163
|
+
const isEntity = this._isFieldEntity(fieldData, fieldTypeInfo);
|
|
1164
|
+
const hasArgsOrDirectives = fieldTypeInfo.hasArguments || fieldTypeInfo.hasDirectives;
|
|
1121
1165
|
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1166
|
+
if (context.operation === OperationTypeNode.QUERY && (isEntity || hasArgsOrDirectives)) {
|
|
1167
|
+
if (isPlainObject(fieldData) && field.selectionSet?.selections) {
|
|
1168
|
+
fieldData = filterOutPropsWithArgsOrDirectives(fieldData, field.selectionSet.selections, keysAndPaths, context);
|
|
1169
|
+
}
|
|
1126
1170
|
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1171
|
+
const result = await this._checkCacheEntry(REQUEST_FIELD_PATHS, hashedRequestFieldCacheKey, options, {
|
|
1172
|
+
...context,
|
|
1173
|
+
requestFieldCacheKey,
|
|
1174
|
+
});
|
|
1130
1175
|
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1176
|
+
if (result && isObjectLike(result.entry) && isObjectLike(fieldData)) {
|
|
1177
|
+
fieldData = mergeDataSets(result.entry, fieldData, this._typeIDKey);
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
await this._setCacheEntry(
|
|
1181
|
+
REQUEST_FIELD_PATHS,
|
|
1182
|
+
hashedRequestFieldCacheKey,
|
|
1183
|
+
fieldData,
|
|
1184
|
+
{ cacheHeaders: { cacheControl: cacheability.printCacheControl() }, tag: options.tag },
|
|
1185
|
+
options,
|
|
1186
|
+
{ ...context, requestFieldCacheKey }
|
|
1187
|
+
);
|
|
1188
|
+
|
|
1189
|
+
if (hasChildFields(field, { fragmentDefinitions: context.fragmentDefinitions })) {
|
|
1190
|
+
if (isEntity) {
|
|
1191
|
+
set(data, responseDataPath, { __cacheKey: `${REQUEST_FIELD_PATHS}::${hashedRequestFieldCacheKey}` });
|
|
1192
|
+
} else {
|
|
1193
|
+
unset(data, responseDataPath);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1139
1197
|
}
|
|
1140
1198
|
|
|
1141
1199
|
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"}
|