@graphql-box/cache-manager 5.3.1 → 5.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/production.analysis.txt +45 -36
- package/dist/types/cjs/helpers/cacheTiersEnabled.d.cts +8 -0
- package/dist/types/cjs/helpers/cacheTiersEnabled.d.cts.map +1 -0
- package/dist/types/cjs/main.d.cts +2 -1
- package/dist/types/cjs/main.d.cts.map +1 -1
- package/dist/types/cjs/types.d.cts +10 -0
- package/dist/types/cjs/types.d.cts.map +1 -1
- package/dist/types/esm/helpers/cacheTiersEnabled.d.ts +8 -0
- package/dist/types/esm/helpers/cacheTiersEnabled.d.ts.map +1 -0
- package/dist/types/esm/main.d.ts +2 -1
- package/dist/types/esm/main.d.ts.map +1 -1
- package/dist/types/esm/types.d.ts +10 -0
- package/dist/types/esm/types.d.ts.map +1 -1
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/helpers/cacheTiersEnabled.ts +15 -0
- package/src/main.ts +82 -39
- package/src/types.ts +11 -0
package/package.json
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type CacheTiersEnabled } from '../types.ts';
|
|
2
|
+
|
|
3
|
+
export const allCacheTiersDisabled = ({ entity, queryResponse, requestPath }: CacheTiersEnabled) =>
|
|
4
|
+
!entity && !queryResponse && !requestPath;
|
|
5
|
+
|
|
6
|
+
export const entityCacheTierEnabled = (tiersEnabled: CacheTiersEnabled) => !!tiersEnabled.entity;
|
|
7
|
+
|
|
8
|
+
export const entityOrRequestPathCacheTiersEnabled = ({ entity, requestPath }: CacheTiersEnabled) =>
|
|
9
|
+
!!(entity ?? requestPath);
|
|
10
|
+
|
|
11
|
+
export const queryResponseCacheTierEnabled = (tiersEnabled: CacheTiersEnabled) => !!tiersEnabled.queryResponse;
|
|
12
|
+
|
|
13
|
+
export const requestPathCacheTierEnabled = (tiersEnabled: CacheTiersEnabled) => !!tiersEnabled.requestPath;
|
|
14
|
+
|
|
15
|
+
export const someCacheTiersEnabled = (tiersEnabled: CacheTiersEnabled) => !allCacheTiersDisabled(tiersEnabled);
|
package/src/main.ts
CHANGED
|
@@ -40,6 +40,14 @@ import { assign, get, isEqual, isNumber, isUndefined, set, unset } from 'lodash-
|
|
|
40
40
|
import { CACHE_CONTROL, HEADER_NO_CACHE, METADATA, NO_CACHE } from './constants.ts';
|
|
41
41
|
import { logCacheEntry, logCacheQuery, logPartialCompiled } from './debug/index.ts';
|
|
42
42
|
import { areOnlyPopulatedFieldsTypeIdKeys } from './helpers/areOnlyPopulatedFieldsTypeIdKeys.ts';
|
|
43
|
+
import {
|
|
44
|
+
allCacheTiersDisabled,
|
|
45
|
+
entityCacheTierEnabled,
|
|
46
|
+
entityOrRequestPathCacheTiersEnabled,
|
|
47
|
+
queryResponseCacheTierEnabled,
|
|
48
|
+
requestPathCacheTierEnabled,
|
|
49
|
+
someCacheTiersEnabled,
|
|
50
|
+
} from './helpers/cacheTiersEnabled.ts';
|
|
43
51
|
import { combineDataSets } from './helpers/combineData.ts';
|
|
44
52
|
import { createEntityDataKey } from './helpers/createEntityDataKey.ts';
|
|
45
53
|
import { deriveOpCacheability } from './helpers/deriveOpCacheability.ts';
|
|
@@ -61,6 +69,7 @@ import {
|
|
|
61
69
|
type AncestorKeysAndPaths,
|
|
62
70
|
type CacheManagerContext,
|
|
63
71
|
type CacheManagerDef,
|
|
72
|
+
type CacheTiersEnabled,
|
|
64
73
|
type CachedAncestorFieldData,
|
|
65
74
|
type CachedResponseData,
|
|
66
75
|
type CheckCacheEntryResult,
|
|
@@ -159,7 +168,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
159
168
|
}
|
|
160
169
|
}
|
|
161
170
|
|
|
162
|
-
private static
|
|
171
|
+
private static _setCachedResponseSlice(
|
|
163
172
|
cachedFieldData: MergedCachedFieldData,
|
|
164
173
|
{ cacheMetadata, data, fieldPathChecklist }: CachedResponseData,
|
|
165
174
|
{ propNameOrIndex, requestFieldPath }: KeysAndPaths,
|
|
@@ -223,6 +232,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
223
232
|
}
|
|
224
233
|
|
|
225
234
|
private _cache: Core;
|
|
235
|
+
private _cacheTiersEnabled: CacheTiersEnabled = { entity: true, queryResponse: true, requestPath: true };
|
|
226
236
|
private _cascadeCacheControl: boolean;
|
|
227
237
|
private _fallbackOperationCacheability: string;
|
|
228
238
|
private _partialQueryResponses: PartialQueryResponses = new Map();
|
|
@@ -247,6 +257,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
247
257
|
}
|
|
248
258
|
|
|
249
259
|
this._cache = options.cache;
|
|
260
|
+
this._cacheTiersEnabled = { ...this._cacheTiersEnabled, ...options.cacheTiersEnabled };
|
|
250
261
|
this._cascadeCacheControl = options.cascadeCacheControl ?? false;
|
|
251
262
|
this._fallbackOperationCacheability = options.fallbackOperationCacheability ?? NO_CACHE;
|
|
252
263
|
this._typeCacheDirectives = options.typeCacheDirectives ?? {};
|
|
@@ -258,6 +269,13 @@ export class CacheManager implements CacheManagerDef {
|
|
|
258
269
|
options: RequestOptions,
|
|
259
270
|
context: RequestContext
|
|
260
271
|
): Promise<AnalyzeQueryResult> {
|
|
272
|
+
// the client has already checked the query response cache with
|
|
273
|
+
// `checkQueryResponseCacheEntry`, so at this point the entity and
|
|
274
|
+
// request path caches are the only relevant ones.
|
|
275
|
+
if (!entityOrRequestPathCacheTiersEnabled(this._cacheTiersEnabled)) {
|
|
276
|
+
return { updated: requestData };
|
|
277
|
+
}
|
|
278
|
+
|
|
261
279
|
const { ast, hash } = requestData;
|
|
262
280
|
|
|
263
281
|
const cacheManagerContext: CacheManagerContext = {
|
|
@@ -278,7 +296,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
278
296
|
return { updated: requestData };
|
|
279
297
|
}
|
|
280
298
|
|
|
281
|
-
if (!fieldCount.missing) {
|
|
299
|
+
if (!fieldCount.missing && queryResponseCacheTierEnabled(this._cacheTiersEnabled)) {
|
|
282
300
|
const dataCaching = this._setQueryResponseCacheEntry(hash, { cacheMetadata, data }, options, cacheManagerContext);
|
|
283
301
|
|
|
284
302
|
if (options.awaitDataCaching) {
|
|
@@ -293,7 +311,10 @@ export class CacheManager implements CacheManagerDef {
|
|
|
293
311
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
294
312
|
const { fragmentDefinitions, typeIDKey, ...rest } = cacheManagerContext;
|
|
295
313
|
assign(context, { ...rest, filteredRequest });
|
|
296
|
-
|
|
314
|
+
|
|
315
|
+
if (queryResponseCacheTierEnabled(this._cacheTiersEnabled)) {
|
|
316
|
+
this._setPartialQueryResponse(hash, { cacheMetadata, data }, options, context);
|
|
317
|
+
}
|
|
297
318
|
|
|
298
319
|
return {
|
|
299
320
|
updated: { ast: filteredAST, hash: hashRequest(filteredRequest), request: filteredRequest },
|
|
@@ -341,6 +362,10 @@ export class CacheManager implements CacheManagerDef {
|
|
|
341
362
|
options: RequestOptions,
|
|
342
363
|
context: RequestContext & { requestFieldCacheKey?: string }
|
|
343
364
|
): Promise<CheckCacheEntryResult | false> {
|
|
365
|
+
if (allCacheTiersDisabled(this._cacheTiersEnabled)) {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
|
|
344
369
|
return this._checkCacheEntry(cacheType, hash, options, context);
|
|
345
370
|
}
|
|
346
371
|
|
|
@@ -349,6 +374,10 @@ export class CacheManager implements CacheManagerDef {
|
|
|
349
374
|
options: RequestOptions,
|
|
350
375
|
context: RequestContext
|
|
351
376
|
): Promise<ResponseData | false> {
|
|
377
|
+
if (!queryResponseCacheTierEnabled(this._cacheTiersEnabled)) {
|
|
378
|
+
return false;
|
|
379
|
+
}
|
|
380
|
+
|
|
352
381
|
const result = await this._checkCacheEntry(QUERY_RESPONSES, hash, options, context);
|
|
353
382
|
|
|
354
383
|
if (!result) {
|
|
@@ -364,7 +393,9 @@ export class CacheManager implements CacheManagerDef {
|
|
|
364
393
|
}
|
|
365
394
|
|
|
366
395
|
public deletePartialQueryResponse(hash: string): void {
|
|
367
|
-
this.
|
|
396
|
+
if (queryResponseCacheTierEnabled(this._cacheTiersEnabled)) {
|
|
397
|
+
this._partialQueryResponses.delete(hash);
|
|
398
|
+
}
|
|
368
399
|
}
|
|
369
400
|
|
|
370
401
|
public async setQueryResponseCacheEntry(
|
|
@@ -373,7 +404,9 @@ export class CacheManager implements CacheManagerDef {
|
|
|
373
404
|
options: RequestOptions,
|
|
374
405
|
context: CacheManagerContext
|
|
375
406
|
): Promise<void> {
|
|
376
|
-
|
|
407
|
+
if (queryResponseCacheTierEnabled(this._cacheTiersEnabled)) {
|
|
408
|
+
return this._setQueryResponseCacheEntry(requestData.hash, responseData, options, context);
|
|
409
|
+
}
|
|
377
410
|
}
|
|
378
411
|
|
|
379
412
|
private async _analyzeFieldNode(
|
|
@@ -413,7 +446,20 @@ export class CacheManager implements CacheManagerDef {
|
|
|
413
446
|
fragmentName,
|
|
414
447
|
};
|
|
415
448
|
|
|
416
|
-
if (CacheManager._isNodeRequestFieldPath(fieldTypeInfo)) {
|
|
449
|
+
if (!CacheManager._isNodeRequestFieldPath(fieldTypeInfo)) {
|
|
450
|
+
const cachedFieldData =
|
|
451
|
+
CacheManager._getFieldDataFromAncestor(entityData, propNameOrIndex) ??
|
|
452
|
+
CacheManager._getFieldDataFromAncestor(requestFieldPathData, propNameOrIndex);
|
|
453
|
+
|
|
454
|
+
CacheManager._setFieldPathChecklist(
|
|
455
|
+
cachedResponseData.fieldPathChecklist,
|
|
456
|
+
{ data: cachedFieldData },
|
|
457
|
+
requestFieldPath,
|
|
458
|
+
typenamesAndKind
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
CacheManager._setCachedData(cachedResponseData.data, { data: cachedFieldData }, propNameOrIndex);
|
|
462
|
+
} else if (requestPathCacheTierEnabled(this._cacheTiersEnabled)) {
|
|
417
463
|
const { cacheability, entry } = await this._retrieveCachedRequestFieldPathData(
|
|
418
464
|
hashedRequestFieldCacheKey,
|
|
419
465
|
requestFieldCacheKey,
|
|
@@ -421,7 +467,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
421
467
|
context
|
|
422
468
|
);
|
|
423
469
|
|
|
424
|
-
CacheManager.
|
|
470
|
+
CacheManager._setCachedResponseSlice(
|
|
425
471
|
{ cacheability, data: entry },
|
|
426
472
|
cachedResponseData,
|
|
427
473
|
keysAndPaths,
|
|
@@ -429,19 +475,6 @@ export class CacheManager implements CacheManagerDef {
|
|
|
429
475
|
options,
|
|
430
476
|
context
|
|
431
477
|
);
|
|
432
|
-
} else {
|
|
433
|
-
const cachedFieldData =
|
|
434
|
-
CacheManager._getFieldDataFromAncestor(entityData, propNameOrIndex) ??
|
|
435
|
-
CacheManager._getFieldDataFromAncestor(requestFieldPathData, propNameOrIndex);
|
|
436
|
-
|
|
437
|
-
CacheManager._setFieldPathChecklist(
|
|
438
|
-
cachedResponseData.fieldPathChecklist,
|
|
439
|
-
{ data: cachedFieldData },
|
|
440
|
-
requestFieldPath,
|
|
441
|
-
typenamesAndKind
|
|
442
|
-
);
|
|
443
|
-
|
|
444
|
-
CacheManager._setCachedData(cachedResponseData.data, { data: cachedFieldData }, propNameOrIndex);
|
|
445
478
|
}
|
|
446
479
|
}
|
|
447
480
|
|
|
@@ -466,7 +499,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
466
499
|
|
|
467
500
|
const { fragmentKind, fragmentName, typeName } = cachedAncestorFieldData;
|
|
468
501
|
|
|
469
|
-
CacheManager.
|
|
502
|
+
CacheManager._setCachedResponseSlice(
|
|
470
503
|
{ cacheability, data },
|
|
471
504
|
cachedResponseData,
|
|
472
505
|
keysAndPaths,
|
|
@@ -578,27 +611,29 @@ export class CacheManager implements CacheManagerDef {
|
|
|
578
611
|
|
|
579
612
|
const dataCaching: Promise<void>[] = [];
|
|
580
613
|
|
|
581
|
-
if (responseDataForCaching) {
|
|
614
|
+
if (responseDataForCaching && someCacheTiersEnabled(this._cacheTiersEnabled)) {
|
|
582
615
|
const { data } = responseDataForCaching;
|
|
583
616
|
const cacheMetadata = this._buildCacheMetadata(requestData, responseDataForCaching, options, context);
|
|
584
617
|
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
618
|
+
if (entityOrRequestPathCacheTiersEnabled(this._cacheTiersEnabled)) {
|
|
619
|
+
dataCaching.push(
|
|
620
|
+
this._setEntityAndRequestFieldPathCacheEntries(
|
|
621
|
+
requestData,
|
|
622
|
+
{
|
|
623
|
+
cacheMetadata,
|
|
624
|
+
entityData: structuredClone(data),
|
|
625
|
+
requestFieldPathData: structuredClone(data),
|
|
626
|
+
},
|
|
627
|
+
options,
|
|
628
|
+
context
|
|
629
|
+
)
|
|
630
|
+
);
|
|
631
|
+
}
|
|
597
632
|
|
|
598
633
|
let queryCacheMetadata: CacheMetadata | undefined;
|
|
599
634
|
let queryData: PlainData | undefined;
|
|
600
635
|
|
|
601
|
-
if (context.operation === OperationTypeNode.QUERY) {
|
|
636
|
+
if (context.operation === OperationTypeNode.QUERY && queryResponseCacheTierEnabled(this._cacheTiersEnabled)) {
|
|
602
637
|
let partialQueryResponse: PartialQueryResponse | undefined;
|
|
603
638
|
|
|
604
639
|
if (context.queryFiltered && updatedRequestData) {
|
|
@@ -775,7 +810,11 @@ export class CacheManager implements CacheManagerDef {
|
|
|
775
810
|
const isEntity = isFieldEntity(fieldData, fieldTypeInfo, this._typeIDKey);
|
|
776
811
|
const hasArgsOrDirectives = !!fieldTypeInfo.hasArguments || !!fieldTypeInfo.hasDirectives;
|
|
777
812
|
|
|
778
|
-
if (
|
|
813
|
+
if (
|
|
814
|
+
context.operation === OperationTypeNode.QUERY &&
|
|
815
|
+
(isEntity || hasArgsOrDirectives) &&
|
|
816
|
+
requestPathCacheTierEnabled(this._cacheTiersEnabled)
|
|
817
|
+
) {
|
|
779
818
|
await this._setRequestFieldPathCacheEntry(
|
|
780
819
|
keysAndPaths,
|
|
781
820
|
{
|
|
@@ -798,7 +837,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
798
837
|
}
|
|
799
838
|
}
|
|
800
839
|
|
|
801
|
-
if (isEntity) {
|
|
840
|
+
if (isEntity && entityCacheTierEnabled(this._cacheTiersEnabled)) {
|
|
802
841
|
await this._setEntityCacheEntry(
|
|
803
842
|
{
|
|
804
843
|
cacheability,
|
|
@@ -865,7 +904,7 @@ export class CacheManager implements CacheManagerDef {
|
|
|
865
904
|
let requestFieldPathData = CacheManager._getFieldDataFromAncestor(ancestorRequestFieldPathData, propNameOrIndex);
|
|
866
905
|
let cacheability: Cacheability | undefined;
|
|
867
906
|
|
|
868
|
-
if (CacheManager._isNodeRequestFieldPath(fieldTypeInfo)) {
|
|
907
|
+
if (CacheManager._isNodeRequestFieldPath(fieldTypeInfo) && requestPathCacheTierEnabled(this._cacheTiersEnabled)) {
|
|
869
908
|
const { cacheability: entryCacheability, entry } = await this._retrieveCachedRequestFieldPathData(
|
|
870
909
|
hashedRequestFieldCacheKey,
|
|
871
910
|
requestFieldCacheKey,
|
|
@@ -882,7 +921,11 @@ export class CacheManager implements CacheManagerDef {
|
|
|
882
921
|
|
|
883
922
|
const validTypeIDValue = getValidTypeIdValue(requestFieldPathData, fieldTypeInfo, this._typeIDKey);
|
|
884
923
|
|
|
885
|
-
if (
|
|
924
|
+
if (
|
|
925
|
+
CacheManager._isNodeEntity(fieldTypeInfo) &&
|
|
926
|
+
validTypeIDValue &&
|
|
927
|
+
entityCacheTierEnabled(this._cacheTiersEnabled)
|
|
928
|
+
) {
|
|
886
929
|
const { cacheability: entryCacheability, entry } = await this._retrieveCachedEntityData(
|
|
887
930
|
validTypeIDValue,
|
|
888
931
|
fieldTypeInfo,
|
package/src/types.ts
CHANGED
|
@@ -15,12 +15,23 @@ import {
|
|
|
15
15
|
} from '@graphql-box/core';
|
|
16
16
|
import { type Cacheability } from 'cacheability';
|
|
17
17
|
|
|
18
|
+
export type CacheTiersEnabled = {
|
|
19
|
+
entity?: boolean;
|
|
20
|
+
queryResponse?: boolean;
|
|
21
|
+
requestPath?: boolean;
|
|
22
|
+
};
|
|
23
|
+
|
|
18
24
|
export interface UserOptions {
|
|
19
25
|
/**
|
|
20
26
|
* The cache to use for storing query responses, data entities,
|
|
21
27
|
* and request field paths.
|
|
22
28
|
*/
|
|
23
29
|
cache: Core;
|
|
30
|
+
/**
|
|
31
|
+
* Whether to enable/disable any/all of the three cache tiers
|
|
32
|
+
* the CacheManager uses. All three are enabled by default.
|
|
33
|
+
*/
|
|
34
|
+
cacheTiersEnabled?: CacheTiersEnabled;
|
|
24
35
|
/**
|
|
25
36
|
* Whether to cascade cache control directives down to
|
|
26
37
|
* child nodes if a child node does not have its down
|