@graphql-box/cache-manager 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/lib/browser/index.js +1 -1
  2. package/lib/browser/index.js.map +1 -1
  3. package/lib/browser/production.analysis.txt +63 -27
  4. package/lib/main/helpers/isFirstResponseChunk.js +11 -0
  5. package/lib/main/helpers/isFirstResponseChunk.js.map +1 -0
  6. package/lib/main/helpers/isLastResponseChunk.js +11 -0
  7. package/lib/main/helpers/isLastResponseChunk.js.map +1 -0
  8. package/lib/main/helpers/isNotLastResponseChunk.js +11 -0
  9. package/lib/main/helpers/isNotLastResponseChunk.js.map +1 -0
  10. package/lib/main/helpers/isNotResponseChunk.js +11 -0
  11. package/lib/main/helpers/isNotResponseChunk.js.map +1 -0
  12. package/lib/main/helpers/mergeResponseDataSets.js +53 -0
  13. package/lib/main/helpers/mergeResponseDataSets.js.map +1 -0
  14. package/lib/main/helpers/{normalizeResponseData.js → normalizePatchResponseData.js} +13 -8
  15. package/lib/main/helpers/normalizePatchResponseData.js.map +1 -0
  16. package/lib/main/main/index.js +125 -90
  17. package/lib/main/main/index.js.map +1 -1
  18. package/lib/module/helpers/isFirstResponseChunk.js +2 -0
  19. package/lib/module/helpers/isFirstResponseChunk.js.map +1 -0
  20. package/lib/module/helpers/isLastResponseChunk.js +2 -0
  21. package/lib/module/helpers/isLastResponseChunk.js.map +1 -0
  22. package/lib/module/helpers/isNotLastResponseChunk.js +2 -0
  23. package/lib/module/helpers/isNotLastResponseChunk.js.map +1 -0
  24. package/lib/module/helpers/isNotResponseChunk.js +2 -0
  25. package/lib/module/helpers/isNotResponseChunk.js.map +1 -0
  26. package/lib/module/helpers/mergeResponseDataSets.js +41 -0
  27. package/lib/module/helpers/mergeResponseDataSets.js.map +1 -0
  28. package/lib/module/helpers/normalizePatchResponseData.js +17 -0
  29. package/lib/module/helpers/normalizePatchResponseData.js.map +1 -0
  30. package/lib/module/main/index.js +122 -90
  31. package/lib/module/main/index.js.map +1 -1
  32. package/lib/types/defs/index.d.ts +2 -2
  33. package/lib/types/defs/index.d.ts.map +1 -1
  34. package/lib/types/helpers/isFirstResponseChunk.d.ts +5 -0
  35. package/lib/types/helpers/isFirstResponseChunk.d.ts.map +1 -0
  36. package/lib/types/helpers/isLastResponseChunk.d.ts +5 -0
  37. package/lib/types/helpers/isLastResponseChunk.d.ts.map +1 -0
  38. package/lib/types/helpers/isNotLastResponseChunk.d.ts +5 -0
  39. package/lib/types/helpers/isNotLastResponseChunk.d.ts.map +1 -0
  40. package/lib/types/helpers/isNotResponseChunk.d.ts +5 -0
  41. package/lib/types/helpers/isNotResponseChunk.d.ts.map +1 -0
  42. package/lib/types/helpers/mergeResponseDataSets.d.ts +4 -0
  43. package/lib/types/helpers/mergeResponseDataSets.d.ts.map +1 -0
  44. package/lib/types/helpers/normalizePatchResponseData.d.ts +5 -0
  45. package/lib/types/helpers/normalizePatchResponseData.d.ts.map +1 -0
  46. package/lib/types/main/index.d.ts +6 -3
  47. package/lib/types/main/index.d.ts.map +1 -1
  48. package/package.json +1 -1
  49. package/src/__snapshots__/index.test.ts.snap +12483 -11883
  50. package/src/defs/index.ts +13 -13
  51. package/src/helpers/isFirstResponseChunk.ts +5 -0
  52. package/src/helpers/isLastResponseChunk.ts +5 -0
  53. package/src/helpers/isNotLastResponseChunk.ts +5 -0
  54. package/src/helpers/isNotResponseChunk.ts +5 -0
  55. package/src/helpers/mergeResponseDataSets.ts +35 -0
  56. package/src/helpers/normalizePatchResponseData.ts +17 -0
  57. package/src/index.test.ts +162 -86
  58. package/src/main/index.ts +151 -107
  59. package/lib/main/helpers/normalizeResponseData.js.map +0 -1
  60. package/lib/module/helpers/normalizeResponseData.js +0 -12
  61. package/lib/module/helpers/normalizeResponseData.js.map +0 -1
  62. package/lib/types/helpers/normalizeResponseData.d.ts +0 -11
  63. package/lib/types/helpers/normalizeResponseData.d.ts.map +0 -1
  64. package/src/helpers/normalizeResponseData.ts +0 -10
package/src/main/index.ts CHANGED
@@ -63,7 +63,11 @@ import { buildFieldKeysAndPaths } from "../helpers/buildKeysAndPaths";
63
63
  import deriveOpCacheability from "../helpers/deriveOpCacheability";
64
64
  import filterOutPropsWithArgsOrDirectives from "../helpers/filterOutPropsWithArgsOrDirectives";
65
65
  import filterQuery from "../helpers/filterQuery";
66
- import normalizeResponseData from "../helpers/normalizeResponseData";
66
+ import isLastResponseChunk from "../helpers/isLastResponseChunk";
67
+ import isNotLastResponseChunk from "../helpers/isNotLastResponseChunk";
68
+ import isNotResponseChunk from "../helpers/isNotResponseChunk";
69
+ import mergeResponseDataSets from "../helpers/mergeResponseDataSets";
70
+ import normalizePatchResponseData from "../helpers/normalizePatchResponseData";
67
71
  import { getValidTypeIDValue } from "../helpers/validTypeIDValue";
68
72
 
69
73
  export class CacheManager implements CacheManagerDef {
@@ -225,6 +229,7 @@ export class CacheManager implements CacheManagerDef {
225
229
  private _cascadeCacheControl: boolean;
226
230
  private _fallbackOperationCacheability: string;
227
231
  private _partialQueryResponses: PartialQueryResponses = new Map();
232
+ private _responseChunksAwaitingCaching: Map<string, RawResponseDataWithMaybeCacheMetadata[]> = new Map();
228
233
  private _typeCacheDirectives: PlainObjectStringMap;
229
234
  private _typeIDKey: string;
230
235
 
@@ -283,6 +288,37 @@ export class CacheManager implements CacheManagerDef {
283
288
  return { updated: { ast: filteredAST, hash: hashRequest(request), request } };
284
289
  }
285
290
 
291
+ public async cacheQuery(
292
+ requestData: RequestData,
293
+ updatedRequestData: RequestData,
294
+ rawResponseData: RawResponseDataWithMaybeCacheMetadata,
295
+ options: RequestOptions,
296
+ context: RequestContext,
297
+ ): Promise<ResponseData> {
298
+ const cacheManagerContext: CacheManagerContext = {
299
+ ...context,
300
+ fragmentDefinitions: getFragmentDefinitions(updatedRequestData.ast),
301
+ typeIDKey: this._typeIDKey,
302
+ };
303
+
304
+ return this._cacheResponse(requestData, updatedRequestData, rawResponseData, options, cacheManagerContext);
305
+ }
306
+
307
+ public async cacheResponse(
308
+ requestData: RequestData,
309
+ rawResponseData: RawResponseDataWithMaybeCacheMetadata,
310
+ options: RequestOptions,
311
+ context: RequestContext,
312
+ ): Promise<ResponseData> {
313
+ const cacheManagerContext: CacheManagerContext = {
314
+ ...context,
315
+ fragmentDefinitions: getFragmentDefinitions(requestData.ast),
316
+ typeIDKey: this._typeIDKey,
317
+ };
318
+
319
+ return this._cacheResponse(requestData, undefined, rawResponseData, options, cacheManagerContext);
320
+ }
321
+
286
322
  public async checkCacheEntry(
287
323
  cacheType: CacheTypes,
288
324
  hash: string,
@@ -315,83 +351,6 @@ export class CacheManager implements CacheManagerDef {
315
351
  this._partialQueryResponses.delete(hash);
316
352
  }
317
353
 
318
- public async resolveQuery(
319
- requestData: RequestData,
320
- updatedRequestData: RequestData,
321
- rawResponseData: RawResponseDataWithMaybeCacheMetadata,
322
- options: RequestOptions,
323
- context: RequestContext,
324
- ): Promise<ResponseData> {
325
- const cacheManagerContext: CacheManagerContext = {
326
- ...context,
327
- fragmentDefinitions: getFragmentDefinitions(updatedRequestData.ast),
328
- typeIDKey: this._typeIDKey,
329
- };
330
-
331
- const dataCaching: Promise<void>[] = [];
332
-
333
- const { cacheMetadata, data, hasNext, path } = await this._resolveRequest(
334
- updatedRequestData,
335
- rawResponseData,
336
- options,
337
- cacheManagerContext,
338
- );
339
-
340
- let partialQueryResponse: PartialQueryResponse | undefined;
341
-
342
- if (cacheManagerContext.queryFiltered) {
343
- if (!(rawResponseData.hasNext || rawResponseData.path)) {
344
- dataCaching.push(
345
- this._setQueryResponseCacheEntry(
346
- updatedRequestData.hash,
347
- { cacheMetadata, data },
348
- options,
349
- cacheManagerContext,
350
- ),
351
- );
352
- }
353
-
354
- if (!rawResponseData.path) {
355
- partialQueryResponse = this._getPartialQueryResponse(requestData.hash);
356
- }
357
- }
358
-
359
- const responseCacheMetadata = CacheManager._mergeResponseCacheMetadata(cacheMetadata, partialQueryResponse);
360
- const responseData = this._mergeResponseData(data, partialQueryResponse);
361
-
362
- if (!(rawResponseData.hasNext || rawResponseData.path)) {
363
- dataCaching.push(
364
- this._setQueryResponseCacheEntry(
365
- requestData.hash,
366
- { cacheMetadata: responseCacheMetadata, data: responseData },
367
- options,
368
- cacheManagerContext,
369
- ),
370
- );
371
- }
372
-
373
- if (options.awaitDataCaching) {
374
- await Promise.all(dataCaching);
375
- }
376
-
377
- return { cacheMetadata: responseCacheMetadata, data: responseData, hasNext, path };
378
- }
379
-
380
- public async resolveRequest(
381
- requestData: RequestData,
382
- rawResponseData: RawResponseDataWithMaybeCacheMetadata,
383
- options: RequestOptions,
384
- context: RequestContext,
385
- ): Promise<ResponseData> {
386
- const cacheManagerContext: CacheManagerContext = {
387
- ...context,
388
- fragmentDefinitions: getFragmentDefinitions(requestData.ast),
389
- typeIDKey: this._typeIDKey,
390
- };
391
-
392
- return this._resolveRequest(requestData, rawResponseData, options, cacheManagerContext);
393
- }
394
-
395
354
  private async _analyzeFieldNode(
396
355
  fieldNode: FieldNode,
397
356
  cachedAncestorFieldData: CachedAncestorFieldData,
@@ -399,7 +358,7 @@ export class CacheManager implements CacheManagerDef {
399
358
  options: RequestOptions,
400
359
  context: CacheManagerContext,
401
360
  ): Promise<void> {
402
- if (hasChildFields(fieldNode)) {
361
+ if (hasChildFields(fieldNode, { fragmentDefinitions: context.fragmentDefinitions })) {
403
362
  await this._analyzeParentFieldNode(fieldNode, cachedAncestorFieldData, cachedResponseData, options, context);
404
363
  } else {
405
364
  await this._analyzeLeafFieldNode(fieldNode, cachedAncestorFieldData, cachedResponseData, options, context);
@@ -556,6 +515,93 @@ export class CacheManager implements CacheManagerDef {
556
515
  return cacheMetadata;
557
516
  }
558
517
 
518
+ private async _cacheResponse(
519
+ requestData: RequestData,
520
+ updatedRequestData: RequestData | undefined,
521
+ rawResponseData: RawResponseDataWithMaybeCacheMetadata,
522
+ options: RequestOptions,
523
+ context: CacheManagerContext,
524
+ ): Promise<ResponseData> {
525
+ const normalizedResponseData = normalizePatchResponseData(rawResponseData, context);
526
+ let responseDataForCaching: RawResponseDataWithMaybeCacheMetadata | undefined = normalizedResponseData;
527
+
528
+ if (isNotLastResponseChunk(rawResponseData, context)) {
529
+ this._setResponseChunksAwaitingCaching(normalizedResponseData, context);
530
+ responseDataForCaching = undefined;
531
+ }
532
+
533
+ if (isLastResponseChunk(rawResponseData, context)) {
534
+ responseDataForCaching = this._retrieveResponseDataForCaching(normalizedResponseData, context);
535
+ }
536
+
537
+ const dataCaching: Promise<void>[] = [];
538
+
539
+ if (responseDataForCaching) {
540
+ const { data } = responseDataForCaching;
541
+ const cacheMetadata = this._buildCacheMetadata(requestData, responseDataForCaching, options, context);
542
+
543
+ dataCaching.push(
544
+ this._setEntityAndRequestFieldPathCacheEntries(
545
+ requestData,
546
+ {
547
+ cacheMetadata,
548
+ entityData: cloneDeep(data),
549
+ requestFieldPathData: cloneDeep(data),
550
+ },
551
+ options,
552
+ context,
553
+ ),
554
+ );
555
+
556
+ let queryCacheMetadata: CacheMetadata | undefined;
557
+ let queryData: PlainObjectMap | undefined;
558
+
559
+ if (context.operation === QUERY) {
560
+ let partialQueryResponse: PartialQueryResponse | undefined;
561
+
562
+ if (context.queryFiltered && updatedRequestData) {
563
+ dataCaching.push(
564
+ this._setQueryResponseCacheEntry(updatedRequestData.hash, { cacheMetadata, data }, options, context),
565
+ );
566
+
567
+ partialQueryResponse = this._getPartialQueryResponse(requestData.hash);
568
+ }
569
+
570
+ queryCacheMetadata = CacheManager._mergeResponseCacheMetadata(cacheMetadata, partialQueryResponse);
571
+ queryData = this._mergeResponseData(data, partialQueryResponse);
572
+
573
+ dataCaching.push(
574
+ this._setQueryResponseCacheEntry(
575
+ requestData.hash,
576
+ { cacheMetadata: queryCacheMetadata, data: queryData },
577
+ options,
578
+ context,
579
+ ),
580
+ );
581
+ }
582
+
583
+ if (options.awaitDataCaching) {
584
+ await Promise.all(dataCaching);
585
+ }
586
+
587
+ if (isNotResponseChunk(normalizedResponseData, context) && queryCacheMetadata && queryData) {
588
+ return {
589
+ cacheMetadata: queryCacheMetadata,
590
+ data: queryData,
591
+ };
592
+ }
593
+ }
594
+
595
+ const { data, hasNext, paths } = normalizedResponseData;
596
+
597
+ return {
598
+ cacheMetadata: this._buildCacheMetadata(requestData, normalizedResponseData, options, context),
599
+ data,
600
+ hasNext,
601
+ paths,
602
+ };
603
+ }
604
+
559
605
  private async _checkCacheEntry(
560
606
  cacheType: CacheTypes,
561
607
  hash: string,
@@ -717,33 +763,6 @@ export class CacheManager implements CacheManagerDef {
717
763
  );
718
764
  }
719
765
 
720
- private async _resolveRequest(
721
- requestData: RequestData,
722
- rawResponseData: RawResponseDataWithMaybeCacheMetadata,
723
- options: RequestOptions,
724
- context: CacheManagerContext,
725
- ): Promise<ResponseData> {
726
- const normalizedResponseData = rawResponseData.path ? normalizeResponseData(rawResponseData) : rawResponseData;
727
- const dataCaching: Promise<void>[] = [];
728
- const cacheMetadata = this._buildCacheMetadata(requestData, normalizedResponseData, options, context);
729
- const { data, hasNext, path } = normalizedResponseData;
730
-
731
- dataCaching.push(
732
- this._setEntityAndRequestFieldPathCacheEntries(
733
- requestData,
734
- { cacheMetadata, entityData: cloneDeep(data), requestFieldPathData: cloneDeep(data) },
735
- options,
736
- context,
737
- ),
738
- );
739
-
740
- if (options.awaitDataCaching) {
741
- await Promise.all(dataCaching);
742
- }
743
-
744
- return { cacheMetadata, data, hasNext, path };
745
- }
746
-
747
766
  private async _retrieveCachedEntityData(
748
767
  validTypeIDValue: string | number,
749
768
  { possibleTypes, typeName }: FieldTypeInfo,
@@ -875,6 +894,18 @@ export class CacheManager implements CacheManagerDef {
875
894
  return cachedResponseData;
876
895
  }
877
896
 
897
+ private _retrieveResponseDataForCaching(
898
+ normalizedResponseData: RawResponseDataWithMaybeCacheMetadata,
899
+ context: CacheManagerContext,
900
+ ) {
901
+ const responseChunks = this._responseChunksAwaitingCaching.get(
902
+ context.boxID,
903
+ ) as RawResponseDataWithMaybeCacheMetadata[];
904
+
905
+ this._responseChunksAwaitingCaching.delete(context.boxID);
906
+ return mergeResponseDataSets([...responseChunks, normalizedResponseData]);
907
+ }
908
+
878
909
  @logCacheEntry()
879
910
  private async _setCacheEntry(
880
911
  cacheType: CacheTypes,
@@ -1115,7 +1146,7 @@ export class CacheManager implements CacheManagerDef {
1115
1146
  context,
1116
1147
  );
1117
1148
 
1118
- if (hasChildFields(field)) {
1149
+ if (hasChildFields(field, { fragmentDefinitions: context.fragmentDefinitions })) {
1119
1150
  if (isEntity) {
1120
1151
  set(data, responseDataPath, { __cacheKey: `${REQUEST_FIELD_PATHS}::${hashedRequestFieldCacheKey}` });
1121
1152
  } else {
@@ -1124,6 +1155,19 @@ export class CacheManager implements CacheManagerDef {
1124
1155
  }
1125
1156
  }
1126
1157
  }
1158
+
1159
+ private _setResponseChunksAwaitingCaching(
1160
+ normalizedResponseData: RawResponseDataWithMaybeCacheMetadata,
1161
+ context: CacheManagerContext,
1162
+ ) {
1163
+ const responseChunks = this._responseChunksAwaitingCaching.get(context.boxID);
1164
+
1165
+ if (responseChunks) {
1166
+ this._responseChunksAwaitingCaching.set(context.boxID, [...responseChunks, normalizedResponseData]);
1167
+ } else {
1168
+ this._responseChunksAwaitingCaching.set(context.boxID, [normalizedResponseData]);
1169
+ }
1170
+ }
1127
1171
  }
1128
1172
 
1129
1173
  export default function init(userOptions: UserOptions): CacheManagerInit {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/helpers/normalizeResponseData.ts"],"names":["data","path","rest"],"mappings":";;;;;;;;;;;eAGe,CAAC;AAAEA,EAAAA,IAAF;AAAQC,EAAAA,IAAR;AAAc,KAAGC;AAAjB,CAAD,KAAoE;AACjF,SAAO,EACL,GAAGA,IADE;AAELF,IAAAA,IAAI,EAAE,mBAAI,EAAJ,EAAQC,IAAR,EAAqCD,IAArC,CAFD;AAGLC,IAAAA;AAHK,GAAP;AAKD,C","sourcesContent":["import { RawResponseDataWithMaybeCacheMetadata } from \"@graphql-box/core\";\nimport { set } from \"lodash\";\n\nexport default ({ data, path, ...rest }: RawResponseDataWithMaybeCacheMetadata) => {\n return {\n ...rest,\n data: set({}, path as (string | number)[], data),\n path,\n };\n};\n"],"file":"normalizeResponseData.js"}
@@ -1,12 +0,0 @@
1
- import _set from "lodash/set";
2
- export default (({
3
- data,
4
- path,
5
- ...rest
6
- }) => {
7
- return { ...rest,
8
- data: _set({}, path, data),
9
- path
10
- };
11
- });
12
- //# sourceMappingURL=normalizeResponseData.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/helpers/normalizeResponseData.ts"],"names":["data","path","rest"],"mappings":";AAGA,gBAAe,CAAC;AAAEA,EAAAA,IAAF;AAAQC,EAAAA,IAAR;AAAc,KAAGC;AAAjB,CAAD,KAAoE;AACjF,SAAO,EACL,GAAGA,IADE;AAELF,IAAAA,IAAI,EAAE,KAAI,EAAJ,EAAQC,IAAR,EAAqCD,IAArC,CAFD;AAGLC,IAAAA;AAHK,GAAP;AAKD,CAND","sourcesContent":["import { RawResponseDataWithMaybeCacheMetadata } from \"@graphql-box/core\";\nimport { set } from \"lodash\";\n\nexport default ({ data, path, ...rest }: RawResponseDataWithMaybeCacheMetadata) => {\n return {\n ...rest,\n data: set({}, path as (string | number)[], data),\n path,\n };\n};\n"],"file":"normalizeResponseData.js"}
@@ -1,11 +0,0 @@
1
- import { RawResponseDataWithMaybeCacheMetadata } from "@graphql-box/core";
2
- declare const _default: ({ data, path, ...rest }: RawResponseDataWithMaybeCacheMetadata) => {
3
- data: {};
4
- path: (string | number)[] | undefined;
5
- _cacheMetadata?: import("@graphql-box/core").DehydratedCacheMetadata | undefined;
6
- hasNext?: boolean | undefined;
7
- headers?: Headers | undefined;
8
- label?: string | undefined;
9
- };
10
- export default _default;
11
- //# sourceMappingURL=normalizeResponseData.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"normalizeResponseData.d.ts","sourceRoot":"","sources":["../../../src/helpers/normalizeResponseData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qCAAqC,EAAE,MAAM,mBAAmB,CAAC;kDAGjC,qCAAqC;;;;;;;;AAA9E,wBAME"}
@@ -1,10 +0,0 @@
1
- import { RawResponseDataWithMaybeCacheMetadata } from "@graphql-box/core";
2
- import { set } from "lodash";
3
-
4
- export default ({ data, path, ...rest }: RawResponseDataWithMaybeCacheMetadata) => {
5
- return {
6
- ...rest,
7
- data: set({}, path as (string | number)[], data),
8
- path,
9
- };
10
- };