@envelop/response-cache 3.0.0-alpha-2869053.0 → 3.0.0-alpha-7c8ceda.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.
- package/cjs/cache.js +2 -0
- package/cjs/hashSHA256.js +66 -0
- package/cjs/in-memory-cache.js +86 -0
- package/cjs/index.js +6 -0
- package/cjs/package.json +1 -0
- package/{index.js → cjs/plugin.js} +27 -177
- package/esm/cache.js +1 -0
- package/esm/hashSHA256.js +62 -0
- package/esm/in-memory-cache.js +80 -0
- package/esm/index.js +3 -0
- package/{index.mjs → esm/plugin.js} +10 -157
- package/package.json +35 -14
- package/{cache.d.ts → typings/cache.d.ts} +0 -0
- package/{hashSHA256.d.ts → typings/hashSHA256.d.ts} +0 -0
- package/{in-memory-cache.d.ts → typings/in-memory-cache.d.ts} +2 -2
- package/typings/index.d.ts +3 -0
- package/{plugin.d.ts → typings/plugin.d.ts} +2 -6
- package/index.d.ts +0 -3
package/cjs/cache.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hashSHA256 = void 0;
|
|
4
|
+
const webCrypto = globalThis.crypto;
|
|
5
|
+
const sha256Browser = (bytes) => {
|
|
6
|
+
const hash = webCrypto.subtle.digest({ name: 'SHA-256' }, bytes);
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
Promise.resolve(hash)
|
|
9
|
+
.then(function (result) {
|
|
10
|
+
resolve(new Uint8Array(result));
|
|
11
|
+
})
|
|
12
|
+
.catch(function (error) {
|
|
13
|
+
reject(error);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
let nodeCrypto;
|
|
18
|
+
if (typeof window === 'undefined' && !webCrypto) {
|
|
19
|
+
// Indirect eval'd require/import to guarantee no side-effects in module scope
|
|
20
|
+
// (optimization for minifier)
|
|
21
|
+
try {
|
|
22
|
+
// eslint-disable-next-line no-new-func
|
|
23
|
+
nodeCrypto = Promise.resolve(new Function('require', 'return require("crypto")')(require));
|
|
24
|
+
}
|
|
25
|
+
catch (_error) {
|
|
26
|
+
try {
|
|
27
|
+
// eslint-disable-next-line no-new-func
|
|
28
|
+
nodeCrypto = new Function('return import("crypto")')();
|
|
29
|
+
}
|
|
30
|
+
catch (_error) { }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const hashSHA256 = async (text) => {
|
|
34
|
+
// Node.js support
|
|
35
|
+
if (nodeCrypto) {
|
|
36
|
+
return nodeCrypto.then(crypto => crypto.createHash('sha256').update(text).digest('hex'));
|
|
37
|
+
}
|
|
38
|
+
if (webCrypto) {
|
|
39
|
+
let buf;
|
|
40
|
+
if (typeof TextEncoder !== 'undefined') {
|
|
41
|
+
buf = new TextEncoder().encode(text);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
buf = new Uint8Array(text.length);
|
|
45
|
+
for (let i = 0, l = text.length; i < l; i++) {
|
|
46
|
+
// NOTE: We assume that the input GraphQL Query only uses UTF-8 at most
|
|
47
|
+
// since GraphQL mostly consists of ASCII, this is completely fine
|
|
48
|
+
buf[i] = text.charCodeAt(i);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const out = await sha256Browser(buf);
|
|
52
|
+
let hash = '';
|
|
53
|
+
for (let i = 0, l = out.length; i < l; i++) {
|
|
54
|
+
const hex = out[i].toString(16);
|
|
55
|
+
hash += '00'.slice(0, Math.max(0, 2 - hex.length)) + hex;
|
|
56
|
+
}
|
|
57
|
+
return hash;
|
|
58
|
+
}
|
|
59
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
60
|
+
// eslint-disable-next-line no-console
|
|
61
|
+
console.warn('[@envelop/response-cache]: The Node Crypto and Web Crypto APIs are not available.\n' +
|
|
62
|
+
'This is an unexpected error. Please report it by filing a GitHub Issue.');
|
|
63
|
+
}
|
|
64
|
+
return Promise.resolve('');
|
|
65
|
+
};
|
|
66
|
+
exports.hashSHA256 = hashSHA256;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultBuildEntityId = exports.createInMemoryCache = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const lru_cache_1 = tslib_1.__importDefault(require("lru-cache"));
|
|
6
|
+
const createInMemoryCache = (params) => {
|
|
7
|
+
var _a;
|
|
8
|
+
const buildEntityId = (_a = params === null || params === void 0 ? void 0 : params.buildEntityId) !== null && _a !== void 0 ? _a : exports.defaultBuildEntityId;
|
|
9
|
+
const cachedResponses = new lru_cache_1.default({
|
|
10
|
+
max: params === null || params === void 0 ? void 0 : params.max,
|
|
11
|
+
stale: false,
|
|
12
|
+
noDisposeOnSet: true,
|
|
13
|
+
dispose(responseId) {
|
|
14
|
+
purgeResponse(responseId, false);
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
const entityToResponseIds = new Map();
|
|
18
|
+
const responseIdToEntityIds = new Map();
|
|
19
|
+
function purgeResponse(responseId, shouldRemove = true) {
|
|
20
|
+
var _a;
|
|
21
|
+
const entityIds = responseIdToEntityIds.get(responseId);
|
|
22
|
+
// get entities related to the response
|
|
23
|
+
if (entityIds !== undefined) {
|
|
24
|
+
for (const entityId of entityIds) {
|
|
25
|
+
// remove the response mapping from the entity
|
|
26
|
+
(_a = entityToResponseIds.get(entityId)) === null || _a === void 0 ? void 0 : _a.delete(responseId);
|
|
27
|
+
}
|
|
28
|
+
// remove all the entity mappings from the response
|
|
29
|
+
responseIdToEntityIds.delete(responseId);
|
|
30
|
+
}
|
|
31
|
+
if (shouldRemove) {
|
|
32
|
+
// remove the response from the cache
|
|
33
|
+
cachedResponses.del(responseId);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function purgeEntity(entity) {
|
|
37
|
+
const responseIds = entityToResponseIds.get(entity);
|
|
38
|
+
if (responseIds !== undefined) {
|
|
39
|
+
for (const responseId of responseIds) {
|
|
40
|
+
purgeResponse(responseId);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
set(responseId, result, collectedEntities, ttl) {
|
|
46
|
+
cachedResponses.set(responseId, result, ttl);
|
|
47
|
+
const entityIds = new Set();
|
|
48
|
+
responseIdToEntityIds.set(responseId, entityIds);
|
|
49
|
+
for (const { typename, id } of collectedEntities) {
|
|
50
|
+
let operationIds = entityToResponseIds.get(typename);
|
|
51
|
+
if (operationIds == null) {
|
|
52
|
+
operationIds = new Set();
|
|
53
|
+
entityToResponseIds.set(typename, operationIds);
|
|
54
|
+
}
|
|
55
|
+
// typename => operation
|
|
56
|
+
operationIds.add(responseId);
|
|
57
|
+
// operation => typename
|
|
58
|
+
entityIds.add(typename);
|
|
59
|
+
if (id !== undefined) {
|
|
60
|
+
const entityId = buildEntityId(typename, id);
|
|
61
|
+
let responseIds = entityToResponseIds.get(entityId);
|
|
62
|
+
if (responseIds == null) {
|
|
63
|
+
responseIds = new Set();
|
|
64
|
+
entityToResponseIds.set(entityId, responseIds);
|
|
65
|
+
}
|
|
66
|
+
// typename:id => operation
|
|
67
|
+
responseIds.add(responseId);
|
|
68
|
+
// operation => typename:id
|
|
69
|
+
entityIds.add(entityId);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
get(responseId) {
|
|
74
|
+
var _a;
|
|
75
|
+
return (_a = cachedResponses.get(responseId)) !== null && _a !== void 0 ? _a : null;
|
|
76
|
+
},
|
|
77
|
+
invalidate(entitiesToRemove) {
|
|
78
|
+
for (const { typename, id } of entitiesToRemove) {
|
|
79
|
+
purgeEntity(id != null ? buildEntityId(typename, id) : typename);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
exports.createInMemoryCache = createInMemoryCache;
|
|
85
|
+
const defaultBuildEntityId = (typename, id) => `${typename}:${id}`;
|
|
86
|
+
exports.defaultBuildEntityId = defaultBuildEntityId;
|
package/cjs/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./in-memory-cache.js"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./plugin.js"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./cache.js"), exports);
|
package/cjs/package.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -1,158 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const jsonStableStringify = _interopDefault(require('fast-json-stable-stringify'));
|
|
12
|
-
|
|
13
|
-
const createInMemoryCache = (params) => {
|
|
14
|
-
var _a;
|
|
15
|
-
const buildEntityId = (_a = params === null || params === void 0 ? void 0 : params.buildEntityId) !== null && _a !== void 0 ? _a : defaultBuildEntityId;
|
|
16
|
-
const cachedResponses = new LRU({
|
|
17
|
-
max: params === null || params === void 0 ? void 0 : params.max,
|
|
18
|
-
stale: false,
|
|
19
|
-
noDisposeOnSet: true,
|
|
20
|
-
dispose(responseId) {
|
|
21
|
-
purgeResponse(responseId, false);
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
const entityToResponseIds = new Map();
|
|
25
|
-
const responseIdToEntityIds = new Map();
|
|
26
|
-
function purgeResponse(responseId, shouldRemove = true) {
|
|
27
|
-
var _a;
|
|
28
|
-
const entityIds = responseIdToEntityIds.get(responseId);
|
|
29
|
-
// get entities related to the response
|
|
30
|
-
if (entityIds !== undefined) {
|
|
31
|
-
for (const entityId of entityIds) {
|
|
32
|
-
// remove the response mapping from the entity
|
|
33
|
-
(_a = entityToResponseIds.get(entityId)) === null || _a === void 0 ? void 0 : _a.delete(responseId);
|
|
34
|
-
}
|
|
35
|
-
// remove all the entity mappings from the response
|
|
36
|
-
responseIdToEntityIds.delete(responseId);
|
|
37
|
-
}
|
|
38
|
-
if (shouldRemove) {
|
|
39
|
-
// remove the response from the cache
|
|
40
|
-
cachedResponses.del(responseId);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
function purgeEntity(entity) {
|
|
44
|
-
const responseIds = entityToResponseIds.get(entity);
|
|
45
|
-
if (responseIds !== undefined) {
|
|
46
|
-
for (const responseId of responseIds) {
|
|
47
|
-
purgeResponse(responseId);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return {
|
|
52
|
-
set(responseId, result, collectedEntities, ttl) {
|
|
53
|
-
cachedResponses.set(responseId, result, ttl);
|
|
54
|
-
const entityIds = new Set();
|
|
55
|
-
responseIdToEntityIds.set(responseId, entityIds);
|
|
56
|
-
for (const { typename, id } of collectedEntities) {
|
|
57
|
-
let operationIds = entityToResponseIds.get(typename);
|
|
58
|
-
if (operationIds == null) {
|
|
59
|
-
operationIds = new Set();
|
|
60
|
-
entityToResponseIds.set(typename, operationIds);
|
|
61
|
-
}
|
|
62
|
-
// typename => operation
|
|
63
|
-
operationIds.add(responseId);
|
|
64
|
-
// operation => typename
|
|
65
|
-
entityIds.add(typename);
|
|
66
|
-
if (id !== undefined) {
|
|
67
|
-
const entityId = buildEntityId(typename, id);
|
|
68
|
-
let responseIds = entityToResponseIds.get(entityId);
|
|
69
|
-
if (responseIds == null) {
|
|
70
|
-
responseIds = new Set();
|
|
71
|
-
entityToResponseIds.set(entityId, responseIds);
|
|
72
|
-
}
|
|
73
|
-
// typename:id => operation
|
|
74
|
-
responseIds.add(responseId);
|
|
75
|
-
// operation => typename:id
|
|
76
|
-
entityIds.add(entityId);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
get(responseId) {
|
|
81
|
-
var _a;
|
|
82
|
-
return (_a = cachedResponses.get(responseId)) !== null && _a !== void 0 ? _a : null;
|
|
83
|
-
},
|
|
84
|
-
invalidate(entitiesToRemove) {
|
|
85
|
-
for (const { typename, id } of entitiesToRemove) {
|
|
86
|
-
purgeEntity(id != null ? buildEntityId(typename, id) : typename);
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
};
|
|
91
|
-
const defaultBuildEntityId = (typename, id) => `${typename}:${id}`;
|
|
92
|
-
|
|
93
|
-
const webCrypto = globalThis.crypto;
|
|
94
|
-
const sha256Browser = (bytes) => {
|
|
95
|
-
const hash = webCrypto.subtle.digest({ name: 'SHA-256' }, bytes);
|
|
96
|
-
return new Promise((resolve, reject) => {
|
|
97
|
-
Promise.resolve(hash)
|
|
98
|
-
.then(function (result) {
|
|
99
|
-
resolve(new Uint8Array(result));
|
|
100
|
-
})
|
|
101
|
-
.catch(function (error) {
|
|
102
|
-
reject(error);
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
};
|
|
106
|
-
let nodeCrypto;
|
|
107
|
-
if (typeof window === 'undefined' && !webCrypto) {
|
|
108
|
-
// Indirect eval'd require/import to guarantee no side-effects in module scope
|
|
109
|
-
// (optimization for minifier)
|
|
110
|
-
try {
|
|
111
|
-
// eslint-disable-next-line no-new-func
|
|
112
|
-
nodeCrypto = Promise.resolve(new Function('require', 'return require("crypto")')(require));
|
|
113
|
-
}
|
|
114
|
-
catch (_error) {
|
|
115
|
-
try {
|
|
116
|
-
// eslint-disable-next-line no-new-func
|
|
117
|
-
nodeCrypto = new Function('return import("crypto")')();
|
|
118
|
-
}
|
|
119
|
-
catch (_error) { }
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
const hashSHA256 = async (text) => {
|
|
123
|
-
// Node.js support
|
|
124
|
-
if (nodeCrypto) {
|
|
125
|
-
return nodeCrypto.then(crypto => crypto.createHash('sha256').update(text).digest('hex'));
|
|
126
|
-
}
|
|
127
|
-
if (webCrypto) {
|
|
128
|
-
let buf;
|
|
129
|
-
if (typeof TextEncoder !== 'undefined') {
|
|
130
|
-
buf = new TextEncoder().encode(text);
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
buf = new Uint8Array(text.length);
|
|
134
|
-
for (let i = 0, l = text.length; i < l; i++) {
|
|
135
|
-
// NOTE: We assume that the input GraphQL Query only uses UTF-8 at most
|
|
136
|
-
// since GraphQL mostly consists of ASCII, this is completely fine
|
|
137
|
-
buf[i] = text.charCodeAt(i);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
const out = await sha256Browser(buf);
|
|
141
|
-
let hash = '';
|
|
142
|
-
for (let i = 0, l = out.length; i < l; i++) {
|
|
143
|
-
const hex = out[i].toString(16);
|
|
144
|
-
hash += '00'.slice(0, Math.max(0, 2 - hex.length)) + hex;
|
|
145
|
-
}
|
|
146
|
-
return hash;
|
|
147
|
-
}
|
|
148
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
149
|
-
// eslint-disable-next-line no-console
|
|
150
|
-
console.warn('[@envelop/response-cache]: The Node Crypto and Web Crypto APIs are not available.\n' +
|
|
151
|
-
'This is an unexpected error. Please report it by filing a GitHub Issue.');
|
|
152
|
-
}
|
|
153
|
-
return Promise.resolve('');
|
|
154
|
-
};
|
|
155
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useResponseCache = exports.defaultGetDocumentString = exports.defaultShouldCacheResult = exports.defaultBuildResponseCacheKey = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const core_1 = require("@envelop/core");
|
|
6
|
+
const utils_1 = require("@graphql-tools/utils");
|
|
7
|
+
const graphql_1 = require("graphql");
|
|
8
|
+
const fast_json_stable_stringify_1 = tslib_1.__importDefault(require("fast-json-stable-stringify"));
|
|
9
|
+
const in_memory_cache_js_1 = require("./in-memory-cache.js");
|
|
10
|
+
const hashSHA256_js_1 = require("./hashSHA256.js");
|
|
156
11
|
const contextSymbol = Symbol('responseCache');
|
|
157
12
|
/**
|
|
158
13
|
* Default function used for building the response cache key.
|
|
@@ -160,13 +15,14 @@ const contextSymbol = Symbol('responseCache');
|
|
|
160
15
|
*/
|
|
161
16
|
const defaultBuildResponseCacheKey = params => {
|
|
162
17
|
var _a, _b, _c;
|
|
163
|
-
return hashSHA256([
|
|
18
|
+
return (0, hashSHA256_js_1.hashSHA256)([
|
|
164
19
|
params.documentString,
|
|
165
20
|
(_a = params.operationName) !== null && _a !== void 0 ? _a : '',
|
|
166
|
-
|
|
21
|
+
(0, fast_json_stable_stringify_1.default)((_b = params.variableValues) !== null && _b !== void 0 ? _b : {}),
|
|
167
22
|
(_c = params.sessionId) !== null && _c !== void 0 ? _c : '',
|
|
168
23
|
].join('|'));
|
|
169
24
|
};
|
|
25
|
+
exports.defaultBuildResponseCacheKey = defaultBuildResponseCacheKey;
|
|
170
26
|
/**
|
|
171
27
|
* Default function used to check if the result should be cached.
|
|
172
28
|
*
|
|
@@ -183,16 +39,18 @@ const defaultShouldCacheResult = (params) => {
|
|
|
183
39
|
}
|
|
184
40
|
return true;
|
|
185
41
|
};
|
|
42
|
+
exports.defaultShouldCacheResult = defaultShouldCacheResult;
|
|
186
43
|
const documentStringByDocument = new WeakMap();
|
|
187
44
|
function defaultGetDocumentString(executionArgs) {
|
|
188
45
|
let documentString = documentStringByDocument.get(executionArgs.document);
|
|
189
46
|
if (!documentString) {
|
|
190
|
-
documentString =
|
|
47
|
+
documentString = (0, graphql_1.print)(executionArgs.document);
|
|
191
48
|
documentStringByDocument.set(executionArgs.document, documentString);
|
|
192
49
|
}
|
|
193
50
|
return documentString;
|
|
194
51
|
}
|
|
195
|
-
|
|
52
|
+
exports.defaultGetDocumentString = defaultGetDocumentString;
|
|
53
|
+
function useResponseCache({ cache = (0, in_memory_cache_js_1.createInMemoryCache)(), ttl: globalTtl = Infinity, session = () => null, enabled, ignoredTypes = [], ttlPerType = {}, ttlPerSchemaCoordinate = {}, idFields = ['id'], invalidateViaMutation = true, buildResponseCacheKey = exports.defaultBuildResponseCacheKey, getDocumentString = defaultGetDocumentString, shouldCacheResult = exports.defaultShouldCacheResult,
|
|
196
54
|
// eslint-disable-next-line dot-notation
|
|
197
55
|
includeExtensionMetadata = typeof process !== 'undefined' ? process.env['NODE_ENV'] === 'development' : false, } = {}) {
|
|
198
56
|
const appliedTransform = Symbol('responseCache.appliedTransform');
|
|
@@ -241,7 +99,7 @@ includeExtensionMetadata = typeof process !== 'undefined' ? process.env['NODE_EN
|
|
|
241
99
|
}
|
|
242
100
|
return {
|
|
243
101
|
onExecuteDone({ result, setResult }) {
|
|
244
|
-
if (
|
|
102
|
+
if ((0, core_1.isAsyncIterable)(result)) {
|
|
245
103
|
// eslint-disable-next-line no-console
|
|
246
104
|
console.warn('[useResponseCache] AsyncIterable returned from execute is currently unsupported.');
|
|
247
105
|
return;
|
|
@@ -261,12 +119,10 @@ includeExtensionMetadata = typeof process !== 'undefined' ? process.env['NODE_EN
|
|
|
261
119
|
},
|
|
262
120
|
};
|
|
263
121
|
}
|
|
264
|
-
const documentString = getDocumentString(ctx.args);
|
|
265
122
|
const operationId = await buildResponseCacheKey({
|
|
266
|
-
documentString,
|
|
267
|
-
variableValues: ctx.args.variableValues,
|
|
268
|
-
operationName: ctx.args.operationName,
|
|
123
|
+
documentString: getDocumentString(ctx.args),
|
|
269
124
|
sessionId: session(ctx.args.contextValue),
|
|
125
|
+
...ctx.args,
|
|
270
126
|
});
|
|
271
127
|
if (((_a = enabled === null || enabled === void 0 ? void 0 : enabled(ctx.args.contextValue)) !== null && _a !== void 0 ? _a : true) === true) {
|
|
272
128
|
const cachedResponse = await cache.get(operationId);
|
|
@@ -288,8 +144,8 @@ includeExtensionMetadata = typeof process !== 'undefined' ? process.env['NODE_EN
|
|
|
288
144
|
}
|
|
289
145
|
}
|
|
290
146
|
if (ttlPerSchemaCoordinate) {
|
|
291
|
-
const typeInfo = new
|
|
292
|
-
|
|
147
|
+
const typeInfo = new graphql_1.TypeInfo(ctx.args.schema);
|
|
148
|
+
(0, graphql_1.visit)(ctx.args.document, (0, graphql_1.visitWithTypeInfo)(typeInfo, {
|
|
293
149
|
Field(fieldNode) {
|
|
294
150
|
const parentType = typeInfo.getParentType();
|
|
295
151
|
if (parentType) {
|
|
@@ -305,7 +161,7 @@ includeExtensionMetadata = typeof process !== 'undefined' ? process.env['NODE_EN
|
|
|
305
161
|
return {
|
|
306
162
|
onExecuteDone({ result, setResult }) {
|
|
307
163
|
var _a;
|
|
308
|
-
if (
|
|
164
|
+
if ((0, core_1.isAsyncIterable)(result)) {
|
|
309
165
|
// eslint-disable-next-line no-console
|
|
310
166
|
console.warn('[useResponseCache] AsyncIterable returned from execute is currently unsupported.');
|
|
311
167
|
return;
|
|
@@ -350,6 +206,7 @@ includeExtensionMetadata = typeof process !== 'undefined' ? process.env['NODE_EN
|
|
|
350
206
|
},
|
|
351
207
|
};
|
|
352
208
|
}
|
|
209
|
+
exports.useResponseCache = useResponseCache;
|
|
353
210
|
function isOperationDefinition(node) {
|
|
354
211
|
return (node === null || node === void 0 ? void 0 : node.kind) === 'OperationDefinition';
|
|
355
212
|
}
|
|
@@ -371,14 +228,14 @@ function runWith(input, callback) {
|
|
|
371
228
|
}
|
|
372
229
|
}
|
|
373
230
|
function applyResponseCacheLogic(schema, idFieldNames) {
|
|
374
|
-
return
|
|
375
|
-
[
|
|
231
|
+
return (0, utils_1.mapSchema)(schema, {
|
|
232
|
+
[utils_1.MapperKind.OBJECT_FIELD](fieldConfig, fieldName, typename) {
|
|
376
233
|
if (idFieldNames.includes(fieldName)) {
|
|
377
234
|
return {
|
|
378
235
|
...fieldConfig,
|
|
379
236
|
resolve(src, args, context, info) {
|
|
380
237
|
var _a;
|
|
381
|
-
const result = ((_a = fieldConfig.resolve) !== null && _a !== void 0 ? _a :
|
|
238
|
+
const result = ((_a = fieldConfig.resolve) !== null && _a !== void 0 ? _a : graphql_1.defaultFieldResolver)(src, args, context, info);
|
|
382
239
|
runWith(result, (id) => {
|
|
383
240
|
const ctx = context[contextSymbol];
|
|
384
241
|
if (ctx !== undefined) {
|
|
@@ -406,10 +263,3 @@ function applyResponseCacheLogic(schema, idFieldNames) {
|
|
|
406
263
|
},
|
|
407
264
|
});
|
|
408
265
|
}
|
|
409
|
-
|
|
410
|
-
exports.createInMemoryCache = createInMemoryCache;
|
|
411
|
-
exports.defaultBuildEntityId = defaultBuildEntityId;
|
|
412
|
-
exports.defaultBuildResponseCacheKey = defaultBuildResponseCacheKey;
|
|
413
|
-
exports.defaultGetDocumentString = defaultGetDocumentString;
|
|
414
|
-
exports.defaultShouldCacheResult = defaultShouldCacheResult;
|
|
415
|
-
exports.useResponseCache = useResponseCache;
|
package/esm/cache.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const webCrypto = globalThis.crypto;
|
|
2
|
+
const sha256Browser = (bytes) => {
|
|
3
|
+
const hash = webCrypto.subtle.digest({ name: 'SHA-256' }, bytes);
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
Promise.resolve(hash)
|
|
6
|
+
.then(function (result) {
|
|
7
|
+
resolve(new Uint8Array(result));
|
|
8
|
+
})
|
|
9
|
+
.catch(function (error) {
|
|
10
|
+
reject(error);
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
let nodeCrypto;
|
|
15
|
+
if (typeof window === 'undefined' && !webCrypto) {
|
|
16
|
+
// Indirect eval'd require/import to guarantee no side-effects in module scope
|
|
17
|
+
// (optimization for minifier)
|
|
18
|
+
try {
|
|
19
|
+
// eslint-disable-next-line no-new-func
|
|
20
|
+
nodeCrypto = Promise.resolve(new Function('require', 'return require("crypto")')(require));
|
|
21
|
+
}
|
|
22
|
+
catch (_error) {
|
|
23
|
+
try {
|
|
24
|
+
// eslint-disable-next-line no-new-func
|
|
25
|
+
nodeCrypto = new Function('return import("crypto")')();
|
|
26
|
+
}
|
|
27
|
+
catch (_error) { }
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export const hashSHA256 = async (text) => {
|
|
31
|
+
// Node.js support
|
|
32
|
+
if (nodeCrypto) {
|
|
33
|
+
return nodeCrypto.then(crypto => crypto.createHash('sha256').update(text).digest('hex'));
|
|
34
|
+
}
|
|
35
|
+
if (webCrypto) {
|
|
36
|
+
let buf;
|
|
37
|
+
if (typeof TextEncoder !== 'undefined') {
|
|
38
|
+
buf = new TextEncoder().encode(text);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
buf = new Uint8Array(text.length);
|
|
42
|
+
for (let i = 0, l = text.length; i < l; i++) {
|
|
43
|
+
// NOTE: We assume that the input GraphQL Query only uses UTF-8 at most
|
|
44
|
+
// since GraphQL mostly consists of ASCII, this is completely fine
|
|
45
|
+
buf[i] = text.charCodeAt(i);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const out = await sha256Browser(buf);
|
|
49
|
+
let hash = '';
|
|
50
|
+
for (let i = 0, l = out.length; i < l; i++) {
|
|
51
|
+
const hex = out[i].toString(16);
|
|
52
|
+
hash += '00'.slice(0, Math.max(0, 2 - hex.length)) + hex;
|
|
53
|
+
}
|
|
54
|
+
return hash;
|
|
55
|
+
}
|
|
56
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
57
|
+
// eslint-disable-next-line no-console
|
|
58
|
+
console.warn('[@envelop/response-cache]: The Node Crypto and Web Crypto APIs are not available.\n' +
|
|
59
|
+
'This is an unexpected error. Please report it by filing a GitHub Issue.');
|
|
60
|
+
}
|
|
61
|
+
return Promise.resolve('');
|
|
62
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import LRU from 'lru-cache';
|
|
2
|
+
export const createInMemoryCache = (params) => {
|
|
3
|
+
var _a;
|
|
4
|
+
const buildEntityId = (_a = params === null || params === void 0 ? void 0 : params.buildEntityId) !== null && _a !== void 0 ? _a : defaultBuildEntityId;
|
|
5
|
+
const cachedResponses = new LRU({
|
|
6
|
+
max: params === null || params === void 0 ? void 0 : params.max,
|
|
7
|
+
stale: false,
|
|
8
|
+
noDisposeOnSet: true,
|
|
9
|
+
dispose(responseId) {
|
|
10
|
+
purgeResponse(responseId, false);
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
const entityToResponseIds = new Map();
|
|
14
|
+
const responseIdToEntityIds = new Map();
|
|
15
|
+
function purgeResponse(responseId, shouldRemove = true) {
|
|
16
|
+
var _a;
|
|
17
|
+
const entityIds = responseIdToEntityIds.get(responseId);
|
|
18
|
+
// get entities related to the response
|
|
19
|
+
if (entityIds !== undefined) {
|
|
20
|
+
for (const entityId of entityIds) {
|
|
21
|
+
// remove the response mapping from the entity
|
|
22
|
+
(_a = entityToResponseIds.get(entityId)) === null || _a === void 0 ? void 0 : _a.delete(responseId);
|
|
23
|
+
}
|
|
24
|
+
// remove all the entity mappings from the response
|
|
25
|
+
responseIdToEntityIds.delete(responseId);
|
|
26
|
+
}
|
|
27
|
+
if (shouldRemove) {
|
|
28
|
+
// remove the response from the cache
|
|
29
|
+
cachedResponses.del(responseId);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function purgeEntity(entity) {
|
|
33
|
+
const responseIds = entityToResponseIds.get(entity);
|
|
34
|
+
if (responseIds !== undefined) {
|
|
35
|
+
for (const responseId of responseIds) {
|
|
36
|
+
purgeResponse(responseId);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
set(responseId, result, collectedEntities, ttl) {
|
|
42
|
+
cachedResponses.set(responseId, result, ttl);
|
|
43
|
+
const entityIds = new Set();
|
|
44
|
+
responseIdToEntityIds.set(responseId, entityIds);
|
|
45
|
+
for (const { typename, id } of collectedEntities) {
|
|
46
|
+
let operationIds = entityToResponseIds.get(typename);
|
|
47
|
+
if (operationIds == null) {
|
|
48
|
+
operationIds = new Set();
|
|
49
|
+
entityToResponseIds.set(typename, operationIds);
|
|
50
|
+
}
|
|
51
|
+
// typename => operation
|
|
52
|
+
operationIds.add(responseId);
|
|
53
|
+
// operation => typename
|
|
54
|
+
entityIds.add(typename);
|
|
55
|
+
if (id !== undefined) {
|
|
56
|
+
const entityId = buildEntityId(typename, id);
|
|
57
|
+
let responseIds = entityToResponseIds.get(entityId);
|
|
58
|
+
if (responseIds == null) {
|
|
59
|
+
responseIds = new Set();
|
|
60
|
+
entityToResponseIds.set(entityId, responseIds);
|
|
61
|
+
}
|
|
62
|
+
// typename:id => operation
|
|
63
|
+
responseIds.add(responseId);
|
|
64
|
+
// operation => typename:id
|
|
65
|
+
entityIds.add(entityId);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
get(responseId) {
|
|
70
|
+
var _a;
|
|
71
|
+
return (_a = cachedResponses.get(responseId)) !== null && _a !== void 0 ? _a : null;
|
|
72
|
+
},
|
|
73
|
+
invalidate(entitiesToRemove) {
|
|
74
|
+
for (const { typename, id } of entitiesToRemove) {
|
|
75
|
+
purgeEntity(id != null ? buildEntityId(typename, id) : typename);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
export const defaultBuildEntityId = (typename, id) => `${typename}:${id}`;
|
package/esm/index.js
ADDED
|
@@ -1,158 +1,15 @@
|
|
|
1
|
-
import LRU from 'lru-cache';
|
|
2
1
|
import { isAsyncIterable } from '@envelop/core';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { MapperKind, mapSchema } from '@graphql-tools/utils';
|
|
3
|
+
import { visit, TypeInfo, visitWithTypeInfo, defaultFieldResolver, print, } from 'graphql';
|
|
5
4
|
import jsonStableStringify from 'fast-json-stable-stringify';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
var _a;
|
|
9
|
-
const buildEntityId = (_a = params === null || params === void 0 ? void 0 : params.buildEntityId) !== null && _a !== void 0 ? _a : defaultBuildEntityId;
|
|
10
|
-
const cachedResponses = new LRU({
|
|
11
|
-
max: params === null || params === void 0 ? void 0 : params.max,
|
|
12
|
-
stale: false,
|
|
13
|
-
noDisposeOnSet: true,
|
|
14
|
-
dispose(responseId) {
|
|
15
|
-
purgeResponse(responseId, false);
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
|
-
const entityToResponseIds = new Map();
|
|
19
|
-
const responseIdToEntityIds = new Map();
|
|
20
|
-
function purgeResponse(responseId, shouldRemove = true) {
|
|
21
|
-
var _a;
|
|
22
|
-
const entityIds = responseIdToEntityIds.get(responseId);
|
|
23
|
-
// get entities related to the response
|
|
24
|
-
if (entityIds !== undefined) {
|
|
25
|
-
for (const entityId of entityIds) {
|
|
26
|
-
// remove the response mapping from the entity
|
|
27
|
-
(_a = entityToResponseIds.get(entityId)) === null || _a === void 0 ? void 0 : _a.delete(responseId);
|
|
28
|
-
}
|
|
29
|
-
// remove all the entity mappings from the response
|
|
30
|
-
responseIdToEntityIds.delete(responseId);
|
|
31
|
-
}
|
|
32
|
-
if (shouldRemove) {
|
|
33
|
-
// remove the response from the cache
|
|
34
|
-
cachedResponses.del(responseId);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
function purgeEntity(entity) {
|
|
38
|
-
const responseIds = entityToResponseIds.get(entity);
|
|
39
|
-
if (responseIds !== undefined) {
|
|
40
|
-
for (const responseId of responseIds) {
|
|
41
|
-
purgeResponse(responseId);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return {
|
|
46
|
-
set(responseId, result, collectedEntities, ttl) {
|
|
47
|
-
cachedResponses.set(responseId, result, ttl);
|
|
48
|
-
const entityIds = new Set();
|
|
49
|
-
responseIdToEntityIds.set(responseId, entityIds);
|
|
50
|
-
for (const { typename, id } of collectedEntities) {
|
|
51
|
-
let operationIds = entityToResponseIds.get(typename);
|
|
52
|
-
if (operationIds == null) {
|
|
53
|
-
operationIds = new Set();
|
|
54
|
-
entityToResponseIds.set(typename, operationIds);
|
|
55
|
-
}
|
|
56
|
-
// typename => operation
|
|
57
|
-
operationIds.add(responseId);
|
|
58
|
-
// operation => typename
|
|
59
|
-
entityIds.add(typename);
|
|
60
|
-
if (id !== undefined) {
|
|
61
|
-
const entityId = buildEntityId(typename, id);
|
|
62
|
-
let responseIds = entityToResponseIds.get(entityId);
|
|
63
|
-
if (responseIds == null) {
|
|
64
|
-
responseIds = new Set();
|
|
65
|
-
entityToResponseIds.set(entityId, responseIds);
|
|
66
|
-
}
|
|
67
|
-
// typename:id => operation
|
|
68
|
-
responseIds.add(responseId);
|
|
69
|
-
// operation => typename:id
|
|
70
|
-
entityIds.add(entityId);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
get(responseId) {
|
|
75
|
-
var _a;
|
|
76
|
-
return (_a = cachedResponses.get(responseId)) !== null && _a !== void 0 ? _a : null;
|
|
77
|
-
},
|
|
78
|
-
invalidate(entitiesToRemove) {
|
|
79
|
-
for (const { typename, id } of entitiesToRemove) {
|
|
80
|
-
purgeEntity(id != null ? buildEntityId(typename, id) : typename);
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
};
|
|
85
|
-
const defaultBuildEntityId = (typename, id) => `${typename}:${id}`;
|
|
86
|
-
|
|
87
|
-
const webCrypto = globalThis.crypto;
|
|
88
|
-
const sha256Browser = (bytes) => {
|
|
89
|
-
const hash = webCrypto.subtle.digest({ name: 'SHA-256' }, bytes);
|
|
90
|
-
return new Promise((resolve, reject) => {
|
|
91
|
-
Promise.resolve(hash)
|
|
92
|
-
.then(function (result) {
|
|
93
|
-
resolve(new Uint8Array(result));
|
|
94
|
-
})
|
|
95
|
-
.catch(function (error) {
|
|
96
|
-
reject(error);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
};
|
|
100
|
-
let nodeCrypto;
|
|
101
|
-
if (typeof window === 'undefined' && !webCrypto) {
|
|
102
|
-
// Indirect eval'd require/import to guarantee no side-effects in module scope
|
|
103
|
-
// (optimization for minifier)
|
|
104
|
-
try {
|
|
105
|
-
// eslint-disable-next-line no-new-func
|
|
106
|
-
nodeCrypto = Promise.resolve(new Function('require', 'return require("crypto")')(require));
|
|
107
|
-
}
|
|
108
|
-
catch (_error) {
|
|
109
|
-
try {
|
|
110
|
-
// eslint-disable-next-line no-new-func
|
|
111
|
-
nodeCrypto = new Function('return import("crypto")')();
|
|
112
|
-
}
|
|
113
|
-
catch (_error) { }
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
const hashSHA256 = async (text) => {
|
|
117
|
-
// Node.js support
|
|
118
|
-
if (nodeCrypto) {
|
|
119
|
-
return nodeCrypto.then(crypto => crypto.createHash('sha256').update(text).digest('hex'));
|
|
120
|
-
}
|
|
121
|
-
if (webCrypto) {
|
|
122
|
-
let buf;
|
|
123
|
-
if (typeof TextEncoder !== 'undefined') {
|
|
124
|
-
buf = new TextEncoder().encode(text);
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
buf = new Uint8Array(text.length);
|
|
128
|
-
for (let i = 0, l = text.length; i < l; i++) {
|
|
129
|
-
// NOTE: We assume that the input GraphQL Query only uses UTF-8 at most
|
|
130
|
-
// since GraphQL mostly consists of ASCII, this is completely fine
|
|
131
|
-
buf[i] = text.charCodeAt(i);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
const out = await sha256Browser(buf);
|
|
135
|
-
let hash = '';
|
|
136
|
-
for (let i = 0, l = out.length; i < l; i++) {
|
|
137
|
-
const hex = out[i].toString(16);
|
|
138
|
-
hash += '00'.slice(0, Math.max(0, 2 - hex.length)) + hex;
|
|
139
|
-
}
|
|
140
|
-
return hash;
|
|
141
|
-
}
|
|
142
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
143
|
-
// eslint-disable-next-line no-console
|
|
144
|
-
console.warn('[@envelop/response-cache]: The Node Crypto and Web Crypto APIs are not available.\n' +
|
|
145
|
-
'This is an unexpected error. Please report it by filing a GitHub Issue.');
|
|
146
|
-
}
|
|
147
|
-
return Promise.resolve('');
|
|
148
|
-
};
|
|
149
|
-
|
|
5
|
+
import { createInMemoryCache } from './in-memory-cache.js';
|
|
6
|
+
import { hashSHA256 } from './hashSHA256.js';
|
|
150
7
|
const contextSymbol = Symbol('responseCache');
|
|
151
8
|
/**
|
|
152
9
|
* Default function used for building the response cache key.
|
|
153
10
|
* 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.
|
|
154
11
|
*/
|
|
155
|
-
const defaultBuildResponseCacheKey = params => {
|
|
12
|
+
export const defaultBuildResponseCacheKey = params => {
|
|
156
13
|
var _a, _b, _c;
|
|
157
14
|
return hashSHA256([
|
|
158
15
|
params.documentString,
|
|
@@ -169,7 +26,7 @@ const defaultBuildResponseCacheKey = params => {
|
|
|
169
26
|
*
|
|
170
27
|
* By default, results with errors (unexpected, EnvelopError, or GraphQLError) are not cached.
|
|
171
28
|
*/
|
|
172
|
-
const defaultShouldCacheResult = (params) => {
|
|
29
|
+
export const defaultShouldCacheResult = (params) => {
|
|
173
30
|
if (params.result.errors) {
|
|
174
31
|
// eslint-disable-next-line no-console
|
|
175
32
|
console.warn('[useResponseCache] Failed to cache due to errors');
|
|
@@ -178,7 +35,7 @@ const defaultShouldCacheResult = (params) => {
|
|
|
178
35
|
return true;
|
|
179
36
|
};
|
|
180
37
|
const documentStringByDocument = new WeakMap();
|
|
181
|
-
function defaultGetDocumentString(executionArgs) {
|
|
38
|
+
export function defaultGetDocumentString(executionArgs) {
|
|
182
39
|
let documentString = documentStringByDocument.get(executionArgs.document);
|
|
183
40
|
if (!documentString) {
|
|
184
41
|
documentString = print(executionArgs.document);
|
|
@@ -186,7 +43,7 @@ function defaultGetDocumentString(executionArgs) {
|
|
|
186
43
|
}
|
|
187
44
|
return documentString;
|
|
188
45
|
}
|
|
189
|
-
function useResponseCache({ cache = createInMemoryCache(), ttl: globalTtl = Infinity, session = () => null, enabled, ignoredTypes = [], ttlPerType = {}, ttlPerSchemaCoordinate = {}, idFields = ['id'], invalidateViaMutation = true, buildResponseCacheKey = defaultBuildResponseCacheKey, getDocumentString = defaultGetDocumentString, shouldCacheResult = defaultShouldCacheResult,
|
|
46
|
+
export function useResponseCache({ cache = createInMemoryCache(), ttl: globalTtl = Infinity, session = () => null, enabled, ignoredTypes = [], ttlPerType = {}, ttlPerSchemaCoordinate = {}, idFields = ['id'], invalidateViaMutation = true, buildResponseCacheKey = defaultBuildResponseCacheKey, getDocumentString = defaultGetDocumentString, shouldCacheResult = defaultShouldCacheResult,
|
|
190
47
|
// eslint-disable-next-line dot-notation
|
|
191
48
|
includeExtensionMetadata = typeof process !== 'undefined' ? process.env['NODE_ENV'] === 'development' : false, } = {}) {
|
|
192
49
|
const appliedTransform = Symbol('responseCache.appliedTransform');
|
|
@@ -255,12 +112,10 @@ includeExtensionMetadata = typeof process !== 'undefined' ? process.env['NODE_EN
|
|
|
255
112
|
},
|
|
256
113
|
};
|
|
257
114
|
}
|
|
258
|
-
const documentString = getDocumentString(ctx.args);
|
|
259
115
|
const operationId = await buildResponseCacheKey({
|
|
260
|
-
documentString,
|
|
261
|
-
variableValues: ctx.args.variableValues,
|
|
262
|
-
operationName: ctx.args.operationName,
|
|
116
|
+
documentString: getDocumentString(ctx.args),
|
|
263
117
|
sessionId: session(ctx.args.contextValue),
|
|
118
|
+
...ctx.args,
|
|
264
119
|
});
|
|
265
120
|
if (((_a = enabled === null || enabled === void 0 ? void 0 : enabled(ctx.args.contextValue)) !== null && _a !== void 0 ? _a : true) === true) {
|
|
266
121
|
const cachedResponse = await cache.get(operationId);
|
|
@@ -400,5 +255,3 @@ function applyResponseCacheLogic(schema, idFieldNames) {
|
|
|
400
255
|
},
|
|
401
256
|
});
|
|
402
257
|
}
|
|
403
|
-
|
|
404
|
-
export { createInMemoryCache, defaultBuildEntityId, defaultBuildResponseCacheKey, defaultGetDocumentString, defaultShouldCacheResult, useResponseCache };
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@envelop/response-cache",
|
|
3
|
-
"version": "3.0.0-alpha-
|
|
3
|
+
"version": "3.0.0-alpha-7c8ceda.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"peerDependencies": {
|
|
6
|
-
"@envelop/core": "^2.
|
|
6
|
+
"@envelop/core": "^2.4.0",
|
|
7
7
|
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@graphql-tools/utils": "^8.
|
|
11
|
-
"
|
|
12
|
-
"
|
|
10
|
+
"@graphql-tools/utils": "^8.8.0",
|
|
11
|
+
"lru-cache": "^6.0.0",
|
|
12
|
+
"fast-json-stable-stringify": "^2.1.0"
|
|
13
13
|
},
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
@@ -18,21 +18,42 @@
|
|
|
18
18
|
},
|
|
19
19
|
"author": "Kamil Kisiela <kamilkisiela@gmail.com>",
|
|
20
20
|
"license": "MIT",
|
|
21
|
-
"main": "index.js",
|
|
22
|
-
"module": "index.
|
|
23
|
-
"typings": "index.d.ts",
|
|
21
|
+
"main": "cjs/index.js",
|
|
22
|
+
"module": "esm/index.js",
|
|
23
|
+
"typings": "typings/index.d.ts",
|
|
24
24
|
"typescript": {
|
|
25
|
-
"definition": "index.d.ts"
|
|
25
|
+
"definition": "typings/index.d.ts"
|
|
26
26
|
},
|
|
27
|
+
"type": "module",
|
|
27
28
|
"exports": {
|
|
28
29
|
".": {
|
|
29
|
-
"require":
|
|
30
|
-
|
|
30
|
+
"require": {
|
|
31
|
+
"types": "./typings/index.d.ts",
|
|
32
|
+
"default": "./cjs/index.js"
|
|
33
|
+
},
|
|
34
|
+
"import": {
|
|
35
|
+
"types": "./typings/index.d.ts",
|
|
36
|
+
"default": "./esm/index.js"
|
|
37
|
+
},
|
|
38
|
+
"default": {
|
|
39
|
+
"types": "./typings/index.d.ts",
|
|
40
|
+
"default": "./esm/index.js"
|
|
41
|
+
}
|
|
31
42
|
},
|
|
32
43
|
"./*": {
|
|
33
|
-
"require":
|
|
34
|
-
|
|
44
|
+
"require": {
|
|
45
|
+
"types": "./typings/*.d.ts",
|
|
46
|
+
"default": "./cjs/*.js"
|
|
47
|
+
},
|
|
48
|
+
"import": {
|
|
49
|
+
"types": "./typings/*.d.ts",
|
|
50
|
+
"default": "./esm/*.js"
|
|
51
|
+
},
|
|
52
|
+
"default": {
|
|
53
|
+
"types": "./typings/*.d.ts",
|
|
54
|
+
"default": "./esm/*.js"
|
|
55
|
+
}
|
|
35
56
|
},
|
|
36
57
|
"./package.json": "./package.json"
|
|
37
58
|
}
|
|
38
|
-
}
|
|
59
|
+
}
|
|
File without changes
|
|
File without changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Cache } from './cache';
|
|
1
|
+
import type { Cache } from './cache.js';
|
|
2
2
|
export declare type BuildEntityId = (typename: string, id: number | string) => string;
|
|
3
3
|
export declare type InMemoryCacheParameter = {
|
|
4
4
|
/**
|
|
@@ -11,5 +11,5 @@ export declare type InMemoryCacheParameter = {
|
|
|
11
11
|
*/
|
|
12
12
|
buildEntityId?: BuildEntityId;
|
|
13
13
|
};
|
|
14
|
-
export declare const createInMemoryCache: (params?: InMemoryCacheParameter
|
|
14
|
+
export declare const createInMemoryCache: (params?: InMemoryCacheParameter) => Cache;
|
|
15
15
|
export declare const defaultBuildEntityId: BuildEntityId;
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
import { Plugin, Maybe } from '@envelop/core';
|
|
2
2
|
import { ExecutionArgs, ExecutionResult } from 'graphql';
|
|
3
|
-
import type { Cache } from './cache';
|
|
3
|
+
import type { Cache } from './cache.js';
|
|
4
4
|
/**
|
|
5
5
|
* Function for building the response cache key based on the input parameters
|
|
6
6
|
*/
|
|
7
7
|
export declare type BuildResponseCacheKeyFunction = (params: {
|
|
8
8
|
/** Raw document string as sent from the client. */
|
|
9
9
|
documentString: string;
|
|
10
|
-
/** Variable values as sent form the client. */
|
|
11
|
-
variableValues: ExecutionArgs['variableValues'];
|
|
12
|
-
/** The name of the GraphQL operation that should be executed from within the document. */
|
|
13
|
-
operationName?: Maybe<string>;
|
|
14
10
|
/** optional sessionId for make unique cache keys based on the session. */
|
|
15
11
|
sessionId?: Maybe<string>;
|
|
16
|
-
}) => Promise<string>;
|
|
12
|
+
} & ExecutionArgs) => Promise<string>;
|
|
17
13
|
export declare type GetDocumentStringFunction = (executionArgs: ExecutionArgs) => string;
|
|
18
14
|
export declare type ShouldCacheResultFunction = (params: {
|
|
19
15
|
result: ExecutionResult;
|
package/index.d.ts
DELETED