@graphql-box/cache-manager 5.3.3 → 5.4.1

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 (78) 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 +148 -148
  6. package/dist/types/cjs/constants.d.cts +5 -5
  7. package/dist/types/cjs/constants.d.cts.map +1 -1
  8. package/dist/types/cjs/debug/logCacheEntry.d.cts.map +1 -1
  9. package/dist/types/cjs/debug/logCacheQuery.d.cts.map +1 -1
  10. package/dist/types/cjs/debug/logPartialCompiled.d.cts.map +1 -1
  11. package/dist/types/cjs/helpers/createEntityDataKey.d.cts.map +1 -1
  12. package/dist/types/cjs/helpers/filterField.d.cts.map +1 -1
  13. package/dist/types/cjs/helpers/filterFragmentDefinitions.d.cts.map +1 -1
  14. package/dist/types/cjs/helpers/filterOutPropsWithEntityArgsOrDirectives.d.cts.map +1 -1
  15. package/dist/types/cjs/helpers/filterOutPropsWithEntityOrArgs.d.cts.map +1 -1
  16. package/dist/types/cjs/helpers/filterQuery.d.cts.map +1 -1
  17. package/dist/types/cjs/helpers/getDataValue.d.cts.map +1 -1
  18. package/dist/types/cjs/helpers/hasTypename.d.cts.map +1 -1
  19. package/dist/types/cjs/helpers/isFieldEntity.d.cts.map +1 -1
  20. package/dist/types/cjs/helpers/mergeObjects.d.cts.map +1 -1
  21. package/dist/types/cjs/helpers/normalizePatchResponseData.d.cts +4 -4
  22. package/dist/types/cjs/helpers/validTypeIdValue.d.cts.map +1 -1
  23. package/dist/types/cjs/main.d.cts +6 -6
  24. package/dist/types/cjs/main.d.cts.map +1 -1
  25. package/dist/types/cjs/types.d.cts +4 -4
  26. package/dist/types/cjs/types.d.cts.map +1 -1
  27. package/dist/types/esm/constants.d.ts +5 -5
  28. package/dist/types/esm/constants.d.ts.map +1 -1
  29. package/dist/types/esm/debug/logCacheEntry.d.ts.map +1 -1
  30. package/dist/types/esm/debug/logCacheQuery.d.ts.map +1 -1
  31. package/dist/types/esm/debug/logPartialCompiled.d.ts.map +1 -1
  32. package/dist/types/esm/helpers/createEntityDataKey.d.ts.map +1 -1
  33. package/dist/types/esm/helpers/filterField.d.ts.map +1 -1
  34. package/dist/types/esm/helpers/filterFragmentDefinitions.d.ts.map +1 -1
  35. package/dist/types/esm/helpers/filterOutPropsWithEntityArgsOrDirectives.d.ts.map +1 -1
  36. package/dist/types/esm/helpers/filterOutPropsWithEntityOrArgs.d.ts.map +1 -1
  37. package/dist/types/esm/helpers/filterQuery.d.ts.map +1 -1
  38. package/dist/types/esm/helpers/getDataValue.d.ts.map +1 -1
  39. package/dist/types/esm/helpers/hasTypename.d.ts.map +1 -1
  40. package/dist/types/esm/helpers/isFieldEntity.d.ts.map +1 -1
  41. package/dist/types/esm/helpers/mergeObjects.d.ts.map +1 -1
  42. package/dist/types/esm/helpers/normalizePatchResponseData.d.ts +4 -4
  43. package/dist/types/esm/helpers/validTypeIdValue.d.ts.map +1 -1
  44. package/dist/types/esm/main.d.ts +6 -6
  45. package/dist/types/esm/main.d.ts.map +1 -1
  46. package/dist/types/esm/types.d.ts +4 -4
  47. package/dist/types/esm/types.d.ts.map +1 -1
  48. package/dist/types/tsconfig.build.tsbuildinfo +1 -1
  49. package/package.json +17 -19
  50. package/src/__snapshots__/index.test.ts.snap +2592 -2592
  51. package/src/constants.ts +5 -5
  52. package/src/debug/logCacheEntry.ts +5 -3
  53. package/src/debug/logCacheQuery.ts +14 -4
  54. package/src/debug/logPartialCompiled.ts +1 -1
  55. package/src/helpers/checkFieldPathChecklist.ts +1 -1
  56. package/src/helpers/createEntityDataKey.ts +3 -1
  57. package/src/helpers/filterField.ts +3 -3
  58. package/src/helpers/filterFragmentDefinitions.ts +4 -2
  59. package/src/helpers/filterFragmentSpreads.ts +3 -3
  60. package/src/helpers/filterIDsAndTypeNames.ts +4 -4
  61. package/src/helpers/filterInlineFragments.ts +1 -1
  62. package/src/helpers/filterOperationAndFragmentDefinitions.ts +2 -2
  63. package/src/helpers/filterOutPropsWithEntityArgsOrDirectives.ts +4 -1
  64. package/src/helpers/filterOutPropsWithEntityOrArgs.ts +7 -3
  65. package/src/helpers/filterQuery.ts +4 -2
  66. package/src/helpers/getDataValue.ts +4 -0
  67. package/src/helpers/isFieldEntity.ts +1 -1
  68. package/src/helpers/isFirstResponseChunk.ts +1 -1
  69. package/src/helpers/isLastResponseChunk.ts +1 -1
  70. package/src/helpers/isNotLastResponseChunk.ts +1 -1
  71. package/src/helpers/isNotResponseChunk.ts +1 -1
  72. package/src/helpers/mergeObjects.ts +2 -0
  73. package/src/helpers/mergeResponseDataSets.ts +1 -1
  74. package/src/helpers/normalizePatchResponseData.ts +1 -1
  75. package/src/helpers/validTypeIdValue.ts +3 -1
  76. package/src/index.test.ts +84 -84
  77. package/src/main.ts +150 -109
  78. package/src/types.ts +9 -9
package/src/main.ts CHANGED
@@ -120,7 +120,7 @@ export class CacheManager implements CacheManagerDef {
120
120
  }
121
121
 
122
122
  const { isEntity, possibleTypes } = fieldTypeInfo;
123
- return isEntity || possibleTypes.some(type => !!type.isEntity);
123
+ return isEntity || possibleTypes.some(type => type.isEntity);
124
124
  }
125
125
 
126
126
  private static _isNodeRequestFieldPath(fieldTypeInfo?: FieldTypeInfo): boolean {
@@ -137,7 +137,7 @@ export class CacheManager implements CacheManagerDef {
137
137
 
138
138
  private static _mergeResponseCacheMetadata(
139
139
  cacheMetadata: CacheMetadata,
140
- partialQueryResponse?: PartialQueryResponse
140
+ partialQueryResponse?: PartialQueryResponse,
141
141
  ): CacheMetadata {
142
142
  if (!partialQueryResponse) {
143
143
  return cacheMetadata;
@@ -149,7 +149,7 @@ export class CacheManager implements CacheManagerDef {
149
149
  private static _setCachedData(
150
150
  responseData: unknown,
151
151
  { data }: MergedCachedFieldData,
152
- propNameOrIndex: string | number
152
+ propNameOrIndex: string | number,
153
153
  ): void {
154
154
  const setData = (value: unknown) => {
155
155
  if (isArray(responseData) && isNumber(propNameOrIndex)) {
@@ -174,7 +174,7 @@ export class CacheManager implements CacheManagerDef {
174
174
  { propNameOrIndex, requestFieldPath }: KeysAndPaths,
175
175
  typeNamesAndKind: TypenamesAndKind,
176
176
  _options: RequestOptions,
177
- { operation }: CacheManagerContext
177
+ { operation }: CacheManagerContext,
178
178
  ) {
179
179
  CacheManager._setCacheMetadata(cacheMetadata, cachedFieldData.cacheability, requestFieldPath, operation);
180
180
  CacheManager._setFieldPathChecklist(fieldPathChecklist, cachedFieldData, requestFieldPath, typeNamesAndKind);
@@ -185,7 +185,7 @@ export class CacheManager implements CacheManagerDef {
185
185
  cacheMetadata: CacheMetadata,
186
186
  cacheability: Cacheability | undefined,
187
187
  requestFieldPath: string,
188
- operation: string
188
+ operation: string,
189
189
  ): void {
190
190
  if (!cacheability) {
191
191
  return;
@@ -203,7 +203,7 @@ export class CacheManager implements CacheManagerDef {
203
203
  fieldPathChecklist: FieldPathChecklist,
204
204
  { data }: MergedCachedFieldData,
205
205
  requestFieldPath: string,
206
- { dataTypename: dataTypeName, fieldTypename: fieldTypeName, fragmentKind, fragmentName }: TypenamesAndKind
206
+ { dataTypename: dataTypeName, fieldTypename: fieldTypeName, fragmentKind, fragmentName }: TypenamesAndKind,
207
207
  ): void {
208
208
  if (isUndefined(fieldTypeName) || fragmentKind === Kind.FRAGMENT_SPREAD) {
209
209
  if (fieldPathChecklist.has(requestFieldPath)) {
@@ -231,14 +231,14 @@ export class CacheManager implements CacheManagerDef {
231
231
  ]);
232
232
  }
233
233
 
234
- private _cache: Core;
235
- private _cacheTiersEnabled: CacheTiersEnabled = { entity: false, queryResponse: true, requestPath: false };
236
- private _cascadeCacheControl: boolean;
237
- private _fallbackOperationCacheability: string;
234
+ private _cache: Core | undefined;
235
+ private readonly _cacheTiersEnabled: CacheTiersEnabled = { entity: false, queryResponse: true, requestPath: false };
236
+ private readonly _cascadeCacheControl: boolean;
237
+ private readonly _fallbackOperationCacheability: string;
238
238
  private _partialQueryResponses: PartialQueryResponses = new Map();
239
239
  private _responseChunksAwaitingCaching = new Map<string, RawResponseDataWithMaybeCacheMetadata[]>();
240
- private _typeCacheDirectives: Record<string, string>;
241
- private _typeIDKey: string;
240
+ private readonly _typeCacheDirectives: Record<string, string>;
241
+ private readonly _typeIDKey: string;
242
242
 
243
243
  constructor(options: UserOptions) {
244
244
  const errors: ArgsError[] = [];
@@ -256,7 +256,19 @@ export class CacheManager implements CacheManagerDef {
256
256
  throw new GroupedError('@graphql-box/cache-manager argument validation errors.', errors);
257
257
  }
258
258
 
259
- this._cache = options.cache;
259
+ if (typeof options.cache === 'function') {
260
+ void options
261
+ .cache()
262
+ .then(cache => {
263
+ this._cache = cache;
264
+ })
265
+ .catch((error: unknown) => {
266
+ throw error;
267
+ });
268
+ } else {
269
+ this._cache = options.cache;
270
+ }
271
+
260
272
  this._cacheTiersEnabled = { ...this._cacheTiersEnabled, ...options.cacheTiersEnabled };
261
273
  this._cascadeCacheControl = options.cascadeCacheControl ?? false;
262
274
  this._fallbackOperationCacheability = options.fallbackOperationCacheability ?? NO_CACHE;
@@ -267,7 +279,7 @@ export class CacheManager implements CacheManagerDef {
267
279
  public async analyzeQuery(
268
280
  requestData: RequestData,
269
281
  options: RequestOptions,
270
- context: RequestContext
282
+ context: RequestContext,
271
283
  ): Promise<AnalyzeQueryResult> {
272
284
  // the client has already checked the query response cache with
273
285
  // `checkQueryResponseCacheEntry`, so at this point the entity and
@@ -290,7 +302,7 @@ export class CacheManager implements CacheManagerDef {
290
302
  /**
291
303
  * Second half of check is required for the scenario where the only matching data is
292
304
  * the typeIDKey field, i.e. "id", in which case there is no point settings a partial
293
- * query reponse because we request the typeIDKey field with every request.
305
+ * query response because we request the typeIDKey field with every request.
294
306
  */
295
307
  if (fieldCount.missing === fieldCount.total || areOnlyPopulatedFieldsTypeIdKeys(data, this._typeIDKey)) {
296
308
  return { updated: requestData };
@@ -321,7 +333,7 @@ export class CacheManager implements CacheManagerDef {
321
333
  };
322
334
  }
323
335
 
324
- get cache(): Core {
336
+ get cache(): Core | undefined {
325
337
  return this._cache;
326
338
  }
327
339
 
@@ -330,7 +342,7 @@ export class CacheManager implements CacheManagerDef {
330
342
  updatedRequestData: RequestData | undefined,
331
343
  rawResponseData: RawResponseDataWithMaybeCacheMetadata,
332
344
  options: RequestOptions,
333
- context: RequestContext
345
+ context: RequestContext,
334
346
  ): Promise<ResponseData> {
335
347
  const cacheManagerContext: CacheManagerContext = {
336
348
  ...context,
@@ -345,7 +357,7 @@ export class CacheManager implements CacheManagerDef {
345
357
  requestData: RequestData,
346
358
  rawResponseData: RawResponseDataWithMaybeCacheMetadata,
347
359
  options: RequestOptions,
348
- context: RequestContext
360
+ context: RequestContext,
349
361
  ): Promise<ResponseData> {
350
362
  const cacheManagerContext: CacheManagerContext = {
351
363
  ...context,
@@ -360,7 +372,7 @@ export class CacheManager implements CacheManagerDef {
360
372
  cacheType: CacheTypes,
361
373
  hash: string,
362
374
  options: RequestOptions,
363
- context: RequestContext & { requestFieldCacheKey?: string }
375
+ context: RequestContext & { requestFieldCacheKey?: string },
364
376
  ): Promise<CheckCacheEntryResult | false> {
365
377
  if (allCacheTiersDisabled(this._cacheTiersEnabled)) {
366
378
  return false;
@@ -372,19 +384,19 @@ export class CacheManager implements CacheManagerDef {
372
384
  public async checkQueryResponseCacheEntry(
373
385
  hash: string,
374
386
  options: RequestOptions,
375
- context: RequestContext
387
+ context: RequestContext,
376
388
  ): Promise<ResponseData | false> {
377
389
  if (!queryResponseCacheTierEnabled(this._cacheTiersEnabled)) {
378
390
  return false;
379
391
  }
380
392
 
381
- const result = await this._checkCacheEntry(QUERY_RESPONSES, hash, options, context);
393
+ const result = await this._checkCacheEntry<QueryResponseCacheEntry>(QUERY_RESPONSES, hash, options, context);
382
394
 
383
395
  if (!result) {
384
396
  return false;
385
397
  }
386
398
 
387
- const { cacheMetadata, data } = result.entry as QueryResponseCacheEntry;
399
+ const { cacheMetadata, data } = result.entry;
388
400
 
389
401
  return {
390
402
  cacheMetadata: rehydrateCacheMetadata(cacheMetadata),
@@ -402,7 +414,7 @@ export class CacheManager implements CacheManagerDef {
402
414
  requestData: RequestData,
403
415
  responseData: ResponseData,
404
416
  options: RequestOptions,
405
- context: CacheManagerContext
417
+ context: CacheManagerContext,
406
418
  ): Promise<void> {
407
419
  if (queryResponseCacheTierEnabled(this._cacheTiersEnabled)) {
408
420
  return this._setQueryResponseCacheEntry(requestData.hash, responseData, options, context);
@@ -414,7 +426,7 @@ export class CacheManager implements CacheManagerDef {
414
426
  cachedAncestorFieldData: CachedAncestorFieldData,
415
427
  cachedResponseData: CachedResponseData & { data: unknown },
416
428
  options: RequestOptions,
417
- context: CacheManagerContext
429
+ context: CacheManagerContext,
418
430
  ): Promise<void> {
419
431
  await (hasChildFields(fieldNode, { fragmentDefinitions: context.fragmentDefinitions })
420
432
  ? this._analyzeParentFieldNode(fieldNode, cachedAncestorFieldData, cachedResponseData, options, context)
@@ -426,7 +438,7 @@ export class CacheManager implements CacheManagerDef {
426
438
  cachedAncestorFieldData: CachedAncestorFieldData,
427
439
  cachedResponseData: CachedResponseData & { data: unknown },
428
440
  options: RequestOptions,
429
- context: CacheManagerContext
441
+ context: CacheManagerContext,
430
442
  ): Promise<void> {
431
443
  const keysAndPaths = buildFieldKeysAndPaths(fieldNode, cachedAncestorFieldData, context);
432
444
  const { hashedRequestFieldCacheKey, propNameOrIndex, requestFieldCacheKey, requestFieldPath } = keysAndPaths;
@@ -436,8 +448,8 @@ export class CacheManager implements CacheManagerDef {
436
448
  const dataTypename = hasTypename(entityData)
437
449
  ? entityData.__typename
438
450
  : hasTypename(requestFieldPathData)
439
- ? requestFieldPathData.__typename
440
- : undefined;
451
+ ? requestFieldPathData.__typename
452
+ : undefined;
441
453
 
442
454
  const typenamesAndKind = {
443
455
  dataTypename,
@@ -455,7 +467,7 @@ export class CacheManager implements CacheManagerDef {
455
467
  cachedResponseData.fieldPathChecklist,
456
468
  { data: cachedFieldData },
457
469
  requestFieldPath,
458
- typenamesAndKind
470
+ typenamesAndKind,
459
471
  );
460
472
 
461
473
  CacheManager._setCachedData(cachedResponseData.data, { data: cachedFieldData }, propNameOrIndex);
@@ -464,7 +476,7 @@ export class CacheManager implements CacheManagerDef {
464
476
  hashedRequestFieldCacheKey,
465
477
  requestFieldCacheKey,
466
478
  options,
467
- context
479
+ context,
468
480
  );
469
481
 
470
482
  CacheManager._setCachedResponseSlice(
@@ -473,7 +485,7 @@ export class CacheManager implements CacheManagerDef {
473
485
  keysAndPaths,
474
486
  typenamesAndKind,
475
487
  options,
476
- context
488
+ context,
477
489
  );
478
490
  }
479
491
  }
@@ -483,29 +495,42 @@ export class CacheManager implements CacheManagerDef {
483
495
  cachedAncestorFieldData: CachedAncestorFieldData,
484
496
  cachedResponseData: CachedResponseData,
485
497
  options: RequestOptions,
486
- context: CacheManagerContext
498
+ context: CacheManagerContext,
487
499
  ): Promise<void> {
488
500
  const keysAndPaths = buildFieldKeysAndPaths(fieldNode, cachedAncestorFieldData, context);
489
501
  const { propNameOrIndex, requestFieldCacheKey, requestFieldPath } = keysAndPaths;
490
- const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath)!;
502
+ const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
503
+
504
+ if (!fieldTypeInfo) {
505
+ return;
506
+ }
491
507
 
492
508
  const { cacheability, data, entityData, requestFieldPathData } = await this._retrieveCachedParentNodeData(
493
509
  cachedAncestorFieldData,
494
510
  keysAndPaths,
495
511
  fieldTypeInfo,
496
512
  options,
497
- context
513
+ context,
498
514
  );
499
515
 
500
516
  const { fragmentKind, fragmentName, typeName } = cachedAncestorFieldData;
517
+ // Don't get this one, need to look into it more
518
+ // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
519
+ const dataTypename = get(data, TYPE_NAME_KEY);
501
520
 
502
521
  CacheManager._setCachedResponseSlice(
503
522
  { cacheability, data },
504
523
  cachedResponseData,
505
524
  keysAndPaths,
506
- { dataTypename: get(data, TYPE_NAME_KEY), fieldTypename: typeName, fragmentKind, fragmentName },
525
+
526
+ {
527
+ dataTypename,
528
+ fieldTypename: typeName,
529
+ fragmentKind,
530
+ fragmentName,
531
+ },
507
532
  options,
508
- context
533
+ context,
509
534
  );
510
535
 
511
536
  if (!isObjectLike(data)) {
@@ -523,7 +548,7 @@ export class CacheManager implements CacheManagerDef {
523
548
  childTypeName: string | undefined,
524
549
  childFragmentKind: string | undefined,
525
550
  childFragmentName: string | undefined,
526
- childIndex?: number
551
+ childIndex?: number,
527
552
  ) => {
528
553
  promises.push(
529
554
  this._analyzeFieldNode(
@@ -541,19 +566,18 @@ export class CacheManager implements CacheManagerDef {
541
566
  },
542
567
  {
543
568
  ...cachedResponseData,
544
- /**
545
- * `cachedResponseData.data[propNameOrIndex]` will always be either an empty array
546
- * or an empty object at this point as based on whether `data` is object-like
547
- * `cachedResponseData.data[propNameOrIndex]` is set accordingly in
548
- * _setCachedResponseData > _setCachedData
549
- */
569
+ // `cachedResponseData.data[propNameOrIndex]` will always be either an empty array
570
+ // or an empty object at this point as based on whether `data` is object-like
571
+ // `cachedResponseData.data[propNameOrIndex]` is set accordingly in
572
+ // _setCachedResponseData > _setCachedData
573
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
550
574
  data: getDataValue<PlainData>(cachedResponseData.data, propNameOrIndex)!,
551
575
  },
552
576
  options,
553
- context
554
- )
577
+ context,
578
+ ),
555
579
  );
556
- }
580
+ },
557
581
  );
558
582
 
559
583
  await Promise.all(promises);
@@ -563,7 +587,7 @@ export class CacheManager implements CacheManagerDef {
563
587
  { ast }: RequestData,
564
588
  { data, ...otherProps }: RawResponseDataWithMaybeCacheMetadata,
565
589
  options: RequestOptions,
566
- context: CacheManagerContext
590
+ context: CacheManagerContext,
567
591
  ): CacheMetadata {
568
592
  const cacheMetadata = this._createCacheMetadata({ data, ...otherProps }, context);
569
593
  const queryNode = getOperationDefinitions(ast, context.operation)[0];
@@ -584,7 +608,7 @@ export class CacheManager implements CacheManagerDef {
584
608
  { requestFieldPath: context.operation },
585
609
  { cacheMetadata, data },
586
610
  options,
587
- context
611
+ context,
588
612
  );
589
613
 
590
614
  return cacheMetadata;
@@ -595,7 +619,7 @@ export class CacheManager implements CacheManagerDef {
595
619
  updatedRequestData: RequestData | undefined,
596
620
  rawResponseData: RawResponseDataWithMaybeCacheMetadata,
597
621
  options: RequestOptions,
598
- context: CacheManagerContext
622
+ context: CacheManagerContext,
599
623
  ): Promise<ResponseData> {
600
624
  const normalizedResponseData = normalizePatchResponseData(rawResponseData, context);
601
625
  let responseDataForCaching: RawResponseDataWithMaybeCacheMetadata | undefined = normalizedResponseData;
@@ -625,8 +649,8 @@ export class CacheManager implements CacheManagerDef {
625
649
  requestFieldPathData: structuredClone(data),
626
650
  },
627
651
  options,
628
- context
629
- )
652
+ context,
653
+ ),
630
654
  );
631
655
  }
632
656
 
@@ -638,7 +662,7 @@ export class CacheManager implements CacheManagerDef {
638
662
 
639
663
  if (context.queryFiltered && updatedRequestData) {
640
664
  dataCaching.push(
641
- this._setQueryResponseCacheEntry(updatedRequestData.hash, { cacheMetadata, data }, options, context)
665
+ this._setQueryResponseCacheEntry(updatedRequestData.hash, { cacheMetadata, data }, options, context),
642
666
  );
643
667
 
644
668
  partialQueryResponse = this._getPartialQueryResponse(requestData.hash);
@@ -652,8 +676,8 @@ export class CacheManager implements CacheManagerDef {
652
676
  requestData.hash,
653
677
  { cacheMetadata: queryCacheMetadata, data: queryData },
654
678
  options,
655
- context
656
- )
679
+ context,
680
+ ),
657
681
  );
658
682
  }
659
683
 
@@ -683,7 +707,7 @@ export class CacheManager implements CacheManagerDef {
683
707
  cacheType: CacheTypes,
684
708
  hash: string,
685
709
  options: RequestOptions,
686
- context: CacheManagerContext & { requestFieldCacheKey?: string }
710
+ context: CacheManagerContext & { requestFieldCacheKey?: string },
687
711
  ): Promise<CheckCacheEntryResult<T> | false> {
688
712
  try {
689
713
  const cacheability = await this._hasCacheEntry(cacheType, hash);
@@ -706,7 +730,7 @@ export class CacheManager implements CacheManagerDef {
706
730
 
707
731
  private _createCacheMetadata(
708
732
  { _cacheMetadata, headers }: RawResponseDataWithMaybeCacheMetadata,
709
- { operation }: CacheManagerContext
733
+ { operation }: CacheManagerContext,
710
734
  ): CacheMetadata {
711
735
  const cacheMetadata = new Map<string, Cacheability>();
712
736
 
@@ -730,9 +754,9 @@ export class CacheManager implements CacheManagerDef {
730
754
  cacheType: CacheTypes,
731
755
  hash: string,
732
756
  _options: RequestOptions,
733
- _context: CacheManagerContext & { requestFieldCacheKey?: string }
757
+ _context: CacheManagerContext & { requestFieldCacheKey?: string },
734
758
  ): Promise<T | undefined> {
735
- return this._cache.get<T>(`${cacheType}::${hash}`);
759
+ return this._cache?.get<T>(`${cacheType}::${hash}`);
736
760
  }
737
761
 
738
762
  private _getPartialQueryResponse(hash: string): PartialQueryResponse | undefined {
@@ -743,7 +767,7 @@ export class CacheManager implements CacheManagerDef {
743
767
 
744
768
  private async _hasCacheEntry(cacheType: CacheTypes, hash: string): Promise<Cacheability | false> {
745
769
  try {
746
- return await this._cache.has(`${cacheType}::${hash}`);
770
+ return (await this._cache?.has(`${cacheType}::${hash}`)) ?? false;
747
771
  } catch {
748
772
  return false;
749
773
  }
@@ -762,10 +786,12 @@ export class CacheManager implements CacheManagerDef {
762
786
  ancestorKeysAndPaths: AncestorKeysAndPaths,
763
787
  { cacheMetadata, entityData, requestFieldPathData }: ResponseDataForCaching,
764
788
  options: RequestOptions,
765
- context: CacheManagerContext
789
+ context: CacheManagerContext,
766
790
  ): Promise<void> {
767
791
  const keysAndPaths = buildFieldKeysAndPaths(field, ancestorKeysAndPaths, context);
768
792
  const { hashedRequestFieldCacheKey, requestFieldCacheKey, requestFieldPath, responseDataPath } = keysAndPaths;
793
+ // get has rubbish return typing
794
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
769
795
  const fieldData = get(requestFieldPathData, responseDataPath) as unknown;
770
796
  const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
771
797
  const cacheability = cacheMetadata.get(requestFieldPath);
@@ -786,7 +812,7 @@ export class CacheManager implements CacheManagerDef {
786
812
  _typeName: string | undefined,
787
813
  _fragmentKind: string | undefined,
788
814
  _fragmentName: string | undefined,
789
- childIndex?: number
815
+ childIndex?: number,
790
816
  ) => {
791
817
  promises.push(
792
818
  this._parseEntityAndRequestFieldPathCacheEntryData(
@@ -794,10 +820,10 @@ export class CacheManager implements CacheManagerDef {
794
820
  { index: childIndex, requestFieldCacheKey, requestFieldPath, responseDataPath },
795
821
  { cacheMetadata, entityData, requestFieldPathData },
796
822
  options,
797
- context
798
- )
823
+ context,
824
+ ),
799
825
  );
800
- }
826
+ },
801
827
  );
802
828
 
803
829
  await Promise.all(promises);
@@ -808,7 +834,7 @@ export class CacheManager implements CacheManagerDef {
808
834
  }
809
835
 
810
836
  const isEntity = isFieldEntity(fieldData, fieldTypeInfo, this._typeIDKey);
811
- const hasArgsOrDirectives = !!fieldTypeInfo.hasArguments || !!fieldTypeInfo.hasDirectives;
837
+ const hasArgsOrDirectives = fieldTypeInfo.hasArguments || fieldTypeInfo.hasDirectives;
812
838
 
813
839
  if (
814
840
  context.operation === OperationTypeNode.QUERY &&
@@ -823,7 +849,7 @@ export class CacheManager implements CacheManagerDef {
823
849
  fieldTypeInfo,
824
850
  },
825
851
  options,
826
- context
852
+ context,
827
853
  );
828
854
 
829
855
  if (hasChildFields(field, { fragmentDefinitions: context.fragmentDefinitions })) {
@@ -842,15 +868,17 @@ export class CacheManager implements CacheManagerDef {
842
868
  {
843
869
  cacheability,
844
870
  fieldData: filterOutPropsWithEntityOrArgs(
845
- structuredClone(get(entityData, responseDataPath)) as EntityData,
871
+ // Casting here for ease of typing
872
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
873
+ structuredClone(get(entityData, responseDataPath) as EntityData),
846
874
  field,
847
875
  keysAndPaths,
848
- context
876
+ context,
849
877
  ),
850
878
  fieldTypeInfo,
851
879
  },
852
880
  options,
853
- context
881
+ context,
854
882
  );
855
883
 
856
884
  set(entityData, responseDataPath, {
@@ -863,17 +891,17 @@ export class CacheManager implements CacheManagerDef {
863
891
  validTypeIDValue: string | number,
864
892
  { possibleTypes, typeName }: FieldTypeInfo,
865
893
  options: RequestOptions,
866
- context: CacheManagerContext
894
+ context: CacheManagerContext,
867
895
  ): Promise<Partial<CheckCacheEntryResult<EntityData>>> {
868
896
  const typeNames = [...possibleTypes.map(type => type.typeName), typeName];
869
897
 
870
898
  const checkResults = await Promise.all(
871
899
  typeNames.map(name =>
872
- this._checkCacheEntry<EntityData>(DATA_ENTITIES, `${name}::${validTypeIDValue}`, options, context)
873
- )
900
+ this._checkCacheEntry<EntityData>(DATA_ENTITIES, `${name}::${String(validTypeIDValue)}`, options, context),
901
+ ),
874
902
  );
875
903
 
876
- const validResults = checkResults.filter(result => !!result) as CheckCacheEntryResult<EntityData>[];
904
+ const validResults = checkResults.filter(result => !!result);
877
905
  let validResult: CheckCacheEntryResult<EntityData> | undefined;
878
906
 
879
907
  if (validResults.length === 1) {
@@ -881,13 +909,19 @@ export class CacheManager implements CacheManagerDef {
881
909
  } else if (validResults.length > 1) {
882
910
  validResults.sort(({ cacheability: a }, { cacheability: b }) => a.metadata.ttl - b.metadata.ttl);
883
911
 
884
- validResult = {
885
- cacheability: validResults[0]!.cacheability,
886
- entry: validResults.reduce<Partial<EntityData>>(
887
- (obj, { entry }) => mergeDataSets(obj, entry, this._typeIDKey),
888
- {}
889
- ) as EntityData,
890
- };
912
+ const firstResult = validResults[0];
913
+
914
+ if (firstResult) {
915
+ validResult = {
916
+ cacheability: firstResult.cacheability,
917
+ // By the time the merge has happened, the type is EntityData
918
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
919
+ entry: validResults.reduce<Partial<EntityData>>(
920
+ (obj, { entry }) => mergeDataSets(obj, entry, this._typeIDKey),
921
+ {},
922
+ ) as EntityData,
923
+ };
924
+ }
891
925
  }
892
926
 
893
927
  return validResult ?? {};
@@ -898,7 +932,7 @@ export class CacheManager implements CacheManagerDef {
898
932
  { hashedRequestFieldCacheKey, propNameOrIndex, requestFieldCacheKey }: KeysAndPaths,
899
933
  fieldTypeInfo: FieldTypeInfo,
900
934
  options: RequestOptions,
901
- context: CacheManagerContext
935
+ context: CacheManagerContext,
902
936
  ) {
903
937
  let entityData = CacheManager._getFieldDataFromAncestor(ancestorEntityData, propNameOrIndex);
904
938
  let requestFieldPathData = CacheManager._getFieldDataFromAncestor(ancestorRequestFieldPathData, propNameOrIndex);
@@ -909,7 +943,7 @@ export class CacheManager implements CacheManagerDef {
909
943
  hashedRequestFieldCacheKey,
910
944
  requestFieldCacheKey,
911
945
  options,
912
- context
946
+ context,
913
947
  );
914
948
 
915
949
  requestFieldPathData = combineDataSets(requestFieldPathData, entry, this._typeIDKey);
@@ -930,7 +964,7 @@ export class CacheManager implements CacheManagerDef {
930
964
  validTypeIDValue,
931
965
  fieldTypeInfo,
932
966
  options,
933
- context
967
+ context,
934
968
  );
935
969
 
936
970
  entityData = combineDataSets(entityData, entry, this._typeIDKey);
@@ -956,7 +990,7 @@ export class CacheManager implements CacheManagerDef {
956
990
  hash: string,
957
991
  requestFieldCacheKey: string,
958
992
  options: RequestOptions,
959
- context: CacheManagerContext
993
+ context: CacheManagerContext,
960
994
  ): Promise<Partial<CheckCacheEntryResult>> {
961
995
  return (
962
996
  (await this._checkCacheEntry(REQUEST_FIELD_PATHS, hash, options, { ...context, requestFieldCacheKey })) || {}
@@ -966,7 +1000,7 @@ export class CacheManager implements CacheManagerDef {
966
1000
  private async _retrieveCachedResponseData(
967
1001
  { ast }: RequestData,
968
1002
  options: RequestOptions,
969
- context: CacheManagerContext
1003
+ context: CacheManagerContext,
970
1004
  ): Promise<CachedResponseData> {
971
1005
  const cachedResponseData: CachedResponseData = {
972
1006
  cacheMetadata: new Map(),
@@ -989,8 +1023,14 @@ export class CacheManager implements CacheManagerDef {
989
1023
 
990
1024
  await Promise.all(
991
1025
  fieldsAndTypeNames.map(({ fieldNode }) =>
992
- this._analyzeFieldNode(fieldNode, { requestFieldPath: context.operation }, cachedResponseData, options, context)
993
- )
1026
+ this._analyzeFieldNode(
1027
+ fieldNode,
1028
+ { requestFieldPath: context.operation },
1029
+ cachedResponseData,
1030
+ options,
1031
+ context,
1032
+ ),
1033
+ ),
994
1034
  );
995
1035
 
996
1036
  cachedResponseData.fieldCount = CacheManager._countFieldPathChecklist(cachedResponseData.fieldPathChecklist);
@@ -999,12 +1039,11 @@ export class CacheManager implements CacheManagerDef {
999
1039
 
1000
1040
  private _retrieveResponseDataForCaching(
1001
1041
  normalizedResponseData: RawResponseDataWithMaybeCacheMetadata,
1002
- context: CacheManagerContext
1042
+ context: CacheManagerContext,
1003
1043
  ) {
1004
- const responseChunks = this._responseChunksAwaitingCaching.get(context.requestID)!;
1005
-
1044
+ const responseChunks = this._responseChunksAwaitingCaching.get(context.requestID);
1006
1045
  this._responseChunksAwaitingCaching.delete(context.requestID);
1007
- return mergeResponseDataSets([...responseChunks, normalizedResponseData]);
1046
+ return mergeResponseDataSets([...(responseChunks ?? []), normalizedResponseData]);
1008
1047
  }
1009
1048
 
1010
1049
  @logCacheEntry()
@@ -1014,10 +1053,10 @@ export class CacheManager implements CacheManagerDef {
1014
1053
  value: unknown,
1015
1054
  cachemapOptions: CachemapOptions,
1016
1055
  _options: RequestOptions,
1017
- _context: CacheManagerContext & { requestFieldCacheKey?: string }
1056
+ _context: CacheManagerContext & { requestFieldCacheKey?: string },
1018
1057
  ): Promise<void> {
1019
1058
  try {
1020
- await this._cache.set(`${cacheType}::${hash}`, structuredClone(value), cachemapOptions);
1059
+ await this._cache?.set(`${cacheType}::${hash}`, structuredClone(value), cachemapOptions);
1021
1060
  } catch {
1022
1061
  // no catch
1023
1062
  }
@@ -1027,7 +1066,7 @@ export class CacheManager implements CacheManagerDef {
1027
1066
  requestData: RequestData,
1028
1067
  responseData: ResponseDataForCaching,
1029
1068
  options: RequestOptions,
1030
- context: CacheManagerContext
1069
+ context: CacheManagerContext,
1031
1070
  ): Promise<void> {
1032
1071
  const operationNode = getOperationDefinitions(requestData.ast, context.operation)[0];
1033
1072
 
@@ -1048,16 +1087,16 @@ export class CacheManager implements CacheManagerDef {
1048
1087
  { requestFieldPath: context.operation },
1049
1088
  responseData,
1050
1089
  options,
1051
- context
1090
+ context,
1052
1091
  );
1053
- })
1092
+ }),
1054
1093
  );
1055
1094
  }
1056
1095
 
1057
1096
  private async _setEntityCacheEntry(
1058
1097
  { cacheability, fieldData, fieldTypeInfo }: DataForCachingEntry<EntityData>,
1059
1098
  options: RequestOptions,
1060
- context: CacheManagerContext
1099
+ context: CacheManagerContext,
1061
1100
  ) {
1062
1101
  const fieldTypeName = fieldTypeInfo.isEntity ? fieldTypeInfo.typeName : fieldData.__typename;
1063
1102
  const entityDataKey = `${fieldTypeName}::${String(fieldData[this._typeIDKey])}`;
@@ -1073,7 +1112,7 @@ export class CacheManager implements CacheManagerDef {
1073
1112
  fieldData,
1074
1113
  { cacheHeaders: { cacheControl: cacheability.printCacheControl() }, tag: options.tag },
1075
1114
  options,
1076
- context
1115
+ context,
1077
1116
  );
1078
1117
  }
1079
1118
 
@@ -1082,7 +1121,7 @@ export class CacheManager implements CacheManagerDef {
1082
1121
  ancestorKeysAndPaths: AncestorKeysAndPaths,
1083
1122
  { cacheMetadata, data }: ResponseData,
1084
1123
  options: RequestOptions,
1085
- context: CacheManagerContext
1124
+ context: CacheManagerContext,
1086
1125
  ): void {
1087
1126
  const { requestFieldPath: ancestorRequestFieldPath } = ancestorKeysAndPaths;
1088
1127
  const keysAndPaths = buildFieldKeysAndPaths(field, ancestorKeysAndPaths, context);
@@ -1092,6 +1131,8 @@ export class CacheManager implements CacheManagerDef {
1092
1131
  return;
1093
1132
  }
1094
1133
 
1134
+ // get return type annotation is rubbish
1135
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1095
1136
  const fieldData = get(data, responseDataPath) as unknown;
1096
1137
  const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
1097
1138
 
@@ -1111,16 +1152,16 @@ export class CacheManager implements CacheManagerDef {
1111
1152
  _typeName: string | undefined,
1112
1153
  _fragmentKind: string | undefined,
1113
1154
  _fragmentName: string | undefined,
1114
- childIndex?: number
1155
+ childIndex?: number,
1115
1156
  ) => {
1116
1157
  this._setFieldCacheability(
1117
1158
  childField,
1118
1159
  { index: childIndex, requestFieldPath, responseDataPath },
1119
1160
  { cacheMetadata, data },
1120
1161
  options,
1121
- context
1162
+ context,
1122
1163
  );
1123
- }
1164
+ },
1124
1165
  );
1125
1166
  }
1126
1167
  }
@@ -1128,7 +1169,7 @@ export class CacheManager implements CacheManagerDef {
1128
1169
  private _setFieldTypeCacheDirective(
1129
1170
  cacheMetadata: CacheMetadata,
1130
1171
  { ancestorRequestFieldPath, requestFieldPath }: { ancestorRequestFieldPath?: string; requestFieldPath: string },
1131
- { fieldTypeMap, operation }: CacheManagerContext
1172
+ { fieldTypeMap, operation }: CacheManagerContext,
1132
1173
  ): void {
1133
1174
  if (cacheMetadata.has(requestFieldPath)) {
1134
1175
  return;
@@ -1144,7 +1185,7 @@ export class CacheManager implements CacheManagerDef {
1144
1185
  cacheMetadata,
1145
1186
  cacheMetadata.get(ancestorRequestFieldPath),
1146
1187
  requestFieldPath,
1147
- operation
1188
+ operation,
1148
1189
  );
1149
1190
  }
1150
1191
  }
@@ -1154,7 +1195,7 @@ export class CacheManager implements CacheManagerDef {
1154
1195
  hash: string,
1155
1196
  partialQueryResponse: PartialQueryResponse,
1156
1197
  _options: RequestOptions,
1157
- _context: CacheManagerContext
1198
+ _context: CacheManagerContext,
1158
1199
  ): void {
1159
1200
  this._partialQueryResponses.set(hash, partialQueryResponse);
1160
1201
  }
@@ -1163,7 +1204,7 @@ export class CacheManager implements CacheManagerDef {
1163
1204
  hash: string,
1164
1205
  { cacheMetadata, data }: ResponseData,
1165
1206
  options: RequestOptions,
1166
- context: CacheManagerContext
1207
+ context: CacheManagerContext,
1167
1208
  ): Promise<void> {
1168
1209
  const dehydratedCacheMetadata = dehydrateCacheMetadata(cacheMetadata);
1169
1210
  const cacheControl = CacheManager._getOperationCacheControl(cacheMetadata, context.operation);
@@ -1174,7 +1215,7 @@ export class CacheManager implements CacheManagerDef {
1174
1215
  { cacheMetadata: dehydratedCacheMetadata, data },
1175
1216
  { cacheHeaders: { cacheControl }, tag: options.tag },
1176
1217
  options,
1177
- context
1218
+ context,
1178
1219
  );
1179
1220
  }
1180
1221
 
@@ -1182,7 +1223,7 @@ export class CacheManager implements CacheManagerDef {
1182
1223
  keysAndPaths: KeysAndPaths,
1183
1224
  { cacheability, fieldData }: DataForCachingEntry,
1184
1225
  options: RequestOptions,
1185
- context: CacheManagerContext
1226
+ context: CacheManagerContext,
1186
1227
  ): Promise<void> {
1187
1228
  const { hashedRequestFieldCacheKey, requestFieldCacheKey } = keysAndPaths;
1188
1229
 
@@ -1201,13 +1242,13 @@ export class CacheManager implements CacheManagerDef {
1201
1242
  fieldData,
1202
1243
  { cacheHeaders: { cacheControl: cacheability.printCacheControl() }, tag: options.tag },
1203
1244
  options,
1204
- { ...context, requestFieldCacheKey }
1245
+ { ...context, requestFieldCacheKey },
1205
1246
  );
1206
1247
  }
1207
1248
 
1208
1249
  private _setResponseChunksAwaitingCaching(
1209
1250
  normalizedResponseData: RawResponseDataWithMaybeCacheMetadata,
1210
- context: CacheManagerContext
1251
+ context: CacheManagerContext,
1211
1252
  ) {
1212
1253
  const responseChunks = this._responseChunksAwaitingCaching.get(context.requestID);
1213
1254