@graphql-box/cache-manager 2.1.2 → 2.3.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 (116) 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 +139 -17
  4. package/lib/main/debug/log-cache-entry/index.js.map +1 -1
  5. package/lib/main/debug/log-partial-compiled/index.js.map +1 -1
  6. package/lib/main/helpers/buildKeysAndPaths.js +73 -0
  7. package/lib/main/helpers/buildKeysAndPaths.js.map +1 -0
  8. package/lib/main/helpers/checkFieldPathChecklist.js +40 -0
  9. package/lib/main/helpers/checkFieldPathChecklist.js.map +1 -0
  10. package/lib/main/helpers/createFragmentSpreadChecklist.js +28 -0
  11. package/lib/main/helpers/createFragmentSpreadChecklist.js.map +1 -0
  12. package/lib/main/helpers/deriveOpCacheability.js +46 -0
  13. package/lib/main/helpers/deriveOpCacheability.js.map +1 -0
  14. package/lib/main/helpers/filterField.js +97 -0
  15. package/lib/main/helpers/filterField.js.map +1 -0
  16. package/lib/main/helpers/filterFragmentDefinitions.js +50 -0
  17. package/lib/main/helpers/filterFragmentDefinitions.js.map +1 -0
  18. package/lib/main/helpers/filterFragmentSpreads.js +37 -0
  19. package/lib/main/helpers/filterFragmentSpreads.js.map +1 -0
  20. package/lib/main/helpers/filterIDsAndTypeNames.js +47 -0
  21. package/lib/main/helpers/filterIDsAndTypeNames.js.map +1 -0
  22. package/lib/main/helpers/filterInlineFragments.js +42 -0
  23. package/lib/main/helpers/filterInlineFragments.js.map +1 -0
  24. package/lib/main/helpers/filterOutPropsWithArgsOrDirectives.js +39 -0
  25. package/lib/main/helpers/filterOutPropsWithArgsOrDirectives.js.map +1 -0
  26. package/lib/main/helpers/filterQuery.js +59 -0
  27. package/lib/main/helpers/filterQuery.js.map +1 -0
  28. package/lib/main/helpers/normalizeResponseData.js +23 -0
  29. package/lib/main/helpers/normalizeResponseData.js.map +1 -0
  30. package/lib/main/helpers/validTypeIDValue.js +20 -0
  31. package/lib/main/helpers/validTypeIDValue.js.map +1 -0
  32. package/lib/main/main/index.js +477 -476
  33. package/lib/main/main/index.js.map +1 -1
  34. package/lib/module/debug/log-cache-entry/index.js.map +1 -1
  35. package/lib/module/debug/log-partial-compiled/index.js.map +1 -1
  36. package/lib/module/helpers/buildKeysAndPaths.js +54 -0
  37. package/lib/module/helpers/buildKeysAndPaths.js.map +1 -0
  38. package/lib/module/helpers/checkFieldPathChecklist.js +31 -0
  39. package/lib/module/helpers/checkFieldPathChecklist.js.map +1 -0
  40. package/lib/module/helpers/createFragmentSpreadChecklist.js +15 -0
  41. package/lib/module/helpers/createFragmentSpreadChecklist.js.map +1 -0
  42. package/lib/module/helpers/deriveOpCacheability.js +32 -0
  43. package/lib/module/helpers/deriveOpCacheability.js.map +1 -0
  44. package/lib/module/helpers/filterField.js +81 -0
  45. package/lib/module/helpers/filterField.js.map +1 -0
  46. package/lib/module/helpers/filterFragmentDefinitions.js +39 -0
  47. package/lib/module/helpers/filterFragmentDefinitions.js.map +1 -0
  48. package/lib/module/helpers/filterFragmentSpreads.js +23 -0
  49. package/lib/module/helpers/filterFragmentSpreads.js.map +1 -0
  50. package/lib/module/helpers/filterIDsAndTypeNames.js +36 -0
  51. package/lib/module/helpers/filterIDsAndTypeNames.js.map +1 -0
  52. package/lib/module/helpers/filterInlineFragments.js +32 -0
  53. package/lib/module/helpers/filterInlineFragments.js.map +1 -0
  54. package/lib/module/helpers/filterOutPropsWithArgsOrDirectives.js +25 -0
  55. package/lib/module/helpers/filterOutPropsWithArgsOrDirectives.js.map +1 -0
  56. package/lib/module/helpers/filterQuery.js +43 -0
  57. package/lib/module/helpers/filterQuery.js.map +1 -0
  58. package/lib/module/helpers/normalizeResponseData.js +11 -0
  59. package/lib/module/helpers/normalizeResponseData.js.map +1 -0
  60. package/lib/module/helpers/validTypeIDValue.js +8 -0
  61. package/lib/module/helpers/validTypeIDValue.js.map +1 -0
  62. package/lib/module/main/index.js +474 -475
  63. package/lib/module/main/index.js.map +1 -1
  64. package/lib/types/debug/log-cache-entry/index.d.ts.map +1 -1
  65. package/lib/types/debug/log-cache-query/index.d.ts.map +1 -1
  66. package/lib/types/debug/log-partial-compiled/index.d.ts.map +1 -1
  67. package/lib/types/defs/index.d.ts +19 -9
  68. package/lib/types/defs/index.d.ts.map +1 -1
  69. package/lib/types/helpers/buildKeysAndPaths.d.ts +10 -0
  70. package/lib/types/helpers/buildKeysAndPaths.d.ts.map +1 -0
  71. package/lib/types/helpers/checkFieldPathChecklist.d.ts +4 -0
  72. package/lib/types/helpers/checkFieldPathChecklist.d.ts.map +1 -0
  73. package/lib/types/helpers/createFragmentSpreadChecklist.d.ts +11 -0
  74. package/lib/types/helpers/createFragmentSpreadChecklist.d.ts.map +1 -0
  75. package/lib/types/helpers/deriveOpCacheability.d.ts +10 -0
  76. package/lib/types/helpers/deriveOpCacheability.d.ts.map +1 -0
  77. package/lib/types/helpers/filterField.d.ts +6 -0
  78. package/lib/types/helpers/filterField.d.ts.map +1 -0
  79. package/lib/types/helpers/filterFragmentDefinitions.d.ts +10 -0
  80. package/lib/types/helpers/filterFragmentDefinitions.d.ts.map +1 -0
  81. package/lib/types/helpers/filterFragmentSpreads.d.ts +6 -0
  82. package/lib/types/helpers/filterFragmentSpreads.d.ts.map +1 -0
  83. package/lib/types/helpers/filterIDsAndTypeNames.d.ts +5 -0
  84. package/lib/types/helpers/filterIDsAndTypeNames.d.ts.map +1 -0
  85. package/lib/types/helpers/filterInlineFragments.d.ts +5 -0
  86. package/lib/types/helpers/filterInlineFragments.d.ts.map +1 -0
  87. package/lib/types/helpers/filterOutPropsWithArgsOrDirectives.d.ts +6 -0
  88. package/lib/types/helpers/filterOutPropsWithArgsOrDirectives.d.ts.map +1 -0
  89. package/lib/types/helpers/filterQuery.d.ts +5 -0
  90. package/lib/types/helpers/filterQuery.d.ts.map +1 -0
  91. package/lib/types/helpers/normalizeResponseData.d.ts +10 -0
  92. package/lib/types/helpers/normalizeResponseData.d.ts.map +1 -0
  93. package/lib/types/helpers/validTypeIDValue.d.ts +3 -0
  94. package/lib/types/helpers/validTypeIDValue.d.ts.map +1 -0
  95. package/lib/types/main/index.d.ts +13 -20
  96. package/lib/types/main/index.d.ts.map +1 -1
  97. package/package.json +2 -2
  98. package/src/__snapshots__/index.test.ts.snap +17449 -7185
  99. package/src/debug/log-cache-entry/index.ts +1 -1
  100. package/src/debug/log-partial-compiled/index.ts +1 -1
  101. package/src/defs/index.ts +18 -10
  102. package/src/helpers/buildKeysAndPaths.ts +71 -0
  103. package/src/helpers/checkFieldPathChecklist.ts +21 -0
  104. package/src/helpers/createFragmentSpreadChecklist.ts +17 -0
  105. package/src/helpers/deriveOpCacheability.ts +32 -0
  106. package/src/helpers/filterField.ts +73 -0
  107. package/src/helpers/filterFragmentDefinitions.ts +40 -0
  108. package/src/helpers/filterFragmentSpreads.ts +28 -0
  109. package/src/helpers/filterIDsAndTypeNames.ts +31 -0
  110. package/src/helpers/filterInlineFragments.ts +29 -0
  111. package/src/helpers/filterOutPropsWithArgsOrDirectives.ts +30 -0
  112. package/src/helpers/filterQuery.ts +38 -0
  113. package/src/helpers/normalizeResponseData.ts +9 -0
  114. package/src/helpers/validTypeIDValue.ts +11 -0
  115. package/src/index.test.ts +179 -3
  116. package/src/main/index.ts +516 -499
@@ -5,20 +5,26 @@ import _set from "lodash/set";
5
5
  import _isUndefined from "lodash/isUndefined";
6
6
  import _isPlainObject from "lodash/isPlainObject";
7
7
  import _isObjectLike from "lodash/isObjectLike";
8
- import _isNumber from "lodash/isNumber";
9
8
  import _isArray from "lodash/isArray";
10
9
  import _get from "lodash/get";
11
10
  import _cloneDeep from "lodash/cloneDeep";
11
+ import _assign from "lodash/assign";
12
12
 
13
13
  var _dec, _dec2, _dec3, _class;
14
14
 
15
15
  import "core-js/modules/es.promise.js";
16
16
  import { DATA_ENTITIES, QUERY, QUERY_RESPONSES, REQUEST_FIELD_PATHS, TYPE_NAME_KEY } from "@graphql-box/core";
17
- import { dehydrateCacheMetadata, deleteChildFields, deleteInlineFragments, getAlias, getArguments, getChildFields, getDirectives, getInlineFragments, getName, getOperationDefinitions, hasChildFields, hashRequest, iterateChildFields, mergeObjects, rehydrateCacheMetadata } from "@graphql-box/helpers";
17
+ import { FRAGMENT_SPREAD, dehydrateCacheMetadata, getChildFields, getFragmentDefinitions, getOperationDefinitions, hasChildFields, hashRequest, iterateChildFields, mergeObjects, rehydrateCacheMetadata } from "@graphql-box/helpers";
18
18
  import Cacheability from "cacheability";
19
19
  import { print } from "graphql";
20
- import { CACHE_CONTROL, HEADER_CACHE_CONTROL, HEADER_NO_CACHE, METADATA, NO_CACHE } from "../consts";
20
+ import { CACHE_CONTROL, HEADER_NO_CACHE, METADATA, NO_CACHE } from "../consts";
21
21
  import { logCacheEntry, logCacheQuery, logPartialCompiled } from "../debug";
22
+ import { buildFieldKeysAndPaths } from "../helpers/buildKeysAndPaths";
23
+ import deriveOpCacheability from "../helpers/deriveOpCacheability";
24
+ import filterOutPropsWithArgsOrDirectives from "../helpers/filterOutPropsWithArgsOrDirectives";
25
+ import filterQuery from "../helpers/filterQuery";
26
+ import normalizeResponseData from "../helpers/normalizeResponseData";
27
+ import { getValidTypeIDValue } from "../helpers/validTypeIDValue";
22
28
  export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec3 = logPartialCompiled(), (_class = class CacheManager {
23
29
  static async init(options) {
24
30
  const errors = [];
@@ -32,85 +38,11 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
32
38
  errors.push(new TypeError(message));
33
39
  }
34
40
 
35
- if (errors.length) return Promise.reject(errors);
36
- return new CacheManager(options);
37
- }
38
-
39
- static _analyzeLeafField(field, cachedAncestorFieldData, {
40
- data,
41
- fieldPathChecklist
42
- }, _options, _context) {
43
- const keysAndPaths = CacheManager._getFieldKeysAndPaths(field, cachedAncestorFieldData);
44
-
45
- const {
46
- propNameOrIndex,
47
- requestFieldPath
48
- } = keysAndPaths;
49
- const {
50
- dataEntityData,
51
- requestFieldPathData,
52
- typeName
53
- } = cachedAncestorFieldData;
54
-
55
- const cachedFieldData = CacheManager._getFieldDataFromAncestor(dataEntityData, propNameOrIndex) || CacheManager._getFieldDataFromAncestor(requestFieldPathData, propNameOrIndex);
56
-
57
- const typeNames = {
58
- dataTypeName: dataEntityData.__typename || requestFieldPathData.__typename,
59
- fieldTypeName: typeName
60
- };
61
-
62
- CacheManager._setFieldPathChecklist(fieldPathChecklist, {
63
- data: cachedFieldData
64
- }, requestFieldPath, typeNames);
65
-
66
- CacheManager._setCachedData(data, {
67
- data: cachedFieldData
68
- }, propNameOrIndex);
69
- }
70
-
71
- static _buildKey(key, path) {
72
- const paths = [];
73
- if (path.length) paths.push(path);
74
- paths.push(key);
75
- return paths.join(".");
76
- }
77
-
78
- static _buildRequestFieldCacheKey(name, requestFieldCacheKey, args, directives, index) {
79
- let key = `${_isNumber(index) ? index : name}`;
80
- if (args) key = `${key}(${JSON.stringify(args)})`;
81
- if (directives) key = `${key}(${JSON.stringify(directives)})`;
82
- return CacheManager._buildKey(key, requestFieldCacheKey);
83
- }
84
-
85
- static _checkFieldPathChecklist(fieldPathChecklistValues, fieldTypeName) {
86
- if (!fieldPathChecklistValues || !fieldPathChecklistValues.length) {
87
- return {
88
- hasData: false,
89
- typeUnused: !!fieldTypeName
90
- };
91
- }
92
-
93
- if (fieldPathChecklistValues.length === 1) {
94
- const {
95
- hasData,
96
- typeName
97
- } = fieldPathChecklistValues[0];
98
- const typeUnused = !typeName ? undefined : typeName !== fieldTypeName;
99
- return {
100
- hasData,
101
- typeUnused
102
- };
41
+ if (errors.length) {
42
+ return Promise.reject(errors);
103
43
  }
104
44
 
105
- return {
106
- hasData: fieldPathChecklistValues.some(({
107
- hasData,
108
- typeName
109
- }) => typeName === fieldTypeName && hasData),
110
- typeUnused: !fieldPathChecklistValues.every(({
111
- typeName
112
- }) => typeName === fieldTypeName)
113
- };
45
+ return new CacheManager(options);
114
46
  }
115
47
 
116
48
  static _countFieldPathChecklist(fieldPathChecklist) {
@@ -129,49 +61,33 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
129
61
  }
130
62
 
131
63
  static _getFieldDataFromAncestor(ancestorFieldData, propNameOrIndex) {
132
- return _isObjectLike(ancestorFieldData) ? ancestorFieldData[propNameOrIndex] : undefined;
133
- }
134
-
135
- static _getFieldKeysAndPaths(field, options) {
136
- const {
137
- index,
138
- requestFieldCacheKey = "",
139
- requestFieldPath = "",
140
- responseDataPath = ""
141
- } = options;
142
- const name = getName(field);
143
-
144
- const updatedRequestFieldCacheKey = CacheManager._buildRequestFieldCacheKey(name, requestFieldCacheKey, getArguments(field), getDirectives(field), index);
145
-
146
- const fieldAliasOrName = getAlias(field) || name;
147
- const updatedRequestFieldPath = _isNumber(index) ? requestFieldPath : CacheManager._buildKey(fieldAliasOrName, requestFieldPath);
148
- const propNameOrIndex = _isNumber(index) ? index : fieldAliasOrName;
149
-
150
- const updatedResponseDataPath = CacheManager._buildKey(propNameOrIndex, responseDataPath);
151
-
152
- return {
153
- hashedRequestFieldCacheKey: hashRequest(updatedRequestFieldCacheKey),
154
- propNameOrIndex,
155
- requestFieldCacheKey: updatedRequestFieldCacheKey,
156
- requestFieldPath: updatedRequestFieldPath,
157
- responseDataPath: updatedResponseDataPath
158
- };
64
+ return _isObjectLike(ancestorFieldData) ? _cloneDeep(ancestorFieldData[propNameOrIndex]) : undefined;
159
65
  }
160
66
 
161
67
  static _getOperationCacheControl(cacheMetadata, operation) {
162
68
  const defaultCacheControl = HEADER_NO_CACHE;
163
- if (!cacheMetadata) return defaultCacheControl;
69
+
70
+ if (!cacheMetadata) {
71
+ return defaultCacheControl;
72
+ }
73
+
164
74
  const cacheability = cacheMetadata.get(operation);
165
75
  return cacheability ? cacheability.printCacheControl() : defaultCacheControl;
166
76
  }
167
77
 
168
78
  static _getResponseCacheMetadata(cacheMetadata, partialQueryResponse) {
169
- if (!partialQueryResponse) return cacheMetadata;
79
+ if (!partialQueryResponse) {
80
+ return cacheMetadata;
81
+ }
82
+
170
83
  return new Map([...partialQueryResponse.cacheMetadata, ...cacheMetadata]);
171
84
  }
172
85
 
173
- static _isDataEntity(fieldTypeInfo) {
174
- if (!fieldTypeInfo) return false;
86
+ static _isNodeEntity(fieldTypeInfo) {
87
+ if (!fieldTypeInfo) {
88
+ return false;
89
+ }
90
+
175
91
  const {
176
92
  isEntity,
177
93
  possibleTypes
@@ -179,8 +95,8 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
179
95
  return isEntity || possibleTypes.some(type => !!type.isEntity);
180
96
  }
181
97
 
182
- static _isRequestFieldPath(fieldTypeInfo) {
183
- return !!fieldTypeInfo && (this._isDataEntity(fieldTypeInfo) || fieldTypeInfo.hasArguments || fieldTypeInfo.hasDirectives);
98
+ static _isNodeRequestFieldPath(fieldTypeInfo) {
99
+ return !!fieldTypeInfo && (this._isNodeEntity(fieldTypeInfo) || fieldTypeInfo.hasArguments || fieldTypeInfo.hasDirectives);
184
100
  }
185
101
 
186
102
  static _isValid(cacheability) {
@@ -207,18 +123,21 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
207
123
  }, {
208
124
  propNameOrIndex,
209
125
  requestFieldPath
210
- }, typeNames, _options, {
126
+ }, typeNamesAndKind, _options, {
211
127
  operation
212
128
  }) {
213
129
  CacheManager._setCacheMetadata(cacheMetadata, cachedFieldData.cacheability, requestFieldPath, operation);
214
130
 
215
- CacheManager._setFieldPathChecklist(fieldPathChecklist, cachedFieldData, requestFieldPath, typeNames);
131
+ CacheManager._setFieldPathChecklist(fieldPathChecklist, cachedFieldData, requestFieldPath, typeNamesAndKind);
216
132
 
217
133
  CacheManager._setCachedData(data, cachedFieldData, propNameOrIndex);
218
134
  }
219
135
 
220
136
  static _setCacheMetadata(cacheMetadata, cacheability, requestFieldPath, operation) {
221
- if (!cacheability) return;
137
+ if (!cacheability) {
138
+ return;
139
+ }
140
+
222
141
  cacheMetadata.set(requestFieldPath, cacheability);
223
142
  const operationCacheability = cacheMetadata.get(operation);
224
143
 
@@ -231,23 +150,39 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
231
150
  data
232
151
  }, requestFieldPath, {
233
152
  dataTypeName,
234
- fieldTypeName
153
+ fieldTypeName,
154
+ fragmentKind,
155
+ fragmentName
235
156
  }) {
236
- if (_isUndefined(fieldTypeName)) {
237
- if (fieldPathChecklist.has(requestFieldPath)) return;
157
+ if (_isUndefined(fieldTypeName) || fragmentKind === FRAGMENT_SPREAD) {
158
+ if (fieldPathChecklist.has(requestFieldPath)) {
159
+ return;
160
+ }
161
+
238
162
  fieldPathChecklist.set(requestFieldPath, [{
163
+ fragmentKind,
164
+ fragmentName,
239
165
  hasData: !_isUndefined(data)
240
166
  }]);
241
167
  return;
242
168
  }
243
169
 
244
- if (dataTypeName !== fieldTypeName) return;
170
+ if (dataTypeName !== fieldTypeName) {
171
+ return;
172
+ }
173
+
245
174
  const entry = fieldPathChecklist.get(requestFieldPath);
246
175
  const checklistValues = entry ? entry : [];
176
+
247
177
  if (checklistValues.some(({
248
178
  typeName
249
- }) => typeName === dataTypeName)) return;
179
+ }) => typeName === dataTypeName)) {
180
+ return;
181
+ }
182
+
250
183
  fieldPathChecklist.set(requestFieldPath, [...checklistValues, {
184
+ fragmentKind,
185
+ fragmentName,
251
186
  hasData: !_isUndefined(data),
252
187
  typeName: dataTypeName
253
188
  }]);
@@ -294,23 +229,33 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
294
229
  return Promise.reject(new TypeError("@graphql-box/cache-manager expected an AST."));
295
230
  }
296
231
 
297
- const cachedResponseData = await this._getCachedResponseData(requestData, options, context);
232
+ const cacheManagerContext = { ...context,
233
+ fragmentDefinitions: getFragmentDefinitions(ast),
234
+ typeIDKey: this._typeIDKey
235
+ };
236
+ const cachedResponseData = await this._retrieveCachedResponseData(requestData, options, cacheManagerContext);
298
237
  const {
299
238
  cacheMetadata,
300
239
  data,
301
240
  fieldCount
302
241
  } = cachedResponseData;
303
- if (fieldCount.missing === fieldCount.total) return {
304
- updated: requestData
305
- };
242
+
243
+ if (fieldCount.missing === fieldCount.total) {
244
+ return {
245
+ updated: requestData
246
+ };
247
+ }
306
248
 
307
249
  if (!fieldCount.missing) {
308
250
  const dataCaching = this._setQueryResponseCacheEntry(hash, {
309
251
  cacheMetadata,
310
252
  data
311
- }, options, context);
253
+ }, options, cacheManagerContext);
254
+
255
+ if (options.awaitDataCaching) {
256
+ await dataCaching;
257
+ }
312
258
 
313
- if (options.awaitDataCaching) await dataCaching;
314
259
  return {
315
260
  response: {
316
261
  cacheMetadata,
@@ -322,14 +267,21 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
322
267
  this._setPartialQueryResponse(hash, {
323
268
  cacheMetadata,
324
269
  data
325
- }, options, context);
270
+ }, options, cacheManagerContext);
326
271
 
327
- this._filterQuery(requestData, cachedResponseData, context);
272
+ const filteredAST = filterQuery(requestData, cachedResponseData, cacheManagerContext);
273
+ const {
274
+ fragmentDefinitions,
275
+ typeIDKey,
276
+ ...rest
277
+ } = cacheManagerContext;
278
+
279
+ _assign(context, rest);
328
280
 
329
- const request = print(ast);
281
+ const request = print(filteredAST);
330
282
  return {
331
283
  updated: {
332
- ast,
284
+ ast: filteredAST,
333
285
  hash: hashRequest(request),
334
286
  request
335
287
  }
@@ -342,7 +294,11 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
342
294
 
343
295
  async checkQueryResponseCacheEntry(hash, options, context) {
344
296
  const result = await this._checkCacheEntry(QUERY_RESPONSES, hash, options, context);
345
- if (!result) return false;
297
+
298
+ if (!result) {
299
+ return false;
300
+ }
301
+
346
302
  const {
347
303
  cacheMetadata,
348
304
  data
@@ -358,18 +314,23 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
358
314
  }
359
315
 
360
316
  async resolveQuery(requestData, updatedRequestData, rawResponseData, options, context) {
317
+ const cacheManagerContext = { ...context,
318
+ fragmentDefinitions: getFragmentDefinitions(updatedRequestData.ast),
319
+ typeIDKey: this._typeIDKey
320
+ };
361
321
  const dataCaching = [];
362
322
  const {
363
323
  cacheMetadata,
364
- data
365
- } = await this._resolveRequest(updatedRequestData, rawResponseData, options, context);
324
+ data,
325
+ hasNext
326
+ } = await this._resolveRequest(updatedRequestData, rawResponseData, options, cacheManagerContext);
366
327
  let partialQueryResponse;
367
328
 
368
- if (context.queryFiltered) {
329
+ if (cacheManagerContext.queryFiltered) {
369
330
  dataCaching.push(this._setQueryResponseCacheEntry(updatedRequestData.hash, {
370
331
  cacheMetadata,
371
332
  data
372
- }, options, context));
333
+ }, options, cacheManagerContext));
373
334
  partialQueryResponse = this._getPartialQueryResponse(requestData.hash);
374
335
  }
375
336
 
@@ -380,79 +341,127 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
380
341
  dataCaching.push(this._setQueryResponseCacheEntry(requestData.hash, {
381
342
  cacheMetadata: responseCacheMetadata,
382
343
  data: responseData
383
- }, options, context));
384
- if (options.awaitDataCaching) await Promise.all(dataCaching);
344
+ }, options, cacheManagerContext));
345
+
346
+ if (options.awaitDataCaching) {
347
+ await Promise.all(dataCaching);
348
+ }
349
+
385
350
  return {
386
351
  cacheMetadata: responseCacheMetadata,
387
- data: responseData
352
+ data: responseData,
353
+ hasNext
388
354
  };
389
355
  }
390
356
 
391
357
  async resolveRequest(requestData, rawResponseData, options, context) {
392
- return this._resolveRequest(requestData, rawResponseData, options, context);
358
+ const cacheManagerContext = { ...context,
359
+ fragmentDefinitions: getFragmentDefinitions(requestData.ast),
360
+ typeIDKey: this._typeIDKey
361
+ };
362
+ return this._resolveRequest(requestData, rawResponseData, options, cacheManagerContext);
393
363
  }
394
364
 
395
- async _analyzeField(field, cachedAncestorFieldData, cachedResponseData, options, context) {
396
- if (hasChildFields(field)) {
397
- await this._analyzeParentField(field, cachedAncestorFieldData, cachedResponseData, options, context);
365
+ async _analyzeFieldNode(fieldNode, cachedAncestorFieldData, cachedResponseData, options, context) {
366
+ if (hasChildFields(fieldNode)) {
367
+ await this._analyzeParentFieldNode(fieldNode, cachedAncestorFieldData, cachedResponseData, options, context);
398
368
  } else {
399
- await CacheManager._analyzeLeafField(field, cachedAncestorFieldData, cachedResponseData, options, context);
369
+ await this._analyzeLeafFieldNode(fieldNode, cachedAncestorFieldData, cachedResponseData, options, context);
400
370
  }
401
371
  }
402
372
 
403
- async _analyzeParentField(field, cachedAncestorFieldData, cachedResponseData, options, context) {
404
- const keysAndPaths = CacheManager._getFieldKeysAndPaths(field, cachedAncestorFieldData);
405
-
373
+ async _analyzeLeafFieldNode(fieldNode, cachedAncestorFieldData, cachedResponseData, options, context) {
374
+ const keysAndPaths = buildFieldKeysAndPaths(fieldNode, cachedAncestorFieldData, context);
406
375
  const {
407
376
  hashedRequestFieldCacheKey,
408
377
  propNameOrIndex,
409
- requestFieldCacheKey,
410
378
  requestFieldPath
411
379
  } = keysAndPaths;
412
380
  const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
413
381
  const {
414
- dataEntityData: ancestorDataEntityData,
415
- requestFieldPathData: ancestorRequestFieldPathData,
382
+ entityData,
383
+ fragmentKind,
384
+ fragmentName,
385
+ requestFieldPathData,
416
386
  typeName
417
387
  } = cachedAncestorFieldData;
418
- const cachedFieldData = {
419
- dataEntityData: CacheManager._getFieldDataFromAncestor(ancestorDataEntityData, propNameOrIndex),
420
- requestFieldPathData: CacheManager._getFieldDataFromAncestor(ancestorRequestFieldPathData, propNameOrIndex)
388
+ const typeNamesAndKind = {
389
+ dataTypeName: (entityData === null || entityData === void 0 ? void 0 : entityData.__typename) || (requestFieldPathData === null || requestFieldPathData === void 0 ? void 0 : requestFieldPathData.__typename),
390
+ fieldTypeName: typeName,
391
+ fragmentKind,
392
+ fragmentName
421
393
  };
422
394
 
423
- if (CacheManager._isRequestFieldPath(fieldTypeInfo)) {
424
- await this._setRequestFieldPathData(cachedFieldData, hashedRequestFieldCacheKey, options, context);
425
- }
395
+ if (CacheManager._isNodeRequestFieldPath(fieldTypeInfo)) {
396
+ const {
397
+ cacheability,
398
+ entry
399
+ } = await this._retrieveCachedRequestFieldPathData(hashedRequestFieldCacheKey, options, context);
426
400
 
427
- if (CacheManager._isDataEntity(fieldTypeInfo)) {
428
- await this._setDataEntityData(cachedFieldData, fieldTypeInfo, options, context);
401
+ CacheManager._setCachedResponseData({
402
+ cacheability,
403
+ data: entry
404
+ }, cachedResponseData, keysAndPaths, typeNamesAndKind, options, context);
405
+ } else {
406
+ const cachedFieldData = CacheManager._getFieldDataFromAncestor(entityData, propNameOrIndex) || CacheManager._getFieldDataFromAncestor(requestFieldPathData, propNameOrIndex);
407
+
408
+ CacheManager._setFieldPathChecklist(cachedResponseData.fieldPathChecklist, {
409
+ data: cachedFieldData
410
+ }, requestFieldPath, typeNamesAndKind);
411
+
412
+ CacheManager._setCachedData(cachedResponseData.data, {
413
+ data: cachedFieldData
414
+ }, propNameOrIndex);
429
415
  }
416
+ }
430
417
 
418
+ async _analyzeParentFieldNode(fieldNode, cachedAncestorFieldData, cachedResponseData, options, context) {
419
+ const keysAndPaths = buildFieldKeysAndPaths(fieldNode, cachedAncestorFieldData, context);
420
+ const {
421
+ propNameOrIndex,
422
+ requestFieldCacheKey,
423
+ requestFieldPath
424
+ } = keysAndPaths;
425
+ const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
431
426
  const {
432
427
  cacheability,
433
- dataEntityData,
428
+ data,
429
+ entityData,
434
430
  requestFieldPathData
435
- } = cachedFieldData;
436
- const data = !_isUndefined(requestFieldPathData) || !_isUndefined(dataEntityData) ? this._mergeObjects(requestFieldPathData, dataEntityData) : undefined;
431
+ } = await this._retrieveCachedParentNodeData(cachedAncestorFieldData, keysAndPaths, fieldTypeInfo, options, context);
432
+ const {
433
+ fragmentKind,
434
+ fragmentName,
435
+ typeName
436
+ } = cachedAncestorFieldData;
437
437
 
438
438
  CacheManager._setCachedResponseData({
439
439
  cacheability,
440
440
  data
441
441
  }, cachedResponseData, keysAndPaths, {
442
442
  dataTypeName: _get(data, TYPE_NAME_KEY),
443
- fieldTypeName: typeName
443
+ fieldTypeName: typeName,
444
+ fragmentKind,
445
+ fragmentName
444
446
  }, options, context);
445
447
 
446
- if (!_isObjectLike(data)) return;
448
+ if (!_isObjectLike(data)) {
449
+ return;
450
+ }
451
+
447
452
  const objectLikeData = data;
448
453
  const promises = [];
449
- iterateChildFields(field, objectLikeData, (childField, childTypeName, childIndex) => {
450
- promises.push(this._analyzeField(childField, {
454
+ iterateChildFields(fieldNode, objectLikeData, context.fragmentDefinitions, (childField, childTypeName, childFragmentKind, childFragmentName, childIndex) => {
455
+ promises.push(this._analyzeFieldNode(childField, {
456
+ cacheability,
457
+ entityData,
458
+ fragmentKind: childFragmentKind,
459
+ fragmentName: childFragmentName,
451
460
  index: childIndex,
452
461
  requestFieldCacheKey,
453
462
  requestFieldPath,
454
- typeName: childTypeName,
455
- ...cachedFieldData
463
+ requestFieldPathData,
464
+ typeName: childTypeName
456
465
  }, { ...cachedResponseData,
457
466
  data: cachedResponseData.data[propNameOrIndex]
458
467
  }, options, context));
@@ -473,7 +482,11 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
473
482
 
474
483
  const queryNode = getOperationDefinitions(ast, context.operation)[0];
475
484
  const fieldsAndTypeNames = getChildFields(queryNode);
476
- if (!fieldsAndTypeNames) return cacheMetadata;
485
+
486
+ if (!fieldsAndTypeNames) {
487
+ return cacheMetadata;
488
+ }
489
+
477
490
  fieldsAndTypeNames.forEach(({
478
491
  fieldNode
479
492
  }) => this._setFieldCacheability(fieldNode, {
@@ -488,9 +501,17 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
488
501
  async _checkCacheEntry(cacheType, hash, options, context) {
489
502
  try {
490
503
  const cacheability = await this._hasCacheEntry(cacheType, hash);
491
- if (!cacheability || !CacheManager._isValid(cacheability)) return false;
504
+
505
+ if (!cacheability || !CacheManager._isValid(cacheability)) {
506
+ return false;
507
+ }
508
+
492
509
  const entry = await this._getCacheEntry(cacheType, hash, options, context);
493
- if (!entry) return false;
510
+
511
+ if (_isUndefined(entry)) {
512
+ return false;
513
+ }
514
+
494
515
  return {
495
516
  cacheability,
496
517
  entry
@@ -507,157 +528,18 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
507
528
  operation
508
529
  }) {
509
530
  const cacheMetadata = new Map();
510
-
511
- const cacheControl = headers && headers.get(HEADER_CACHE_CONTROL) || this._fallbackOperationCacheability;
512
-
513
- const cacheability = new Cacheability({
514
- cacheControl
531
+ const cacheability = deriveOpCacheability({
532
+ _cacheMetadata,
533
+ fallback: this._fallbackOperationCacheability,
534
+ headers
515
535
  });
516
536
  cacheMetadata.set(operation, cacheability);
517
- if (_cacheMetadata) rehydrateCacheMetadata(_cacheMetadata, cacheMetadata);
518
- return cacheMetadata;
519
- }
520
-
521
- _filterField(field, fieldPathChecklist, ancestorRequestFieldPath, context) {
522
- const fieldsAndTypeNames = getChildFields(field);
523
- if (!fieldsAndTypeNames) return false;
524
-
525
- for (let i = fieldsAndTypeNames.length - 1; i >= 0; i -= 1) {
526
- const {
527
- fieldNode: childField,
528
- typeName: childTypeName
529
- } = fieldsAndTypeNames[i];
530
- const childFieldName = getName(childField);
531
- if (childFieldName === this._typeIDKey || childFieldName === TYPE_NAME_KEY) continue;
532
-
533
- const {
534
- requestFieldPath
535
- } = CacheManager._getFieldKeysAndPaths(childField, {
536
- requestFieldPath: ancestorRequestFieldPath
537
- });
538
-
539
- const {
540
- hasData,
541
- typeUnused
542
- } = CacheManager._checkFieldPathChecklist(fieldPathChecklist.get(requestFieldPath), childTypeName);
543
-
544
- if (hasData || typeUnused) {
545
- if (!hasChildFields(childField)) {
546
- deleteChildFields(field, childField);
547
- } else if (this._filterField(childField, fieldPathChecklist, requestFieldPath, context)) {
548
- deleteChildFields(field, childField);
549
- }
550
- }
551
- }
552
-
553
- this._filterInlineFragments(field);
554
-
555
- this._filterIDsAndTypeNames(field);
556
-
557
- return !hasChildFields(field);
558
- }
559
-
560
- _filterIDsAndTypeNames(field) {
561
- const fieldsAndTypeNames = getChildFields(field);
562
- if (!fieldsAndTypeNames || fieldsAndTypeNames.length > 3) return false;
563
- const fieldNames = fieldsAndTypeNames.map(({
564
- fieldNode
565
- }) => getName(fieldNode));
566
-
567
- if (fieldNames.length === 2 && fieldNames.every(name => name === this._typeIDKey || name === TYPE_NAME_KEY)) {
568
- deleteChildFields(field, fieldsAndTypeNames.map(({
569
- fieldNode
570
- }) => fieldNode));
571
- return true;
572
- }
573
-
574
- if (fieldNames.length === 1 && fieldNames[0] === this._typeIDKey || fieldNames[0] === TYPE_NAME_KEY) {
575
- const {
576
- fieldNode
577
- } = fieldsAndTypeNames[0];
578
- deleteChildFields(field, fieldNode);
579
- return true;
580
- }
581
-
582
- return false;
583
- }
584
-
585
- _filterInlineFragments(field) {
586
- const inlineFragments = getInlineFragments(field);
587
- let filtered = false;
588
- inlineFragments.forEach(fragment => {
589
- const fieldsAndTypeNames = getChildFields(fragment);
590
-
591
- if (!fieldsAndTypeNames || !fieldsAndTypeNames.length) {
592
- deleteInlineFragments(field, fragment);
593
- filtered = true;
594
- return;
595
- }
596
-
597
- if (fieldsAndTypeNames.length === 1) {
598
- const {
599
- fieldNode
600
- } = fieldsAndTypeNames[0];
601
-
602
- if (getName(fieldNode) === this._typeIDKey) {
603
- deleteInlineFragments(field, fragment);
604
- filtered = true;
605
- }
606
- }
607
- });
608
- return filtered;
609
- }
610
-
611
- _filterQuery({
612
- ast
613
- }, {
614
- fieldPathChecklist
615
- }, context) {
616
- const queryNode = getOperationDefinitions(ast, context.operation)[0];
617
- const fieldsAndTypeNames = getChildFields(queryNode);
618
- if (!fieldsAndTypeNames) return;
619
-
620
- for (let i = fieldsAndTypeNames.length - 1; i >= 0; i -= 1) {
621
- const {
622
- fieldNode
623
- } = fieldsAndTypeNames[i];
624
-
625
- const {
626
- requestFieldPath
627
- } = CacheManager._getFieldKeysAndPaths(fieldNode, {
628
- requestFieldPath: context.operation
629
- });
630
537
 
631
- if (this._filterField(fieldNode, fieldPathChecklist, requestFieldPath, context)) {
632
- deleteChildFields(queryNode, fieldNode);
633
- }
538
+ if (_cacheMetadata) {
539
+ rehydrateCacheMetadata(_cacheMetadata, cacheMetadata);
634
540
  }
635
541
 
636
- context.queryFiltered = true;
637
- }
638
-
639
- async _getCachedResponseData({
640
- ast
641
- }, options, context) {
642
- const cachedResponseData = {
643
- cacheMetadata: new Map(),
644
- data: {},
645
- fieldCount: {
646
- missing: 0,
647
- total: 0
648
- },
649
- fieldPathChecklist: new Map()
650
- };
651
- const queryNode = getOperationDefinitions(ast, context.operation)[0];
652
- const fieldsAndTypeNames = getChildFields(queryNode);
653
- if (!fieldsAndTypeNames) return cachedResponseData;
654
- await Promise.all(fieldsAndTypeNames.map(({
655
- fieldNode
656
- }) => this._analyzeField(fieldNode, {
657
- requestFieldPath: context.operation
658
- }, cachedResponseData, options, context)));
659
- cachedResponseData.fieldCount = CacheManager._countFieldPathChecklist(cachedResponseData.fieldPathChecklist);
660
- return cachedResponseData;
542
+ return cacheMetadata;
661
543
  }
662
544
 
663
545
  async _getCacheEntry(cacheType, hash, _options, _context) {
@@ -677,7 +559,10 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
677
559
  }
678
560
 
679
561
  _getResponseData(responseData, partialQueryResponse) {
680
- if (!partialQueryResponse) return responseData;
562
+ if (!partialQueryResponse) {
563
+ return responseData;
564
+ }
565
+
681
566
  return this._mergeObjects(partialQueryResponse.data, responseData);
682
567
  }
683
568
 
@@ -693,9 +578,18 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
693
578
  isEntity,
694
579
  possibleTypes
695
580
  }) {
696
- if (!_get(fieldData, this._typeIDKey, null)) return false;
697
- if (isEntity) return true;
698
- if (!possibleTypes.length) return false;
581
+ if (!_get(fieldData, this._typeIDKey, null)) {
582
+ return false;
583
+ }
584
+
585
+ if (isEntity) {
586
+ return true;
587
+ }
588
+
589
+ if (!possibleTypes.length) {
590
+ return false;
591
+ }
592
+
699
593
  return possibleTypes.some(type => type.typeName === fieldData.__typename);
700
594
  }
701
595
 
@@ -705,159 +599,288 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
705
599
  });
706
600
  }
707
601
 
708
- async _parseFieldDataEntityAndRequestFieldPathCacheEntryData(field, ancestorKeysAndPaths, {
602
+ async _parseEntityAndRequestFieldPathCacheEntryData(field, ancestorKeysAndPaths, {
709
603
  cacheMetadata,
710
- dataEntityData,
604
+ entityData,
711
605
  requestFieldPathData
712
606
  }, options, context) {
713
- const keysAndPaths = CacheManager._getFieldKeysAndPaths(field, ancestorKeysAndPaths);
714
-
607
+ const keysAndPaths = buildFieldKeysAndPaths(field, ancestorKeysAndPaths, context);
715
608
  const {
716
609
  requestFieldCacheKey,
717
610
  requestFieldPath,
718
611
  responseDataPath
719
612
  } = keysAndPaths;
720
613
 
721
- const fieldData = _get(requestFieldPathData, responseDataPath, null);
614
+ const fieldData = _get(requestFieldPathData, responseDataPath);
722
615
 
723
- if (!_isObjectLike(fieldData)) return;
724
- const objectLikeFieldData = fieldData;
725
- const promises = [];
726
- iterateChildFields(field, objectLikeFieldData, (childField, _typeName, childIndex) => {
727
- promises.push(this._parseFieldDataEntityAndRequestFieldPathCacheEntryData(childField, {
728
- index: childIndex,
729
- requestFieldCacheKey,
730
- requestFieldPath,
731
- responseDataPath
732
- }, {
733
- cacheMetadata,
734
- dataEntityData,
735
- requestFieldPathData
736
- }, options, context));
737
- });
738
- await Promise.all(promises);
739
- await this._setFieldDataEntityAndRequestFieldPathCacheEntry(field, keysAndPaths, {
616
+ const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
617
+
618
+ if (!_isObjectLike(fieldData) && !(fieldTypeInfo !== null && fieldTypeInfo !== void 0 && fieldTypeInfo.hasDirectives)) {
619
+ return;
620
+ }
621
+
622
+ if (_isObjectLike(fieldData)) {
623
+ const promises = [];
624
+ iterateChildFields(field, fieldData, context.fragmentDefinitions, (childField, _typeName, _fragmentKind, _fragmentName, childIndex) => {
625
+ promises.push(this._parseEntityAndRequestFieldPathCacheEntryData(childField, {
626
+ index: childIndex,
627
+ requestFieldCacheKey,
628
+ requestFieldPath,
629
+ responseDataPath
630
+ }, {
631
+ cacheMetadata,
632
+ entityData,
633
+ requestFieldPathData
634
+ }, options, context));
635
+ });
636
+ await Promise.all(promises);
637
+ }
638
+
639
+ await this._setEntityAndRequestFieldPathCacheEntry(field, keysAndPaths, {
740
640
  cacheMetadata,
741
- dataEntityData,
641
+ entityData,
742
642
  requestFieldPathData
743
643
  }, options, context);
744
644
  }
745
645
 
746
646
  async _resolveRequest(requestData, rawResponseData, options, context) {
647
+ const normalizedResponseData = rawResponseData.path ? normalizeResponseData(rawResponseData) : rawResponseData;
747
648
  const dataCaching = [];
748
649
 
749
- const cacheMetadata = this._buildCacheMetadata(requestData, rawResponseData, options, context);
650
+ const cacheMetadata = this._buildCacheMetadata(requestData, normalizedResponseData, options, context);
750
651
 
751
652
  const {
752
- data
753
- } = rawResponseData;
754
- dataCaching.push(this._setDataEntityAndRequestFieldPathCacheEntries(requestData, {
653
+ data,
654
+ hasNext
655
+ } = normalizedResponseData;
656
+ dataCaching.push(this._setEntityAndRequestFieldPathCacheEntries(requestData, {
755
657
  cacheMetadata,
756
- dataEntityData: _cloneDeep(data),
658
+ entityData: _cloneDeep(data),
757
659
  requestFieldPathData: _cloneDeep(data)
758
660
  }, options, context));
759
- if (options.awaitDataCaching) await Promise.all(dataCaching);
661
+
662
+ if (options.awaitDataCaching) {
663
+ await Promise.all(dataCaching);
664
+ }
665
+
760
666
  return {
761
667
  cacheMetadata,
762
- data
668
+ data,
669
+ hasNext
670
+ };
671
+ }
672
+
673
+ async _retrieveCachedEntityData(validTypeIDValue, {
674
+ possibleTypes,
675
+ typeName
676
+ }, options, context) {
677
+ const typeNames = [...possibleTypes.map(type => type.typeName), typeName];
678
+ const checkResults = await Promise.all(typeNames.map(name => this._checkCacheEntry(DATA_ENTITIES, `${name}::${validTypeIDValue}`, options, context)));
679
+ const validResults = checkResults.filter(result => !!result);
680
+ let validResult;
681
+
682
+ if (validResults.length === 1) {
683
+ validResult = validResults[0];
684
+ } else if (validResults.length > 1) {
685
+ validResults.sort(({
686
+ cacheability: a
687
+ }, {
688
+ cacheability: b
689
+ }) => a.metadata.ttl - b.metadata.ttl);
690
+ validResult = {
691
+ cacheability: validResults[0].cacheability,
692
+ entry: validResults.reduce((obj, {
693
+ entry
694
+ }) => this._mergeObjects(obj, entry), {})
695
+ };
696
+ }
697
+
698
+ return validResult || {};
699
+ }
700
+
701
+ async _retrieveCachedParentNodeData({
702
+ entityData: ancestorEntityData,
703
+ requestFieldPathData: ancestorRequestFieldPathData
704
+ }, {
705
+ hashedRequestFieldCacheKey,
706
+ propNameOrIndex
707
+ }, fieldTypeInfo, options, context) {
708
+ var _entityData;
709
+
710
+ let entityData = CacheManager._getFieldDataFromAncestor(ancestorEntityData, propNameOrIndex);
711
+
712
+ let requestFieldPathData = CacheManager._getFieldDataFromAncestor(ancestorRequestFieldPathData, propNameOrIndex);
713
+
714
+ let cacheability;
715
+
716
+ if (CacheManager._isNodeRequestFieldPath(fieldTypeInfo)) {
717
+ const {
718
+ cacheability: entryCacheability,
719
+ entry
720
+ } = await this._retrieveCachedRequestFieldPathData(hashedRequestFieldCacheKey, options, context);
721
+
722
+ if (entry) {
723
+ requestFieldPathData = this._mergeObjects(requestFieldPathData, entry);
724
+ }
725
+
726
+ if (entryCacheability) {
727
+ cacheability = entryCacheability;
728
+ }
729
+ }
730
+
731
+ const validTypeIDValue = getValidTypeIDValue(requestFieldPathData, fieldTypeInfo, this._typeIDKey);
732
+
733
+ if (CacheManager._isNodeEntity(fieldTypeInfo) && validTypeIDValue) {
734
+ var _cacheability;
735
+
736
+ const {
737
+ cacheability: entryCacheability,
738
+ entry
739
+ } = await this._retrieveCachedEntityData(validTypeIDValue, fieldTypeInfo, options, context);
740
+
741
+ if (entry) {
742
+ entityData = this._mergeObjects(entityData, entry);
743
+ }
744
+
745
+ if (entryCacheability && (!cacheability || entryCacheability.metadata.ttl > ((_cacheability = cacheability) === null || _cacheability === void 0 ? void 0 : _cacheability.metadata.ttl))) {
746
+ cacheability = entryCacheability;
747
+ }
748
+ }
749
+
750
+ const data = !_isUndefined(requestFieldPathData) || !_isUndefined(entityData) ? this._mergeObjects(requestFieldPathData, entityData) : (_entityData = entityData) !== null && _entityData !== void 0 ? _entityData : requestFieldPathData;
751
+ return {
752
+ cacheability,
753
+ data,
754
+ entityData,
755
+ requestFieldPathData
763
756
  };
764
757
  }
765
758
 
759
+ async _retrieveCachedRequestFieldPathData(hash, options, context) {
760
+ return this._checkCacheEntry(REQUEST_FIELD_PATHS, hash, options, context) || {};
761
+ }
762
+
763
+ async _retrieveCachedResponseData({
764
+ ast
765
+ }, options, context) {
766
+ const cachedResponseData = {
767
+ cacheMetadata: new Map(),
768
+ data: {},
769
+ fieldCount: {
770
+ missing: 0,
771
+ total: 0
772
+ },
773
+ fieldPathChecklist: new Map()
774
+ };
775
+ const queryNode = getOperationDefinitions(ast, context.operation)[0];
776
+ const fieldsAndTypeNames = getChildFields(queryNode);
777
+
778
+ if (!fieldsAndTypeNames) {
779
+ return cachedResponseData;
780
+ }
781
+
782
+ await Promise.all(fieldsAndTypeNames.map(({
783
+ fieldNode
784
+ }) => this._analyzeFieldNode(fieldNode, {
785
+ requestFieldPath: context.operation
786
+ }, cachedResponseData, options, context)));
787
+ cachedResponseData.fieldCount = CacheManager._countFieldPathChecklist(cachedResponseData.fieldPathChecklist);
788
+ return cachedResponseData;
789
+ }
790
+
766
791
  async _setCacheEntry(cacheType, hash, value, cachemapOptions, _options, _context) {
767
792
  try {
768
793
  await this._cache.set(`${cacheType}::${hash}`, _cloneDeep(value), cachemapOptions);
769
794
  } catch (error) {}
770
795
  }
771
796
 
772
- async _setDataEntityAndRequestFieldPathCacheEntries(requestData, responseData, options, context) {
797
+ async _setEntityAndRequestFieldPathCacheEntries(requestData, responseData, options, context) {
773
798
  const operationNode = getOperationDefinitions(requestData.ast, context.operation)[0];
774
799
  const fieldsAndTypeNames = getChildFields(operationNode);
775
- if (!fieldsAndTypeNames) return;
800
+
801
+ if (!fieldsAndTypeNames) {
802
+ return;
803
+ }
804
+
776
805
  await Promise.all(fieldsAndTypeNames.map(({
777
806
  fieldNode
778
807
  }) => {
779
- return this._parseFieldDataEntityAndRequestFieldPathCacheEntryData(fieldNode, {
808
+ return this._parseEntityAndRequestFieldPathCacheEntryData(fieldNode, {
780
809
  requestFieldPath: context.operation
781
810
  }, responseData, options, context);
782
811
  }));
783
812
  }
784
813
 
785
- async _setDataEntityCacheEntry({
786
- responseDataPath
787
- }, {
788
- cacheability,
789
- data,
790
- fieldTypeInfo
814
+ async _setEntityAndRequestFieldPathCacheEntry(field, keysAndPaths, {
815
+ cacheMetadata,
816
+ entityData,
817
+ requestFieldPathData
791
818
  }, options, context) {
792
- const hasArgsOrDirectives = fieldTypeInfo.hasArguments || fieldTypeInfo.hasDirectives;
819
+ const {
820
+ requestFieldPath,
821
+ responseDataPath
822
+ } = keysAndPaths;
793
823
 
794
- let fieldData = _get(data, responseDataPath, null);
824
+ const fieldData = _get(entityData, responseDataPath);
795
825
 
796
- const isEntity = this._isFieldEntity(fieldData, fieldTypeInfo);
826
+ const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
827
+ const cacheability = cacheMetadata.get(requestFieldPath);
797
828
 
798
- if (!isEntity && hasArgsOrDirectives) {
799
- _unset(data, responseDataPath);
829
+ if (_isUndefined(fieldData) || !fieldTypeInfo || !cacheability) {
830
+ return;
800
831
  }
801
832
 
802
- if (isEntity) {
803
- const fieldTypeName = fieldTypeInfo.isEntity ? fieldTypeInfo.typeName : fieldData.__typename;
804
- const entityDataKey = `${fieldTypeName}::${fieldData[this._typeIDKey]}`;
805
- const result = await this._checkCacheEntry(DATA_ENTITIES, entityDataKey, options, context);
833
+ const promises = [];
834
+ promises.push(this._setRequestFieldPathCacheEntry(field, keysAndPaths, {
835
+ cacheability,
836
+ data: requestFieldPathData,
837
+ fieldTypeInfo
838
+ }, options, context));
806
839
 
807
- if (result) {
808
- fieldData = this._mergeObjects(result.entry, fieldData);
809
- }
840
+ const isEntity = this._isFieldEntity(fieldData, fieldTypeInfo);
810
841
 
811
- await this._setCacheEntry(DATA_ENTITIES, entityDataKey, fieldData, {
812
- cacheHeaders: {
813
- cacheControl: cacheability.printCacheControl()
814
- },
815
- tag: options.tag
816
- }, options, context);
842
+ if (!isEntity && fieldTypeInfo.hasArguments) {
843
+ _unset(entityData, responseDataPath);
844
+ }
817
845
 
818
- _set(data, responseDataPath, {
819
- __cacheKey: `${DATA_ENTITIES}::${entityDataKey}`
820
- });
846
+ if (isEntity) {
847
+ promises.push(this._setEntityCacheEntry(keysAndPaths, {
848
+ cacheability,
849
+ data: entityData,
850
+ fieldTypeInfo
851
+ }, options, context));
821
852
  }
853
+
854
+ await Promise.all(promises);
822
855
  }
823
856
 
824
- async _setDataEntityData(cachedFieldData, {
825
- possibleTypes,
826
- typeIDValue,
827
- typeName
857
+ async _setEntityCacheEntry({
858
+ responseDataPath
859
+ }, {
860
+ cacheability,
861
+ data,
862
+ fieldTypeInfo
828
863
  }, options, context) {
829
- const requestFieldPathDataIDValue = _isPlainObject(cachedFieldData.requestFieldPathData) ? cachedFieldData.requestFieldPathData[this._typeIDKey] : undefined;
830
- const validTypeIDValue = typeIDValue || requestFieldPathDataIDValue;
831
- if (!validTypeIDValue) return;
832
- const typeNames = [...possibleTypes.map(type => type.typeName), typeName];
833
- const checkResults = await Promise.all(typeNames.map(name => this._checkCacheEntry(DATA_ENTITIES, `${name}::${validTypeIDValue}`, options, context)));
834
- const validResults = checkResults.filter(result => !!result);
835
- let validResult;
864
+ let fieldData = _get(data, responseDataPath);
836
865
 
837
- if (validResults.length === 1) {
838
- validResult = validResults[0];
839
- } else if (validResults.length > 1) {
840
- validResults.sort(({
841
- cacheability: a
842
- }, {
843
- cacheability: b
844
- }) => a.metadata.ttl - b.metadata.ttl);
845
- validResult = {
846
- cacheability: validResults[0].cacheability,
847
- entry: validResults.reduce((obj, {
848
- entry
849
- }) => this._mergeObjects(obj, entry), {})
850
- };
851
- }
866
+ const fieldTypeName = fieldTypeInfo.isEntity ? fieldTypeInfo.typeName : fieldData.__typename;
867
+ const entityDataKey = `${fieldTypeName}::${fieldData[this._typeIDKey]}`;
868
+ const result = await this._checkCacheEntry(DATA_ENTITIES, entityDataKey, options, context);
852
869
 
853
- if (validResult) {
854
- const {
855
- cacheability,
856
- entry
857
- } = validResult;
858
- if (cacheability && !cachedFieldData.cacheability) cachedFieldData.cacheability = cacheability;
859
- if (entry) cachedFieldData.dataEntityData = entry;
870
+ if (result) {
871
+ fieldData = this._mergeObjects(result.entry, fieldData);
860
872
  }
873
+
874
+ await this._setCacheEntry(DATA_ENTITIES, entityDataKey, fieldData, {
875
+ cacheHeaders: {
876
+ cacheControl: cacheability.printCacheControl()
877
+ },
878
+ tag: options.tag
879
+ }, options, context);
880
+
881
+ _set(data, responseDataPath, {
882
+ __cacheKey: `${DATA_ENTITIES}::${entityDataKey}`
883
+ });
861
884
  }
862
885
 
863
886
  _setFieldCacheability(field, ancestorKeysAndPaths, {
@@ -867,59 +890,37 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
867
890
  const {
868
891
  requestFieldPath: ancestorRequestFieldPath
869
892
  } = ancestorKeysAndPaths;
870
-
871
- const keysAndPaths = CacheManager._getFieldKeysAndPaths(field, ancestorKeysAndPaths);
872
-
893
+ const keysAndPaths = buildFieldKeysAndPaths(field, ancestorKeysAndPaths, context);
873
894
  const {
874
895
  requestFieldPath,
875
896
  responseDataPath
876
897
  } = keysAndPaths;
877
898
 
878
- const fieldData = _get(data, responseDataPath, null);
899
+ const fieldData = _get(data, responseDataPath);
879
900
 
880
- if (!_isObjectLike(fieldData)) return;
881
- const objectLikeFieldData = fieldData;
901
+ const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
902
+
903
+ if (!_isObjectLike(fieldData) && !(fieldTypeInfo !== null && fieldTypeInfo !== void 0 && fieldTypeInfo.hasDirectives)) {
904
+ return;
905
+ }
882
906
 
883
907
  this._setFieldTypeCacheDirective(cacheMetadata, {
884
908
  ancestorRequestFieldPath,
885
909
  requestFieldPath
886
910
  }, context);
887
911
 
888
- iterateChildFields(field, objectLikeFieldData, (childField, _typeName, childIndex) => {
889
- this._setFieldCacheability(childField, {
890
- index: childIndex,
891
- requestFieldPath,
892
- responseDataPath
893
- }, {
894
- cacheMetadata,
895
- data
896
- }, options, context);
897
- });
898
- }
899
-
900
- async _setFieldDataEntityAndRequestFieldPathCacheEntry(field, keysAndPaths, {
901
- cacheMetadata,
902
- dataEntityData,
903
- requestFieldPathData
904
- }, options, context) {
905
- const {
906
- requestFieldPath
907
- } = keysAndPaths;
908
- const fieldTypeInfo = context.fieldTypeMap.get(requestFieldPath);
909
- const cacheability = cacheMetadata.get(requestFieldPath);
910
- if (!fieldTypeInfo || !cacheability) return;
911
- const promises = [];
912
- promises.push(this._setRequestFieldPathCacheEntry(field, keysAndPaths, {
913
- cacheability,
914
- data: requestFieldPathData,
915
- fieldTypeInfo
916
- }, options, context));
917
- promises.push(this._setDataEntityCacheEntry(keysAndPaths, {
918
- cacheability,
919
- data: dataEntityData,
920
- fieldTypeInfo
921
- }, options, context));
922
- await Promise.all(promises);
912
+ if (_isObjectLike(fieldData)) {
913
+ iterateChildFields(field, fieldData, context.fragmentDefinitions, (childField, _typeName, _fragmentKind, _fragmentName, childIndex) => {
914
+ this._setFieldCacheability(childField, {
915
+ index: childIndex,
916
+ requestFieldPath,
917
+ responseDataPath
918
+ }, {
919
+ cacheMetadata,
920
+ data
921
+ }, options, context);
922
+ });
923
+ }
923
924
  }
924
925
 
925
926
  _setFieldTypeCacheDirective(cacheMetadata, {
@@ -929,7 +930,10 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
929
930
  fieldTypeMap,
930
931
  operation
931
932
  }) {
932
- if (cacheMetadata.has(requestFieldPath)) return;
933
+ if (cacheMetadata.has(requestFieldPath)) {
934
+ return;
935
+ }
936
+
933
937
  const fieldTypeInfo = fieldTypeMap.get(requestFieldPath);
934
938
 
935
939
  if (fieldTypeInfo && this._typeCacheDirectives[fieldTypeInfo.typeName]) {
@@ -966,24 +970,32 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
966
970
  }, options, context);
967
971
  }
968
972
 
969
- async _setRequestFieldPathCacheEntry(field, {
970
- hashedRequestFieldCacheKey,
971
- responseDataPath
972
- }, {
973
+ async _setRequestFieldPathCacheEntry(field, keysAndPaths, {
973
974
  cacheability,
974
975
  data,
975
976
  fieldTypeInfo
976
977
  }, options, context) {
977
- const hasArgsOrDirectives = fieldTypeInfo.hasArguments || fieldTypeInfo.hasDirectives;
978
+ const {
979
+ hashedRequestFieldCacheKey,
980
+ responseDataPath
981
+ } = keysAndPaths;
978
982
 
979
- let fieldData = _get(data, responseDataPath, null);
983
+ let fieldData = _get(data, responseDataPath);
980
984
 
981
985
  const isEntity = this._isFieldEntity(fieldData, fieldTypeInfo);
982
986
 
987
+ const hasArgsOrDirectives = fieldTypeInfo.hasArguments || fieldTypeInfo.hasDirectives;
988
+
983
989
  if (context.operation === QUERY && (isEntity || hasArgsOrDirectives)) {
990
+ var _field$selectionSet;
991
+
992
+ if (_isPlainObject(fieldData) && (_field$selectionSet = field.selectionSet) !== null && _field$selectionSet !== void 0 && _field$selectionSet.selections) {
993
+ fieldData = filterOutPropsWithArgsOrDirectives(fieldData, field.selectionSet.selections, keysAndPaths, context);
994
+ }
995
+
984
996
  const result = await this._checkCacheEntry(REQUEST_FIELD_PATHS, hashedRequestFieldCacheKey, options, context);
985
997
 
986
- if (result) {
998
+ if (result && _isObjectLike(fieldData)) {
987
999
  fieldData = this._mergeObjects(result.entry, fieldData);
988
1000
  }
989
1001
 
@@ -1006,19 +1018,6 @@ export let CacheManager = (_dec = logCacheQuery(), _dec2 = logCacheEntry(), _dec
1006
1018
  }
1007
1019
  }
1008
1020
 
1009
- async _setRequestFieldPathData(cachedFieldData, hash, options, context) {
1010
- const checkResult = await this._checkCacheEntry(REQUEST_FIELD_PATHS, hash, options, context);
1011
-
1012
- if (checkResult) {
1013
- const {
1014
- cacheability,
1015
- entry
1016
- } = checkResult;
1017
- if (cacheability) cachedFieldData.cacheability = cacheability;
1018
- if (entry) cachedFieldData.requestFieldPathData = entry;
1019
- }
1020
- }
1021
-
1022
1021
  }, (_applyDecoratedDescriptor(_class.prototype, "_getCacheEntry", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "_getCacheEntry"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "_setCacheEntry", [_dec2], Object.getOwnPropertyDescriptor(_class.prototype, "_setCacheEntry"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "_setPartialQueryResponse", [_dec3], Object.getOwnPropertyDescriptor(_class.prototype, "_setPartialQueryResponse"), _class.prototype)), _class));
1023
1022
  export default function init(userOptions) {
1024
1023
  if (!_isPlainObject(userOptions)) {