@envelop/response-cache 4.0.7 → 4.0.8-alpha-20230220182043-f8ef4f61
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/cjs/plugin.js +54 -57
- package/esm/plugin.js +54 -58
- package/package.json +2 -2
- package/typings/plugin.d.cts +1 -0
- package/typings/plugin.d.ts +1 -0
- package/cjs/cache-document-str.js +0 -26
- package/esm/cache-document-str.js +0 -21
- package/typings/cache-document-str.d.cts +0 -4
- package/typings/cache-document-str.d.ts +0 -4
package/cjs/plugin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useResponseCache = exports.defaultShouldCacheResult = exports.defaultBuildResponseCacheKey = void 0;
|
|
3
|
+
exports.useResponseCache = exports.defaultGetDocumentString = exports.defaultShouldCacheResult = exports.defaultBuildResponseCacheKey = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const core_1 = require("@envelop/core");
|
|
6
6
|
const utils_1 = require("@graphql-tools/utils");
|
|
@@ -8,7 +8,6 @@ const graphql_1 = require("graphql");
|
|
|
8
8
|
const fast_json_stable_stringify_1 = tslib_1.__importDefault(require("fast-json-stable-stringify"));
|
|
9
9
|
const in_memory_cache_js_1 = require("./in-memory-cache.js");
|
|
10
10
|
const hash_sha256_js_1 = require("./hash-sha256.js");
|
|
11
|
-
const cache_document_str_js_1 = require("./cache-document-str.js");
|
|
12
11
|
/**
|
|
13
12
|
* Default function used for building the response cache key.
|
|
14
13
|
* It is exported here for advanced use-cases. E.g. if you want to short circuit and serve responses from the cache on a global level in order to completely by-pass the GraphQL flow.
|
|
@@ -37,53 +36,53 @@ const defaultShouldCacheResult = (params) => {
|
|
|
37
36
|
return true;
|
|
38
37
|
};
|
|
39
38
|
exports.defaultShouldCacheResult = defaultShouldCacheResult;
|
|
40
|
-
function
|
|
39
|
+
function defaultGetDocumentString(executionArgs) {
|
|
40
|
+
return (0, core_1.getDocumentString)(executionArgs.document, graphql_1.print);
|
|
41
|
+
}
|
|
42
|
+
exports.defaultGetDocumentString = defaultGetDocumentString;
|
|
43
|
+
const addTypeNameToDocument = (0, utils_1.memoize1)(function addTypeNameToDocument(document) {
|
|
44
|
+
let documentChanged = false;
|
|
45
|
+
const newDocument = (0, graphql_1.visit)(document, {
|
|
46
|
+
SelectionSet(node) {
|
|
47
|
+
if (!node.selections.some(selection => selection.kind === graphql_1.Kind.FIELD && selection.name.value === '__typename')) {
|
|
48
|
+
documentChanged = true;
|
|
49
|
+
return {
|
|
50
|
+
...node,
|
|
51
|
+
selections: [
|
|
52
|
+
{
|
|
53
|
+
kind: graphql_1.Kind.FIELD,
|
|
54
|
+
name: {
|
|
55
|
+
kind: graphql_1.Kind.NAME,
|
|
56
|
+
value: '__typename',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
...node.selections,
|
|
60
|
+
],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return node;
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
if (documentChanged) {
|
|
67
|
+
return newDocument;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
function useResponseCache({ cache = (0, in_memory_cache_js_1.createInMemoryCache)(), ttl: globalTtl = Infinity, session, enabled, ignoredTypes = [], ttlPerType = {}, ttlPerSchemaCoordinate = {}, idFields = ['id'], invalidateViaMutation = true, buildResponseCacheKey = exports.defaultBuildResponseCacheKey, getDocumentString = defaultGetDocumentString, shouldCacheResult = exports.defaultShouldCacheResult,
|
|
41
71
|
// eslint-disable-next-line dot-notation
|
|
42
72
|
includeExtensionMetadata = typeof process !== 'undefined' ? process.env['NODE_ENV'] === 'development' : false, }) {
|
|
43
73
|
const ignoredTypesMap = new Set(ignoredTypes);
|
|
44
74
|
// never cache Introspections
|
|
45
75
|
ttlPerSchemaCoordinate = { 'Query.__schema': 0, ...ttlPerSchemaCoordinate };
|
|
46
76
|
return {
|
|
47
|
-
onPluginInit({ addPlugin }) {
|
|
48
|
-
if (getDocumentString === cache_document_str_js_1.defaultGetDocumentString) {
|
|
49
|
-
addPlugin((0, cache_document_str_js_1.useCacheDocumentString)());
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
77
|
async onExecute(onExecuteParams) {
|
|
53
|
-
let documentChanged = false;
|
|
54
|
-
const newDocument = (0, graphql_1.visit)(onExecuteParams.args.document, {
|
|
55
|
-
SelectionSet(node) {
|
|
56
|
-
if (!node.selections.some(selection => selection.kind === graphql_1.Kind.FIELD && selection.name.value === '__typename')) {
|
|
57
|
-
documentChanged = true;
|
|
58
|
-
return {
|
|
59
|
-
...node,
|
|
60
|
-
selections: [
|
|
61
|
-
{
|
|
62
|
-
kind: graphql_1.Kind.FIELD,
|
|
63
|
-
name: {
|
|
64
|
-
kind: graphql_1.Kind.NAME,
|
|
65
|
-
value: '__typename',
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
...node.selections,
|
|
69
|
-
],
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
return node;
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
if (documentChanged) {
|
|
76
|
-
onExecuteParams.setExecuteFn(function typeNameAddedExecute() {
|
|
77
|
-
return onExecuteParams.executeFn({
|
|
78
|
-
...onExecuteParams.args,
|
|
79
|
-
document: newDocument,
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
78
|
const identifier = new Map();
|
|
84
79
|
const types = new Set();
|
|
85
80
|
let currentTtl;
|
|
86
81
|
let skip = false;
|
|
82
|
+
onExecuteParams.setExecuteFn(function typeAddedExecuteFn(args) {
|
|
83
|
+
args.document = addTypeNameToDocument(onExecuteParams.args.document);
|
|
84
|
+
return onExecuteParams.executeFn(args);
|
|
85
|
+
});
|
|
87
86
|
const processResult = (result) => (0, utils_1.visitResult)(result, {
|
|
88
87
|
document: onExecuteParams.args.document,
|
|
89
88
|
variables: onExecuteParams.args.variableValues,
|
|
@@ -100,25 +99,23 @@ includeExtensionMetadata = typeof process !== 'undefined' ? process.env['NODE_EN
|
|
|
100
99
|
return val;
|
|
101
100
|
},
|
|
102
101
|
get(_, fieldName) {
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
};
|
|
121
|
-
}
|
|
102
|
+
if (fieldName === '__typename') {
|
|
103
|
+
typenameCalled++;
|
|
104
|
+
}
|
|
105
|
+
if (fieldName === '__leave' &&
|
|
106
|
+
/**
|
|
107
|
+
* The visitResult function is called for each field in the selection set.
|
|
108
|
+
* But visitResult function looks for __typename field visitor even if it is not there in the document
|
|
109
|
+
* So it calls __typename field visitor twice if it is also in the selection set.
|
|
110
|
+
* That's why we need to count the number of times it is called.
|
|
111
|
+
*
|
|
112
|
+
* Default call of __typename https://github.com/ardatan/graphql-tools/blob/master/packages/utils/src/visitResult.ts#L277
|
|
113
|
+
* Call for the field node https://github.com/ardatan/graphql-tools/blob/master/packages/utils/src/visitResult.ts#L272
|
|
114
|
+
*/ typenameCalled < 2) {
|
|
115
|
+
return (root) => {
|
|
116
|
+
delete root.__typename;
|
|
117
|
+
return root;
|
|
118
|
+
};
|
|
122
119
|
}
|
|
123
120
|
if (ignoredTypesMap.has(typename)) {
|
|
124
121
|
skip = true;
|
package/esm/plugin.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { isAsyncIterable } from '@envelop/core';
|
|
2
|
-
import { visitResult } from '@graphql-tools/utils';
|
|
3
|
-
import { visit, TypeInfo, visitWithTypeInfo, getOperationAST, Kind } from 'graphql';
|
|
1
|
+
import { isAsyncIterable, getDocumentString } from '@envelop/core';
|
|
2
|
+
import { memoize1, visitResult } from '@graphql-tools/utils';
|
|
3
|
+
import { visit, TypeInfo, visitWithTypeInfo, getOperationAST, Kind, print, } from 'graphql';
|
|
4
4
|
import jsonStableStringify from 'fast-json-stable-stringify';
|
|
5
5
|
import { createInMemoryCache } from './in-memory-cache.js';
|
|
6
6
|
import { hashSHA256 } from './hash-sha256.js';
|
|
7
|
-
import { defaultGetDocumentString, useCacheDocumentString } from './cache-document-str.js';
|
|
8
7
|
/**
|
|
9
8
|
* Default function used for building the response cache key.
|
|
10
9
|
* It is exported here for advanced use-cases. E.g. if you want to short circuit and serve responses from the cache on a global level in order to completely by-pass the GraphQL flow.
|
|
@@ -31,6 +30,36 @@ export const defaultShouldCacheResult = (params) => {
|
|
|
31
30
|
}
|
|
32
31
|
return true;
|
|
33
32
|
};
|
|
33
|
+
export function defaultGetDocumentString(executionArgs) {
|
|
34
|
+
return getDocumentString(executionArgs.document, print);
|
|
35
|
+
}
|
|
36
|
+
const addTypeNameToDocument = memoize1(function addTypeNameToDocument(document) {
|
|
37
|
+
let documentChanged = false;
|
|
38
|
+
const newDocument = visit(document, {
|
|
39
|
+
SelectionSet(node) {
|
|
40
|
+
if (!node.selections.some(selection => selection.kind === Kind.FIELD && selection.name.value === '__typename')) {
|
|
41
|
+
documentChanged = true;
|
|
42
|
+
return {
|
|
43
|
+
...node,
|
|
44
|
+
selections: [
|
|
45
|
+
{
|
|
46
|
+
kind: Kind.FIELD,
|
|
47
|
+
name: {
|
|
48
|
+
kind: Kind.NAME,
|
|
49
|
+
value: '__typename',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
...node.selections,
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return node;
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
if (documentChanged) {
|
|
60
|
+
return newDocument;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
34
63
|
export function useResponseCache({ cache = createInMemoryCache(), ttl: globalTtl = Infinity, session, enabled, ignoredTypes = [], ttlPerType = {}, ttlPerSchemaCoordinate = {}, idFields = ['id'], invalidateViaMutation = true, buildResponseCacheKey = defaultBuildResponseCacheKey, getDocumentString = defaultGetDocumentString, shouldCacheResult = defaultShouldCacheResult,
|
|
35
64
|
// eslint-disable-next-line dot-notation
|
|
36
65
|
includeExtensionMetadata = typeof process !== 'undefined' ? process.env['NODE_ENV'] === 'development' : false, }) {
|
|
@@ -38,46 +67,15 @@ includeExtensionMetadata = typeof process !== 'undefined' ? process.env['NODE_EN
|
|
|
38
67
|
// never cache Introspections
|
|
39
68
|
ttlPerSchemaCoordinate = { 'Query.__schema': 0, ...ttlPerSchemaCoordinate };
|
|
40
69
|
return {
|
|
41
|
-
onPluginInit({ addPlugin }) {
|
|
42
|
-
if (getDocumentString === defaultGetDocumentString) {
|
|
43
|
-
addPlugin(useCacheDocumentString());
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
70
|
async onExecute(onExecuteParams) {
|
|
47
|
-
let documentChanged = false;
|
|
48
|
-
const newDocument = visit(onExecuteParams.args.document, {
|
|
49
|
-
SelectionSet(node) {
|
|
50
|
-
if (!node.selections.some(selection => selection.kind === Kind.FIELD && selection.name.value === '__typename')) {
|
|
51
|
-
documentChanged = true;
|
|
52
|
-
return {
|
|
53
|
-
...node,
|
|
54
|
-
selections: [
|
|
55
|
-
{
|
|
56
|
-
kind: Kind.FIELD,
|
|
57
|
-
name: {
|
|
58
|
-
kind: Kind.NAME,
|
|
59
|
-
value: '__typename',
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
...node.selections,
|
|
63
|
-
],
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
return node;
|
|
67
|
-
},
|
|
68
|
-
});
|
|
69
|
-
if (documentChanged) {
|
|
70
|
-
onExecuteParams.setExecuteFn(function typeNameAddedExecute() {
|
|
71
|
-
return onExecuteParams.executeFn({
|
|
72
|
-
...onExecuteParams.args,
|
|
73
|
-
document: newDocument,
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
71
|
const identifier = new Map();
|
|
78
72
|
const types = new Set();
|
|
79
73
|
let currentTtl;
|
|
80
74
|
let skip = false;
|
|
75
|
+
onExecuteParams.setExecuteFn(function typeAddedExecuteFn(args) {
|
|
76
|
+
args.document = addTypeNameToDocument(onExecuteParams.args.document);
|
|
77
|
+
return onExecuteParams.executeFn(args);
|
|
78
|
+
});
|
|
81
79
|
const processResult = (result) => visitResult(result, {
|
|
82
80
|
document: onExecuteParams.args.document,
|
|
83
81
|
variables: onExecuteParams.args.variableValues,
|
|
@@ -94,25 +92,23 @@ includeExtensionMetadata = typeof process !== 'undefined' ? process.env['NODE_EN
|
|
|
94
92
|
return val;
|
|
95
93
|
},
|
|
96
94
|
get(_, fieldName) {
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
};
|
|
115
|
-
}
|
|
95
|
+
if (fieldName === '__typename') {
|
|
96
|
+
typenameCalled++;
|
|
97
|
+
}
|
|
98
|
+
if (fieldName === '__leave' &&
|
|
99
|
+
/**
|
|
100
|
+
* The visitResult function is called for each field in the selection set.
|
|
101
|
+
* But visitResult function looks for __typename field visitor even if it is not there in the document
|
|
102
|
+
* So it calls __typename field visitor twice if it is also in the selection set.
|
|
103
|
+
* That's why we need to count the number of times it is called.
|
|
104
|
+
*
|
|
105
|
+
* Default call of __typename https://github.com/ardatan/graphql-tools/blob/master/packages/utils/src/visitResult.ts#L277
|
|
106
|
+
* Call for the field node https://github.com/ardatan/graphql-tools/blob/master/packages/utils/src/visitResult.ts#L272
|
|
107
|
+
*/ typenameCalled < 2) {
|
|
108
|
+
return (root) => {
|
|
109
|
+
delete root.__typename;
|
|
110
|
+
return root;
|
|
111
|
+
};
|
|
116
112
|
}
|
|
117
113
|
if (ignoredTypesMap.has(typename)) {
|
|
118
114
|
skip = true;
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@envelop/response-cache",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.8-alpha-20230220182043-f8ef4f61",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"peerDependencies": {
|
|
6
|
-
"@envelop/core": "
|
|
6
|
+
"@envelop/core": "3.0.7-alpha-20230220182043-f8ef4f61",
|
|
7
7
|
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
package/typings/plugin.d.cts
CHANGED
|
@@ -120,6 +120,7 @@ export declare const defaultBuildResponseCacheKey: BuildResponseCacheKeyFunction
|
|
|
120
120
|
* By default, results with errors (unexpected, EnvelopError, or GraphQLError) are not cached.
|
|
121
121
|
*/
|
|
122
122
|
export declare const defaultShouldCacheResult: ShouldCacheResultFunction;
|
|
123
|
+
export declare function defaultGetDocumentString(executionArgs: ExecutionArgs): string;
|
|
123
124
|
export declare type ResponseCacheExtensions = {
|
|
124
125
|
hit: true;
|
|
125
126
|
} | {
|
package/typings/plugin.d.ts
CHANGED
|
@@ -120,6 +120,7 @@ export declare const defaultBuildResponseCacheKey: BuildResponseCacheKeyFunction
|
|
|
120
120
|
* By default, results with errors (unexpected, EnvelopError, or GraphQLError) are not cached.
|
|
121
121
|
*/
|
|
122
122
|
export declare const defaultShouldCacheResult: ShouldCacheResultFunction;
|
|
123
|
+
export declare function defaultGetDocumentString(executionArgs: ExecutionArgs): string;
|
|
123
124
|
export declare type ResponseCacheExtensions = {
|
|
124
125
|
hit: true;
|
|
125
126
|
} | {
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.defaultGetDocumentString = exports.useCacheDocumentString = void 0;
|
|
4
|
-
const graphql_1 = require("graphql");
|
|
5
|
-
const documentStringByDocument = new WeakMap();
|
|
6
|
-
function useCacheDocumentString() {
|
|
7
|
-
return {
|
|
8
|
-
onParse({ params: { source } }) {
|
|
9
|
-
return function onParseEnd({ result }) {
|
|
10
|
-
if (result != null && !(result instanceof Error)) {
|
|
11
|
-
documentStringByDocument.set(result, source.toString());
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
},
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
exports.useCacheDocumentString = useCacheDocumentString;
|
|
18
|
-
function defaultGetDocumentString(executionArgs) {
|
|
19
|
-
let documentString = documentStringByDocument.get(executionArgs.document);
|
|
20
|
-
if (documentString == null) {
|
|
21
|
-
documentString = (0, graphql_1.print)(executionArgs.document);
|
|
22
|
-
documentStringByDocument.set(executionArgs.document, documentString);
|
|
23
|
-
}
|
|
24
|
-
return documentString;
|
|
25
|
-
}
|
|
26
|
-
exports.defaultGetDocumentString = defaultGetDocumentString;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { print } from 'graphql';
|
|
2
|
-
const documentStringByDocument = new WeakMap();
|
|
3
|
-
export function useCacheDocumentString() {
|
|
4
|
-
return {
|
|
5
|
-
onParse({ params: { source } }) {
|
|
6
|
-
return function onParseEnd({ result }) {
|
|
7
|
-
if (result != null && !(result instanceof Error)) {
|
|
8
|
-
documentStringByDocument.set(result, source.toString());
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
},
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
export function defaultGetDocumentString(executionArgs) {
|
|
15
|
-
let documentString = documentStringByDocument.get(executionArgs.document);
|
|
16
|
-
if (documentString == null) {
|
|
17
|
-
documentString = print(executionArgs.document);
|
|
18
|
-
documentStringByDocument.set(executionArgs.document, documentString);
|
|
19
|
-
}
|
|
20
|
-
return documentString;
|
|
21
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { ExecutionArgs } from 'graphql';
|
|
2
|
-
import { Plugin } from '@envelop/core';
|
|
3
|
-
export declare function useCacheDocumentString<PluginContext extends Record<string, any> = {}>(): Plugin<PluginContext>;
|
|
4
|
-
export declare function defaultGetDocumentString(executionArgs: ExecutionArgs): string;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { ExecutionArgs } from 'graphql';
|
|
2
|
-
import { Plugin } from '@envelop/core';
|
|
3
|
-
export declare function useCacheDocumentString<PluginContext extends Record<string, any> = {}>(): Plugin<PluginContext>;
|
|
4
|
-
export declare function defaultGetDocumentString(executionArgs: ExecutionArgs): string;
|